Index: frontend/node_modules/webpack/lib/APIPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/APIPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/APIPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,394 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	getExternalModuleNodeCommonjsInitFragment
+} = require("./ExternalModule");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const ConstDependency = require("./dependencies/ConstDependency");
+const ModuleInitFragmentDependency = require("./dependencies/ModuleInitFragmentDependency");
+const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
+const WebpackError = require("./errors/WebpackError");
+const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression");
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+const {
+	evaluateToString,
+	toConstantDependency
+} = require("./javascript/JavascriptParserHelpers");
+const ChunkNameRuntimeModule = require("./runtime/ChunkNameRuntimeModule");
+const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+/**
+ * Returns the replacement definitions used for webpack API identifiers.
+ * @returns {Record<string, { expr: string, req: string[] | null, type?: string, assign: boolean }>} replacements
+ */
+function getReplacements() {
+	return {
+		__webpack_require__: {
+			expr: RuntimeGlobals.require,
+			req: [RuntimeGlobals.require],
+			type: "function",
+			assign: false
+		},
+		__webpack_global__: {
+			expr: RuntimeGlobals.require,
+			req: [RuntimeGlobals.require],
+			type: "function",
+			assign: false
+		},
+		__webpack_public_path__: {
+			expr: RuntimeGlobals.publicPath,
+			req: [RuntimeGlobals.publicPath],
+			type: "string",
+			assign: true
+		},
+		__webpack_base_uri__: {
+			expr: RuntimeGlobals.baseURI,
+			req: [RuntimeGlobals.baseURI],
+			type: "string",
+			assign: true
+		},
+		__webpack_modules__: {
+			expr: RuntimeGlobals.moduleFactories,
+			req: [RuntimeGlobals.moduleFactories],
+			type: "object",
+			assign: false
+		},
+		__webpack_chunk_load__: {
+			expr: RuntimeGlobals.ensureChunk,
+			req: [RuntimeGlobals.ensureChunk],
+			type: "function",
+			assign: true
+		},
+		__non_webpack_require__: {
+			expr: "require",
+			req: null,
+			type: undefined, // type is not known, depends on environment
+			assign: true
+		},
+		__webpack_nonce__: {
+			expr: RuntimeGlobals.scriptNonce,
+			req: [RuntimeGlobals.scriptNonce],
+			type: "string",
+			assign: true
+		},
+		__webpack_hash__: {
+			expr: `${RuntimeGlobals.getFullHash}()`,
+			req: [RuntimeGlobals.getFullHash],
+			type: "string",
+			assign: false
+		},
+		__webpack_chunkname__: {
+			expr: RuntimeGlobals.chunkName,
+			req: [RuntimeGlobals.chunkName],
+			type: "string",
+			assign: false
+		},
+		__webpack_get_script_filename__: {
+			expr: RuntimeGlobals.getChunkScriptFilename,
+			req: [RuntimeGlobals.getChunkScriptFilename],
+			type: "function",
+			assign: true
+		},
+		__webpack_runtime_id__: {
+			expr: RuntimeGlobals.runtimeId,
+			req: [RuntimeGlobals.runtimeId],
+			assign: false
+		},
+		"require.onError": {
+			expr: RuntimeGlobals.uncaughtErrorHandler,
+			req: [RuntimeGlobals.uncaughtErrorHandler],
+			type: undefined, // type is not known, could be function or undefined
+			assign: true // is never a pattern
+		},
+		__system_context__: {
+			expr: RuntimeGlobals.systemContext,
+			req: [RuntimeGlobals.systemContext],
+			type: "object",
+			assign: false
+		},
+		__webpack_share_scopes__: {
+			expr: RuntimeGlobals.shareScopeMap,
+			req: [RuntimeGlobals.shareScopeMap],
+			type: "object",
+			assign: false
+		},
+		__webpack_init_sharing__: {
+			expr: RuntimeGlobals.initializeSharing,
+			req: [RuntimeGlobals.initializeSharing],
+			type: "function",
+			assign: true
+		}
+	};
+}
+
+const PLUGIN_NAME = "APIPlugin";
+
+class APIPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const moduleOutput = compilation.options.output.module;
+				const nodeTarget = compiler.platform.node;
+				const nodeEsm = moduleOutput && nodeTarget;
+
+				const REPLACEMENTS = getReplacements();
+				if (nodeEsm) {
+					REPLACEMENTS.__non_webpack_require__.expr =
+						"__WEBPACK_EXTERNAL_createRequire_require";
+				}
+
+				compilation.dependencyTemplates.set(
+					ConstDependency,
+					new ConstDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					ModuleInitFragmentDependency,
+					new ModuleInitFragmentDependency.Template()
+				);
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.chunkName)
+					.tap(PLUGIN_NAME, (chunk) => {
+						compilation.addRuntimeModule(
+							chunk,
+							new ChunkNameRuntimeModule(/** @type {string} */ (chunk.name))
+						);
+						return true;
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.getFullHash)
+					.tap(PLUGIN_NAME, (chunk, _set) => {
+						compilation.addRuntimeModule(chunk, new GetFullHashRuntimeModule());
+						return true;
+					});
+
+				const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
+
+				hooks.renderModuleContent.tap(
+					PLUGIN_NAME,
+					(source, module, renderContext) => {
+						if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) {
+							const chunkInitFragments = [
+								getExternalModuleNodeCommonjsInitFragment(
+									renderContext.runtimeTemplate
+								)
+							];
+
+							renderContext.chunkInitFragments.push(...chunkInitFragments);
+						}
+
+						return source;
+					}
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 */
+				const handler = (parser) => {
+					parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
+						if (
+							parser.scope.topLevelScope === true &&
+							declarator.id.type === "Identifier" &&
+							declarator.id.name === "module"
+						) {
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).moduleArgument =
+								"__webpack_module__";
+						}
+					});
+
+					parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
+						if (parser.scope.topLevelScope === true) {
+							if (
+								statement.type === "FunctionDeclaration" &&
+								statement.id &&
+								statement.id.name === "module"
+							) {
+								/** @type {BuildInfo} */
+								(parser.state.module.buildInfo).moduleArgument =
+									"__webpack_module__";
+							} else if (
+								statement.type === "ClassDeclaration" &&
+								statement.id &&
+								statement.id.name === "module"
+							) {
+								/** @type {BuildInfo} */
+								(parser.state.module.buildInfo).moduleArgument =
+									"__webpack_module__";
+							}
+						}
+					});
+
+					for (const key of Object.keys(REPLACEMENTS)) {
+						const info = REPLACEMENTS[key];
+						parser.hooks.expression.for(key).tap(PLUGIN_NAME, (expression) => {
+							const dep = toConstantDependency(parser, info.expr, info.req);
+
+							if (key === "__non_webpack_require__" && moduleOutput) {
+								if (nodeTarget) {
+									/** @type {BuildInfo} */
+									(parser.state.module.buildInfo).needCreateRequire = true;
+								} else {
+									const warning = new WebpackError(
+										`${PLUGIN_NAME}\n__non_webpack_require__ is only allowed in target node`
+									);
+									warning.loc = /** @type {DependencyLocation} */ (
+										expression.loc
+									);
+									warning.module = parser.state.module;
+									compilation.warnings.push(warning);
+								}
+							}
+
+							return dep(expression);
+						});
+						if (info.assign === false) {
+							parser.hooks.assign.for(key).tap(PLUGIN_NAME, (expr) => {
+								const err = new WebpackError(`${key} must not be assigned`);
+								err.loc = /** @type {DependencyLocation} */ (expr.loc);
+								throw err;
+							});
+						}
+						if (info.type) {
+							parser.hooks.evaluateTypeof
+								.for(key)
+								.tap(PLUGIN_NAME, evaluateToString(info.type));
+						}
+					}
+
+					parser.hooks.expression
+						.for("__webpack_layer__")
+						.tap(PLUGIN_NAME, (expr) => {
+							const dep = new ConstDependency(
+								JSON.stringify(parser.state.module.layer),
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+					parser.hooks.evaluateIdentifier
+						.for("__webpack_layer__")
+						.tap(PLUGIN_NAME, (expr) =>
+							(parser.state.module.layer === null
+								? new BasicEvaluatedExpression().setNull()
+								: new BasicEvaluatedExpression().setString(
+										parser.state.module.layer
+									)
+							).setRange(/** @type {Range} */ (expr.range))
+						);
+					parser.hooks.evaluateTypeof
+						.for("__webpack_layer__")
+						.tap(PLUGIN_NAME, (expr) =>
+							new BasicEvaluatedExpression()
+								.setString(
+									parser.state.module.layer === null ? "object" : "string"
+								)
+								.setRange(/** @type {Range} */ (expr.range))
+						);
+
+					parser.hooks.expression
+						.for("__webpack_module__.id")
+						.tap(PLUGIN_NAME, (expr) => {
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).moduleConcatenationBailout =
+								"__webpack_module__.id";
+							const moduleArgument = parser.state.module.moduleArgument;
+							if (moduleArgument === "__webpack_module__") {
+								const dep = new RuntimeRequirementsDependency([
+									RuntimeGlobals.moduleId
+								]);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+							} else {
+								const initDep = new ModuleInitFragmentDependency(
+									`var __webpack_internal_module_id__ = ${moduleArgument}.id;\n`,
+									[RuntimeGlobals.moduleId],
+									"__webpack_internal_module_id__"
+								);
+								parser.state.module.addPresentationalDependency(initDep);
+								const dep = new ConstDependency(
+									"__webpack_internal_module_id__",
+									/** @type {Range} */ (expr.range),
+									[]
+								);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+							}
+							return true;
+						});
+
+					parser.hooks.expression
+						.for("__webpack_module__")
+						.tap(PLUGIN_NAME, (expr) => {
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).moduleConcatenationBailout =
+								"__webpack_module__";
+							const moduleArgument = parser.state.module.moduleArgument;
+							if (moduleArgument === "__webpack_module__") {
+								const dep = new RuntimeRequirementsDependency([
+									RuntimeGlobals.module
+								]);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+							} else {
+								const initDep = new ModuleInitFragmentDependency(
+									`var __webpack_internal_module__ = ${moduleArgument};\n`,
+									[RuntimeGlobals.module],
+									"__webpack_internal_module__"
+								);
+								parser.state.module.addPresentationalDependency(initDep);
+								const dep = new ConstDependency(
+									"__webpack_internal_module__",
+									/** @type {Range} */ (expr.range),
+									[]
+								);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+							}
+							return true;
+						});
+					parser.hooks.evaluateTypeof
+						.for("__webpack_module__")
+						.tap(PLUGIN_NAME, evaluateToString("object"));
+				};
+
+				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);
+			}
+		);
+	}
+}
+
+module.exports = APIPlugin;
Index: frontend/node_modules/webpack/lib/AsyncDependenciesBlock.js
===================================================================
--- frontend/node_modules/webpack/lib/AsyncDependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/AsyncDependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,131 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DependenciesBlock = require("./DependenciesBlock");
+const makeSerializable = require("./util/makeSerializable");
+
+/** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+
+/** @typedef {(ChunkGroupOptions & { entryOptions?: EntryOptions } & { circular?: boolean })} GroupOptions */
+
+class AsyncDependenciesBlock extends DependenciesBlock {
+	/**
+	 * @param {GroupOptions | string | null} groupOptions options for the group
+	 * @param {(DependencyLocation | null)=} loc the line of code
+	 * @param {(string | null)=} request the request
+	 */
+	constructor(groupOptions, loc, request) {
+		super();
+		if (typeof groupOptions === "string") {
+			groupOptions = { name: groupOptions };
+		} else if (!groupOptions) {
+			groupOptions = { name: undefined };
+		}
+		if (typeof groupOptions.circular !== "boolean") {
+			// default allow circular references
+			groupOptions.circular = true;
+		}
+		/** @type {GroupOptions} */
+		this.groupOptions = groupOptions;
+		/** @type {DependencyLocation | null | undefined} */
+		this.loc = loc;
+		/** @type {string | null | undefined} */
+		this.request = request;
+		/** @type {undefined | string} */
+		this._stringifiedGroupOptions = undefined;
+	}
+
+	/**
+	 * @returns {ChunkGroupOptions["name"]} The name of the chunk
+	 */
+	get chunkName() {
+		return this.groupOptions.name;
+	}
+
+	/**
+	 * @param {string | undefined} value The new chunk name
+	 * @returns {void}
+	 */
+	set chunkName(value) {
+		if (this.groupOptions.name !== value) {
+			this.groupOptions.name = value;
+			this._stringifiedGroupOptions = undefined;
+		}
+	}
+
+	/**
+	 * @returns {boolean} Whether circular references are allowed
+	 */
+	get circular() {
+		return Boolean(this.groupOptions.circular);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		const { chunkGraph } = context;
+		if (this._stringifiedGroupOptions === undefined) {
+			this._stringifiedGroupOptions = JSON.stringify(this.groupOptions);
+		}
+		const chunkGroup = chunkGraph.getBlockChunkGroup(this);
+		hash.update(
+			`${this._stringifiedGroupOptions}${chunkGroup ? chunkGroup.id : ""}`
+		);
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.groupOptions);
+		write(this.loc);
+		write(this.request);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.groupOptions = read();
+		this.loc = read();
+		this.request = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(AsyncDependenciesBlock, "webpack/lib/AsyncDependenciesBlock");
+
+Object.defineProperty(AsyncDependenciesBlock.prototype, "module", {
+	get() {
+		throw new Error(
+			"module property was removed from AsyncDependenciesBlock (it's not needed)"
+		);
+	},
+	set() {
+		throw new Error(
+			"module property was removed from AsyncDependenciesBlock (it's not needed)"
+		);
+	}
+});
+
+module.exports = AsyncDependenciesBlock;
Index: frontend/node_modules/webpack/lib/AutomaticPrefetchPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/AutomaticPrefetchPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/AutomaticPrefetchPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const NormalModule = require("./NormalModule");
+const PrefetchDependency = require("./dependencies/PrefetchDependency");
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "AutomaticPrefetchPlugin";
+
+/**
+ * Records modules from one compilation and adds them back as prefetch
+ * dependencies in the next compilation.
+ */
+class AutomaticPrefetchPlugin {
+	/**
+	 * Registers hooks that remember previously built normal modules and enqueue
+	 * them as `PrefetchDependency` requests during the next make phase.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					PrefetchDependency,
+					normalModuleFactory
+				);
+			}
+		);
+		/** @type {{ context: string | null, request: string }[] | null} */
+		let lastModules = null;
+		compiler.hooks.afterCompile.tap(PLUGIN_NAME, (compilation) => {
+			lastModules = [];
+
+			for (const m of compilation.modules) {
+				if (m instanceof NormalModule) {
+					lastModules.push({
+						context: m.context,
+						request: m.request
+					});
+				}
+			}
+		});
+		compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
+			if (!lastModules) return callback();
+			asyncLib.each(
+				lastModules,
+				(m, callback) => {
+					compilation.addModuleChain(
+						m.context || compiler.context,
+						new PrefetchDependency(`!!${m.request}`),
+						callback
+					);
+				},
+				(err) => {
+					lastModules = null;
+					callback(err);
+				}
+			);
+		});
+	}
+}
+
+module.exports = AutomaticPrefetchPlugin;
Index: frontend/node_modules/webpack/lib/BannerPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/BannerPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/BannerPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,146 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const Compilation = require("./Compilation");
+const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
+const Template = require("./Template");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
+/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */
+/** @typedef {import("./Compilation").PathDataChunk} PathDataChunk */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Chunk")} Chunk */
+
+/** @typedef {(data: { hash?: string, chunk: Chunk, filename: string }) => string} BannerFunction */
+
+/**
+ * Wraps banner text in a JavaScript block comment, preserving multi-line
+ * formatting and escaping accidental comment terminators.
+ * @param {string} str string to wrap
+ * @returns {string} wrapped string
+ */
+const wrapComment = (str) => {
+	if (!str.includes("\n")) {
+		return Template.toComment(str);
+	}
+	return `/*!\n * ${str
+		.replace(/\*\//g, "* /")
+		.split("\n")
+		.join("\n * ")
+		.replace(/\s+\n/g, "\n")
+		.trimEnd()}\n */`;
+};
+
+const PLUGIN_NAME = "BannerPlugin";
+
+/**
+ * Prepends or appends banner text to emitted assets that match the configured
+ * file filters.
+ */
+class BannerPlugin {
+	/**
+	 * Normalizes banner options and compiles the configured banner source into a
+	 * function that can render per-asset banner text.
+	 * @param {BannerPluginArgument} options options object
+	 */
+	constructor(options) {
+		if (typeof options === "string" || typeof options === "function") {
+			options = {
+				banner: options
+			};
+		}
+
+		/** @type {BannerPluginOptions} */
+		this.options = options;
+
+		const bannerOption = options.banner;
+		if (typeof bannerOption === "function") {
+			const getBanner = bannerOption;
+			/** @type {BannerFunction} */
+			this.banner = this.options.raw
+				? getBanner
+				: /** @type {BannerFunction} */ (data) => wrapComment(getBanner(data));
+		} else {
+			const banner = this.options.raw
+				? bannerOption
+				: wrapComment(bannerOption);
+			/** @type {BannerFunction} */
+			this.banner = () => banner;
+		}
+	}
+
+	/**
+	 * Validates the configured options and injects rendered banner comments into
+	 * matching compilation assets at the configured process-assets stage.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../schemas/plugins/BannerPlugin.json"),
+				this.options,
+				{
+					name: "Banner Plugin",
+					baseDataPath: "options"
+				},
+				(options) => require("../schemas/plugins/BannerPlugin.check")(options)
+			);
+		});
+		const options = this.options;
+		const banner = this.banner;
+		const matchObject = ModuleFilenameHelpers.matchObject.bind(
+			undefined,
+			options
+		);
+		/** @type {WeakMap<Source, { source: ConcatSource, comment: string }>} */
+		const cache = new WeakMap();
+		const stage =
+			this.options.stage || Compilation.PROCESS_ASSETS_STAGE_ADDITIONS;
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => {
+				for (const chunk of compilation.chunks) {
+					if (options.entryOnly && !chunk.canBeInitial()) {
+						continue;
+					}
+
+					for (const file of chunk.files) {
+						if (!matchObject(file)) {
+							continue;
+						}
+
+						/** @type {PathDataChunk} */
+						const data = { chunk, filename: file };
+
+						const comment = compilation.getPath(
+							/** @type {string | import("./TemplatedPathPlugin").TemplatePathFn<PathDataChunk>} */
+							(banner),
+							data
+						);
+
+						compilation.updateAsset(file, (old) => {
+							const cached = cache.get(old);
+							if (!cached || cached.comment !== comment) {
+								const source = options.footer
+									? new ConcatSource(old, "\n", comment)
+									: new ConcatSource(comment, "\n", old);
+								cache.set(old, { source, comment });
+								return source;
+							}
+							return cached.source;
+						});
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = BannerPlugin;
Index: frontend/node_modules/webpack/lib/Cache.js
===================================================================
--- frontend/node_modules/webpack/lib/Cache.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Cache.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,190 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { AsyncParallelHook, AsyncSeriesBailHook, SyncHook } = require("tapable");
+const {
+	makeWebpackError,
+	makeWebpackErrorCallback
+} = require("./errors/HookWebpackError");
+
+/**
+ * Cache validation token whose string representation identifies the build
+ * inputs associated with a cached value.
+ * @typedef {object} Etag
+ * @property {() => string} toString
+ */
+
+/**
+ * Completion callback used by cache operations that either fail with a `Error` or resolve with a typed result.
+ * @template T
+ * @callback CallbackCache
+ * @param {Error | null} err
+ * @param {T=} result
+ * @returns {void}
+ */
+
+/** @typedef {EXPECTED_ANY} Data */
+
+/**
+ * Handler invoked after a cache read succeeds so additional cache layers can
+ * react to the retrieved value.
+ * @template T
+ * @callback GotHandler
+ * @param {T} result
+ * @param {() => void} callback
+ * @returns {void}
+ */
+
+/**
+ * Creates a callback wrapper that waits for a fixed number of completions and
+ * forwards the first error immediately.
+ * @param {number} times times
+ * @param {(err?: Error | null) => void} callback callback
+ * @returns {(err?: Error | null) => void} callback
+ */
+const needCalls = (times, callback) => (err) => {
+	if (--times === 0) {
+		return callback(err);
+	}
+	if (err && times > 0) {
+		times = 0;
+		return callback(err);
+	}
+};
+
+/**
+ * Abstract cache interface backed by tapable hooks for reading, writing, idle
+ * transitions, and shutdown across webpack cache implementations.
+ */
+class Cache {
+	/**
+	 * Initializes the cache lifecycle hooks implemented by cache backends.
+	 */
+	constructor() {
+		this.hooks = {
+			/** @type {AsyncSeriesBailHook<[string, Etag | null, GotHandler<EXPECTED_ANY>[]], Data>} */
+			get: new AsyncSeriesBailHook(["identifier", "etag", "gotHandlers"]),
+			/** @type {AsyncParallelHook<[string, Etag | null, Data]>} */
+			store: new AsyncParallelHook(["identifier", "etag", "data"]),
+			/** @type {AsyncParallelHook<[Iterable<string>]>} */
+			storeBuildDependencies: new AsyncParallelHook(["dependencies"]),
+			/** @type {SyncHook<[]>} */
+			beginIdle: new SyncHook([]),
+			/** @type {AsyncParallelHook<[]>} */
+			endIdle: new AsyncParallelHook([]),
+			/** @type {AsyncParallelHook<[]>} */
+			shutdown: new AsyncParallelHook([])
+		};
+	}
+
+	/**
+	 * Retrieves a cached value and lets registered `gotHandlers` observe the
+	 * result before the caller receives it.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {CallbackCache<T>} callback signals when the value is retrieved
+	 * @returns {void}
+	 */
+	get(identifier, etag, callback) {
+		/** @type {GotHandler<T>[]} */
+		const gotHandlers = [];
+		this.hooks.get.callAsync(identifier, etag, gotHandlers, (err, result) => {
+			if (err) {
+				callback(makeWebpackError(err, "Cache.hooks.get"));
+				return;
+			}
+			if (result === null) {
+				result = undefined;
+			}
+			if (gotHandlers.length > 1) {
+				const innerCallback = needCalls(gotHandlers.length, () =>
+					callback(null, result)
+				);
+				for (const gotHandler of gotHandlers) {
+					gotHandler(result, innerCallback);
+				}
+			} else if (gotHandlers.length === 1) {
+				gotHandlers[0](result, () => callback(null, result));
+			} else {
+				callback(null, result);
+			}
+		});
+	}
+
+	/**
+	 * Stores a cache entry for the identifier and etag through the registered
+	 * cache backend hooks.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {T} data the value to store
+	 * @param {CallbackCache<void>} callback signals when the value is stored
+	 * @returns {void}
+	 */
+	store(identifier, etag, data, callback) {
+		this.hooks.store.callAsync(
+			identifier,
+			etag,
+			data,
+			makeWebpackErrorCallback(callback, "Cache.hooks.store")
+		);
+	}
+
+	/**
+	 * Persists the set of build dependencies required to determine whether the
+	 * cache can be restored in a future compilation.
+	 * @param {Iterable<string>} dependencies list of all build dependencies
+	 * @param {CallbackCache<void>} callback signals when the dependencies are stored
+	 * @returns {void}
+	 */
+	storeBuildDependencies(dependencies, callback) {
+		this.hooks.storeBuildDependencies.callAsync(
+			dependencies,
+			makeWebpackErrorCallback(callback, "Cache.hooks.storeBuildDependencies")
+		);
+	}
+
+	/**
+	 * Signals that webpack is entering an idle phase and cache backends may flush
+	 * or compact pending work.
+	 * @returns {void}
+	 */
+	beginIdle() {
+		this.hooks.beginIdle.call();
+	}
+
+	/**
+	 * Signals that webpack is leaving the idle phase and waits for cache
+	 * backends to finish any asynchronous resume work.
+	 * @param {CallbackCache<void>} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	endIdle(callback) {
+		this.hooks.endIdle.callAsync(
+			makeWebpackErrorCallback(callback, "Cache.hooks.endIdle")
+		);
+	}
+
+	/**
+	 * Shuts down every registered cache backend and waits for cleanup to finish.
+	 * @param {CallbackCache<void>} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	shutdown(callback) {
+		this.hooks.shutdown.callAsync(
+			makeWebpackErrorCallback(callback, "Cache.hooks.shutdown")
+		);
+	}
+}
+
+Cache.STAGE_MEMORY = -10;
+Cache.STAGE_DEFAULT = 0;
+Cache.STAGE_DISK = 10;
+Cache.STAGE_NETWORK = 20;
+
+module.exports = Cache;
Index: frontend/node_modules/webpack/lib/CacheFacade.js
===================================================================
--- frontend/node_modules/webpack/lib/CacheFacade.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/CacheFacade.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,375 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { forEachBail } = require("enhanced-resolve");
+const asyncLib = require("neo-async");
+const getLazyHashedEtag = require("./cache/getLazyHashedEtag");
+const mergeEtags = require("./cache/mergeEtags");
+
+/** @typedef {import("./Cache")} Cache */
+/** @typedef {import("./Cache").Etag} Etag */
+/** @typedef {import("./cache/getLazyHashedEtag").HashableObject} HashableObject */
+/** @typedef {import("./util/Hash").HashFunction} HashFunction */
+
+/**
+ * Defines the callback cache callback.
+ * @template T
+ * @callback CallbackCache
+ * @param {(Error | null)=} err
+ * @param {(T | null)=} result
+ * @returns {void}
+ */
+
+/**
+ * Defines the callback normal error cache callback.
+ * @template T
+ * @callback CallbackNormalErrorCache
+ * @param {(Error | null)=} err
+ * @param {T=} result
+ * @returns {void}
+ */
+
+class MultiItemCache {
+	/**
+	 * Creates an instance of MultiItemCache.
+	 * @param {ItemCacheFacade[]} items item caches
+	 */
+	constructor(items) {
+		this._items = items;
+		// @ts-expect-error expected - returns the single ItemCacheFacade when passed an array of length 1
+		// eslint-disable-next-line no-constructor-return
+		if (items.length === 1) return /** @type {ItemCacheFacade} */ (items[0]);
+	}
+
+	/**
+	 * Returns value.
+	 * @template T
+	 * @param {CallbackCache<T>} callback signals when the value is retrieved
+	 * @returns {void}
+	 */
+	get(callback) {
+		forEachBail(this._items, (item, callback) => item.get(callback), callback);
+	}
+
+	/**
+	 * Returns promise with the data.
+	 * @template T
+	 * @returns {Promise<T>} promise with the data
+	 */
+	getPromise() {
+		/**
+		 * Returns promise with the data.
+		 * @param {number} i index
+		 * @returns {Promise<T>} promise with the data
+		 */
+		const next = (i) =>
+			this._items[i].getPromise().then((result) => {
+				if (result !== undefined) return result;
+				if (++i < this._items.length) return next(i);
+			});
+		return next(0);
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @template T
+	 * @param {T} data the value to store
+	 * @param {CallbackCache<void>} callback signals when the value is stored
+	 * @returns {void}
+	 */
+	store(data, callback) {
+		asyncLib.each(
+			this._items,
+			(item, callback) => item.store(data, callback),
+			callback
+		);
+	}
+
+	/**
+	 * Stores the provided data.
+	 * @template T
+	 * @param {T} data the value to store
+	 * @returns {Promise<void>} promise signals when the value is stored
+	 */
+	storePromise(data) {
+		return Promise.all(this._items.map((item) => item.storePromise(data))).then(
+			() => {}
+		);
+	}
+}
+
+class ItemCacheFacade {
+	/**
+	 * Creates an instance of ItemCacheFacade.
+	 * @param {Cache} cache the root cache
+	 * @param {string} name the child cache item name
+	 * @param {Etag | null} etag the etag
+	 */
+	constructor(cache, name, etag) {
+		this._cache = cache;
+		this._name = name;
+		this._etag = etag;
+	}
+
+	/**
+	 * Returns value.
+	 * @template T
+	 * @param {CallbackCache<T>} callback signals when the value is retrieved
+	 * @returns {void}
+	 */
+	get(callback) {
+		this._cache.get(this._name, this._etag, callback);
+	}
+
+	/**
+	 * Returns promise with the data.
+	 * @template T
+	 * @returns {Promise<T>} promise with the data
+	 */
+	getPromise() {
+		return new Promise((resolve, reject) => {
+			this._cache.get(this._name, this._etag, (err, data) => {
+				if (err) {
+					reject(err);
+				} else {
+					resolve(data);
+				}
+			});
+		});
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @template T
+	 * @param {T} data the value to store
+	 * @param {CallbackCache<void>} callback signals when the value is stored
+	 * @returns {void}
+	 */
+	store(data, callback) {
+		this._cache.store(this._name, this._etag, data, callback);
+	}
+
+	/**
+	 * Stores the provided data.
+	 * @template T
+	 * @param {T} data the value to store
+	 * @returns {Promise<void>} promise signals when the value is stored
+	 */
+	storePromise(data) {
+		return new Promise((resolve, reject) => {
+			this._cache.store(this._name, this._etag, data, (err) => {
+				if (err) {
+					reject(err);
+				} else {
+					resolve();
+				}
+			});
+		});
+	}
+
+	/**
+	 * Processes the provided computer.
+	 * @template T
+	 * @param {(callback: CallbackNormalErrorCache<T>) => void} computer function to compute the value if not cached
+	 * @param {CallbackNormalErrorCache<T>} callback signals when the value is retrieved
+	 * @returns {void}
+	 */
+	provide(computer, callback) {
+		this.get((err, cacheEntry) => {
+			if (err) return callback(err);
+			if (cacheEntry !== undefined) return cacheEntry;
+			computer((err, result) => {
+				if (err) return callback(err);
+				this.store(result, (err) => {
+					if (err) return callback(err);
+					callback(null, result);
+				});
+			});
+		});
+	}
+
+	/**
+	 * Returns promise with the data.
+	 * @template T
+	 * @param {() => Promise<T> | T} computer function to compute the value if not cached
+	 * @returns {Promise<T>} promise with the data
+	 */
+	async providePromise(computer) {
+		const cacheEntry = await this.getPromise();
+		if (cacheEntry !== undefined) return cacheEntry;
+		const result = await computer();
+		await this.storePromise(result);
+		return result;
+	}
+}
+
+class CacheFacade {
+	/**
+	 * Creates an instance of CacheFacade.
+	 * @param {Cache} cache the root cache
+	 * @param {string} name the child cache name
+	 * @param {HashFunction=} hashFunction the hash function to use
+	 */
+	constructor(cache, name, hashFunction) {
+		this._cache = cache;
+		this._name = name;
+		this._hashFunction = hashFunction;
+	}
+
+	/**
+	 * Returns child cache.
+	 * @param {string} name the child cache name#
+	 * @returns {CacheFacade} child cache
+	 */
+	getChildCache(name) {
+		return new CacheFacade(
+			this._cache,
+			`${this._name}|${name}`,
+			this._hashFunction
+		);
+	}
+
+	/**
+	 * Returns item cache.
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @returns {ItemCacheFacade} item cache
+	 */
+	getItemCache(identifier, etag) {
+		return new ItemCacheFacade(
+			this._cache,
+			`${this._name}|${identifier}`,
+			etag
+		);
+	}
+
+	/**
+	 * Gets lazy hashed etag.
+	 * @param {HashableObject} obj an hashable object
+	 * @returns {Etag} an etag that is lazy hashed
+	 */
+	getLazyHashedEtag(obj) {
+		return getLazyHashedEtag(obj, this._hashFunction);
+	}
+
+	/**
+	 * Merges the provided values into a single result.
+	 * @param {Etag} a an etag
+	 * @param {Etag} b another etag
+	 * @returns {Etag} an etag that represents both
+	 */
+	mergeEtags(a, b) {
+		return mergeEtags(a, b);
+	}
+
+	/**
+	 * Returns value.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {CallbackCache<T>} callback signals when the value is retrieved
+	 * @returns {void}
+	 */
+	get(identifier, etag, callback) {
+		this._cache.get(`${this._name}|${identifier}`, etag, callback);
+	}
+
+	/**
+	 * Returns promise with the data.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @returns {Promise<T>} promise with the data
+	 */
+	getPromise(identifier, etag) {
+		return new Promise((resolve, reject) => {
+			this._cache.get(`${this._name}|${identifier}`, etag, (err, data) => {
+				if (err) {
+					reject(err);
+				} else {
+					resolve(data);
+				}
+			});
+		});
+	}
+
+	/**
+	 * Processes the provided identifier.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {T} data the value to store
+	 * @param {CallbackCache<void>} callback signals when the value is stored
+	 * @returns {void}
+	 */
+	store(identifier, etag, data, callback) {
+		this._cache.store(`${this._name}|${identifier}`, etag, data, callback);
+	}
+
+	/**
+	 * Stores the provided identifier.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {T} data the value to store
+	 * @returns {Promise<void>} promise signals when the value is stored
+	 */
+	storePromise(identifier, etag, data) {
+		return new Promise((resolve, reject) => {
+			this._cache.store(`${this._name}|${identifier}`, etag, data, (err) => {
+				if (err) {
+					reject(err);
+				} else {
+					resolve();
+				}
+			});
+		});
+	}
+
+	/**
+	 * Processes the provided identifier.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {(callback: CallbackNormalErrorCache<T>) => void} computer function to compute the value if not cached
+	 * @param {CallbackNormalErrorCache<T>} callback signals when the value is retrieved
+	 * @returns {void}
+	 */
+	provide(identifier, etag, computer, callback) {
+		this.get(identifier, etag, (err, cacheEntry) => {
+			if (err) return callback(err);
+			if (cacheEntry !== undefined) return cacheEntry;
+			computer((err, result) => {
+				if (err) return callback(err);
+				this.store(identifier, etag, result, (err) => {
+					if (err) return callback(err);
+					callback(null, result);
+				});
+			});
+		});
+	}
+
+	/**
+	 * Returns promise with the data.
+	 * @template T
+	 * @param {string} identifier the cache identifier
+	 * @param {Etag | null} etag the etag
+	 * @param {() => Promise<T> | T} computer function to compute the value if not cached
+	 * @returns {Promise<T>} promise with the data
+	 */
+	async providePromise(identifier, etag, computer) {
+		const cacheEntry = await this.getPromise(identifier, etag);
+		if (cacheEntry !== undefined) return cacheEntry;
+		const result = await computer();
+		await this.storePromise(identifier, etag, result);
+		return result;
+	}
+}
+
+module.exports = CacheFacade;
+module.exports.ItemCacheFacade = ItemCacheFacade;
+module.exports.MultiItemCache = MultiItemCache;
Index: frontend/node_modules/webpack/lib/Chunk.js
===================================================================
--- frontend/node_modules/webpack/lib/Chunk.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Chunk.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,966 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ChunkGraph = require("./ChunkGraph");
+const Entrypoint = require("./Entrypoint");
+const { intersect } = require("./util/SetHelpers");
+const SortableSet = require("./util/SortableSet");
+const StringXor = require("./util/StringXor");
+const {
+	compareChunkGroupsByIndex,
+	compareModulesById,
+	compareModulesByIdentifier
+} = require("./util/comparators");
+const { createArrayToSetDeprecationSet } = require("./util/deprecation");
+const { mergeRuntime } = require("./util/runtime");
+
+/** @typedef {import("./ChunkGraph").ChunkFilterPredicate} ChunkFilterPredicate */
+/** @typedef {import("./ChunkGraph").ChunkSizeOptions} ChunkSizeOptions */
+/** @typedef {import("./ChunkGraph").ModuleFilterPredicate} ModuleFilterPredicate */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./ChunkGroup")} ChunkGroup */
+/** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */
+/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Compilation").PathDataChunk} PathDataChunk */
+/** @typedef {import("./TemplatedPathPlugin").TemplatePathFn<PathDataChunk>} ChunkFilenameTemplateFn */
+/** @typedef {string | ChunkFilenameTemplateFn} ChunkFilenameTemplate */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {string | null} ChunkName */
+/** @typedef {string | number} ChunkId */
+/** @typedef {SortableSet<string>} IdNameHints */
+
+const ChunkFilesSet = createArrayToSetDeprecationSet("chunk.files");
+
+/**
+ * Defines the chunk maps type used by this module.
+ * @deprecated
+ * @typedef {object} ChunkMaps
+ * @property {Record<ChunkId, string>} hash
+ * @property {Record<ChunkId, Record<string, string>>} contentHash
+ * @property {Record<ChunkId, string>} name
+ */
+
+/**
+ * Defines the chunk module id map type used by this module.
+ * @deprecated
+ * @typedef {Record<ChunkId, ChunkId[]>} ChunkModuleIdMap
+ */
+
+/**
+ * Defines the chunk module hash map type used by this module.
+ * @deprecated
+ * @typedef {Record<ModuleId, string>} chunkModuleHashMap
+ */
+
+/**
+ * Defines the chunk module maps type used by this module.
+ * @deprecated
+ * @typedef {object} ChunkModuleMaps
+ * @property {ChunkModuleIdMap} id
+ * @property {chunkModuleHashMap} hash
+ */
+
+/** @typedef {Set<Chunk>} Chunks */
+/** @typedef {Set<Entrypoint>} Entrypoints */
+/** @typedef {Set<ChunkGroup>} Queue */
+/** @typedef {SortableSet<ChunkGroup>} SortableChunkGroups */
+/** @typedef {Record<string, ChunkId[]>} ChunkChildIdsByOrdersMap */
+/** @typedef {Record<string, ChunkChildIdsByOrdersMap>} ChunkChildIdsByOrdersMapByData */
+/** @typedef {{ onChunks: Chunk[], chunks: Chunks }} ChunkChildOfTypeInOrder */
+
+let debugId = 1000;
+
+/**
+ * A Chunk is a unit of encapsulation for Modules.
+ * Chunks are "rendered" into bundles that get emitted when the build completes.
+ */
+class Chunk {
+	/**
+	 * Creates an instance of Chunk.
+	 * @param {ChunkName=} name of chunk being created, is optional (for subclasses)
+	 * @param {boolean} backCompat enable backward-compatibility
+	 */
+	constructor(name, backCompat = true) {
+		/** @type {ChunkId | null} */
+		this.id = null;
+		/** @type {ChunkId[] | null} */
+		this.ids = null;
+		/** @type {number} */
+		this.debugId = debugId++;
+		/** @type {ChunkName | undefined} */
+		this.name = name;
+		/** @type {IdNameHints} */
+		this.idNameHints = new SortableSet();
+		/** @type {boolean} */
+		this.preventIntegration = false;
+		/** @type {ChunkFilenameTemplate | undefined} */
+		this.filenameTemplate = undefined;
+		/** @type {ChunkFilenameTemplate | undefined} */
+		this.cssFilenameTemplate = undefined;
+		/**
+		 * @private
+		 * @type {SortableChunkGroups}
+		 */
+		this._groups = new SortableSet(undefined, compareChunkGroupsByIndex);
+		/** @type {RuntimeSpec} */
+		this.runtime = undefined;
+		/** @type {Set<string>} */
+		this.files = backCompat ? new ChunkFilesSet() : new Set();
+		/** @type {Set<string>} */
+		this.auxiliaryFiles = new Set();
+		/** @type {boolean} */
+		this.rendered = false;
+		/** @type {string=} */
+		this.hash = undefined;
+		/** @type {Record<string, string>} */
+		this.contentHash = Object.create(null);
+		/** @type {string=} */
+		this.renderedHash = undefined;
+		/** @type {string=} */
+		this.chunkReason = undefined;
+		/** @type {boolean} */
+		this.extraAsync = false;
+	}
+
+	// TODO remove in webpack 6
+	// BACKWARD-COMPAT START
+	/**
+	 * Returns entry module.
+	 * @deprecated
+	 * @returns {Module | undefined} entry module
+	 */
+	get entryModule() {
+		const entryModules = [
+			...ChunkGraph.getChunkGraphForChunk(
+				this,
+				"Chunk.entryModule",
+				"DEP_WEBPACK_CHUNK_ENTRY_MODULE"
+			).getChunkEntryModulesIterable(this)
+		];
+		if (entryModules.length === 0) {
+			return undefined;
+		} else if (entryModules.length === 1) {
+			return entryModules[0];
+		}
+
+		throw new Error(
+			"Module.entryModule: Multiple entry modules are not supported by the deprecated API (Use the new ChunkGroup API)"
+		);
+	}
+
+	/**
+	 * Checks whether this chunk has an entry module.
+	 * @deprecated
+	 * @returns {boolean} true, if the chunk contains an entry module
+	 */
+	hasEntryModule() {
+		return (
+			ChunkGraph.getChunkGraphForChunk(
+				this,
+				"Chunk.hasEntryModule",
+				"DEP_WEBPACK_CHUNK_HAS_ENTRY_MODULE"
+			).getNumberOfEntryModules(this) > 0
+		);
+	}
+
+	/**
+	 * Adds the provided module to the chunk.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @returns {boolean} true, if the chunk could be added
+	 */
+	addModule(module) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.addModule",
+			"DEP_WEBPACK_CHUNK_ADD_MODULE"
+		);
+		if (chunkGraph.isModuleInChunk(module, this)) return false;
+		chunkGraph.connectChunkAndModule(this, module);
+		return true;
+	}
+
+	/**
+	 * Removes the provided module from the chunk.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	removeModule(module) {
+		ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.removeModule",
+			"DEP_WEBPACK_CHUNK_REMOVE_MODULE"
+		).disconnectChunkAndModule(this, module);
+	}
+
+	/**
+	 * Gets the number of modules in this chunk.
+	 * @deprecated
+	 * @returns {number} the number of module which are contained in this chunk
+	 */
+	getNumberOfModules() {
+		return ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.getNumberOfModules",
+			"DEP_WEBPACK_CHUNK_GET_NUMBER_OF_MODULES"
+		).getNumberOfChunkModules(this);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {Iterable<Module>} modules
+	 */
+	get modulesIterable() {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.modulesIterable",
+			"DEP_WEBPACK_CHUNK_MODULES_ITERABLE"
+		);
+		return chunkGraph.getOrderedChunkModulesIterable(
+			this,
+			compareModulesByIdentifier
+		);
+	}
+
+	/**
+	 * Compares this chunk with another chunk.
+	 * @deprecated
+	 * @param {Chunk} otherChunk the chunk to compare with
+	 * @returns {-1 | 0 | 1} the comparison result
+	 */
+	compareTo(otherChunk) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.compareTo",
+			"DEP_WEBPACK_CHUNK_COMPARE_TO"
+		);
+		return chunkGraph.compareChunks(this, otherChunk);
+	}
+
+	/**
+	 * Checks whether this chunk contains the module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @returns {boolean} true, if the chunk contains the module
+	 */
+	containsModule(module) {
+		return ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.containsModule",
+			"DEP_WEBPACK_CHUNK_CONTAINS_MODULE"
+		).isModuleInChunk(module, this);
+	}
+
+	/**
+	 * Returns the modules for this chunk.
+	 * @deprecated
+	 * @returns {Module[]} the modules for this chunk
+	 */
+	getModules() {
+		return ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.getModules",
+			"DEP_WEBPACK_CHUNK_GET_MODULES"
+		).getChunkModules(this);
+	}
+
+	/**
+	 * Removes this chunk from the chunk graph and chunk groups.
+	 * @deprecated
+	 * @returns {void}
+	 */
+	remove() {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.remove",
+			"DEP_WEBPACK_CHUNK_REMOVE"
+		);
+		chunkGraph.disconnectChunk(this);
+		this.disconnectFromGroups();
+	}
+
+	/**
+	 * Moves a module from this chunk to another chunk.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @param {Chunk} otherChunk the target chunk
+	 * @returns {void}
+	 */
+	moveModule(module, otherChunk) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.moveModule",
+			"DEP_WEBPACK_CHUNK_MOVE_MODULE"
+		);
+		chunkGraph.disconnectChunkAndModule(this, module);
+		chunkGraph.connectChunkAndModule(otherChunk, module);
+	}
+
+	/**
+	 * Integrates another chunk into this chunk when possible.
+	 * @deprecated
+	 * @param {Chunk} otherChunk the other chunk
+	 * @returns {boolean} true, if the specified chunk has been integrated
+	 */
+	integrate(otherChunk) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.integrate",
+			"DEP_WEBPACK_CHUNK_INTEGRATE"
+		);
+		if (chunkGraph.canChunksBeIntegrated(this, otherChunk)) {
+			chunkGraph.integrateChunks(this, otherChunk);
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Checks whether this chunk can be integrated with another chunk.
+	 * @deprecated
+	 * @param {Chunk} otherChunk the other chunk
+	 * @returns {boolean} true, if chunks could be integrated
+	 */
+	canBeIntegrated(otherChunk) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.canBeIntegrated",
+			"DEP_WEBPACK_CHUNK_CAN_BE_INTEGRATED"
+		);
+		return chunkGraph.canChunksBeIntegrated(this, otherChunk);
+	}
+
+	/**
+	 * Checks whether this chunk is empty.
+	 * @deprecated
+	 * @returns {boolean} true, if this chunk contains no module
+	 */
+	isEmpty() {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.isEmpty",
+			"DEP_WEBPACK_CHUNK_IS_EMPTY"
+		);
+		return chunkGraph.getNumberOfChunkModules(this) === 0;
+	}
+
+	/**
+	 * Returns the total size of all modules in this chunk.
+	 * @deprecated
+	 * @returns {number} total size of all modules in this chunk
+	 */
+	modulesSize() {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.modulesSize",
+			"DEP_WEBPACK_CHUNK_MODULES_SIZE"
+		);
+		return chunkGraph.getChunkModulesSize(this);
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @deprecated
+	 * @param {ChunkSizeOptions} options options object
+	 * @returns {number} total size of this chunk
+	 */
+	size(options = {}) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.size",
+			"DEP_WEBPACK_CHUNK_SIZE"
+		);
+		return chunkGraph.getChunkSize(this, options);
+	}
+
+	/**
+	 * Returns the integrated size with another chunk.
+	 * @deprecated
+	 * @param {Chunk} otherChunk the other chunk
+	 * @param {ChunkSizeOptions} options options object
+	 * @returns {number} total size of the chunk or false if the chunk can't be integrated
+	 */
+	integratedSize(otherChunk, options) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.integratedSize",
+			"DEP_WEBPACK_CHUNK_INTEGRATED_SIZE"
+		);
+		return chunkGraph.getIntegratedChunksSize(this, otherChunk, options);
+	}
+
+	/**
+	 * Gets chunk module maps.
+	 * @deprecated
+	 * @param {ModuleFilterPredicate} filterFn function used to filter modules
+	 * @returns {ChunkModuleMaps} module map information
+	 */
+	getChunkModuleMaps(filterFn) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.getChunkModuleMaps",
+			"DEP_WEBPACK_CHUNK_GET_CHUNK_MODULE_MAPS"
+		);
+		/** @type {ChunkModuleIdMap} */
+		const chunkModuleIdMap = Object.create(null);
+		/** @type {chunkModuleHashMap} */
+		const chunkModuleHashMap = Object.create(null);
+
+		for (const asyncChunk of this.getAllAsyncChunks()) {
+			/** @type {ChunkId[] | undefined} */
+			let array;
+			for (const module of chunkGraph.getOrderedChunkModulesIterable(
+				asyncChunk,
+				compareModulesById(chunkGraph)
+			)) {
+				if (filterFn(module)) {
+					if (array === undefined) {
+						array = [];
+						chunkModuleIdMap[/** @type {ChunkId} */ (asyncChunk.id)] = array;
+					}
+					const moduleId =
+						/** @type {ModuleId} */
+						(chunkGraph.getModuleId(module));
+					array.push(moduleId);
+					chunkModuleHashMap[moduleId] = chunkGraph.getRenderedModuleHash(
+						module,
+						undefined
+					);
+				}
+			}
+		}
+
+		return {
+			id: chunkModuleIdMap,
+			hash: chunkModuleHashMap
+		};
+	}
+
+	/**
+	 * Checks whether this chunk contains a matching module in the graph.
+	 * @deprecated
+	 * @param {ModuleFilterPredicate} filterFn predicate function used to filter modules
+	 * @param {ChunkFilterPredicate=} filterChunkFn predicate function used to filter chunks
+	 * @returns {boolean} return true if module exists in graph
+	 */
+	hasModuleInGraph(filterFn, filterChunkFn) {
+		const chunkGraph = ChunkGraph.getChunkGraphForChunk(
+			this,
+			"Chunk.hasModuleInGraph",
+			"DEP_WEBPACK_CHUNK_HAS_MODULE_IN_GRAPH"
+		);
+		return chunkGraph.hasModuleInGraph(this, filterFn, filterChunkFn);
+	}
+
+	/**
+	 * Returns the chunk map information.
+	 * @deprecated
+	 * @param {boolean} realHash whether the full hash or the rendered hash is to be used
+	 * @returns {ChunkMaps} the chunk map information
+	 */
+	getChunkMaps(realHash) {
+		/** @type {Record<ChunkId, string>} */
+		const chunkHashMap = Object.create(null);
+		/** @type {Record<string, Record<ChunkId, string>>} */
+		const chunkContentHashMap = Object.create(null);
+		/** @type {Record<ChunkId, string>} */
+		const chunkNameMap = Object.create(null);
+
+		for (const chunk of this.getAllAsyncChunks()) {
+			const id = /** @type {ChunkId} */ (chunk.id);
+			chunkHashMap[id] =
+				/** @type {string} */
+				(realHash ? chunk.hash : chunk.renderedHash);
+			for (const key of Object.keys(chunk.contentHash)) {
+				if (!chunkContentHashMap[key]) {
+					chunkContentHashMap[key] = Object.create(null);
+				}
+				chunkContentHashMap[key][id] = chunk.contentHash[key];
+			}
+			if (chunk.name) {
+				chunkNameMap[id] = chunk.name;
+			}
+		}
+
+		return {
+			hash: chunkHashMap,
+			contentHash: chunkContentHashMap,
+			name: chunkNameMap
+		};
+	}
+	// BACKWARD-COMPAT END
+
+	/**
+	 * Checks whether this chunk has runtime.
+	 * @returns {boolean} whether or not the Chunk will have a runtime
+	 */
+	hasRuntime() {
+		for (const chunkGroup of this._groups) {
+			if (
+				chunkGroup instanceof Entrypoint &&
+				chunkGroup.getRuntimeChunk() === this
+			) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether it can be initial.
+	 * @returns {boolean} whether or not this chunk can be an initial chunk
+	 */
+	canBeInitial() {
+		for (const chunkGroup of this._groups) {
+			if (chunkGroup.isInitial()) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether this chunk is only initial.
+	 * @returns {boolean} whether this chunk can only be an initial chunk
+	 */
+	isOnlyInitial() {
+		if (this._groups.size <= 0) return false;
+		for (const chunkGroup of this._groups) {
+			if (!chunkGroup.isInitial()) return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Gets entry options.
+	 * @returns {EntryOptions | undefined} the entry options for this chunk
+	 */
+	getEntryOptions() {
+		for (const chunkGroup of this._groups) {
+			if (chunkGroup instanceof Entrypoint) {
+				return chunkGroup.options;
+			}
+		}
+		return undefined;
+	}
+
+	/**
+	 * Adds the provided chunk group to the chunk.
+	 * @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being added
+	 * @returns {void}
+	 */
+	addGroup(chunkGroup) {
+		this._groups.add(chunkGroup);
+	}
+
+	/**
+	 * Removes the provided chunk group from the chunk.
+	 * @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being removed from
+	 * @returns {void}
+	 */
+	removeGroup(chunkGroup) {
+		this._groups.delete(chunkGroup);
+	}
+
+	/**
+	 * Checks whether this chunk is in group.
+	 * @param {ChunkGroup} chunkGroup the chunkGroup to check
+	 * @returns {boolean} returns true if chunk has chunkGroup reference and exists in chunkGroup
+	 */
+	isInGroup(chunkGroup) {
+		return this._groups.has(chunkGroup);
+	}
+
+	/**
+	 * Gets number of groups.
+	 * @returns {number} the amount of groups that the said chunk is in
+	 */
+	getNumberOfGroups() {
+		return this._groups.size;
+	}
+
+	/**
+	 * Gets groups iterable.
+	 * @returns {SortableChunkGroups} the chunkGroups that the said chunk is referenced in
+	 */
+	get groupsIterable() {
+		this._groups.sort();
+		return this._groups;
+	}
+
+	/**
+	 * Disconnects from groups.
+	 * @returns {void}
+	 */
+	disconnectFromGroups() {
+		for (const chunkGroup of this._groups) {
+			chunkGroup.removeChunk(this);
+		}
+	}
+
+	/**
+	 * Processes the provided new chunk.
+	 * @param {Chunk} newChunk the new chunk that will be split out of
+	 * @returns {void}
+	 */
+	split(newChunk) {
+		for (const chunkGroup of this._groups) {
+			chunkGroup.insertChunk(newChunk, this);
+			newChunk.addGroup(chunkGroup);
+		}
+		for (const idHint of this.idNameHints) {
+			newChunk.idNameHints.add(idHint);
+		}
+		newChunk.runtime = mergeRuntime(newChunk.runtime, this.runtime);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash (will be modified)
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {void}
+	 */
+	updateHash(hash, chunkGraph) {
+		hash.update(
+			`${this.id} ${this.ids ? this.ids.join() : ""} ${this.name || ""} `
+		);
+		const xor = new StringXor();
+		for (const m of chunkGraph.getChunkModulesIterable(this)) {
+			xor.add(chunkGraph.getModuleHash(m, this.runtime));
+		}
+		xor.updateHash(hash);
+		const entryModules =
+			chunkGraph.getChunkEntryModulesWithChunkGroupIterable(this);
+		for (const [m, chunkGroup] of entryModules) {
+			hash.update(
+				`entry${chunkGraph.getModuleId(m)}${
+					/** @type {ChunkGroup} */ (chunkGroup).id
+				}`
+			);
+		}
+	}
+
+	/**
+	 * Gets all async chunks.
+	 * @returns {Chunks} a set of all the async chunks
+	 */
+	getAllAsyncChunks() {
+		/** @type {Queue} */
+		const queue = new Set();
+		/** @type {Chunks} */
+		const chunks = new Set();
+
+		const initialChunks = intersect(
+			Array.from(this.groupsIterable, (g) => new Set(g.chunks))
+		);
+
+		/** @type {Queue} */
+		const initialQueue = new Set(this.groupsIterable);
+
+		for (const chunkGroup of initialQueue) {
+			for (const child of chunkGroup.childrenIterable) {
+				if (child instanceof Entrypoint) {
+					initialQueue.add(child);
+				} else {
+					queue.add(child);
+				}
+			}
+		}
+
+		for (const chunkGroup of queue) {
+			for (const chunk of chunkGroup.chunks) {
+				if (!initialChunks.has(chunk)) {
+					chunks.add(chunk);
+				}
+			}
+			for (const child of chunkGroup.childrenIterable) {
+				queue.add(child);
+			}
+		}
+
+		return chunks;
+	}
+
+	/**
+	 * Gets all initial chunks.
+	 * @returns {Chunks} a set of all the initial chunks (including itself)
+	 */
+	getAllInitialChunks() {
+		/** @type {Chunks} */
+		const chunks = new Set();
+		/** @type {Queue} */
+		const queue = new Set(this.groupsIterable);
+		for (const group of queue) {
+			if (group.isInitial()) {
+				for (const c of group.chunks) chunks.add(c);
+				for (const g of group.childrenIterable) queue.add(g);
+			}
+		}
+		return chunks;
+	}
+
+	/**
+	 * Gets all referenced chunks.
+	 * @returns {Chunks} a set of all the referenced chunks (including itself)
+	 */
+	getAllReferencedChunks() {
+		/** @type {Queue} */
+		const queue = new Set(this.groupsIterable);
+		/** @type {Chunks} */
+		const chunks = new Set();
+
+		for (const chunkGroup of queue) {
+			for (const chunk of chunkGroup.chunks) {
+				chunks.add(chunk);
+			}
+			for (const child of chunkGroup.childrenIterable) {
+				queue.add(child);
+			}
+		}
+
+		return chunks;
+	}
+
+	/**
+	 * Gets all referenced async entrypoints.
+	 * @returns {Entrypoints} a set of all the referenced entrypoints
+	 */
+	getAllReferencedAsyncEntrypoints() {
+		/** @type {Queue} */
+		const queue = new Set(this.groupsIterable);
+		/** @type {Entrypoints} */
+		const entrypoints = new Set();
+
+		for (const chunkGroup of queue) {
+			for (const entrypoint of chunkGroup.asyncEntrypointsIterable) {
+				entrypoints.add(/** @type {Entrypoint} */ (entrypoint));
+			}
+			for (const child of chunkGroup.childrenIterable) {
+				queue.add(child);
+			}
+		}
+
+		return entrypoints;
+	}
+
+	/**
+	 * Checks whether this chunk has async chunks.
+	 * @returns {boolean} true, if the chunk references async chunks
+	 */
+	hasAsyncChunks() {
+		/** @type {Queue} */
+		const queue = new Set();
+
+		const initialChunks = intersect(
+			Array.from(this.groupsIterable, (g) => new Set(g.chunks))
+		);
+
+		for (const chunkGroup of this.groupsIterable) {
+			for (const child of chunkGroup.childrenIterable) {
+				queue.add(child);
+			}
+		}
+
+		for (const chunkGroup of queue) {
+			for (const chunk of chunkGroup.chunks) {
+				if (!initialChunks.has(chunk)) {
+					return true;
+				}
+			}
+			for (const child of chunkGroup.childrenIterable) {
+				queue.add(child);
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Gets child ids by orders.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {ChunkFilterPredicate=} filterFn function used to filter chunks
+	 * @returns {Record<string, ChunkId[]>} a record object of names to lists of child ids(?)
+	 */
+	getChildIdsByOrders(chunkGraph, filterFn) {
+		/** @type {Map<string, { order: number, group: ChunkGroup }[]>} */
+		const lists = new Map();
+		for (const group of this.groupsIterable) {
+			if (group.chunks[group.chunks.length - 1] === this) {
+				for (const childGroup of group.childrenIterable) {
+					const edgeOptions = group.getChildOrderOptions(
+						childGroup,
+						chunkGraph
+					);
+					for (const key of Object.keys(edgeOptions)) {
+						const name = key.slice(0, key.length - "Order".length);
+						let list = lists.get(name);
+						if (list === undefined) {
+							list = [];
+							lists.set(name, list);
+						}
+						list.push({
+							order: edgeOptions[key],
+							group: childGroup
+						});
+					}
+				}
+			}
+		}
+		/** @type {Record<string, ChunkId[]>} */
+		const result = Object.create(null);
+		for (const [name, list] of lists) {
+			list.sort((a, b) => {
+				const cmp = b.order - a.order;
+				if (cmp !== 0) return cmp;
+				return a.group.compareTo(chunkGraph, b.group);
+			});
+			/** @type {Set<ChunkId>} */
+			const chunkIdSet = new Set();
+			for (const item of list) {
+				for (const chunk of item.group.chunks) {
+					if (filterFn && !filterFn(chunk, chunkGraph)) continue;
+					chunkIdSet.add(/** @type {ChunkId} */ (chunk.id));
+				}
+			}
+			if (chunkIdSet.size > 0) {
+				result[name] = [...chunkIdSet];
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Gets children of type in order.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {string} type option name
+	 * @returns {ChunkChildOfTypeInOrder[] | undefined} referenced chunks for a specific type
+	 */
+	getChildrenOfTypeInOrder(chunkGraph, type) {
+		/** @type {{ order: number, group: ChunkGroup, childGroup: ChunkGroup }[]} */
+		const list = [];
+		for (const group of this.groupsIterable) {
+			for (const childGroup of group.childrenIterable) {
+				const edgeOptions = group.getChildOrderOptions(childGroup, chunkGraph);
+				const order = edgeOptions[type];
+				if (order === undefined) continue;
+				list.push({
+					order,
+					group,
+					childGroup
+				});
+			}
+		}
+		if (list.length === 0) return;
+		list.sort((a, b) => {
+			const cmp = b.order - a.order;
+			if (cmp !== 0) return cmp;
+			return a.group.compareTo(chunkGraph, b.group);
+		});
+		/** @type {ChunkChildOfTypeInOrder[]} */
+		const result = [];
+		/** @type {undefined | ChunkChildOfTypeInOrder} */
+		let lastEntry;
+		for (const { group, childGroup } of list) {
+			if (lastEntry && lastEntry.onChunks === group.chunks) {
+				for (const chunk of childGroup.chunks) {
+					lastEntry.chunks.add(chunk);
+				}
+			} else {
+				result.push(
+					(lastEntry = {
+						onChunks: group.chunks,
+						chunks: new Set(childGroup.chunks)
+					})
+				);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Gets child ids by orders map.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {boolean=} includeDirectChildren include direct children (by default only children of async children are included)
+	 * @param {ChunkFilterPredicate=} filterFn function used to filter chunks
+	 * @returns {ChunkChildIdsByOrdersMapByData} a record object of names to lists of child ids(?) by chunk id
+	 */
+	getChildIdsByOrdersMap(chunkGraph, includeDirectChildren, filterFn) {
+		/** @type {ChunkChildIdsByOrdersMapByData} */
+		const chunkMaps = Object.create(null);
+
+		/**
+		 * Adds child ids by orders to map.
+		 * @param {Chunk} chunk a chunk
+		 * @returns {void}
+		 */
+		const addChildIdsByOrdersToMap = (chunk) => {
+			const data = chunk.getChildIdsByOrders(chunkGraph, filterFn);
+			for (const key of Object.keys(data)) {
+				let chunkMap = chunkMaps[key];
+				if (chunkMap === undefined) {
+					chunkMaps[key] = chunkMap = Object.create(null);
+				}
+				chunkMap[/** @type {ChunkId} */ (chunk.id)] = data[key];
+			}
+		};
+
+		if (includeDirectChildren) {
+			/** @type {Chunks} */
+			const chunks = new Set();
+			for (const chunkGroup of this.groupsIterable) {
+				for (const chunk of chunkGroup.chunks) {
+					chunks.add(chunk);
+				}
+			}
+			for (const chunk of chunks) {
+				addChildIdsByOrdersToMap(chunk);
+			}
+		}
+
+		for (const chunk of this.getAllAsyncChunks()) {
+			addChildIdsByOrdersToMap(chunk);
+		}
+
+		return chunkMaps;
+	}
+
+	/**
+	 * Checks whether this chunk contains the chunk graph.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {string} type option name
+	 * @param {boolean=} includeDirectChildren include direct children (by default only children of async children are included)
+	 * @param {ChunkFilterPredicate=} filterFn function used to filter chunks
+	 * @returns {boolean} true when the child is of type order, otherwise false
+	 */
+	hasChildByOrder(chunkGraph, type, includeDirectChildren, filterFn) {
+		if (includeDirectChildren) {
+			/** @type {Chunks} */
+			const chunks = new Set();
+			for (const chunkGroup of this.groupsIterable) {
+				for (const chunk of chunkGroup.chunks) {
+					chunks.add(chunk);
+				}
+			}
+			for (const chunk of chunks) {
+				const data = chunk.getChildIdsByOrders(chunkGraph, filterFn);
+				if (data[type] !== undefined) return true;
+			}
+		}
+
+		for (const chunk of this.getAllAsyncChunks()) {
+			const data = chunk.getChildIdsByOrders(chunkGraph, filterFn);
+			if (data[type] !== undefined) return true;
+		}
+
+		return false;
+	}
+}
+
+module.exports = Chunk;
Index: frontend/node_modules/webpack/lib/ChunkGraph.js
===================================================================
--- frontend/node_modules/webpack/lib/ChunkGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ChunkGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2083 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const Entrypoint = require("./Entrypoint");
+const ModuleGraphConnection = require("./ModuleGraphConnection");
+const { DEFAULTS } = require("./config/defaults");
+const { first } = require("./util/SetHelpers");
+const SortableSet = require("./util/SortableSet");
+const {
+	compareIds,
+	compareIterables,
+	compareModulesById,
+	compareModulesByIdentifier,
+	compareSelect,
+	concatComparators
+} = require("./util/comparators");
+const createHash = require("./util/createHash");
+const findGraphRoots = require("./util/findGraphRoots");
+const {
+	RuntimeSpecMap,
+	RuntimeSpecSet,
+	forEachRuntime,
+	mergeRuntime,
+	runtimeToString
+} = require("./util/runtime");
+
+/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Chunk").Chunks} Chunks */
+/** @typedef {import("./Chunk").Entrypoints} Entrypoints */
+/** @typedef {import("./Chunk").ChunkId} ChunkId */
+/** @typedef {import("./ChunkGroup")} ChunkGroup */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").SourceType} SourceType */
+/** @typedef {import("./Module").SourceTypes} SourceTypes */
+/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("./RuntimeModule")} RuntimeModule */
+/** @typedef {import("./util/Hash").HashFunction} HashFunction */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @type {ReadonlySet<string>} */
+const EMPTY_SET = new Set();
+
+const ZERO_BIG_INT = BigInt(0);
+
+const compareModuleIterables = compareIterables(compareModulesByIdentifier);
+
+/** @typedef {(c: Chunk, chunkGraph: ChunkGraph) => boolean} ChunkFilterPredicate */
+/** @typedef {(m: Module) => boolean} ModuleFilterPredicate */
+/** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */
+
+/**
+ * Represents the module hash info runtime component.
+ * @typedef {object} ChunkSizeOptions
+ * @property {number=} chunkOverhead constant overhead for a chunk
+ * @property {number=} entryChunkMultiplicator multiplicator for initial chunks
+ */
+
+class ModuleHashInfo {
+	/**
+	 * Creates an instance of ModuleHashInfo.
+	 * @param {string} hash hash
+	 * @param {string} renderedHash rendered hash
+	 */
+	constructor(hash, renderedHash) {
+		/** @type {string} */
+		this.hash = hash;
+		/** @type {string} */
+		this.renderedHash = renderedHash;
+	}
+}
+
+/**
+ * Returns set as array.
+ * @template T
+ * @param {SortableSet<T>} set the set
+ * @returns {T[]} set as array
+ */
+const getArray = (set) => [...set];
+
+/**
+ * Gets module runtimes.
+ * @param {SortableChunks} chunks the chunks
+ * @returns {RuntimeSpecSet} runtimes
+ */
+const getModuleRuntimes = (chunks) => {
+	const runtimes = new RuntimeSpecSet();
+	for (const chunk of chunks) {
+		runtimes.add(chunk.runtime);
+	}
+	return runtimes;
+};
+
+/**
+ * Modules by source type.
+ * @param {SourceTypesByModule | undefined} sourceTypesByModule sourceTypesByModule
+ * @returns {ModulesBySourceType} modules by source type
+ */
+const modulesBySourceType = (sourceTypesByModule) => (set) => {
+	/** @typedef {SortableSet<Module>} ModuleSortableSet */
+	/** @type {Map<SourceType, ModuleSortableSet>} */
+	const map = new Map();
+	for (const module of set) {
+		const sourceTypes =
+			(sourceTypesByModule && sourceTypesByModule.get(module)) ||
+			module.getSourceTypes();
+		for (const sourceType of sourceTypes) {
+			let innerSet = map.get(sourceType);
+			if (innerSet === undefined) {
+				/** @type {ModuleSortableSet} */
+				innerSet = new SortableSet();
+				map.set(sourceType, innerSet);
+			}
+			innerSet.add(module);
+		}
+	}
+	for (const [key, innerSet] of map) {
+		// When all modules have the source type, we reuse the original SortableSet
+		// to benefit from the shared cache (especially for sorting)
+		if (innerSet.size === set.size) {
+			map.set(key, set);
+		}
+	}
+	return map;
+};
+
+/** @typedef {(set: SortableSet<Module>) => Map<string, SortableSet<Module>>} ModulesBySourceType */
+
+/** @type {ModulesBySourceType} */
+const defaultModulesBySourceType = modulesBySourceType(undefined);
+
+/**
+ * Defines the module set to array function type used by this module.
+ * @typedef {(set: SortableSet<Module>) => Module[]} ModuleSetToArrayFunction
+ */
+
+/**
+ * @template T
+ * @type {WeakMap<ModuleComparator, ModuleSetToArrayFunction>}
+ */
+const createOrderedArrayFunctionMap = new WeakMap();
+
+/**
+ * Creates an ordered array function.
+ * @template T
+ * @param {ModuleComparator} comparator comparator function
+ * @returns {ModuleSetToArrayFunction} set as ordered array
+ */
+const createOrderedArrayFunction = (comparator) => {
+	let fn = createOrderedArrayFunctionMap.get(comparator);
+	if (fn !== undefined) return fn;
+	fn = (set) => {
+		set.sortWith(comparator);
+		return [...set];
+	};
+	createOrderedArrayFunctionMap.set(comparator, fn);
+	return fn;
+};
+
+/**
+ * Returns the size of the modules.
+ * @param {Iterable<Module>} modules the modules to get the count/size of
+ * @returns {number} the size of the modules
+ */
+const getModulesSize = (modules) => {
+	let size = 0;
+	for (const module of modules) {
+		for (const type of module.getSourceTypes()) {
+			size += module.size(type);
+		}
+	}
+	return size;
+};
+
+/** @typedef {Record<string, number>} SizesOfModules */
+
+/**
+ * Gets modules sizes.
+ * @param {Iterable<Module>} modules the sortable Set to get the size of
+ * @returns {SizesOfModules} the sizes of the modules
+ */
+const getModulesSizes = (modules) => {
+	/** @type {SizesOfModules} */
+	const sizes = Object.create(null);
+	for (const module of modules) {
+		for (const type of module.getSourceTypes()) {
+			sizes[type] = (sizes[type] || 0) + module.size(type);
+		}
+	}
+	return sizes;
+};
+
+/**
+ * Checks whether this module hash info is available chunk.
+ * @param {Chunk} a chunk
+ * @param {Chunk} b chunk
+ * @returns {boolean} true, if a is always a parent of b
+ */
+const isAvailableChunk = (a, b) => {
+	const queue = new Set(b.groupsIterable);
+	for (const chunkGroup of queue) {
+		if (a.isInGroup(chunkGroup)) continue;
+		if (chunkGroup.isInitial()) return false;
+		for (const parent of chunkGroup.parentsIterable) {
+			queue.add(parent);
+		}
+	}
+	return true;
+};
+
+/** @typedef {SortableSet<Chunk>} SortableChunks */
+/** @typedef {Set<Chunk>} EntryInChunks */
+/** @typedef {Set<Chunk>} RuntimeInChunks */
+/** @typedef {string | number} ModuleId */
+/** @typedef {RuntimeSpecMap<Set<string>, RuntimeRequirements>} ChunkGraphRuntimeRequirements */
+
+class ChunkGraphModule {
+	constructor() {
+		/** @type {SortableChunks} */
+		this.chunks = new SortableSet();
+		/** @type {EntryInChunks | undefined} */
+		this.entryInChunks = undefined;
+		/** @type {RuntimeInChunks | undefined} */
+		this.runtimeInChunks = undefined;
+		/** @type {RuntimeSpecMap<ModuleHashInfo> | undefined} */
+		this.hashes = undefined;
+		/** @type {ModuleId | null} */
+		this.id = null;
+		/** @type {ChunkGraphRuntimeRequirements | undefined} */
+		this.runtimeRequirements = undefined;
+		/** @type {RuntimeSpecMap<string, bigint> | undefined} */
+		this.graphHashes = undefined;
+		/** @type {RuntimeSpecMap<string, string> | undefined} */
+		this.graphHashesWithConnections = undefined;
+	}
+}
+
+/** @typedef {WeakMap<Module, SourceTypes>} SourceTypesByModule */
+/** @typedef {Map<Module, Entrypoint>} EntryModules */
+
+class ChunkGraphChunk {
+	constructor() {
+		/** @type {SortableSet<Module>} */
+		this.modules = new SortableSet();
+		/** @type {SourceTypesByModule | undefined} */
+		this.sourceTypesByModule = undefined;
+		/** @type {EntryModules} */
+		this.entryModules = new Map();
+		/** @type {SortableSet<RuntimeModule>} */
+		this.runtimeModules = new SortableSet();
+		/** @type {Set<RuntimeModule> | undefined} */
+		this.fullHashModules = undefined;
+		/** @type {Set<RuntimeModule> | undefined} */
+		this.dependentHashModules = undefined;
+		/** @type {RuntimeRequirements | undefined} */
+		this.runtimeRequirements = undefined;
+		/** @type {Set<string>} */
+		this.runtimeRequirementsInTree = new Set();
+		/** @type {ModulesBySourceType} */
+		this._modulesBySourceType = defaultModulesBySourceType;
+	}
+}
+
+/** @typedef {string | number} RuntimeId */
+/** @typedef {Record<ModuleId, string>} IdToHashMap */
+/** @typedef {Record<ChunkId, IdToHashMap>} ChunkModuleHashMap */
+/** @typedef {Record<ChunkId, ModuleId[]>} ChunkModuleIdMap */
+/** @typedef {Record<ChunkId, boolean>} ChunkConditionMap */
+
+/** @typedef {(a: Module, b: Module) => -1 | 0 | 1} ModuleComparator */
+
+class ChunkGraph {
+	/**
+	 * Creates an instance of ChunkGraph.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {HashFunction} hashFunction the hash function to use
+	 */
+	constructor(moduleGraph, hashFunction = DEFAULTS.HASH_FUNCTION) {
+		/**
+		 * @private
+		 * @type {WeakMap<Module, ChunkGraphModule>}
+		 */
+		this._modules = new WeakMap();
+		/**
+		 * @private
+		 * @type {WeakMap<Chunk, ChunkGraphChunk>}
+		 */
+		this._chunks = new WeakMap();
+		/**
+		 * @private
+		 * @type {WeakMap<AsyncDependenciesBlock, ChunkGroup>}
+		 */
+		this._blockChunkGroups = new WeakMap();
+		/**
+		 * @private
+		 * @type {Map<string, RuntimeId>}
+		 */
+		this._runtimeIds = new Map();
+		/** @type {ModuleGraph} */
+		this.moduleGraph = moduleGraph;
+
+		this._hashFunction = hashFunction;
+
+		this._getGraphRoots = this._getGraphRoots.bind(this);
+	}
+
+	/**
+	 * Get chunk graph module.
+	 * @private
+	 * @param {Module} module the module
+	 * @returns {ChunkGraphModule} internal module
+	 */
+	_getChunkGraphModule(module) {
+		let cgm = this._modules.get(module);
+		if (cgm === undefined) {
+			cgm = new ChunkGraphModule();
+			this._modules.set(module, cgm);
+		}
+		return cgm;
+	}
+
+	/**
+	 * Get chunk graph chunk.
+	 * @private
+	 * @param {Chunk} chunk the chunk
+	 * @returns {ChunkGraphChunk} internal chunk
+	 */
+	_getChunkGraphChunk(chunk) {
+		let cgc = this._chunks.get(chunk);
+		if (cgc === undefined) {
+			cgc = new ChunkGraphChunk();
+			this._chunks.set(chunk, cgc);
+		}
+		return cgc;
+	}
+
+	/**
+	 * Returns the graph roots.
+	 * @param {SortableSet<Module>} set the sortable Set to get the roots of
+	 * @returns {Module[]} the graph roots
+	 */
+	_getGraphRoots(set) {
+		const { moduleGraph } = this;
+		return [
+			...findGraphRoots(set, (module) => {
+				/** @type {Set<Module>} */
+				const set = new Set();
+				/**
+				 * Adds the provided module to the chunk graph.
+				 * @param {Module} module module
+				 */
+				const addDependencies = (module) => {
+					for (const connection of moduleGraph.getOutgoingConnections(module)) {
+						if (!connection.module) continue;
+						const activeState = connection.getActiveState(undefined);
+						if (activeState === false) continue;
+						if (activeState === ModuleGraphConnection.TRANSITIVE_ONLY) {
+							addDependencies(connection.module);
+							continue;
+						}
+						set.add(connection.module);
+					}
+				};
+				addDependencies(module);
+				return set;
+			})
+		].sort(compareModulesByIdentifier);
+	}
+
+	/**
+	 * Connects chunk and module.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	connectChunkAndModule(chunk, module) {
+		const cgm = this._getChunkGraphModule(module);
+		const cgc = this._getChunkGraphChunk(chunk);
+		cgm.chunks.add(chunk);
+		cgc.modules.add(module);
+	}
+
+	/**
+	 * Disconnects chunk and module.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	disconnectChunkAndModule(chunk, module) {
+		const cgm = this._getChunkGraphModule(module);
+		const cgc = this._getChunkGraphChunk(chunk);
+		cgc.modules.delete(module);
+		// No need to invalidate cgc._modulesBySourceType because we modified cgc.modules anyway
+		if (cgc.sourceTypesByModule) cgc.sourceTypesByModule.delete(module);
+		cgm.chunks.delete(chunk);
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk which will be disconnected
+	 * @returns {void}
+	 */
+	disconnectChunk(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		for (const module of cgc.modules) {
+			const cgm = this._getChunkGraphModule(module);
+			cgm.chunks.delete(chunk);
+		}
+		cgc.modules.clear();
+		chunk.disconnectFromGroups();
+		ChunkGraph.clearChunkGraphForChunk(chunk);
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Iterable<Module>} modules the modules
+	 * @returns {void}
+	 */
+	attachModules(chunk, modules) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		for (const module of modules) {
+			cgc.modules.add(module);
+		}
+	}
+
+	/**
+	 * Attach runtime modules.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Iterable<RuntimeModule>} modules the runtime modules
+	 * @returns {void}
+	 */
+	attachRuntimeModules(chunk, modules) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		for (const module of modules) {
+			cgc.runtimeModules.add(module);
+		}
+	}
+
+	/**
+	 * Attach full hash modules.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Iterable<RuntimeModule>} modules the modules that require a full hash
+	 * @returns {void}
+	 */
+	attachFullHashModules(chunk, modules) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.fullHashModules === undefined) cgc.fullHashModules = new Set();
+		for (const module of modules) {
+			cgc.fullHashModules.add(module);
+		}
+	}
+
+	/**
+	 * Attach dependent hash modules.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Iterable<RuntimeModule>} modules the modules that require a full hash
+	 * @returns {void}
+	 */
+	attachDependentHashModules(chunk, modules) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.dependentHashModules === undefined) {
+			cgc.dependentHashModules = new Set();
+		}
+		for (const module of modules) {
+			cgc.dependentHashModules.add(module);
+		}
+	}
+
+	/**
+	 * Processes the provided old module.
+	 * @param {Module} oldModule the replaced module
+	 * @param {Module} newModule the replacing module
+	 * @returns {void}
+	 */
+	replaceModule(oldModule, newModule) {
+		const oldCgm = this._getChunkGraphModule(oldModule);
+		const newCgm = this._getChunkGraphModule(newModule);
+
+		for (const chunk of oldCgm.chunks) {
+			const cgc = this._getChunkGraphChunk(chunk);
+			cgc.modules.delete(oldModule);
+			cgc.modules.add(newModule);
+			newCgm.chunks.add(chunk);
+		}
+		oldCgm.chunks.clear();
+
+		if (oldCgm.entryInChunks !== undefined) {
+			if (newCgm.entryInChunks === undefined) {
+				newCgm.entryInChunks = new Set();
+			}
+			for (const chunk of oldCgm.entryInChunks) {
+				const cgc = this._getChunkGraphChunk(chunk);
+				const old = /** @type {Entrypoint} */ (cgc.entryModules.get(oldModule));
+				/** @type {EntryModules} */
+				const newEntryModules = new Map();
+				for (const [m, cg] of cgc.entryModules) {
+					if (m === oldModule) {
+						newEntryModules.set(newModule, old);
+					} else {
+						newEntryModules.set(m, cg);
+					}
+				}
+				cgc.entryModules = newEntryModules;
+				newCgm.entryInChunks.add(chunk);
+			}
+			oldCgm.entryInChunks = undefined;
+		}
+
+		if (oldCgm.runtimeInChunks !== undefined) {
+			if (newCgm.runtimeInChunks === undefined) {
+				newCgm.runtimeInChunks = new Set();
+			}
+			for (const chunk of oldCgm.runtimeInChunks) {
+				const cgc = this._getChunkGraphChunk(chunk);
+				cgc.runtimeModules.delete(/** @type {RuntimeModule} */ (oldModule));
+				cgc.runtimeModules.add(/** @type {RuntimeModule} */ (newModule));
+				newCgm.runtimeInChunks.add(chunk);
+				if (
+					cgc.fullHashModules !== undefined &&
+					cgc.fullHashModules.has(/** @type {RuntimeModule} */ (oldModule))
+				) {
+					cgc.fullHashModules.delete(/** @type {RuntimeModule} */ (oldModule));
+					cgc.fullHashModules.add(/** @type {RuntimeModule} */ (newModule));
+				}
+				if (
+					cgc.dependentHashModules !== undefined &&
+					cgc.dependentHashModules.has(/** @type {RuntimeModule} */ (oldModule))
+				) {
+					cgc.dependentHashModules.delete(
+						/** @type {RuntimeModule} */ (oldModule)
+					);
+					cgc.dependentHashModules.add(
+						/** @type {RuntimeModule} */ (newModule)
+					);
+				}
+			}
+			oldCgm.runtimeInChunks = undefined;
+		}
+	}
+
+	/**
+	 * Checks whether this chunk graph is module in chunk.
+	 * @param {Module} module the checked module
+	 * @param {Chunk} chunk the checked chunk
+	 * @returns {boolean} true, if the chunk contains the module
+	 */
+	isModuleInChunk(module, chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules.has(module);
+	}
+
+	/**
+	 * Checks whether this chunk graph is module in chunk group.
+	 * @param {Module} module the checked module
+	 * @param {ChunkGroup} chunkGroup the checked chunk group
+	 * @returns {boolean} true, if the chunk contains the module
+	 */
+	isModuleInChunkGroup(module, chunkGroup) {
+		for (const chunk of chunkGroup.chunks) {
+			if (this.isModuleInChunk(module, chunk)) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether this chunk graph is entry module.
+	 * @param {Module} module the checked module
+	 * @returns {boolean} true, if the module is entry of any chunk
+	 */
+	isEntryModule(module) {
+		const cgm = this._getChunkGraphModule(module);
+		return cgm.entryInChunks !== undefined;
+	}
+
+	/**
+	 * Gets module chunks iterable.
+	 * @param {Module} module the module
+	 * @returns {Iterable<Chunk>} iterable of chunks (do not modify)
+	 */
+	getModuleChunksIterable(module) {
+		const cgm = this._getChunkGraphModule(module);
+		return cgm.chunks;
+	}
+
+	/**
+	 * Gets ordered module chunks iterable.
+	 * @param {Module} module the module
+	 * @param {(a: Chunk, b: Chunk) => -1 | 0 | 1} sortFn sort function
+	 * @returns {Iterable<Chunk>} iterable of chunks (do not modify)
+	 */
+	getOrderedModuleChunksIterable(module, sortFn) {
+		const cgm = this._getChunkGraphModule(module);
+		cgm.chunks.sortWith(sortFn);
+		return cgm.chunks;
+	}
+
+	/**
+	 * Gets module chunks.
+	 * @param {Module} module the module
+	 * @returns {Chunk[]} array of chunks (cached, do not modify)
+	 */
+	getModuleChunks(module) {
+		const cgm = this._getChunkGraphModule(module);
+		return cgm.chunks.getFromCache(getArray);
+	}
+
+	/**
+	 * Gets number of module chunks.
+	 * @param {Module} module the module
+	 * @returns {number} the number of chunk which contain the module
+	 */
+	getNumberOfModuleChunks(module) {
+		const cgm = this._getChunkGraphModule(module);
+		return cgm.chunks.size;
+	}
+
+	/**
+	 * Gets module runtimes.
+	 * @param {Module} module the module
+	 * @returns {RuntimeSpecSet} runtimes
+	 */
+	getModuleRuntimes(module) {
+		const cgm = this._getChunkGraphModule(module);
+		return cgm.chunks.getFromUnorderedCache(getModuleRuntimes);
+	}
+
+	/**
+	 * Gets number of chunk modules.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {number} the number of modules which are contained in this chunk
+	 */
+	getNumberOfChunkModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules.size;
+	}
+
+	/**
+	 * Gets number of chunk full hash modules.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {number} the number of full hash modules which are contained in this chunk
+	 */
+	getNumberOfChunkFullHashModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.fullHashModules === undefined ? 0 : cgc.fullHashModules.size;
+	}
+
+	/**
+	 * Gets chunk modules iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<Module>} return the modules for this chunk
+	 */
+	getChunkModulesIterable(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules;
+	}
+
+	/**
+	 * Gets chunk modules iterable by source type.
+	 * @param {Chunk} chunk the chunk
+	 * @param {string} sourceType source type
+	 * @returns {Iterable<Module> | undefined} return the modules for this chunk
+	 */
+	getChunkModulesIterableBySourceType(chunk, sourceType) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const modulesWithSourceType = cgc.modules
+			.getFromUnorderedCache(cgc._modulesBySourceType)
+			.get(sourceType);
+		return modulesWithSourceType;
+	}
+
+	/**
+	 * Sets chunk module source types.
+	 * @param {Chunk} chunk chunk
+	 * @param {Module} module chunk module
+	 * @param {SourceTypes} sourceTypes source types
+	 */
+	setChunkModuleSourceTypes(chunk, module, sourceTypes) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.sourceTypesByModule === undefined) {
+			cgc.sourceTypesByModule = new WeakMap();
+		}
+		cgc.sourceTypesByModule.set(module, sourceTypes);
+		// Update cgc._modulesBySourceType to invalidate the cache
+		cgc._modulesBySourceType = modulesBySourceType(cgc.sourceTypesByModule);
+	}
+
+	/**
+	 * Gets chunk module source types.
+	 * @param {Chunk} chunk chunk
+	 * @param {Module} module chunk module
+	 * @returns {SourceTypes} source types
+	 */
+	getChunkModuleSourceTypes(chunk, module) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.sourceTypesByModule === undefined) {
+			return module.getSourceTypes();
+		}
+		return cgc.sourceTypesByModule.get(module) || module.getSourceTypes();
+	}
+
+	/**
+	 * Gets module source types.
+	 * @param {Module} module module
+	 * @returns {SourceTypes} source types
+	 */
+	getModuleSourceTypes(module) {
+		return (
+			this._getOverwrittenModuleSourceTypes(module) || module.getSourceTypes()
+		);
+	}
+
+	/**
+	 * Get overwritten module source types.
+	 * @param {Module} module module
+	 * @returns {SourceTypes | undefined} source types
+	 */
+	_getOverwrittenModuleSourceTypes(module) {
+		let newSet = false;
+		/** @type {Set<SourceType> | undefined} */
+		let sourceTypes;
+		for (const chunk of this.getModuleChunksIterable(module)) {
+			const cgc = this._getChunkGraphChunk(chunk);
+			if (cgc.sourceTypesByModule === undefined) return;
+			const st = cgc.sourceTypesByModule.get(module);
+			if (st === undefined) return;
+			if (!sourceTypes) {
+				sourceTypes = /** @type {Set<SourceType>} */ (st);
+			} else if (!newSet) {
+				for (const type of st) {
+					if (!newSet) {
+						if (!sourceTypes.has(type)) {
+							newSet = true;
+							sourceTypes = new Set(sourceTypes);
+							sourceTypes.add(type);
+						}
+					} else {
+						sourceTypes.add(type);
+					}
+				}
+			} else {
+				for (const type of st) sourceTypes.add(type);
+			}
+		}
+
+		return sourceTypes;
+	}
+
+	/**
+	 * Gets ordered chunk modules iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ModuleComparator} comparator comparator function
+	 * @returns {Iterable<Module>} return the modules for this chunk
+	 */
+	getOrderedChunkModulesIterable(chunk, comparator) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		cgc.modules.sortWith(comparator);
+		return cgc.modules;
+	}
+
+	/**
+	 * Gets ordered chunk modules iterable by source type.
+	 * @param {Chunk} chunk the chunk
+	 * @param {string} sourceType source type
+	 * @param {ModuleComparator} comparator comparator function
+	 * @returns {Iterable<Module> | undefined} return the modules for this chunk
+	 */
+	getOrderedChunkModulesIterableBySourceType(chunk, sourceType, comparator) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const modulesWithSourceType = cgc.modules
+			.getFromUnorderedCache(cgc._modulesBySourceType)
+			.get(sourceType);
+		if (modulesWithSourceType === undefined) return;
+		modulesWithSourceType.sortWith(comparator);
+		return modulesWithSourceType;
+	}
+
+	/**
+	 * Gets chunk modules.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Module[]} return the modules for this chunk (cached, do not modify)
+	 */
+	getChunkModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules.getFromUnorderedCache(getArray);
+	}
+
+	/**
+	 * Gets ordered chunk modules.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ModuleComparator} comparator comparator function
+	 * @returns {Module[]} return the modules for this chunk (cached, do not modify)
+	 */
+	getOrderedChunkModules(chunk, comparator) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const arrayFunction = createOrderedArrayFunction(comparator);
+		return cgc.modules.getFromUnorderedCache(arrayFunction);
+	}
+
+	/**
+	 * Gets chunk module id map.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ModuleFilterPredicate} filterFn function used to filter modules
+	 * @param {boolean} includeAllChunks all chunks or only async chunks
+	 * @returns {ChunkModuleIdMap} chunk to module ids object
+	 */
+	getChunkModuleIdMap(chunk, filterFn, includeAllChunks = false) {
+		/** @type {ChunkModuleIdMap} */
+		const chunkModuleIdMap = Object.create(null);
+
+		for (const asyncChunk of includeAllChunks
+			? chunk.getAllReferencedChunks()
+			: chunk.getAllAsyncChunks()) {
+			/** @type {ModuleId[] | undefined} */
+			let array;
+			for (const module of this.getOrderedChunkModulesIterable(
+				asyncChunk,
+				compareModulesById(this)
+			)) {
+				if (filterFn(module)) {
+					if (array === undefined) {
+						array = [];
+						chunkModuleIdMap[/** @type {ChunkId} */ (asyncChunk.id)] = array;
+					}
+					const moduleId = /** @type {ModuleId} */ (this.getModuleId(module));
+					array.push(moduleId);
+				}
+			}
+		}
+
+		return chunkModuleIdMap;
+	}
+
+	/**
+	 * Gets chunk module rendered hash map.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ModuleFilterPredicate} filterFn function used to filter modules
+	 * @param {number} hashLength length of the hash
+	 * @param {boolean} includeAllChunks all chunks or only async chunks
+	 * @returns {ChunkModuleHashMap} chunk to module id to module hash object
+	 */
+	getChunkModuleRenderedHashMap(
+		chunk,
+		filterFn,
+		hashLength = 0,
+		includeAllChunks = false
+	) {
+		/** @type {ChunkModuleHashMap} */
+		const chunkModuleHashMap = Object.create(null);
+
+		for (const asyncChunk of includeAllChunks
+			? chunk.getAllReferencedChunks()
+			: chunk.getAllAsyncChunks()) {
+			/** @type {IdToHashMap | undefined} */
+			let idToHashMap;
+			for (const module of this.getOrderedChunkModulesIterable(
+				asyncChunk,
+				compareModulesById(this)
+			)) {
+				if (filterFn(module)) {
+					if (idToHashMap === undefined) {
+						/** @type {IdToHashMap} */
+						idToHashMap = Object.create(null);
+						chunkModuleHashMap[/** @type {ChunkId} */ (asyncChunk.id)] =
+							/** @type {IdToHashMap} */
+							(idToHashMap);
+					}
+					const moduleId = this.getModuleId(module);
+					const hash = this.getRenderedModuleHash(module, asyncChunk.runtime);
+					/** @type {IdToHashMap} */
+					(idToHashMap)[/** @type {ModuleId} */ (moduleId)] = hashLength
+						? hash.slice(0, hashLength)
+						: hash;
+				}
+			}
+		}
+
+		return chunkModuleHashMap;
+	}
+
+	/**
+	 * Gets chunk condition map.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ChunkFilterPredicate} filterFn function used to filter chunks
+	 * @returns {ChunkConditionMap} chunk condition map
+	 */
+	getChunkConditionMap(chunk, filterFn) {
+		/** @type {ChunkConditionMap} */
+		const map = Object.create(null);
+		for (const c of chunk.getAllReferencedChunks()) {
+			map[/** @type {ChunkId} */ (c.id)] = filterFn(c, this);
+		}
+		return map;
+	}
+
+	/**
+	 * Checks whether this chunk graph contains the chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ModuleFilterPredicate} filterFn predicate function used to filter modules
+	 * @param {ChunkFilterPredicate=} filterChunkFn predicate function used to filter chunks
+	 * @returns {boolean} return true if module exists in graph
+	 */
+	hasModuleInGraph(chunk, filterFn, filterChunkFn) {
+		const queue = new Set(chunk.groupsIterable);
+		/** @type {Set<Chunk>} */
+		const chunksProcessed = new Set();
+
+		for (const chunkGroup of queue) {
+			for (const innerChunk of chunkGroup.chunks) {
+				if (!chunksProcessed.has(innerChunk)) {
+					chunksProcessed.add(innerChunk);
+					if (!filterChunkFn || filterChunkFn(innerChunk, this)) {
+						for (const module of this.getChunkModulesIterable(innerChunk)) {
+							if (filterFn(module)) {
+								return true;
+							}
+						}
+					}
+				}
+			}
+			for (const child of chunkGroup.childrenIterable) {
+				queue.add(child);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Compares the provided values and returns their ordering.
+	 * @param {Chunk} chunkA first chunk
+	 * @param {Chunk} chunkB second chunk
+	 * @returns {-1 | 0 | 1} this is a comparator function like sort and returns -1, 0, or 1 based on sort order
+	 */
+	compareChunks(chunkA, chunkB) {
+		const cgcA = this._getChunkGraphChunk(chunkA);
+		const cgcB = this._getChunkGraphChunk(chunkB);
+		if (cgcA.modules.size > cgcB.modules.size) return -1;
+		if (cgcA.modules.size < cgcB.modules.size) return 1;
+		cgcA.modules.sortWith(compareModulesByIdentifier);
+		cgcB.modules.sortWith(compareModulesByIdentifier);
+		return compareModuleIterables(cgcA.modules, cgcB.modules);
+	}
+
+	/**
+	 * Gets chunk modules size.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {number} total size of all modules in the chunk
+	 */
+	getChunkModulesSize(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules.getFromUnorderedCache(getModulesSize);
+	}
+
+	/**
+	 * Gets chunk modules sizes.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Record<string, number>} total sizes of all modules in the chunk by source type
+	 */
+	getChunkModulesSizes(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules.getFromUnorderedCache(getModulesSizes);
+	}
+
+	/**
+	 * Gets chunk root modules.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Module[]} root modules of the chunks (ordered by identifier)
+	 */
+	getChunkRootModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.modules.getFromUnorderedCache(this._getGraphRoots);
+	}
+
+	/**
+	 * Returns total size of the chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {ChunkSizeOptions} options options object
+	 * @returns {number} total size of the chunk
+	 */
+	getChunkSize(chunk, options = {}) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const modulesSize = cgc.modules.getFromUnorderedCache(getModulesSize);
+		const chunkOverhead =
+			typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000;
+		const entryChunkMultiplicator =
+			typeof options.entryChunkMultiplicator === "number"
+				? options.entryChunkMultiplicator
+				: 10;
+		return (
+			chunkOverhead +
+			modulesSize * (chunk.canBeInitial() ? entryChunkMultiplicator : 1)
+		);
+	}
+
+	/**
+	 * Gets integrated chunks size.
+	 * @param {Chunk} chunkA chunk
+	 * @param {Chunk} chunkB chunk
+	 * @param {ChunkSizeOptions} options options object
+	 * @returns {number} total size of the chunk or false if chunks can't be integrated
+	 */
+	getIntegratedChunksSize(chunkA, chunkB, options = {}) {
+		const cgcA = this._getChunkGraphChunk(chunkA);
+		const cgcB = this._getChunkGraphChunk(chunkB);
+		const allModules = new Set(cgcA.modules);
+		for (const m of cgcB.modules) allModules.add(m);
+		const modulesSize = getModulesSize(allModules);
+		const chunkOverhead =
+			typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000;
+		const entryChunkMultiplicator =
+			typeof options.entryChunkMultiplicator === "number"
+				? options.entryChunkMultiplicator
+				: 10;
+		return (
+			chunkOverhead +
+			modulesSize *
+				(chunkA.canBeInitial() || chunkB.canBeInitial()
+					? entryChunkMultiplicator
+					: 1)
+		);
+	}
+
+	/**
+	 * Checks whether it can chunks be integrated.
+	 * @param {Chunk} chunkA chunk
+	 * @param {Chunk} chunkB chunk
+	 * @returns {boolean} true, if chunks could be integrated
+	 */
+	canChunksBeIntegrated(chunkA, chunkB) {
+		if (chunkA.preventIntegration || chunkB.preventIntegration) {
+			return false;
+		}
+
+		const hasRuntimeA = chunkA.hasRuntime();
+		const hasRuntimeB = chunkB.hasRuntime();
+
+		if (hasRuntimeA !== hasRuntimeB) {
+			if (hasRuntimeA) {
+				return isAvailableChunk(chunkA, chunkB);
+			} else if (hasRuntimeB) {
+				return isAvailableChunk(chunkB, chunkA);
+			}
+
+			return false;
+		}
+
+		if (
+			this.getNumberOfEntryModules(chunkA) > 0 ||
+			this.getNumberOfEntryModules(chunkB) > 0
+		) {
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Processes the provided chunk a.
+	 * @param {Chunk} chunkA the target chunk
+	 * @param {Chunk} chunkB the chunk to integrate
+	 * @returns {void}
+	 */
+	integrateChunks(chunkA, chunkB) {
+		// Decide for one name (deterministic)
+		if (chunkA.name && chunkB.name) {
+			if (
+				this.getNumberOfEntryModules(chunkA) > 0 ===
+				this.getNumberOfEntryModules(chunkB) > 0
+			) {
+				// When both chunks have entry modules or none have one, use
+				// shortest name
+				if (chunkA.name.length !== chunkB.name.length) {
+					chunkA.name =
+						chunkA.name.length < chunkB.name.length ? chunkA.name : chunkB.name;
+				} else {
+					chunkA.name = chunkA.name < chunkB.name ? chunkA.name : chunkB.name;
+				}
+			} else if (this.getNumberOfEntryModules(chunkB) > 0) {
+				// Pick the name of the chunk with the entry module
+				chunkA.name = chunkB.name;
+			}
+		} else if (chunkB.name) {
+			chunkA.name = chunkB.name;
+		}
+
+		// Merge id name hints
+		for (const hint of chunkB.idNameHints) {
+			chunkA.idNameHints.add(hint);
+		}
+
+		// Merge runtime
+		chunkA.runtime = mergeRuntime(chunkA.runtime, chunkB.runtime);
+
+		// getChunkModules is used here to create a clone, because disconnectChunkAndModule modifies
+		for (const module of this.getChunkModules(chunkB)) {
+			this.disconnectChunkAndModule(chunkB, module);
+			this.connectChunkAndModule(chunkA, module);
+		}
+
+		for (const [
+			module,
+			chunkGroup
+		] of this.getChunkEntryModulesWithChunkGroupIterable(chunkB)) {
+			this.disconnectChunkAndEntryModule(chunkB, module);
+			this.connectChunkAndEntryModule(
+				chunkA,
+				module,
+				/** @type {Entrypoint} */
+				(chunkGroup)
+			);
+		}
+
+		for (const chunkGroup of chunkB.groupsIterable) {
+			chunkGroup.replaceChunk(chunkB, chunkA);
+			chunkA.addGroup(chunkGroup);
+			chunkB.removeGroup(chunkGroup);
+		}
+		ChunkGraph.clearChunkGraphForChunk(chunkB);
+	}
+
+	/**
+	 * Upgrade dependent to full hash modules.
+	 * @param {Chunk} chunk the chunk to upgrade
+	 * @returns {void}
+	 */
+	upgradeDependentToFullHashModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.dependentHashModules === undefined) return;
+		if (cgc.fullHashModules === undefined) {
+			cgc.fullHashModules = cgc.dependentHashModules;
+		} else {
+			for (const m of cgc.dependentHashModules) {
+				cgc.fullHashModules.add(m);
+			}
+			cgc.dependentHashModules = undefined;
+		}
+	}
+
+	/**
+	 * Checks whether this chunk graph is entry module in chunk.
+	 * @param {Module} module the checked module
+	 * @param {Chunk} chunk the checked chunk
+	 * @returns {boolean} true, if the chunk contains the module as entry
+	 */
+	isEntryModuleInChunk(module, chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.entryModules.has(module);
+	}
+
+	/**
+	 * Connects chunk and entry module.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {Module} module the entry module
+	 * @param {Entrypoint} entrypoint the chunk group which must be loaded before the module is executed
+	 * @returns {void}
+	 */
+	connectChunkAndEntryModule(chunk, module, entrypoint) {
+		const cgm = this._getChunkGraphModule(module);
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgm.entryInChunks === undefined) {
+			cgm.entryInChunks = new Set();
+		}
+		cgm.entryInChunks.add(chunk);
+		cgc.entryModules.set(module, entrypoint);
+	}
+
+	/**
+	 * Connects chunk and runtime module.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {RuntimeModule} module the runtime module
+	 * @returns {void}
+	 */
+	connectChunkAndRuntimeModule(chunk, module) {
+		const cgm = this._getChunkGraphModule(module);
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgm.runtimeInChunks === undefined) {
+			cgm.runtimeInChunks = new Set();
+		}
+		cgm.runtimeInChunks.add(chunk);
+		cgc.runtimeModules.add(module);
+	}
+
+	/**
+	 * Adds full hash module to chunk.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {RuntimeModule} module the module that require a full hash
+	 * @returns {void}
+	 */
+	addFullHashModuleToChunk(chunk, module) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.fullHashModules === undefined) cgc.fullHashModules = new Set();
+		cgc.fullHashModules.add(module);
+	}
+
+	/**
+	 * Adds dependent hash module to chunk.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {RuntimeModule} module the module that require a full hash
+	 * @returns {void}
+	 */
+	addDependentHashModuleToChunk(chunk, module) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		if (cgc.dependentHashModules === undefined) {
+			cgc.dependentHashModules = new Set();
+		}
+		cgc.dependentHashModules.add(module);
+	}
+
+	/**
+	 * Disconnects chunk and entry module.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {Module} module the entry module
+	 * @returns {void}
+	 */
+	disconnectChunkAndEntryModule(chunk, module) {
+		const cgm = this._getChunkGraphModule(module);
+		const cgc = this._getChunkGraphChunk(chunk);
+		/** @type {EntryInChunks} */
+		(cgm.entryInChunks).delete(chunk);
+		if (/** @type {EntryInChunks} */ (cgm.entryInChunks).size === 0) {
+			cgm.entryInChunks = undefined;
+		}
+		cgc.entryModules.delete(module);
+	}
+
+	/**
+	 * Disconnects chunk and runtime module.
+	 * @param {Chunk} chunk the new chunk
+	 * @param {RuntimeModule} module the runtime module
+	 * @returns {void}
+	 */
+	disconnectChunkAndRuntimeModule(chunk, module) {
+		const cgm = this._getChunkGraphModule(module);
+		const cgc = this._getChunkGraphChunk(chunk);
+		/** @type {RuntimeInChunks} */
+		(cgm.runtimeInChunks).delete(chunk);
+		if (/** @type {RuntimeInChunks} */ (cgm.runtimeInChunks).size === 0) {
+			cgm.runtimeInChunks = undefined;
+		}
+		cgc.runtimeModules.delete(module);
+	}
+
+	/**
+	 * Disconnects entry module.
+	 * @param {Module} module the entry module, it will no longer be entry
+	 * @returns {void}
+	 */
+	disconnectEntryModule(module) {
+		const cgm = this._getChunkGraphModule(module);
+		for (const chunk of /** @type {EntryInChunks} */ (cgm.entryInChunks)) {
+			const cgc = this._getChunkGraphChunk(chunk);
+			cgc.entryModules.delete(module);
+		}
+		cgm.entryInChunks = undefined;
+	}
+
+	/**
+	 * Disconnects entries.
+	 * @param {Chunk} chunk the chunk, for which all entries will be removed
+	 * @returns {void}
+	 */
+	disconnectEntries(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		for (const module of cgc.entryModules.keys()) {
+			const cgm = this._getChunkGraphModule(module);
+			/** @type {EntryInChunks} */
+			(cgm.entryInChunks).delete(chunk);
+			if (/** @type {EntryInChunks} */ (cgm.entryInChunks).size === 0) {
+				cgm.entryInChunks = undefined;
+			}
+		}
+		cgc.entryModules.clear();
+	}
+
+	/**
+	 * Gets number of entry modules.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {number} the amount of entry modules in chunk
+	 */
+	getNumberOfEntryModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.entryModules.size;
+	}
+
+	/**
+	 * Gets number of runtime modules.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {number} the amount of entry modules in chunk
+	 */
+	getNumberOfRuntimeModules(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.runtimeModules.size;
+	}
+
+	/**
+	 * Gets chunk entry modules iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<Module>} iterable of modules (do not modify)
+	 */
+	getChunkEntryModulesIterable(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.entryModules.keys();
+	}
+
+	/**
+	 * Gets chunk entry dependent chunks iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<Chunk>} iterable of chunks
+	 */
+	getChunkEntryDependentChunksIterable(chunk) {
+		/** @type {Chunks} */
+		const set = new Set();
+		for (const chunkGroup of chunk.groupsIterable) {
+			if (chunkGroup instanceof Entrypoint) {
+				const entrypointChunk = chunkGroup.getEntrypointChunk();
+				const cgc = this._getChunkGraphChunk(entrypointChunk);
+				for (const chunkGroup of cgc.entryModules.values()) {
+					for (const c of chunkGroup.chunks) {
+						if (c !== chunk && c !== entrypointChunk && !c.hasRuntime()) {
+							set.add(c);
+						}
+					}
+				}
+			}
+		}
+
+		return set;
+	}
+
+	/**
+	 * Gets runtime chunk dependent chunks iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<Chunk>} iterable of chunks and include chunks from children entrypoints
+	 */
+	getRuntimeChunkDependentChunksIterable(chunk) {
+		/** @type {Chunks} */
+		const set = new Set();
+
+		/** @type {Entrypoints} */
+		const entrypoints = new Set();
+
+		for (const chunkGroup of chunk.groupsIterable) {
+			if (chunkGroup instanceof Entrypoint) {
+				const queue = [chunkGroup];
+				while (queue.length > 0) {
+					const current = queue.shift();
+					if (current) {
+						entrypoints.add(current);
+
+						let hasChildrenEntrypoint = false;
+						for (const child of current.childrenIterable) {
+							if (child instanceof Entrypoint && child.dependOn(current)) {
+								hasChildrenEntrypoint = true;
+								queue.push(/** @type {Entrypoint} */ (child));
+							}
+						}
+						// entryChunkB: hasChildrenEntrypoint = true
+						// entryChunkA: dependOn = entryChunkB
+						if (hasChildrenEntrypoint) {
+							const entrypointChunk = current.getEntrypointChunk();
+							if (entrypointChunk !== chunk && !entrypointChunk.hasRuntime()) {
+								// add entryChunkB to set
+								set.add(entrypointChunk);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		for (const entrypoint of entrypoints) {
+			const entrypointChunk = entrypoint.getEntrypointChunk();
+			const cgc = this._getChunkGraphChunk(entrypointChunk);
+			for (const chunkGroup of cgc.entryModules.values()) {
+				for (const c of chunkGroup.chunks) {
+					if (c !== chunk && c !== entrypointChunk && !c.hasRuntime()) {
+						set.add(c);
+					}
+				}
+			}
+		}
+		return set;
+	}
+
+	/**
+	 * Checks whether this chunk graph contains the chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {boolean} true, when it has dependent chunks
+	 */
+	hasChunkEntryDependentChunks(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		for (const chunkGroup of cgc.entryModules.values()) {
+			for (const c of chunkGroup.chunks) {
+				if (c !== chunk) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Gets chunk runtime modules iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<RuntimeModule>} iterable of modules (do not modify)
+	 */
+	getChunkRuntimeModulesIterable(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.runtimeModules;
+	}
+
+	/**
+	 * Gets chunk runtime modules in order.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {RuntimeModule[]} array of modules in order of execution
+	 */
+	getChunkRuntimeModulesInOrder(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const array = [...cgc.runtimeModules];
+		array.sort(
+			concatComparators(
+				compareSelect(
+					(r) => /** @type {RuntimeModule} */ (r).stage,
+					compareIds
+				),
+				compareModulesByIdentifier
+			)
+		);
+		return array;
+	}
+
+	/**
+	 * Gets chunk full hash modules iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<RuntimeModule> | undefined} iterable of modules (do not modify)
+	 */
+	getChunkFullHashModulesIterable(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.fullHashModules;
+	}
+
+	/**
+	 * Gets chunk full hash modules set.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {ReadonlySet<RuntimeModule> | undefined} set of modules (do not modify)
+	 */
+	getChunkFullHashModulesSet(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.fullHashModules;
+	}
+
+	/**
+	 * Gets chunk dependent hash modules iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<RuntimeModule> | undefined} iterable of modules (do not modify)
+	 */
+	getChunkDependentHashModulesIterable(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.dependentHashModules;
+	}
+
+	/**
+	 * Gets chunk entry modules with chunk group iterable.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {Iterable<EntryModuleWithChunkGroup>} iterable of modules (do not modify)
+	 */
+	getChunkEntryModulesWithChunkGroupIterable(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.entryModules;
+	}
+
+	/**
+	 * Gets block chunk group.
+	 * @param {AsyncDependenciesBlock} depBlock the async block
+	 * @returns {ChunkGroup | undefined} the chunk group
+	 */
+	getBlockChunkGroup(depBlock) {
+		return this._blockChunkGroups.get(depBlock);
+	}
+
+	/**
+	 * Connects block and chunk group.
+	 * @param {AsyncDependenciesBlock} depBlock the async block
+	 * @param {ChunkGroup} chunkGroup the chunk group
+	 * @returns {void}
+	 */
+	connectBlockAndChunkGroup(depBlock, chunkGroup) {
+		this._blockChunkGroups.set(depBlock, chunkGroup);
+		chunkGroup.addBlock(depBlock);
+	}
+
+	/**
+	 * Disconnects chunk group.
+	 * @param {ChunkGroup} chunkGroup the chunk group
+	 * @returns {void}
+	 */
+	disconnectChunkGroup(chunkGroup) {
+		for (const block of chunkGroup.blocksIterable) {
+			this._blockChunkGroups.delete(block);
+		}
+		// TODO refactor by moving blocks list into ChunkGraph
+		chunkGroup._blocks.clear();
+	}
+
+	/**
+	 * Returns the id of the module.
+	 * @param {Module} module the module
+	 * @returns {ModuleId | null} the id of the module
+	 */
+	getModuleId(module) {
+		const cgm = this._getChunkGraphModule(module);
+		return cgm.id;
+	}
+
+	/**
+	 * Updates module id using the provided module.
+	 * @param {Module} module the module
+	 * @param {ModuleId} id the id of the module
+	 * @returns {void}
+	 */
+	setModuleId(module, id) {
+		const cgm = this._getChunkGraphModule(module);
+		cgm.id = id;
+	}
+
+	/**
+	 * Returns the id of the runtime.
+	 * @param {string} runtime runtime
+	 * @returns {RuntimeId} the id of the runtime
+	 */
+	getRuntimeId(runtime) {
+		return /** @type {RuntimeId} */ (this._runtimeIds.get(runtime));
+	}
+
+	/**
+	 * Updates runtime id using the provided runtime.
+	 * @param {string} runtime runtime
+	 * @param {RuntimeId} id the id of the runtime
+	 * @returns {void}
+	 */
+	setRuntimeId(runtime, id) {
+		this._runtimeIds.set(runtime, id);
+	}
+
+	/**
+	 * Get module hash info.
+	 * @template T
+	 * @param {Module} module the module
+	 * @param {RuntimeSpecMap<T>} hashes hashes data
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {T} hash
+	 */
+	_getModuleHashInfo(module, hashes, runtime) {
+		if (!hashes) {
+			throw new Error(
+				`Module ${module.identifier()} has no hash info for runtime ${runtimeToString(
+					runtime
+				)} (hashes not set at all)`
+			);
+		} else if (runtime === undefined) {
+			const hashInfoItems = new Set(hashes.values());
+			if (hashInfoItems.size !== 1) {
+				throw new Error(
+					`No unique hash info entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from(
+						hashes.keys(),
+						(r) => runtimeToString(r)
+					).join(", ")}).
+Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
+				);
+			}
+			return /** @type {T} */ (first(hashInfoItems));
+		} else {
+			const hashInfo = hashes.get(runtime);
+			if (!hashInfo) {
+				throw new Error(
+					`Module ${module.identifier()} has no hash info for runtime ${runtimeToString(
+						runtime
+					)} (available runtimes ${Array.from(
+						hashes.keys(),
+						runtimeToString
+					).join(", ")})`
+				);
+			}
+			return hashInfo;
+		}
+	}
+
+	/**
+	 * Checks whether this chunk graph contains the module.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, if the module has hashes for this runtime
+	 */
+	hasModuleHashes(module, runtime) {
+		const cgm = this._getChunkGraphModule(module);
+		const hashes = /** @type {RuntimeSpecMap<ModuleHashInfo>} */ (cgm.hashes);
+		return hashes && hashes.has(runtime);
+	}
+
+	/**
+	 * Returns hash.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {string} hash
+	 */
+	getModuleHash(module, runtime) {
+		const cgm = this._getChunkGraphModule(module);
+		const hashes = /** @type {RuntimeSpecMap<ModuleHashInfo>} */ (cgm.hashes);
+		return this._getModuleHashInfo(module, hashes, runtime).hash;
+	}
+
+	/**
+	 * Gets rendered module hash.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {string} hash
+	 */
+	getRenderedModuleHash(module, runtime) {
+		const cgm = this._getChunkGraphModule(module);
+		const hashes = /** @type {RuntimeSpecMap<ModuleHashInfo>} */ (cgm.hashes);
+		return this._getModuleHashInfo(module, hashes, runtime).renderedHash;
+	}
+
+	/**
+	 * Sets module hashes.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {string} hash the full hash
+	 * @param {string} renderedHash the shortened hash for rendering
+	 * @returns {void}
+	 */
+	setModuleHashes(module, runtime, hash, renderedHash) {
+		const cgm = this._getChunkGraphModule(module);
+		if (cgm.hashes === undefined) {
+			cgm.hashes = new RuntimeSpecMap();
+		}
+		cgm.hashes.set(runtime, new ModuleHashInfo(hash, renderedHash));
+	}
+
+	/**
+	 * Adds module runtime requirements.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {RuntimeRequirements} items runtime requirements to be added (ownership of this Set is given to ChunkGraph when transferOwnership not false)
+	 * @param {boolean} transferOwnership true: transfer ownership of the items object, false: items is immutable and shared and won't be modified
+	 * @returns {void}
+	 */
+	addModuleRuntimeRequirements(
+		module,
+		runtime,
+		items,
+		transferOwnership = true
+	) {
+		const cgm = this._getChunkGraphModule(module);
+		const runtimeRequirementsMap = cgm.runtimeRequirements;
+		if (runtimeRequirementsMap === undefined) {
+			/** @type {ChunkGraphRuntimeRequirements} */
+			const map = new RuntimeSpecMap();
+			// TODO avoid cloning item and track ownership instead
+			map.set(runtime, transferOwnership ? items : new Set(items));
+			cgm.runtimeRequirements = map;
+			return;
+		}
+		runtimeRequirementsMap.update(runtime, (runtimeRequirements) => {
+			if (runtimeRequirements === undefined) {
+				return transferOwnership ? items : new Set(items);
+			} else if (!transferOwnership || runtimeRequirements.size >= items.size) {
+				for (const item of items) runtimeRequirements.add(item);
+				return runtimeRequirements;
+			}
+
+			for (const item of runtimeRequirements) items.add(item);
+			return items;
+		});
+	}
+
+	/**
+	 * Adds chunk runtime requirements.
+	 * @param {Chunk} chunk the chunk
+	 * @param {RuntimeRequirements} items runtime requirements to be added (ownership of this Set is given to ChunkGraph)
+	 * @returns {void}
+	 */
+	addChunkRuntimeRequirements(chunk, items) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const runtimeRequirements = cgc.runtimeRequirements;
+		if (runtimeRequirements === undefined) {
+			cgc.runtimeRequirements = items;
+		} else if (runtimeRequirements.size >= items.size) {
+			for (const item of items) runtimeRequirements.add(item);
+		} else {
+			for (const item of runtimeRequirements) items.add(item);
+			cgc.runtimeRequirements = items;
+		}
+	}
+
+	/**
+	 * Adds tree runtime requirements.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Iterable<string>} items runtime requirements to be added
+	 * @returns {void}
+	 */
+	addTreeRuntimeRequirements(chunk, items) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const runtimeRequirements = cgc.runtimeRequirementsInTree;
+		for (const item of items) runtimeRequirements.add(item);
+	}
+
+	/**
+	 * Gets module runtime requirements.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {ReadOnlyRuntimeRequirements} runtime requirements
+	 */
+	getModuleRuntimeRequirements(module, runtime) {
+		const cgm = this._getChunkGraphModule(module);
+		const runtimeRequirements =
+			cgm.runtimeRequirements && cgm.runtimeRequirements.get(runtime);
+		return runtimeRequirements === undefined ? EMPTY_SET : runtimeRequirements;
+	}
+
+	/**
+	 * Gets chunk runtime requirements.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {ReadOnlyRuntimeRequirements} runtime requirements
+	 */
+	getChunkRuntimeRequirements(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		const runtimeRequirements = cgc.runtimeRequirements;
+		return runtimeRequirements === undefined ? EMPTY_SET : runtimeRequirements;
+	}
+
+	/**
+	 * Gets module graph hash.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {boolean} withConnections include connections
+	 * @returns {string} hash
+	 */
+	getModuleGraphHash(module, runtime, withConnections = true) {
+		const cgm = this._getChunkGraphModule(module);
+		return withConnections
+			? this._getModuleGraphHashWithConnections(cgm, module, runtime)
+			: this._getModuleGraphHashBigInt(cgm, module, runtime).toString(16);
+	}
+
+	/**
+	 * Gets module graph hash big int.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {boolean} withConnections include connections
+	 * @returns {bigint} hash
+	 */
+	getModuleGraphHashBigInt(module, runtime, withConnections = true) {
+		const cgm = this._getChunkGraphModule(module);
+		return withConnections
+			? BigInt(
+					`0x${this._getModuleGraphHashWithConnections(cgm, module, runtime)}`
+				)
+			: this._getModuleGraphHashBigInt(cgm, module, runtime);
+	}
+
+	/**
+	 * Get module graph hash big int.
+	 * @param {ChunkGraphModule} cgm the ChunkGraphModule
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {bigint} hash as big int
+	 */
+	_getModuleGraphHashBigInt(cgm, module, runtime) {
+		if (cgm.graphHashes === undefined) {
+			cgm.graphHashes = new RuntimeSpecMap();
+		}
+		const graphHash = cgm.graphHashes.provide(runtime, () => {
+			const hash = createHash(this._hashFunction);
+			hash.update(`${cgm.id}${this.moduleGraph.isAsync(module)}`);
+			const sourceTypes = this._getOverwrittenModuleSourceTypes(module);
+			if (sourceTypes !== undefined) {
+				for (const type of sourceTypes) hash.update(type);
+			}
+			this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime);
+			return BigInt(`0x${hash.digest("hex")}`);
+		});
+		return graphHash;
+	}
+
+	/**
+	 * Get module graph hash with connections.
+	 * @param {ChunkGraphModule} cgm the ChunkGraphModule
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {string} hash
+	 */
+	_getModuleGraphHashWithConnections(cgm, module, runtime) {
+		if (cgm.graphHashesWithConnections === undefined) {
+			cgm.graphHashesWithConnections = new RuntimeSpecMap();
+		}
+
+		/**
+		 * Active state to string.
+		 * @param {ConnectionState} state state
+		 * @returns {"F" | "T" | "O"} result
+		 */
+		const activeStateToString = (state) => {
+			if (state === false) return "F";
+			if (state === true) return "T";
+			if (state === ModuleGraphConnection.TRANSITIVE_ONLY) return "O";
+			throw new Error("Not implemented active state");
+		};
+		const strict = module.buildMeta && module.buildMeta.strictHarmonyModule;
+		return cgm.graphHashesWithConnections.provide(runtime, () => {
+			const graphHash = this._getModuleGraphHashBigInt(
+				cgm,
+				module,
+				runtime
+			).toString(16);
+			const connections = this.moduleGraph.getOutgoingConnections(module);
+			/** @type {Set<Module>} */
+			const activeNamespaceModules = new Set();
+			/** @type {Map<string, Module | Set<Module>>} */
+			const connectedModules = new Map();
+			/**
+			 * Process connection.
+			 * @param {ModuleGraphConnection} connection connection
+			 * @param {string} stateInfo state info
+			 */
+			const processConnection = (connection, stateInfo) => {
+				const module = connection.module;
+				stateInfo += module.getExportsType(this.moduleGraph, strict);
+				// cspell:word Tnamespace
+				if (stateInfo === "Tnamespace") {
+					activeNamespaceModules.add(module);
+				} else {
+					const oldModule = connectedModules.get(stateInfo);
+					if (oldModule === undefined) {
+						connectedModules.set(stateInfo, module);
+					} else if (oldModule instanceof Set) {
+						oldModule.add(module);
+					} else if (oldModule !== module) {
+						connectedModules.set(stateInfo, new Set([oldModule, module]));
+					}
+				}
+			};
+			if (runtime === undefined || typeof runtime === "string") {
+				for (const connection of connections) {
+					const state = connection.getActiveState(runtime);
+					if (state === false) continue;
+					processConnection(connection, state === true ? "T" : "O");
+				}
+			} else {
+				// cspell:word Tnamespace
+				for (const connection of connections) {
+					/** @type {Set<ConnectionState>} */
+					const states = new Set();
+					let stateInfo = "";
+					forEachRuntime(
+						runtime,
+						(runtime) => {
+							const state = connection.getActiveState(runtime);
+							states.add(state);
+							stateInfo += activeStateToString(state) + runtime;
+						},
+						true
+					);
+					if (states.size === 1) {
+						const state = first(states);
+						if (state === false) continue;
+						stateInfo = activeStateToString(
+							/** @type {ConnectionState} */
+							(state)
+						);
+					}
+					processConnection(connection, stateInfo);
+				}
+			}
+			// cspell:word Tnamespace
+			if (activeNamespaceModules.size === 0 && connectedModules.size === 0) {
+				return graphHash;
+			}
+			const connectedModulesInOrder =
+				connectedModules.size > 1
+					? [...connectedModules].sort(([a], [b]) => (a < b ? -1 : 1))
+					: connectedModules;
+			const hash = createHash(this._hashFunction);
+			/**
+			 * Adds module to hash.
+			 * @param {Module} module module
+			 */
+			const addModuleToHash = (module) => {
+				hash.update(
+					this._getModuleGraphHashBigInt(
+						this._getChunkGraphModule(module),
+						module,
+						runtime
+					).toString(16)
+				);
+			};
+			/**
+			 * Adds modules to hash.
+			 * @param {Set<Module>} modules modules
+			 */
+			const addModulesToHash = (modules) => {
+				let xor = ZERO_BIG_INT;
+				for (const m of modules) {
+					xor ^= this._getModuleGraphHashBigInt(
+						this._getChunkGraphModule(m),
+						m,
+						runtime
+					);
+				}
+				hash.update(xor.toString(16));
+			};
+			if (activeNamespaceModules.size === 1) {
+				addModuleToHash(
+					/** @type {Module} */ (activeNamespaceModules.values().next().value)
+				);
+			} else if (activeNamespaceModules.size > 1) {
+				addModulesToHash(activeNamespaceModules);
+			}
+			for (const [stateInfo, modules] of connectedModulesInOrder) {
+				hash.update(stateInfo);
+				if (modules instanceof Set) {
+					addModulesToHash(modules);
+				} else {
+					addModuleToHash(modules);
+				}
+			}
+			hash.update(graphHash);
+			return hash.digest("hex");
+		});
+	}
+
+	/**
+	 * Gets tree runtime requirements.
+	 * @param {Chunk} chunk the chunk
+	 * @returns {ReadOnlyRuntimeRequirements} runtime requirements
+	 */
+	getTreeRuntimeRequirements(chunk) {
+		const cgc = this._getChunkGraphChunk(chunk);
+		return cgc.runtimeRequirementsInTree;
+	}
+
+	// TODO remove in webpack 6
+	/**
+	 * Gets chunk graph for module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @param {string} deprecateMessage message for the deprecation message
+	 * @param {string} deprecationCode code for the deprecation
+	 * @returns {ChunkGraph} the chunk graph
+	 */
+	static getChunkGraphForModule(module, deprecateMessage, deprecationCode) {
+		const fn = deprecateGetChunkGraphForModuleMap.get(deprecateMessage);
+		if (fn) return fn(module);
+		const newFn = util.deprecate(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {Module} module the module
+			 * @returns {ChunkGraph} the chunk graph
+			 */
+			(module) => {
+				const chunkGraph = chunkGraphForModuleMap.get(module);
+				if (!chunkGraph) {
+					throw new Error(
+						`${
+							deprecateMessage
+						}: There was no ChunkGraph assigned to the Module for backward-compat (Use the new API)`
+					);
+				}
+				return chunkGraph;
+			},
+			`${deprecateMessage}: Use new ChunkGraph API`,
+			deprecationCode
+		);
+		deprecateGetChunkGraphForModuleMap.set(deprecateMessage, newFn);
+		return newFn(module);
+	}
+
+	// TODO remove in webpack 6
+	// BACKWARD-COMPAT START
+	/**
+	 * Sets chunk graph for module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {void}
+	 */
+	static setChunkGraphForModule(module, chunkGraph) {
+		chunkGraphForModuleMap.set(module, chunkGraph);
+	}
+
+	/**
+	 * Clear chunk graph for module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	static clearChunkGraphForModule(module) {
+		chunkGraphForModuleMap.delete(module);
+	}
+
+	/**
+	 * Gets chunk graph for chunk.
+	 * @deprecated
+	 * @param {Chunk} chunk the chunk
+	 * @param {string} deprecateMessage message for the deprecation message
+	 * @param {string} deprecationCode code for the deprecation
+	 * @returns {ChunkGraph} the chunk graph
+	 */
+	static getChunkGraphForChunk(chunk, deprecateMessage, deprecationCode) {
+		const fn = deprecateGetChunkGraphForChunkMap.get(deprecateMessage);
+		if (fn) return fn(chunk);
+		const newFn = util.deprecate(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {Chunk} chunk the chunk
+			 * @returns {ChunkGraph} the chunk graph
+			 */
+			(chunk) => {
+				const chunkGraph = chunkGraphForChunkMap.get(chunk);
+				if (!chunkGraph) {
+					throw new Error(
+						`${
+							deprecateMessage
+						}There was no ChunkGraph assigned to the Chunk for backward-compat (Use the new API)`
+					);
+				}
+				return chunkGraph;
+			},
+			`${deprecateMessage}: Use new ChunkGraph API`,
+			deprecationCode
+		);
+		deprecateGetChunkGraphForChunkMap.set(deprecateMessage, newFn);
+		return newFn(chunk);
+	}
+
+	/**
+	 * Sets chunk graph for chunk.
+	 * @deprecated
+	 * @param {Chunk} chunk the chunk
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {void}
+	 */
+	static setChunkGraphForChunk(chunk, chunkGraph) {
+		chunkGraphForChunkMap.set(chunk, chunkGraph);
+	}
+
+	/**
+	 * Clear chunk graph for chunk.
+	 * @deprecated
+	 * @param {Chunk} chunk the chunk
+	 * @returns {void}
+	 */
+	static clearChunkGraphForChunk(chunk) {
+		chunkGraphForChunkMap.delete(chunk);
+	}
+	// BACKWARD-COMPAT END
+}
+
+// TODO remove in webpack 6
+/** @type {WeakMap<Module, ChunkGraph>} */
+const chunkGraphForModuleMap = new WeakMap();
+
+// TODO remove in webpack 6
+/** @type {WeakMap<Chunk, ChunkGraph>} */
+const chunkGraphForChunkMap = new WeakMap();
+
+// TODO remove in webpack 6
+/** @type {Map<string, (module: Module) => ChunkGraph>} */
+const deprecateGetChunkGraphForModuleMap = new Map();
+
+// TODO remove in webpack 6
+/** @type {Map<string, (chunk: Chunk) => ChunkGraph>} */
+const deprecateGetChunkGraphForChunkMap = new Map();
+
+module.exports = ChunkGraph;
Index: frontend/node_modules/webpack/lib/ChunkGroup.js
===================================================================
--- frontend/node_modules/webpack/lib/ChunkGroup.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ChunkGroup.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,701 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const SortableSet = require("./util/SortableSet");
+const {
+	compareChunks,
+	compareIterables,
+	compareLocations
+} = require("./util/comparators");
+
+/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Entrypoint")} Entrypoint */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+
+/** @typedef {{ module: Module | null, loc: DependencyLocation, request: string }} OriginRecord */
+
+/**
+ * Describes the scheduling hints that can be attached to a chunk group.
+ * These values influence how child groups are ordered for preload/prefetch
+ * and how their fetch priority is exposed to runtime code.
+ * @typedef {object} RawChunkGroupOptions
+ * @property {number=} preloadOrder
+ * @property {number=} prefetchOrder
+ * @property {("low" | "high" | "auto")=} fetchPriority
+ */
+
+/** @typedef {RawChunkGroupOptions & { name?: string | null }} ChunkGroupOptions */
+
+let debugId = 5000;
+
+/**
+ * Materializes a sortable set as an array without changing its current order.
+ * Used with `SortableSet` caches that expect a stable array result.
+ * @template T
+ * @param {SortableSet<T>} set set to convert to array.
+ * @returns {T[]} the array format of existing set
+ */
+const getArray = (set) => [...set];
+
+/**
+ * A convenience method used to sort chunks based on their id's
+ * @param {ChunkGroup} a first sorting comparator
+ * @param {ChunkGroup} b second sorting comparator
+ * @returns {1 | 0 | -1} a sorting index to determine order
+ */
+const sortById = (a, b) => {
+	if (a.id < b.id) return -1;
+	if (b.id < a.id) return 1;
+	return 0;
+};
+
+/**
+ * Orders origin records by referencing module and then by source location.
+ * This keeps origin metadata deterministic for hashing and diagnostics.
+ * @param {OriginRecord} a the first comparator in sort
+ * @param {OriginRecord} b the second comparator in sort
+ * @returns {1 | -1 | 0} returns sorting order as index
+ */
+const sortOrigin = (a, b) => {
+	const aIdent = a.module ? a.module.identifier() : "";
+	const bIdent = b.module ? b.module.identifier() : "";
+	if (aIdent < bIdent) return -1;
+	if (aIdent > bIdent) return 1;
+	return compareLocations(a.loc, b.loc);
+};
+
+/**
+ * Represents a connected group of chunks along with the parent/child
+ * relationships, async blocks, and traversal metadata webpack tracks for it.
+ */
+class ChunkGroup {
+	/**
+	 * Creates a chunk group and initializes the relationship sets and ordering
+	 * metadata used while building and optimizing the chunk graph.
+	 * @param {string | ChunkGroupOptions=} options chunk group options passed to chunkGroup
+	 */
+	constructor(options) {
+		if (typeof options === "string") {
+			options = { name: options };
+		} else if (!options) {
+			options = { name: undefined };
+		}
+		/** @type {number} */
+		this.groupDebugId = debugId++;
+		/** @type {ChunkGroupOptions} */
+		this.options = options;
+		/** @type {SortableSet<ChunkGroup>} */
+		this._children = new SortableSet(undefined, sortById);
+		/** @type {SortableSet<ChunkGroup>} */
+		this._parents = new SortableSet(undefined, sortById);
+		/** @type {SortableSet<ChunkGroup>} */
+		this._asyncEntrypoints = new SortableSet(undefined, sortById);
+		/** @type {SortableSet<AsyncDependenciesBlock>} */
+		this._blocks = new SortableSet();
+		/** @type {Chunk[]} */
+		this.chunks = [];
+		/** @type {OriginRecord[]} */
+		this.origins = [];
+
+		/** @typedef {Map<Module, number>} OrderIndices */
+
+		/** Indices in top-down order */
+		/**
+		 * @private
+		 * @type {OrderIndices}
+		 */
+		this._modulePreOrderIndices = new Map();
+		/** Indices in bottom-up order */
+		/**
+		 * @private
+		 * @type {OrderIndices}
+		 */
+		this._modulePostOrderIndices = new Map();
+		/** @type {number | undefined} */
+		this.index = undefined;
+	}
+
+	/**
+	 * Merges additional options into the chunk group.
+	 * Order-based options are combined by taking the higher priority, while
+	 * unsupported conflicts surface as an explicit error.
+	 * @param {ChunkGroupOptions} options the chunkGroup options passed to addOptions
+	 * @returns {void}
+	 */
+	addOptions(options) {
+		for (const key of /** @type {(keyof ChunkGroupOptions)[]} */ (
+			Object.keys(options)
+		)) {
+			if (this.options[key] === undefined) {
+				/** @type {ChunkGroupOptions[keyof ChunkGroupOptions]} */
+				(this.options[key]) = options[key];
+			} else if (this.options[key] !== options[key]) {
+				if (key.endsWith("Order")) {
+					const orderKey =
+						/** @type {Exclude<keyof ChunkGroupOptions, "name" | "fetchPriority">} */
+						(key);
+
+					this.options[orderKey] = Math.max(
+						/** @type {number} */
+						(this.options[orderKey]),
+						/** @type {number} */
+						(options[orderKey])
+					);
+				} else {
+					throw new Error(
+						`ChunkGroup.addOptions: No option merge strategy for ${key}`
+					);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns the configured name of the chunk group, if one was assigned.
+	 * @returns {ChunkGroupOptions["name"]} returns the ChunkGroup name
+	 */
+	get name() {
+		return this.options.name;
+	}
+
+	/**
+	 * Updates the configured name of the chunk group.
+	 * @param {string | undefined} value the new name for ChunkGroup
+	 * @returns {void}
+	 */
+	set name(value) {
+		this.options.name = value;
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns a debug-only identifier derived from the group's member chunk
+	 * debug ids. This is primarily useful in diagnostics and assertions.
+	 * @returns {string} a unique concatenation of chunk debugId's
+	 */
+	get debugId() {
+		return Array.from(this.chunks, (x) => x.debugId).join("+");
+	}
+
+	/**
+	 * Returns an identifier derived from the ids of the chunks currently in
+	 * the group.
+	 * @returns {string} a unique concatenation of chunk ids
+	 */
+	get id() {
+		return Array.from(this.chunks, (x) => x.id).join("+");
+	}
+
+	/**
+	 * Moves a chunk to the front of the group or inserts it when it is not
+	 * already present.
+	 * @param {Chunk} chunk chunk being unshifted
+	 * @returns {boolean} returns true if attempted chunk shift is accepted
+	 */
+	unshiftChunk(chunk) {
+		const oldIdx = this.chunks.indexOf(chunk);
+		if (oldIdx > 0) {
+			this.chunks.splice(oldIdx, 1);
+			this.chunks.unshift(chunk);
+		} else if (oldIdx < 0) {
+			this.chunks.unshift(chunk);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Inserts a chunk directly before another chunk that already belongs to the
+	 * group, preserving the rest of the ordering.
+	 * @param {Chunk} chunk Chunk being inserted
+	 * @param {Chunk} before Placeholder/target chunk marking new chunk insertion point
+	 * @returns {boolean} return true if insertion was successful
+	 */
+	insertChunk(chunk, before) {
+		const oldIdx = this.chunks.indexOf(chunk);
+		const idx = this.chunks.indexOf(before);
+		if (idx < 0) {
+			throw new Error("before chunk not found");
+		}
+		if (oldIdx >= 0 && oldIdx > idx) {
+			this.chunks.splice(oldIdx, 1);
+			this.chunks.splice(idx, 0, chunk);
+		} else if (oldIdx < 0) {
+			this.chunks.splice(idx, 0, chunk);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Appends a chunk to the group when it is not already a member.
+	 * @param {Chunk} chunk chunk being pushed into ChunkGroupS
+	 * @returns {boolean} returns true if chunk addition was successful.
+	 */
+	pushChunk(chunk) {
+		const oldIdx = this.chunks.indexOf(chunk);
+		if (oldIdx >= 0) {
+			return false;
+		}
+		this.chunks.push(chunk);
+		return true;
+	}
+
+	/**
+	 * Replaces one member chunk with another while preserving the group's
+	 * ordering and avoiding duplicates.
+	 * @param {Chunk} oldChunk chunk to be replaced
+	 * @param {Chunk} newChunk New chunk that will be replaced with
+	 * @returns {boolean | undefined} returns true if the replacement was successful
+	 */
+	replaceChunk(oldChunk, newChunk) {
+		const oldIdx = this.chunks.indexOf(oldChunk);
+		if (oldIdx < 0) return false;
+		const newIdx = this.chunks.indexOf(newChunk);
+		if (newIdx < 0) {
+			this.chunks[oldIdx] = newChunk;
+			return true;
+		}
+		if (newIdx < oldIdx) {
+			this.chunks.splice(oldIdx, 1);
+			return true;
+		} else if (newIdx !== oldIdx) {
+			this.chunks[oldIdx] = newChunk;
+			this.chunks.splice(newIdx, 1);
+			return true;
+		}
+	}
+
+	/**
+	 * Removes a chunk from this group.
+	 * @param {Chunk} chunk chunk to remove
+	 * @returns {boolean} returns true if chunk was removed
+	 */
+	removeChunk(chunk) {
+		const idx = this.chunks.indexOf(chunk);
+		if (idx >= 0) {
+			this.chunks.splice(idx, 1);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Indicates whether this chunk group is loaded as part of the initial page
+	 * load instead of being created lazily.
+	 * @returns {boolean} true, when this chunk group will be loaded on initial page load
+	 */
+	isInitial() {
+		return false;
+	}
+
+	/**
+	 * Adds a child chunk group to the current group.
+	 * @param {ChunkGroup} group chunk group to add
+	 * @returns {boolean} returns true if chunk group was added
+	 */
+	addChild(group) {
+		const size = this._children.size;
+		this._children.add(group);
+		return size !== this._children.size;
+	}
+
+	/**
+	 * Returns the child chunk groups reachable from this group.
+	 * @returns {ChunkGroup[]} returns the children of this group
+	 */
+	getChildren() {
+		return this._children.getFromCache(getArray);
+	}
+
+	getNumberOfChildren() {
+		return this._children.size;
+	}
+
+	get childrenIterable() {
+		return this._children;
+	}
+
+	/**
+	 * Removes a child chunk group and clears the corresponding parent link on
+	 * the removed child.
+	 * @param {ChunkGroup} group the chunk group to remove
+	 * @returns {boolean} returns true if the chunk group was removed
+	 */
+	removeChild(group) {
+		if (!this._children.has(group)) {
+			return false;
+		}
+
+		this._children.delete(group);
+		group.removeParent(this);
+		return true;
+	}
+
+	/**
+	 * Records a parent chunk group relationship.
+	 * @param {ChunkGroup} parentChunk the parent group to be added into
+	 * @returns {boolean} returns true if this chunk group was added to the parent group
+	 */
+	addParent(parentChunk) {
+		if (!this._parents.has(parentChunk)) {
+			this._parents.add(parentChunk);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the parent chunk groups that can lead to this group.
+	 * @returns {ChunkGroup[]} returns the parents of this group
+	 */
+	getParents() {
+		return this._parents.getFromCache(getArray);
+	}
+
+	getNumberOfParents() {
+		return this._parents.size;
+	}
+
+	/**
+	 * Checks whether the provided group is registered as a parent.
+	 * @param {ChunkGroup} parent the parent group
+	 * @returns {boolean} returns true if the parent group contains this group
+	 */
+	hasParent(parent) {
+		return this._parents.has(parent);
+	}
+
+	get parentsIterable() {
+		return this._parents;
+	}
+
+	/**
+	 * Removes a parent chunk group and clears the reverse child relationship.
+	 * @param {ChunkGroup} chunkGroup the parent group
+	 * @returns {boolean} returns true if this group has been removed from the parent
+	 */
+	removeParent(chunkGroup) {
+		if (this._parents.delete(chunkGroup)) {
+			chunkGroup.removeChild(this);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Registers an async entrypoint that is rooted in this chunk group.
+	 * @param {Entrypoint} entrypoint entrypoint to add
+	 * @returns {boolean} returns true if entrypoint was added
+	 */
+	addAsyncEntrypoint(entrypoint) {
+		const size = this._asyncEntrypoints.size;
+		this._asyncEntrypoints.add(entrypoint);
+		return size !== this._asyncEntrypoints.size;
+	}
+
+	get asyncEntrypointsIterable() {
+		return this._asyncEntrypoints;
+	}
+
+	/**
+	 * Returns the async dependency blocks that create or reference this group.
+	 * @returns {AsyncDependenciesBlock[]} an array containing the blocks
+	 */
+	getBlocks() {
+		return this._blocks.getFromCache(getArray);
+	}
+
+	getNumberOfBlocks() {
+		return this._blocks.size;
+	}
+
+	/**
+	 * Checks whether an async dependency block is associated with this group.
+	 * @param {AsyncDependenciesBlock} block block
+	 * @returns {boolean} true, if block exists
+	 */
+	hasBlock(block) {
+		return this._blocks.has(block);
+	}
+
+	/**
+	 * Exposes the group's async dependency blocks as an iterable.
+	 * @returns {Iterable<AsyncDependenciesBlock>} blocks
+	 */
+	get blocksIterable() {
+		return this._blocks;
+	}
+
+	/**
+	 * Associates an async dependency block with this chunk group.
+	 * @param {AsyncDependenciesBlock} block a block
+	 * @returns {boolean} false, if block was already added
+	 */
+	addBlock(block) {
+		if (!this._blocks.has(block)) {
+			this._blocks.add(block);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Records where this chunk group originated from in user code.
+	 * The origin is used for diagnostics, ordering, and reporting.
+	 * @param {Module | null} module origin module
+	 * @param {DependencyLocation} loc location of the reference in the origin module
+	 * @param {string} request request name of the reference
+	 * @returns {void}
+	 */
+	addOrigin(module, loc, request) {
+		this.origins.push({
+			module,
+			loc,
+			request
+		});
+	}
+
+	/**
+	 * Collects the emitted files produced by every chunk in the group.
+	 * @returns {string[]} the files contained this chunk group
+	 */
+	getFiles() {
+		/** @type {Set<string>} */
+		const files = new Set();
+
+		for (const chunk of this.chunks) {
+			for (const file of chunk.files) {
+				files.add(file);
+			}
+		}
+
+		return [...files];
+	}
+
+	/**
+	 * Disconnects this group from its parents, children, and chunks.
+	 * Child groups are reconnected to this group's parents so the surrounding
+	 * graph remains intact after removal.
+	 * @returns {void}
+	 */
+	remove() {
+		// cleanup parents
+		for (const parentChunkGroup of this._parents) {
+			// remove this chunk from its parents
+			parentChunkGroup._children.delete(this);
+
+			// cleanup "sub chunks"
+			for (const chunkGroup of this._children) {
+				/**
+				 * remove this chunk as "intermediary" and connect
+				 * it "sub chunks" and parents directly
+				 */
+				// add parent to each "sub chunk"
+				chunkGroup.addParent(parentChunkGroup);
+				// add "sub chunk" to parent
+				parentChunkGroup.addChild(chunkGroup);
+			}
+		}
+
+		/**
+		 * we need to iterate again over the children
+		 * to remove this from the child's parents.
+		 * This can not be done in the above loop
+		 * as it is not guaranteed that `this._parents` contains anything.
+		 */
+		for (const chunkGroup of this._children) {
+			// remove this as parent of every "sub chunk"
+			chunkGroup._parents.delete(this);
+		}
+
+		// remove chunks
+		for (const chunk of this.chunks) {
+			chunk.removeGroup(this);
+		}
+	}
+
+	sortItems() {
+		this.origins.sort(sortOrigin);
+	}
+
+	/**
+	 * Sorting predicate which allows current ChunkGroup to be compared against another.
+	 * Sorting values are based off of number of chunks in ChunkGroup.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {ChunkGroup} otherGroup the chunkGroup to compare this against
+	 * @returns {-1 | 0 | 1} sort position for comparison
+	 */
+	compareTo(chunkGraph, otherGroup) {
+		if (this.chunks.length > otherGroup.chunks.length) return -1;
+		if (this.chunks.length < otherGroup.chunks.length) return 1;
+		return compareIterables(compareChunks(chunkGraph))(
+			this.chunks,
+			otherGroup.chunks
+		);
+	}
+
+	/**
+	 * Aggregates per-block `*Order` options for the blocks that bridge this
+	 * chunk group to the given child chunk group. `*Order` options are tied to
+	 * the originating `import()` call and must not be sourced from the child's
+	 * shared options, otherwise a webpackPrefetch/Preload directive from one
+	 * parent would leak into other parents that share the child by name.
+	 * @param {ChunkGroup} childGroup the child chunk group
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {Record<string, number>} merged `*Order` options for the edge from this group to `childGroup`
+	 */
+	getChildOrderOptions(childGroup, chunkGraph) {
+		/** @type {Record<string, number>} */
+		const result = Object.create(null);
+		let bridged = false;
+		for (const block of childGroup.blocksIterable) {
+			const rootModule = /** @type {Module} */ (block.getRootBlock());
+			if (!chunkGraph.isModuleInChunkGroup(rootModule, this)) continue;
+			bridged = true;
+			const opts = block.groupOptions;
+			if (!opts) continue;
+			for (const key of Object.keys(opts)) {
+				if (!key.endsWith("Order")) continue;
+				const value =
+					/** @type {number} */
+					(opts[/** @type {keyof ChunkGroupOptions} */ (key)]);
+				if (typeof value !== "number") continue;
+				if (result[key] === undefined || value > result[key]) {
+					result[key] = value;
+				}
+			}
+		}
+		// Fall back to the child's own options only when no block bridges
+		// this edge (e.g. a chunk group created by APIs that don't go through
+		// an AsyncDependenciesBlock). Otherwise we'd reintroduce the leak.
+		if (!bridged) {
+			for (const key of Object.keys(childGroup.options)) {
+				if (!key.endsWith("Order")) continue;
+				const value =
+					childGroup.options[/** @type {keyof ChunkGroupOptions} */ (key)];
+				if (typeof value === "number") {
+					result[key] = value;
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Groups child chunk groups by their `*Order` options and sorts each group
+	 * by descending order and deterministic chunk-group comparison.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {Record<string, ChunkGroup[]>} mapping from children type to ordered list of ChunkGroups
+	 */
+	getChildrenByOrders(moduleGraph, chunkGraph) {
+		/** @type {Map<string, { order: number, group: ChunkGroup }[]>} */
+		const lists = new Map();
+		for (const childGroup of this._children) {
+			const edgeOptions = this.getChildOrderOptions(childGroup, chunkGraph);
+			for (const key of Object.keys(edgeOptions)) {
+				const name = key.slice(0, key.length - "Order".length);
+				let list = lists.get(name);
+				if (list === undefined) {
+					lists.set(name, (list = []));
+				}
+				list.push({
+					order: edgeOptions[key],
+					group: childGroup
+				});
+			}
+		}
+		/** @type {Record<string, ChunkGroup[]>} */
+		const result = Object.create(null);
+		for (const [name, list] of lists) {
+			list.sort((a, b) => {
+				const cmp = b.order - a.order;
+				if (cmp !== 0) return cmp;
+				return a.group.compareTo(chunkGraph, b.group);
+			});
+			result[name] = list.map((i) => i.group);
+		}
+		return result;
+	}
+
+	/**
+	 * Stores the module's top-down traversal index within this group.
+	 * @param {Module} module module for which the index should be set
+	 * @param {number} index the index of the module
+	 * @returns {void}
+	 */
+	setModulePreOrderIndex(module, index) {
+		this._modulePreOrderIndices.set(module, index);
+	}
+
+	/**
+	 * Returns the module's top-down traversal index within this group.
+	 * @param {Module} module the module
+	 * @returns {number | undefined} index
+	 */
+	getModulePreOrderIndex(module) {
+		return this._modulePreOrderIndices.get(module);
+	}
+
+	/**
+	 * Stores the module's bottom-up traversal index within this group.
+	 * @param {Module} module module for which the index should be set
+	 * @param {number} index the index of the module
+	 * @returns {void}
+	 */
+	setModulePostOrderIndex(module, index) {
+		this._modulePostOrderIndices.set(module, index);
+	}
+
+	/**
+	 * Returns the module's bottom-up traversal index within this group.
+	 * @param {Module} module the module
+	 * @returns {number | undefined} index
+	 */
+	getModulePostOrderIndex(module) {
+		return this._modulePostOrderIndices.get(module);
+	}
+
+	/* istanbul ignore next */
+	checkConstraints() {
+		const chunk = this;
+		for (const child of chunk._children) {
+			if (!child._parents.has(chunk)) {
+				throw new Error(
+					`checkConstraints: child missing parent ${chunk.debugId} -> ${child.debugId}`
+				);
+			}
+		}
+		for (const parentChunk of chunk._parents) {
+			if (!parentChunk._children.has(chunk)) {
+				throw new Error(
+					`checkConstraints: parent missing child ${parentChunk.debugId} <- ${chunk.debugId}`
+				);
+			}
+		}
+	}
+}
+
+ChunkGroup.prototype.getModuleIndex = util.deprecate(
+	ChunkGroup.prototype.getModulePreOrderIndex,
+	"ChunkGroup.getModuleIndex was renamed to getModulePreOrderIndex",
+	"DEP_WEBPACK_CHUNK_GROUP_GET_MODULE_INDEX"
+);
+
+ChunkGroup.prototype.getModuleIndex2 = util.deprecate(
+	ChunkGroup.prototype.getModulePostOrderIndex,
+	"ChunkGroup.getModuleIndex2 was renamed to getModulePostOrderIndex",
+	"DEP_WEBPACK_CHUNK_GROUP_GET_MODULE_INDEX_2"
+);
+
+module.exports = ChunkGroup;
Index: frontend/node_modules/webpack/lib/ChunkTemplate.js
===================================================================
--- frontend/node_modules/webpack/lib/ChunkTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ChunkTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,190 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("tapable").Tap} Tap */
+/** @typedef {import("./config/defaults").OutputNormalizedWithDefaults} OutputOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("./Compilation").Hash} Hash */
+/** @typedef {import("./Compilation").RenderManifestEntry} RenderManifestEntry */
+/** @typedef {import("./Compilation").RenderManifestOptions} RenderManifestOptions */
+/** @typedef {import("./Compilation").Source} Source */
+/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/**
+ * Defines the if set type used by this module.
+ * @template T
+ * @typedef {import("tapable").IfSet<T>} IfSet
+ */
+
+const getJavascriptModulesPlugin = memoize(() =>
+	require("./javascript/JavascriptModulesPlugin")
+);
+
+// TODO webpack 6 remove this class
+class ChunkTemplate {
+	/**
+	 * Creates an instance of ChunkTemplate.
+	 * @param {OutputOptions} outputOptions output options
+	 * @param {Compilation} compilation the compilation
+	 */
+	constructor(outputOptions, compilation) {
+		this._outputOptions = outputOptions || {};
+		this.hooks = Object.freeze({
+			renderManifest: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(renderManifestEntries: RenderManifestEntry[], renderManifestOptions: RenderManifestOptions) => RenderManifestEntry[]} fn function
+					 */
+					(options, fn) => {
+						compilation.hooks.renderManifest.tap(
+							options,
+							(entries, options) => {
+								if (options.chunk.hasRuntime()) return entries;
+								return fn(entries, options);
+							}
+						);
+					},
+					"ChunkTemplate.hooks.renderManifest is deprecated (use Compilation.hooks.renderManifest instead)",
+					"DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_MANIFEST"
+				)
+			},
+			modules: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, moduleTemplate: ModuleTemplate, renderContext: RenderContext) => Source} fn function
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderChunk.tap(options, (source, renderContext) =>
+								fn(
+									source,
+									compilation.moduleTemplates.javascript,
+									renderContext
+								)
+							);
+					},
+					"ChunkTemplate.hooks.modules is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderChunk instead)",
+					"DEP_WEBPACK_CHUNK_TEMPLATE_MODULES"
+				)
+			},
+			render: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, moduleTemplate: ModuleTemplate, renderContext: RenderContext) => Source} fn function
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderChunk.tap(options, (source, renderContext) =>
+								fn(
+									source,
+									compilation.moduleTemplates.javascript,
+									renderContext
+								)
+							);
+					},
+					"ChunkTemplate.hooks.render is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderChunk instead)",
+					"DEP_WEBPACK_CHUNK_TEMPLATE_RENDER"
+				)
+			},
+			renderWithEntry: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, chunk: Chunk) => Source} fn function
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.render.tap(options, (source, renderContext) => {
+								if (
+									renderContext.chunkGraph.getNumberOfEntryModules(
+										renderContext.chunk
+									) === 0 ||
+									renderContext.chunk.hasRuntime()
+								) {
+									return source;
+								}
+								return fn(source, renderContext.chunk);
+							});
+					},
+					"ChunkTemplate.hooks.renderWithEntry is deprecated (use JavascriptModulesPlugin.getCompilationHooks().render instead)",
+					"DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_WITH_ENTRY"
+				)
+			},
+			hash: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(hash: Hash) => void} fn function
+					 */
+					(options, fn) => {
+						compilation.hooks.fullHash.tap(options, fn);
+					},
+					"ChunkTemplate.hooks.hash is deprecated (use Compilation.hooks.fullHash instead)",
+					"DEP_WEBPACK_CHUNK_TEMPLATE_HASH"
+				)
+			},
+			hashForChunk: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(hash: Hash, chunk: Chunk, chunkHashContext: ChunkHashContext) => void} fn function
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.chunkHash.tap(options, (chunk, hash, context) => {
+								if (chunk.hasRuntime()) return;
+								fn(hash, chunk, context);
+							});
+					},
+					"ChunkTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)",
+					"DEP_WEBPACK_CHUNK_TEMPLATE_HASH_FOR_CHUNK"
+				)
+			}
+		});
+	}
+}
+
+Object.defineProperty(ChunkTemplate.prototype, "outputOptions", {
+	get: util.deprecate(
+		/**
+		 * Returns output options.
+		 * @this {ChunkTemplate}
+		 * @returns {OutputOptions} output options
+		 */
+		function outputOptions() {
+			return this._outputOptions;
+		},
+		"ChunkTemplate.outputOptions is deprecated (use Compilation.outputOptions instead)",
+		"DEP_WEBPACK_CHUNK_TEMPLATE_OUTPUT_OPTIONS"
+	)
+});
+
+module.exports = ChunkTemplate;
Index: frontend/node_modules/webpack/lib/CleanPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/CleanPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/CleanPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,511 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const path = require("path");
+const asyncLib = require("neo-async");
+const { SyncBailHook } = require("tapable");
+const Compilation = require("./Compilation");
+const { join } = require("./util/fs");
+const processAsyncTree = require("./util/processAsyncTree");
+
+/** @typedef {import("../declarations/WebpackOptions").CleanOptions} CleanOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./util/fs").IStats} IStats */
+/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
+/** @typedef {import("./util/fs").StatsCallback} StatsCallback */
+
+/** @typedef {Map<string, number>} Assets */
+
+/**
+ * Defines the clean plugin compilation hooks type used by this module.
+ * @typedef {object} CleanPluginCompilationHooks
+ * @property {SyncBailHook<[string], boolean | void>} keep when returning true the file/directory will be kept during cleaning, returning false will clean it and ignore the following plugins and config
+ */
+
+/**
+ * Defines the keep fn callback.
+ * @callback KeepFn
+ * @param {string} path path
+ * @returns {boolean | undefined} true, if the path should be kept
+ */
+
+const _10sec = 10 * 1000;
+
+/**
+ * merge assets map 2 into map 1
+ * @param {Assets} as1 assets
+ * @param {Assets} as2 assets
+ * @returns {void}
+ */
+const mergeAssets = (as1, as2) => {
+	for (const [key, value1] of as2) {
+		const value2 = as1.get(key);
+		if (!value2 || value1 > value2) as1.set(key, value1);
+	}
+};
+
+/** @typedef {Map<string, number>} CurrentAssets */
+
+/**
+ * Returns set of directory paths.
+ * @param {CurrentAssets} assets current assets
+ * @returns {Set<string>} Set of directory paths
+ */
+function getDirectories(assets) {
+	/** @type {Set<string>} */
+	const directories = new Set();
+	/**
+	 * Adds the provided filename to this object.
+	 * @param {string} filename asset filename
+	 */
+	const addDirectory = (filename) => {
+		directories.add(path.dirname(filename));
+	};
+
+	// get directories of assets
+	for (const [asset] of assets) {
+		addDirectory(asset);
+	}
+	// and all parent directories
+	for (const directory of directories) {
+		addDirectory(directory);
+	}
+	return directories;
+}
+
+/** @typedef {Set<string>} Diff */
+
+/**
+ * Returns diff to fs.
+ * @param {OutputFileSystem} fs filesystem
+ * @param {string} outputPath output path
+ * @param {CurrentAssets} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
+ * @param {(err?: Error | null, set?: Diff) => void} callback returns the filenames of the assets that shouldn't be there
+ * @returns {void}
+ */
+const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
+	const directories = getDirectories(currentAssets);
+	/** @type {Diff} */
+	const diff = new Set();
+	asyncLib.forEachLimit(
+		directories,
+		10,
+		(directory, callback) => {
+			/** @type {NonNullable<OutputFileSystem["readdir"]>} */
+			(fs.readdir)(join(fs, outputPath, directory), (err, entries) => {
+				if (err) {
+					if (err.code === "ENOENT") return callback();
+					if (err.code === "ENOTDIR") {
+						diff.add(directory);
+						return callback();
+					}
+					return callback(err);
+				}
+				for (const entry of /** @type {string[]} */ (entries)) {
+					const file = entry;
+					// Since path.normalize("./file") === path.normalize("file"),
+					// return file directly when directory === "."
+					const filename =
+						directory && directory !== "." ? `${directory}/${file}` : file;
+					if (!directories.has(filename) && !currentAssets.has(filename)) {
+						diff.add(filename);
+					}
+				}
+				callback();
+			});
+		},
+		(err) => {
+			if (err) return callback(err);
+
+			callback(null, diff);
+		}
+	);
+};
+
+/**
+ * Gets diff to old assets.
+ * @param {Assets} currentAssets assets list
+ * @param {Assets} oldAssets old assets list
+ * @returns {Diff} diff
+ */
+const getDiffToOldAssets = (currentAssets, oldAssets) => {
+	/** @type {Diff} */
+	const diff = new Set();
+	const now = Date.now();
+	for (const [asset, ts] of oldAssets) {
+		if (ts >= now) continue;
+		if (!currentAssets.has(asset)) diff.add(asset);
+	}
+	return diff;
+};
+
+/**
+ * Processes the provided f.
+ * @param {OutputFileSystem} fs filesystem
+ * @param {string} filename path to file
+ * @param {StatsCallback} callback callback for provided filename
+ * @returns {void}
+ */
+const doStat = (fs, filename, callback) => {
+	if ("lstat" in fs) {
+		/** @type {NonNullable<OutputFileSystem["lstat"]>} */
+		(fs.lstat)(filename, callback);
+	} else {
+		fs.stat(filename, callback);
+	}
+};
+
+/**
+ * Processes the provided f.
+ * @param {OutputFileSystem} fs filesystem
+ * @param {string} outputPath output path
+ * @param {boolean} dry only log instead of fs modification
+ * @param {Logger} logger logger
+ * @param {Diff} diff filenames of the assets that shouldn't be there
+ * @param {KeepFn} isKept check if the entry is ignored
+ * @param {(err?: Error, assets?: Assets) => void} callback callback
+ * @returns {void}
+ */
+const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
+	/**
+	 * Processes the provided msg.
+	 * @param {string} msg message
+	 */
+	const log = (msg) => {
+		if (dry) {
+			logger.info(msg);
+		} else {
+			logger.log(msg);
+		}
+	};
+	/** @typedef {{ type: "check" | "unlink" | "rmdir", filename: string, parent: { remaining: number, job: Job } | undefined }} Job */
+	/** @type {Job[]} */
+	const jobs = Array.from(diff.keys(), (filename) => ({
+		type: "check",
+		filename,
+		parent: undefined
+	}));
+	/** @type {Assets} */
+	const keptAssets = new Map();
+	processAsyncTree(
+		jobs,
+		10,
+		({ type, filename, parent }, push, callback) => {
+			const path = join(fs, outputPath, filename);
+			/**
+			 * Describes how this handle error operation behaves.
+			 * @param {Error & { code?: string }} err error
+			 * @returns {void}
+			 */
+			const handleError = (err) => {
+				const isAlreadyRemoved = () =>
+					new Promise((resolve) => {
+						if (err.code === "ENOENT") {
+							resolve(true);
+						} else if (err.code === "EPERM") {
+							// https://github.com/isaacs/rimraf/blob/main/src/fix-eperm.ts#L37
+							// fs.existsSync(path) === false https://github.com/webpack/webpack/actions/runs/15493412975/job/43624272783?pr=19586
+							doStat(fs, path, (err) => {
+								if (err) {
+									resolve(err.code === "ENOENT");
+								} else {
+									resolve(false);
+								}
+							});
+						} else {
+							resolve(false);
+						}
+					});
+
+				isAlreadyRemoved().then((isRemoved) => {
+					if (isRemoved) {
+						log(`${filename} was removed during cleaning by something else`);
+						handleParent();
+						return callback();
+					}
+					return callback(err);
+				});
+			};
+			const handleParent = () => {
+				if (parent && --parent.remaining === 0) push(parent.job);
+			};
+			switch (type) {
+				case "check":
+					if (isKept(filename)) {
+						keptAssets.set(filename, 0);
+						// do not decrement parent entry as we don't want to delete the parent
+						log(`${filename} will be kept`);
+						return process.nextTick(callback);
+					}
+					doStat(fs, path, (err, stats) => {
+						if (err) return handleError(err);
+						if (!(/** @type {IStats} */ (stats).isDirectory())) {
+							push({
+								type: "unlink",
+								filename,
+								parent
+							});
+							return callback();
+						}
+
+						/** @type {NonNullable<OutputFileSystem["readdir"]>} */
+						(fs.readdir)(path, (err, _entries) => {
+							if (err) return handleError(err);
+							/** @type {Job} */
+							const deleteJob = {
+								type: "rmdir",
+								filename,
+								parent
+							};
+							const entries = /** @type {string[]} */ (_entries);
+							if (entries.length === 0) {
+								push(deleteJob);
+							} else {
+								const parentToken = {
+									remaining: entries.length,
+									job: deleteJob
+								};
+								for (const entry of entries) {
+									const file = /** @type {string} */ (entry);
+									if (file.startsWith(".")) {
+										log(
+											`${filename} will be kept (dot-files will never be removed)`
+										);
+										continue;
+									}
+									push({
+										type: "check",
+										filename: `${filename}/${file}`,
+										parent: parentToken
+									});
+								}
+							}
+							return callback();
+						});
+					});
+					break;
+				case "rmdir":
+					log(`${filename} will be removed`);
+					if (dry) {
+						handleParent();
+						return process.nextTick(callback);
+					}
+					if (!fs.rmdir) {
+						logger.warn(
+							`${filename} can't be removed because output file system doesn't support removing directories (rmdir)`
+						);
+						return process.nextTick(callback);
+					}
+					fs.rmdir(path, (err) => {
+						if (err) return handleError(err);
+						handleParent();
+						callback();
+					});
+					break;
+				case "unlink":
+					log(`${filename} will be removed`);
+					if (dry) {
+						handleParent();
+						return process.nextTick(callback);
+					}
+					if (!fs.unlink) {
+						logger.warn(
+							`${filename} can't be removed because output file system doesn't support removing files (rmdir)`
+						);
+						return process.nextTick(callback);
+					}
+					fs.unlink(path, (err) => {
+						if (err) return handleError(err);
+						handleParent();
+						callback();
+					});
+					break;
+			}
+		},
+		(err) => {
+			if (err) return callback(err);
+			callback(undefined, keptAssets);
+		}
+	);
+};
+
+/** @type {WeakMap<Compilation, CleanPluginCompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+const PLUGIN_NAME = "CleanPlugin";
+
+class CleanPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CleanPluginCompilationHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				keep: new SyncBailHook(["ignore"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/** @param {CleanOptions} options options */
+	constructor(options = {}) {
+		/** @type {CleanOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => {
+					const { definitions } = require("../schemas/WebpackOptions.json");
+
+					return {
+						definitions,
+						oneOf: [{ $ref: "#/definitions/CleanOptions" }]
+					};
+				},
+				this.options,
+				{
+					name: "Clean Plugin",
+					baseDataPath: "options"
+				}
+			);
+		});
+
+		const { keep } = this.options;
+
+		/** @type {boolean} */
+		const dry = this.options.dry || false;
+		/** @type {KeepFn} */
+		const keepFn =
+			typeof keep === "function"
+				? keep
+				: typeof keep === "string"
+					? (path) => path.startsWith(keep)
+					: typeof keep === "object" && keep.test
+						? (path) => keep.test(path)
+						: () => false;
+
+		// We assume that no external modification happens while the compiler is active
+		// So we can store the old assets and only diff to them to avoid fs access on
+		// incremental builds
+		/** @type {undefined | Assets} */
+		let oldAssets;
+
+		compiler.hooks.emit.tapAsync(
+			{
+				name: PLUGIN_NAME,
+				stage: 100
+			},
+			(compilation, callback) => {
+				const hooks = CleanPlugin.getCompilationHooks(compilation);
+				const logger = compilation.getLogger(`webpack.${PLUGIN_NAME}`);
+				const fs = /** @type {OutputFileSystem} */ (compiler.outputFileSystem);
+
+				if (!fs.readdir) {
+					return callback(
+						new Error(
+							`${PLUGIN_NAME}: Output filesystem doesn't support listing directories (readdir)`
+						)
+					);
+				}
+
+				/** @type {Assets} */
+				const currentAssets = new Map();
+				const now = Date.now();
+				for (const asset of Object.keys(compilation.assets)) {
+					if (/^[a-z]:\\|^\/|^\\\\/i.test(asset)) continue;
+					/** @type {string} */
+					let normalizedAsset;
+					let newNormalizedAsset = asset.replace(/\\/g, "/");
+					do {
+						normalizedAsset = newNormalizedAsset;
+						newNormalizedAsset = normalizedAsset.replace(
+							/(^|\/)(?!\.\.)[^/]+\/\.\.\//g,
+							"$1"
+						);
+					} while (newNormalizedAsset !== normalizedAsset);
+					if (normalizedAsset.startsWith("../")) continue;
+					const assetInfo = compilation.assetsInfo.get(asset);
+					if (assetInfo && assetInfo.hotModuleReplacement) {
+						currentAssets.set(normalizedAsset, now + _10sec);
+					} else {
+						currentAssets.set(normalizedAsset, 0);
+					}
+				}
+
+				const outputPath = compilation.getPath(compiler.outputPath, {});
+
+				/**
+				 * Checks whether this clean plugin is kept.
+				 * @param {string} path path
+				 * @returns {boolean | undefined} true, if needs to be kept
+				 */
+				const isKept = (path) => {
+					const result = hooks.keep.call(path);
+					if (result !== undefined) return result;
+					return keepFn(path);
+				};
+
+				/**
+				 * Processes the provided err.
+				 * @param {(Error | null)=} err err
+				 * @param {Diff=} diff diff
+				 */
+				const diffCallback = (err, diff) => {
+					if (err) {
+						oldAssets = undefined;
+						callback(err);
+						return;
+					}
+					applyDiff(
+						fs,
+						outputPath,
+						dry,
+						logger,
+						/** @type {Diff} */ (diff),
+						isKept,
+						(err, keptAssets) => {
+							if (err) {
+								oldAssets = undefined;
+							} else {
+								if (oldAssets) mergeAssets(currentAssets, oldAssets);
+								oldAssets = currentAssets;
+								if (keptAssets) mergeAssets(oldAssets, keptAssets);
+							}
+							callback(err);
+						}
+					);
+				};
+
+				if (oldAssets) {
+					diffCallback(null, getDiffToOldAssets(currentAssets, oldAssets));
+				} else {
+					getDiffToFs(fs, outputPath, currentAssets, diffCallback);
+				}
+			}
+		);
+	}
+}
+
+module.exports = CleanPlugin;
+module.exports._getDirectories = getDirectories;
Index: frontend/node_modules/webpack/lib/CodeGenerationResults.js
===================================================================
--- frontend/node_modules/webpack/lib/CodeGenerationResults.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/CodeGenerationResults.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,186 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { DEFAULTS } = require("./config/defaults");
+const { getOrInsert } = require("./util/MapHelpers");
+const { first } = require("./util/SetHelpers");
+const createHash = require("./util/createHash");
+const { RuntimeSpecMap, runtimeToString } = require("./util/runtime");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").SourceType} SourceType */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("./util/Hash").HashFunction} HashFunction */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Stores code generation results keyed by module and runtime so later stages
+ * can retrieve emitted sources, metadata, and derived hashes.
+ */
+class CodeGenerationResults {
+	/**
+	 * Initializes an empty result store and remembers which hash function should
+	 * be used when a result hash needs to be derived lazily.
+	 * @param {HashFunction} hashFunction the hash function to use
+	 */
+	constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
+		/** @type {Map<Module, RuntimeSpecMap<CodeGenerationResult>>} */
+		this.map = new Map();
+		/** @type {HashFunction} */
+		this._hashFunction = hashFunction;
+	}
+
+	/**
+	 * Returns the code generation result for a module/runtime pair, rejecting
+	 * ambiguous lookups where no unique runtime-independent result exists.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @returns {CodeGenerationResult} the CodeGenerationResult
+	 */
+	get(module, runtime) {
+		const entry = this.map.get(module);
+		if (entry === undefined) {
+			throw new Error(
+				`No code generation entry for ${module.identifier()} (existing entries: ${Array.from(
+					this.map.keys(),
+					(m) => m.identifier()
+				).join(", ")})`
+			);
+		}
+		if (runtime === undefined) {
+			if (entry.size > 1) {
+				const results = new Set(entry.values());
+				if (results.size !== 1) {
+					throw new Error(
+						`No unique code generation entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from(
+							entry.keys(),
+							(r) => runtimeToString(r)
+						).join(", ")}).
+Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
+					);
+				}
+				return /** @type {CodeGenerationResult} */ (first(results));
+			}
+			return /** @type {CodeGenerationResult} */ (entry.values().next().value);
+		}
+		const result = entry.get(runtime);
+		if (result === undefined) {
+			throw new Error(
+				`No code generation entry for runtime ${runtimeToString(
+					runtime
+				)} for ${module.identifier()} (existing runtimes: ${Array.from(
+					entry.keys(),
+					(r) => runtimeToString(r)
+				).join(", ")})`
+			);
+		}
+		return result;
+	}
+
+	/**
+	 * Reports whether a module has a stored result for the requested runtime, or
+	 * a single unambiguous result when no runtime is specified.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @returns {boolean} true, when we have data for this
+	 */
+	has(module, runtime) {
+		const entry = this.map.get(module);
+		if (entry === undefined) {
+			return false;
+		}
+		if (runtime !== undefined) {
+			return entry.has(runtime);
+		} else if (entry.size > 1) {
+			const results = new Set(entry.values());
+			return results.size === 1;
+		}
+		return entry.size === 1;
+	}
+
+	/**
+	 * Returns a generated source of the requested source type from a stored code
+	 * generation result.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @param {SourceType} sourceType the source type
+	 * @returns {Source} a source
+	 */
+	getSource(module, runtime, sourceType) {
+		return /** @type {Source} */ (
+			this.get(module, runtime).sources.get(sourceType)
+		);
+	}
+
+	/**
+	 * Returns the runtime requirements captured during code generation for the
+	 * requested module/runtime pair.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @returns {ReadOnlyRuntimeRequirements | null} runtime requirements
+	 */
+	getRuntimeRequirements(module, runtime) {
+		return this.get(module, runtime).runtimeRequirements;
+	}
+
+	/**
+	 * Returns an arbitrary metadata entry recorded during code generation.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @param {string} key data key
+	 * @returns {ReturnType<CodeGenerationResultData["get"]>} data generated by code generation
+	 */
+	getData(module, runtime, key) {
+		const data = this.get(module, runtime).data;
+		return data === undefined ? undefined : data.get(key);
+	}
+
+	/**
+	 * Returns a stable hash for the generated sources and runtime requirements,
+	 * computing and caching it on first access.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @returns {string} hash of the code generation
+	 */
+	getHash(module, runtime) {
+		const info = this.get(module, runtime);
+		if (info.hash !== undefined) return info.hash;
+		const hash = createHash(this._hashFunction);
+		for (const [type, source] of info.sources) {
+			hash.update(type);
+			source.updateHash(hash);
+		}
+		if (info.runtimeRequirements) {
+			for (const rr of info.runtimeRequirements) hash.update(rr);
+		}
+		return (info.hash = hash.digest("hex"));
+	}
+
+	/**
+	 * Stores a code generation result for a module/runtime pair, creating the
+	 * per-module runtime map when needed.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime runtime(s)
+	 * @param {CodeGenerationResult} result result from module
+	 * @returns {void}
+	 */
+	add(module, runtime, result) {
+		const map = getOrInsert(
+			this.map,
+			module,
+			() =>
+				/** @type {RuntimeSpecMap<CodeGenerationResult>} */
+				new RuntimeSpecMap()
+		);
+		map.set(runtime, result);
+	}
+}
+
+module.exports = CodeGenerationResults;
Index: frontend/node_modules/webpack/lib/CompatibilityPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/CompatibilityPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/CompatibilityPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,255 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const ConstDependency = require("./dependencies/ConstDependency");
+
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./dependencies/ContextDependency")} ContextDependency */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+/**
+ * Captures the source range of a renamed compatibility binding so it can be
+ * rewritten exactly once.
+ * @typedef {object} CompatibilitySettingsDeclaration
+ * @property {boolean} updated
+ * @property {DependencyLocation} loc
+ * @property {Range} range
+ */
+
+/**
+ * Stores the replacement variable name and the declaration metadata tracked
+ * for a compatibility rewrite.
+ * @typedef {object} CompatibilitySettings
+ * @property {string} name
+ * @property {CompatibilitySettingsDeclaration} declaration
+ */
+
+const nestedWebpackIdentifierTag = Symbol("nested webpack identifier");
+const PLUGIN_NAME = "CompatibilityPlugin";
+
+/**
+ * Adds parser-time compatibility rewrites for legacy runtime patterns that
+ * webpack still needs to recognize in user and generated code.
+ */
+class CompatibilityPlugin {
+	/**
+	 * Installs parser hooks that preserve compatibility with legacy patterns
+	 * such as nested `__webpack_require__` bindings and hashbang handling.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					ConstDependency,
+					new ConstDependency.Template()
+				);
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, (parser, parserOptions) => {
+						if (
+							parserOptions.browserify !== undefined &&
+							!parserOptions.browserify
+						) {
+							return;
+						}
+
+						parser.hooks.call.for("require").tap(
+							PLUGIN_NAME,
+							/**
+							 * Rewrites browserify-style delegated `require` calls into a
+							 * plain webpack require reference and removes the synthetic
+							 * context dependency created for the delegator pattern.
+							 * @param {CallExpression} expr call expression
+							 * @returns {boolean | void} true when need to handle
+							 */
+							(expr) => {
+								// support for browserify style require delegator: "require(o, !0)"
+								if (expr.arguments.length !== 2) return;
+								const second = parser.evaluateExpression(expr.arguments[1]);
+								if (!second.isBoolean()) return;
+								if (second.asBool() !== true) return;
+								const dep = new ConstDependency(
+									"require",
+									/** @type {Range} */ (expr.callee.range)
+								);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								if (parser.state.current.dependencies.length > 0) {
+									const last =
+										/** @type {ContextDependency} */
+										(
+											parser.state.current.dependencies[
+												parser.state.current.dependencies.length - 1
+											]
+										);
+									if (
+										last.critical &&
+										last.options &&
+										last.options.request === "." &&
+										last.userRequest === "." &&
+										last.options.recursive
+									) {
+										parser.state.current.dependencies.pop();
+									}
+								}
+								parser.state.module.addPresentationalDependency(dep);
+								return true;
+							}
+						);
+					});
+
+				/**
+				 * Attaches the compatibility rewrites for a JavaScript parser
+				 * instance.
+				 * @param {JavascriptParser} parser the parser
+				 * @returns {void}
+				 */
+				const handler = (parser) => {
+					// Handle nested requires
+					parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
+						if (
+							statement.type === "FunctionDeclaration" &&
+							statement.id &&
+							statement.id.name === RuntimeGlobals.require
+						) {
+							const newName = `__nested_webpack_require_${
+								/** @type {Range} */
+								(statement.range)[0]
+							}__`;
+							parser.tagVariable(
+								statement.id.name,
+								nestedWebpackIdentifierTag,
+								{
+									name: newName,
+									declaration: {
+										updated: false,
+										loc: /** @type {DependencyLocation} */ (statement.id.loc),
+										range: /** @type {Range} */ (statement.id.range)
+									}
+								}
+							);
+							return true;
+						}
+					});
+					parser.hooks.pattern
+						.for(RuntimeGlobals.require)
+						.tap(PLUGIN_NAME, (pattern) => {
+							const newName = `__nested_webpack_require_${
+								/** @type {Range} */ (pattern.range)[0]
+							}__`;
+							parser.tagVariable(pattern.name, nestedWebpackIdentifierTag, {
+								name: newName,
+								declaration: {
+									updated: false,
+									loc: /** @type {DependencyLocation} */ (pattern.loc),
+									range: /** @type {Range} */ (pattern.range)
+								}
+							});
+							if (parser.scope.topLevelScope !== true) {
+								return true;
+							}
+						});
+					parser.hooks.pattern
+						.for(RuntimeGlobals.exports)
+						.tap(PLUGIN_NAME, (pattern) => {
+							const newName = "__nested_webpack_exports__";
+							parser.tagVariable(pattern.name, nestedWebpackIdentifierTag, {
+								name: newName,
+								declaration: {
+									updated: false,
+									loc: /** @type {DependencyLocation} */ (pattern.loc),
+									range: /** @type {Range} */ (pattern.range)
+								}
+							});
+							return true;
+						});
+					// Update single `var __webpack_require__ = {};` and `var __webpack_exports__ = {};` without expression
+					parser.hooks.declarator.tap(PLUGIN_NAME, (declarator) => {
+						if (
+							declarator.id.type === "Identifier" &&
+							(declarator.id.name === RuntimeGlobals.exports ||
+								declarator.id.name === RuntimeGlobals.require)
+						) {
+							const tagData = /** @type {CompatibilitySettings | undefined} */ (
+								parser.getTagData(
+									declarator.id.name,
+									nestedWebpackIdentifierTag
+								)
+							);
+							if (!tagData) return;
+							const { name, declaration } = tagData;
+							if (!declaration.updated) {
+								const dep = new ConstDependency(name, declaration.range);
+								dep.loc = declaration.loc;
+								parser.state.module.addPresentationalDependency(dep);
+								declaration.updated = true;
+							}
+						}
+					});
+					parser.hooks.expression
+						.for(nestedWebpackIdentifierTag)
+						.tap(PLUGIN_NAME, (expr) => {
+							const { name, declaration } =
+								/** @type {CompatibilitySettings} */
+								(parser.currentTagData);
+							if (!declaration.updated) {
+								const dep = new ConstDependency(name, declaration.range);
+								dep.loc = declaration.loc;
+								parser.state.module.addPresentationalDependency(dep);
+								declaration.updated = true;
+							}
+							const dep = new ConstDependency(
+								name,
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+
+					// Handle hashbang
+					parser.hooks.program.tap(PLUGIN_NAME, (program, comments) => {
+						if (comments.length === 0) return;
+						const c = comments[0];
+						if (c.type === "Line" && /** @type {Range} */ (c.range)[0] === 0) {
+							if (parser.state.source.slice(0, 2).toString() !== "#!") return;
+							// this is a hashbang comment
+							const dep = new ConstDependency("//", 0);
+							dep.loc = /** @type {DependencyLocation} */ (c.loc);
+							parser.state.module.addPresentationalDependency(dep);
+						}
+					});
+				};
+
+				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);
+			}
+		);
+	}
+}
+
+module.exports = CompatibilityPlugin;
+module.exports.nestedWebpackIdentifierTag = nestedWebpackIdentifierTag;
Index: frontend/node_modules/webpack/lib/Compilation.js
===================================================================
--- frontend/node_modules/webpack/lib/Compilation.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Compilation.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6055 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const asyncLib = require("neo-async");
+const {
+	AsyncParallelHook,
+	AsyncSeriesBailHook,
+	AsyncSeriesHook,
+	HookMap,
+	SyncBailHook,
+	SyncHook,
+	SyncWaterfallHook
+} = require("tapable");
+const { CachedSource } = require("webpack-sources");
+const { MultiItemCache } = require("./CacheFacade");
+const Chunk = require("./Chunk");
+const ChunkGraph = require("./ChunkGraph");
+const ChunkGroup = require("./ChunkGroup");
+const ChunkTemplate = require("./ChunkTemplate");
+const CodeGenerationResults = require("./CodeGenerationResults");
+const Dependency = require("./Dependency");
+const DependencyTemplates = require("./DependencyTemplates");
+const Entrypoint = require("./Entrypoint");
+const ErrorHelpers = require("./ErrorHelpers");
+const FileSystemInfo = require("./FileSystemInfo");
+const MainTemplate = require("./MainTemplate");
+const Module = require("./Module");
+const ModuleGraph = require("./ModuleGraph");
+const ModuleProfile = require("./ModuleProfile");
+const ModuleTemplate = require("./ModuleTemplate");
+const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const RuntimeTemplate = require("./RuntimeTemplate");
+const Stats = require("./Stats");
+const buildChunkGraph = require("./buildChunkGraph");
+const BuildCycleError = require("./errors/BuildCycleError");
+const ChunkRenderError = require("./errors/ChunkRenderError");
+const CodeGenerationError = require("./errors/CodeGenerationError");
+const {
+	makeWebpackError,
+	tryRunOrWebpackError
+} = require("./errors/HookWebpackError");
+const ModuleDependencyError = require("./errors/ModuleDependencyError");
+const ModuleDependencyWarning = require("./errors/ModuleDependencyWarning");
+const ModuleHashingError = require("./errors/ModuleHashingError");
+const ModuleNotFoundError = require("./errors/ModuleNotFoundError");
+const ModuleRestoreError = require("./errors/ModuleRestoreError");
+const ModuleStoreError = require("./errors/ModuleStoreError");
+const WebpackError = require("./errors/WebpackError");
+const { LogType, Logger } = require("./logging/Logger");
+const StatsFactory = require("./stats/StatsFactory");
+const StatsPrinter = require("./stats/StatsPrinter");
+const { equals: arrayEquals } = require("./util/ArrayHelpers");
+const AsyncQueue = require("./util/AsyncQueue");
+const LazySet = require("./util/LazySet");
+const { getOrInsert } = require("./util/MapHelpers");
+const WeakTupleMap = require("./util/WeakTupleMap");
+const { cachedCleverMerge } = require("./util/cleverMerge");
+const {
+	compareIds,
+	compareLocations,
+	compareModulesByIdentifier,
+	compareSelect,
+	compareStringsNumeric,
+	concatComparators
+} = require("./util/comparators");
+const createHash = require("./util/createHash");
+const {
+	arrayToSetDeprecation,
+	createFakeHook,
+	soonFrozenObjectDeprecation
+} = require("./util/deprecation");
+const processAsyncTree = require("./util/processAsyncTree");
+const { getRuntimeKey } = require("./util/runtime");
+const { isSourceEqual } = require("./util/source");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
+/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("../declarations/WebpackOptions").HashDigest} HashDigest */
+/** @typedef {import("../declarations/WebpackOptions").HashDigestLength} HashDigestLength */
+/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
+/** @typedef {import("../declarations/WebpackOptions").Plugins} Plugins */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./config/defaults").OutputNormalizedWithDefaults} OutputOptionsWithDefaults */
+/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("./Cache")} Cache */
+/** @typedef {import("./CacheFacade")} CacheFacade */
+/** @typedef {import("./Chunk").ChunkName} ChunkName */
+/** @typedef {import("./Chunk").ChunkId} ChunkId */
+/** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Compiler").CompilationParams} CompilationParams */
+/** @typedef {import("./Compiler").MemCache} MemCache */
+/** @typedef {import("./Compiler").WeakReferences} WeakReferences */
+/** @typedef {import("./Compiler").ModuleMemCachesItem} ModuleMemCachesItem */
+/** @typedef {import("./Compiler").Records} Records */
+/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
+/** @typedef {import("./Module").NameForCondition} NameForCondition */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./Module").ValueCacheVersions} ValueCacheVersions */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./NormalModule").NormalModuleCompilationHooks} NormalModuleCompilationHooks */
+/** @typedef {import("./Module").FactoryMeta} FactoryMeta */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./ModuleFactory")} ModuleFactory */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
+/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
+/** @typedef {import("./NormalModule")} NormalModule */
+/** @typedef {import("./NormalModule").AnyLoaderContext} AnyLoaderContext */
+/** @typedef {import("./NormalModule").ParserOptions} ParserOptions */
+/** @typedef {import("./NormalModule").GeneratorOptions} GeneratorOptions */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./RuntimeModule")} RuntimeModule */
+/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */
+/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */
+/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
+/** @typedef {import("./util/Hash")} Hash */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("tapable").AsArray<T>} AsArray<T>
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T>
+ */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+
+/**
+ * Defines the callback callback.
+ * @callback Callback
+ * @param {(WebpackError | null)=} err
+ * @returns {void}
+ */
+
+/**
+ * Defines the module callback callback.
+ * @callback ModuleCallback
+ * @param {WebpackError | null=} err
+ * @param {Module | null=} result
+ * @returns {void}
+ */
+
+/**
+ * Defines the module factory result callback callback.
+ * @callback ModuleFactoryResultCallback
+ * @param {WebpackError | null=} err
+ * @param {ModuleFactoryResult | null=} result
+ * @returns {void}
+ */
+
+/**
+ * Defines the module or module factory result callback callback.
+ * @callback ModuleOrModuleFactoryResultCallback
+ * @param {WebpackError | null=} err
+ * @param {Module | ModuleFactoryResult | null=} result
+ * @returns {void}
+ */
+
+/**
+ * Defines the execute module callback callback.
+ * @callback ExecuteModuleCallback
+ * @param {WebpackError | null=} err
+ * @param {ExecuteModuleResult | null=} result
+ * @returns {void}
+ */
+
+/** @typedef {new (...args: EXPECTED_ANY[]) => Dependency} DependencyConstructor */
+
+/** @typedef {Record<string, Source>} CompilationAssets */
+
+/**
+ * Defines the available modules chunk group mapping type used by this module.
+ * @typedef {object} AvailableModulesChunkGroupMapping
+ * @property {ChunkGroup} chunkGroup
+ * @property {Set<Module>} availableModules
+ * @property {boolean} needCopy
+ */
+
+/**
+ * Defines the dependencies block like type used by this module.
+ * @typedef {object} DependenciesBlockLike
+ * @property {Dependency[]} dependencies
+ * @property {AsyncDependenciesBlock[]} blocks
+ */
+
+/** @typedef {Set<Chunk>} Chunks */
+
+/**
+ * Defines the chunk path data type used by this module.
+ * @typedef {object} ChunkPathData
+ * @property {string | number} id
+ * @property {string=} name
+ * @property {string} hash
+ * @property {HashWithLengthFunction=} hashWithLength
+ * @property {(Record<string, string>)=} contentHash
+ * @property {(Record<string, HashWithLengthFunction>)=} contentHashWithLength
+ */
+
+/**
+ * Defines the chunk hash context type used by this module.
+ * @typedef {object} ChunkHashContext
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ */
+
+/**
+ * Defines the runtime requirements context type used by this module.
+ * @typedef {object} RuntimeRequirementsContext
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults the code generation results
+ */
+
+/**
+ * Defines the execute module options type used by this module.
+ * @typedef {object} ExecuteModuleOptions
+ * @property {EntryOptions=} entryOptions
+ */
+
+/** @typedef {LazySet<string>} FileSystemDependencies */
+
+/** @typedef {EXPECTED_ANY} ExecuteModuleExports */
+
+/**
+ * Defines the execute module result type used by this module.
+ * @typedef {object} ExecuteModuleResult
+ * @property {ExecuteModuleExports} exports
+ * @property {boolean} cacheable
+ * @property {ExecuteModuleAssets} assets
+ * @property {FileSystemDependencies} fileDependencies
+ * @property {FileSystemDependencies} contextDependencies
+ * @property {FileSystemDependencies} missingDependencies
+ * @property {FileSystemDependencies} buildDependencies
+ */
+
+/**
+ * Defines the execute module object type used by this module.
+ * @typedef {object} ExecuteModuleObject
+ * @property {string=} id module id
+ * @property {ExecuteModuleExports} exports exports
+ * @property {boolean} loaded is loaded
+ * @property {Error=} error error
+ */
+
+/**
+ * Defines the execute module argument type used by this module.
+ * @typedef {object} ExecuteModuleArgument
+ * @property {Module} module
+ * @property {ExecuteModuleObject=} moduleObject
+ * @property {CodeGenerationResult} codeGenerationResult
+ */
+
+/** @typedef {((id: string) => ExecuteModuleExports) & { i?: ((options: ExecuteOptions) => void)[], c?: Record<string, ExecuteModuleObject> }} WebpackRequire */
+
+/**
+ * Defines the execute options type used by this module.
+ * @typedef {object} ExecuteOptions
+ * @property {string=} id module id
+ * @property {ExecuteModuleObject} module module
+ * @property {WebpackRequire} require require function
+ */
+
+/** @typedef {Map<string, { source: Source, info: AssetInfo | undefined }>} ExecuteModuleAssets */
+
+/**
+ * Defines the execute module context type used by this module.
+ * @typedef {object} ExecuteModuleContext
+ * @property {ExecuteModuleAssets} assets
+ * @property {Chunk} chunk
+ * @property {ChunkGraph} chunkGraph
+ * @property {WebpackRequire=} __webpack_require__
+ */
+
+/**
+ * Defines the entry data type used by this module.
+ * @typedef {object} EntryData
+ * @property {Dependency[]} dependencies dependencies of the entrypoint that should be evaluated at startup
+ * @property {Dependency[]} includeDependencies dependencies of the entrypoint that should be included but not evaluated
+ * @property {EntryOptions} options options of the entrypoint
+ */
+
+/**
+ * Defines the log entry type used by this module.
+ * @typedef {object} LogEntry
+ * @property {keyof LogType} type
+ * @property {EXPECTED_ANY[]=} args
+ * @property {number} time
+ * @property {string[]=} trace
+ */
+
+/**
+ * Defines the known asset info type used by this module.
+ * @typedef {object} KnownAssetInfo
+ * @property {boolean=} immutable true, if the asset can be long term cached forever (contains a hash)
+ * @property {boolean=} minimized whether the asset is minimized
+ * @property {string | string[]=} fullhash the value(s) of the full hash used for this asset
+ * @property {string | string[]=} chunkhash the value(s) of the chunk hash used for this asset
+ * @property {string | string[]=} modulehash the value(s) of the module hash used for this asset
+ * @property {string | string[]=} contenthash the value(s) of the content hash used for this asset
+ * @property {string=} sourceFilename when asset was created from a source file (potentially transformed), the original filename relative to compilation context
+ * @property {number=} size size in bytes, only set after asset has been emitted
+ * @property {boolean=} development true, when asset is only used for development and doesn't count towards user-facing assets
+ * @property {boolean=} hotModuleReplacement true, when asset ships data for updating an existing application (HMR)
+ * @property {boolean=} javascriptModule true, when asset is javascript and an ESM
+ * @property {boolean=} manifest true, when file is a manifest
+ * @property {Record<string, null | string | string[]>=} related object of pointers to other assets, keyed by type of relation (only points from parent to child)
+ */
+
+/** @typedef {KnownAssetInfo & Record<string, EXPECTED_ANY>} AssetInfo */
+
+/** @typedef {{ path: string, info: AssetInfo }} InterpolatedPathAndAssetInfo */
+
+/**
+ * Defines the asset type used by this module.
+ * @typedef {object} Asset
+ * @property {string} name the filename of the asset
+ * @property {Source} source source of the asset
+ * @property {AssetInfo} info info about the asset
+ */
+
+/** @typedef {(length: number) => string} HashWithLengthFunction */
+
+/**
+ * Defines the module path data type used by this module.
+ * @typedef {object} ModulePathData
+ * @property {string | number} id
+ * @property {string} hash
+ * @property {HashWithLengthFunction=} hashWithLength
+ */
+
+/** @typedef {(id: string | number) => string | number} PrepareIdFunction */
+
+/**
+ * Defines the path data type used by this module.
+ * @typedef {object} PathData
+ * @property {ChunkGraph=} chunkGraph
+ * @property {string=} hash
+ * @property {HashWithLengthFunction=} hashWithLength
+ * @property {(Chunk | ChunkPathData)=} chunk
+ * @property {(Module | ModulePathData)=} module
+ * @property {RuntimeSpec=} runtime
+ * @property {string=} filename
+ * @property {string=} basename
+ * @property {string=} query
+ * @property {string=} contentHashType
+ * @property {string=} contentHash
+ * @property {HashWithLengthFunction=} contentHashWithLength
+ * @property {boolean=} noChunkHash
+ * @property {string=} url
+ * @property {string=} local
+ * @property {PrepareIdFunction=} prepareId
+ */
+
+/**
+ * Path data narrowed for the chunk filename / chunk asset interpolation context,
+ * where `chunk` is always provided. Use as the type parameter to `TemplatePathFn`
+ * for callbacks that receive a chunk context (for example `output.filename`,
+ * `output.chunkFilename`, `output.cssFilename`, `output.cssChunkFilename`,
+ * `optimization.splitChunks.cacheGroups[*].filename`).
+ * @typedef {PathData & { chunk: Chunk | ChunkPathData }} PathDataChunk
+ */
+
+/**
+ * Path data narrowed for the module asset interpolation context, where `module`
+ * and `chunkGraph` are always provided. Use as the type parameter to
+ * `TemplatePathFn` for callbacks that receive a module context (for example
+ * `output.assetModuleFilename`, the per-module `generator.filename` /
+ * `generator.outputPath`, and `module.parser.css.localIdentName`).
+ * @typedef {PathData & { module: Module | ModulePathData, chunkGraph: ChunkGraph }} PathDataModule
+ */
+
+/** @typedef {"module" | "chunk" | "root-of-chunk" | "nested"} ExcludeModulesType */
+
+/**
+ * Defines the known normalized stats options type used by this module.
+ * @typedef {object} KnownNormalizedStatsOptions
+ * @property {string} context
+ * @property {RequestShortener} requestShortener
+ * @property {string | false} chunksSort
+ * @property {string | false} modulesSort
+ * @property {string | false} chunkModulesSort
+ * @property {string | false} nestedModulesSort
+ * @property {string | false} assetsSort
+ * @property {boolean} ids
+ * @property {boolean} cachedAssets
+ * @property {boolean} groupAssetsByEmitStatus
+ * @property {boolean} groupAssetsByPath
+ * @property {boolean} groupAssetsByExtension
+ * @property {number} assetsSpace
+ * @property {((value: string, asset: StatsAsset) => boolean)[]} excludeAssets
+ * @property {((name: string, module: StatsModule, type: ExcludeModulesType) => boolean)[]} excludeModules
+ * @property {((warning: StatsError, textValue: string) => boolean)[]} warningsFilter
+ * @property {boolean} cachedModules
+ * @property {boolean} orphanModules
+ * @property {boolean} dependentModules
+ * @property {boolean} runtimeModules
+ * @property {boolean} groupModulesByCacheStatus
+ * @property {boolean} groupModulesByLayer
+ * @property {boolean} groupModulesByAttributes
+ * @property {boolean} groupModulesByPath
+ * @property {boolean} groupModulesByExtension
+ * @property {boolean} groupModulesByType
+ * @property {boolean | "auto"} entrypoints
+ * @property {boolean} chunkGroups
+ * @property {boolean} chunkGroupAuxiliary
+ * @property {boolean} chunkGroupChildren
+ * @property {number} chunkGroupMaxAssets
+ * @property {number} modulesSpace
+ * @property {number} chunkModulesSpace
+ * @property {number} nestedModulesSpace
+ * @property {false | "none" | "error" | "warn" | "info" | "log" | "verbose"} logging
+ * @property {((value: string) => boolean)[]} loggingDebug
+ * @property {boolean} loggingTrace
+ * @property {EXPECTED_ANY} _env
+ */
+
+/** @typedef {KnownNormalizedStatsOptions & Omit<StatsOptions, keyof KnownNormalizedStatsOptions> & Record<string, EXPECTED_ANY>} NormalizedStatsOptions */
+
+/**
+ * Defines the known create stats options context type used by this module.
+ * @typedef {object} KnownCreateStatsOptionsContext
+ * @property {boolean=} forToString
+ */
+
+/** @typedef {KnownCreateStatsOptionsContext & Record<string, EXPECTED_ANY>} CreateStatsOptionsContext */
+
+/** @typedef {{ module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[] }} CodeGenerationJob */
+
+/** @typedef {CodeGenerationJob[]} CodeGenerationJobs */
+
+/** @typedef {{ javascript: ModuleTemplate }} ModuleTemplates */
+
+/** @typedef {Set<Module>} NotCodeGeneratedModules */
+
+/** @type {AssetInfo} */
+const EMPTY_ASSET_INFO = Object.freeze({});
+
+const esmDependencyCategory = "esm";
+
+// TODO webpack 6: remove
+const deprecatedNormalModuleLoaderHook = util.deprecate(
+	/**
+	 * Handles the callback logic for this hook.
+	 * @param {Compilation} compilation compilation
+	 * @returns {NormalModuleCompilationHooks["loader"]} hooks
+	 */
+	(compilation) =>
+		require("./NormalModule").getCompilationHooks(compilation).loader,
+	"Compilation.hooks.normalModuleLoader was moved to NormalModule.getCompilationHooks(compilation).loader",
+	"DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK"
+);
+
+// TODO webpack 6: remove
+/**
+ * Define removed module templates.
+ * @param {ModuleTemplates | undefined} moduleTemplates module templates
+ */
+const defineRemovedModuleTemplates = (moduleTemplates) => {
+	Object.defineProperties(moduleTemplates, {
+		asset: {
+			enumerable: false,
+			configurable: false,
+			get: () => {
+				throw new WebpackError(
+					"Compilation.moduleTemplates.asset has been removed"
+				);
+			}
+		},
+		webassembly: {
+			enumerable: false,
+			configurable: false,
+			get: () => {
+				throw new WebpackError(
+					"Compilation.moduleTemplates.webassembly has been removed"
+				);
+			}
+		}
+	});
+	moduleTemplates = undefined;
+};
+
+const byId = compareSelect((c) => c.id, compareIds);
+
+const byNameOrHash = concatComparators(
+	compareSelect((c) => c.name, compareIds),
+	compareSelect((c) => c.fullHash, compareIds)
+);
+
+const byMessage = compareSelect(
+	(err) => `${err.message}`,
+	compareStringsNumeric
+);
+
+const byModule = compareSelect(
+	(err) => (err.module && err.module.identifier()) || "",
+	compareStringsNumeric
+);
+
+const byLocation = compareSelect((err) => err.loc, compareLocations);
+
+const compareErrors = concatComparators(byModule, byLocation, byMessage);
+
+/**
+ * Defines the known unsafe cache data type used by this module.
+ * @typedef {object} KnownUnsafeCacheData
+ * @property {FactoryMeta=} factoryMeta factory meta
+ * @property {ResolveOptions=} resolveOptions resolve options
+ * @property {ParserOptions=} parserOptions
+ * @property {GeneratorOptions=} generatorOptions
+ */
+
+/** @typedef {KnownUnsafeCacheData & Record<string, EXPECTED_ANY>} UnsafeCacheData */
+
+/**
+ * Defines the module with restore from unsafe cache type used by this module.
+ * @typedef {Module & { restoreFromUnsafeCache?: (unsafeCacheData: UnsafeCacheData, moduleFactory: ModuleFactory, compilationParams: CompilationParams) => void }} ModuleWithRestoreFromUnsafeCache
+ */
+
+/** @typedef {(module: Module) => boolean} UnsafeCachePredicate */
+
+/** @type {WeakMap<Dependency, ModuleWithRestoreFromUnsafeCache | null>} */
+const unsafeCacheDependencies = new WeakMap();
+
+/** @type {WeakMap<ModuleWithRestoreFromUnsafeCache, UnsafeCacheData>} */
+const unsafeCacheData = new WeakMap();
+
+/** @typedef {{ id: ModuleId, modules?: Map<Module, ModuleId>, blocks?: (ChunkId | null)[] }} References */
+/** @typedef {Map<Module, WeakTupleMap<EXPECTED_ANY[], EXPECTED_ANY>>} ModuleMemCaches */
+
+class Compilation {
+	/**
+	 * Creates an instance of Compilation.
+	 * @param {Compiler} compiler the compiler which created the compilation
+	 * @param {CompilationParams} params the compilation parameters
+	 */
+	constructor(compiler, params) {
+		this._backCompat = compiler._backCompat;
+
+		const getNormalModuleLoader = () => deprecatedNormalModuleLoaderHook(this);
+		/** @typedef {{ additionalAssets?: boolean | ((assets: CompilationAssets) => void) }} ProcessAssetsAdditionalOptions */
+		/** @type {AsyncSeriesHook<[CompilationAssets], ProcessAssetsAdditionalOptions>} */
+		const processAssetsHook = new AsyncSeriesHook(["assets"]);
+
+		/** @type {Set<string>} */
+		let savedAssets = new Set();
+		/**
+		 * Returns new assets.
+		 * @param {CompilationAssets} assets assets
+		 * @returns {CompilationAssets} new assets
+		 */
+		const popNewAssets = (assets) => {
+			/** @type {undefined | CompilationAssets} */
+			let newAssets;
+			for (const file of Object.keys(assets)) {
+				if (savedAssets.has(file)) continue;
+				if (newAssets === undefined) {
+					newAssets = Object.create(null);
+				}
+				/** @type {CompilationAssets} */
+				(newAssets)[file] = assets[file];
+				savedAssets.add(file);
+			}
+			return /** @type {CompilationAssets} */ (newAssets);
+		};
+		processAssetsHook.intercept({
+			name: "Compilation",
+			call: () => {
+				savedAssets = new Set(Object.keys(this.assets));
+			},
+			register: (tap) => {
+				const { type, name } = tap;
+				const { fn, additionalAssets, ...remainingTap } = tap;
+				const additionalAssetsFn =
+					additionalAssets === true ? fn : additionalAssets;
+				/** @typedef {WeakSet<CompilationAssets>} ProcessedAssets */
+
+				/** @type {ProcessedAssets | undefined} */
+				const processedAssets = additionalAssetsFn ? new WeakSet() : undefined;
+				/**
+				 * Gets available assets.
+				 * @param {CompilationAssets} assets to be processed by additionalAssetsFn
+				 * @returns {CompilationAssets} available assets
+				 */
+				const getAvailableAssets = (assets) => {
+					/** @type {CompilationAssets} */
+					const availableAssets = {};
+					for (const file of Object.keys(assets)) {
+						// https://github.com/webpack-contrib/compression-webpack-plugin/issues/390
+						if (this.assets[file]) {
+							availableAssets[file] = assets[file];
+						}
+					}
+					return availableAssets;
+				};
+				switch (type) {
+					case "sync":
+						if (additionalAssetsFn) {
+							this.hooks.processAdditionalAssets.tap(name, (assets) => {
+								if (
+									/** @type {ProcessedAssets} */
+									(processedAssets).has(this.assets)
+								) {
+									additionalAssetsFn(getAvailableAssets(assets));
+								}
+							});
+						}
+						return {
+							...remainingTap,
+							type: "async",
+							/**
+							 * Processes the provided asset.
+							 * @param {CompilationAssets} assets assets
+							 * @param {(err?: Error | null, result?: void) => void} callback callback
+							 * @returns {void}
+							 */
+							fn: (assets, callback) => {
+								try {
+									fn(assets);
+								} catch (err) {
+									return callback(/** @type {Error} */ (err));
+								}
+								if (processedAssets !== undefined) {
+									processedAssets.add(this.assets);
+								}
+								const newAssets = popNewAssets(assets);
+								if (newAssets !== undefined) {
+									this.hooks.processAdditionalAssets.callAsync(
+										newAssets,
+										callback
+									);
+									return;
+								}
+								callback();
+							}
+						};
+					case "async":
+						if (additionalAssetsFn) {
+							this.hooks.processAdditionalAssets.tapAsync(
+								name,
+								(assets, callback) => {
+									if (
+										/** @type {ProcessedAssets} */
+										(processedAssets).has(this.assets)
+									) {
+										return additionalAssetsFn(
+											getAvailableAssets(assets),
+											callback
+										);
+									}
+									callback();
+								}
+							);
+						}
+						return {
+							...remainingTap,
+							/**
+							 * Processes the provided asset.
+							 * @param {CompilationAssets} assets assets
+							 * @param {(err?: Error | null, result?: void) => void} callback callback
+							 * @returns {void}
+							 */
+							fn: (assets, callback) => {
+								fn(
+									assets,
+									/**
+									 * Handles the callback logic for this hook.
+									 * @param {Error} err err
+									 * @returns {void}
+									 */
+									(err) => {
+										if (err) return callback(err);
+										if (processedAssets !== undefined) {
+											processedAssets.add(this.assets);
+										}
+										const newAssets = popNewAssets(assets);
+										if (newAssets !== undefined) {
+											this.hooks.processAdditionalAssets.callAsync(
+												newAssets,
+												callback
+											);
+											return;
+										}
+										callback();
+									}
+								);
+							}
+						};
+					case "promise":
+						if (additionalAssetsFn) {
+							this.hooks.processAdditionalAssets.tapPromise(name, (assets) => {
+								if (
+									/** @type {ProcessedAssets} */
+									(processedAssets).has(this.assets)
+								) {
+									return additionalAssetsFn(getAvailableAssets(assets));
+								}
+								return Promise.resolve();
+							});
+						}
+						return {
+							...remainingTap,
+							/**
+							 * Returns result.
+							 * @param {CompilationAssets} assets assets
+							 * @returns {Promise<CompilationAssets>} result
+							 */
+							fn: (assets) => {
+								const p = fn(assets);
+								if (!p || !p.then) return p;
+								return p.then(() => {
+									if (processedAssets !== undefined) {
+										processedAssets.add(this.assets);
+									}
+									const newAssets = popNewAssets(assets);
+									if (newAssets !== undefined) {
+										return this.hooks.processAdditionalAssets.promise(
+											newAssets
+										);
+									}
+								});
+							}
+						};
+				}
+			}
+		});
+
+		/** @type {SyncHook<[CompilationAssets]>} */
+		const afterProcessAssetsHook = new SyncHook(["assets"]);
+
+		/**
+		 * Creates a process assets hook.
+		 * @template T
+		 * @param {string} name name of the hook
+		 * @param {number} stage new stage
+		 * @param {() => AsArray<T>} getArgs get old hook function args
+		 * @param {string=} code deprecation code (not deprecated when unset)
+		 * @returns {FakeHook<Pick<AsyncSeriesHook<T>, "tap" | "tapAsync" | "tapPromise" | "name">> | undefined} fake hook which redirects
+		 */
+		const createProcessAssetsHook = (name, stage, getArgs, code) => {
+			if (!this._backCompat && code) return;
+			/**
+			 * Returns error message.
+			 * @param {string} reason reason
+			 * @returns {string} error message
+			 */
+			const errorMessage = (
+				reason
+			) => `Can't automatically convert plugin using Compilation.hooks.${name} to Compilation.hooks.processAssets because ${reason}.
+BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a single Compilation.hooks.processAssets hook.`;
+			/**
+			 * Normalizes tap options for migrated process-assets hooks.
+			 * @param {string | (import("tapable").TapOptions & { name: string } & ProcessAssetsAdditionalOptions)} options hook options
+			 * @returns {import("tapable").TapOptions & { name: string } & ProcessAssetsAdditionalOptions} modified options
+			 */
+			const getOptions = (options) => {
+				if (typeof options === "string") options = { name: options };
+				if (options.stage) {
+					throw new Error(errorMessage("it's using the 'stage' option"));
+				}
+				return { ...options, stage };
+			};
+			return createFakeHook(
+				{
+					name,
+					/** @type {AsyncSeriesHook<T>["intercept"]} */
+					intercept(_interceptor) {
+						throw new Error(errorMessage("it's using 'intercept'"));
+					},
+					/** @type {AsyncSeriesHook<T>["tap"]} */
+					tap: (options, fn) => {
+						processAssetsHook.tap(getOptions(options), () => fn(...getArgs()));
+					},
+					/** @type {AsyncSeriesHook<T>["tapAsync"]} */
+					tapAsync: (options, fn) => {
+						processAssetsHook.tapAsync(
+							getOptions(options),
+							(assets, callback) =>
+								/** @type {EXPECTED_ANY} */ (fn)(...getArgs(), callback)
+						);
+					},
+					/** @type {AsyncSeriesHook<T>["tapPromise"]} */
+					tapPromise: (options, fn) => {
+						processAssetsHook.tapPromise(getOptions(options), () =>
+							fn(...getArgs())
+						);
+					}
+				},
+				`${name} is deprecated (use Compilation.hooks.processAssets instead and use one of Compilation.PROCESS_ASSETS_STAGE_* as stage option)`,
+				code
+			);
+		};
+		this.hooks = Object.freeze({
+			/** @type {SyncHook<[Module]>} */
+			buildModule: new SyncHook(["module"]),
+			/** @type {SyncHook<[Module]>} */
+			rebuildModule: new SyncHook(["module"]),
+			/** @type {SyncHook<[Module, WebpackError]>} */
+			failedModule: new SyncHook(["module", "error"]),
+			/** @type {SyncHook<[Module]>} */
+			succeedModule: new SyncHook(["module"]),
+			/** @type {SyncHook<[Module]>} */
+			stillValidModule: new SyncHook(["module"]),
+
+			/** @type {SyncHook<[Dependency, EntryOptions]>} */
+			addEntry: new SyncHook(["entry", "options"]),
+			/** @type {SyncHook<[Dependency, EntryOptions, Error]>} */
+			failedEntry: new SyncHook(["entry", "options", "error"]),
+			/** @type {SyncHook<[Dependency, EntryOptions, Module]>} */
+			succeedEntry: new SyncHook(["entry", "options", "module"]),
+
+			/** @type {SyncWaterfallHook<[ReferencedExports, Dependency, RuntimeSpec]>} */
+			dependencyReferencedExports: new SyncWaterfallHook([
+				"referencedExports",
+				"dependency",
+				"runtime"
+			]),
+
+			/** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */
+			executeModule: new SyncHook(["options", "context"]),
+			/** @type {AsyncParallelHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */
+			prepareModuleExecution: new AsyncParallelHook(["options", "context"]),
+
+			/** @type {AsyncSeriesHook<[Iterable<Module>]>} */
+			finishModules: new AsyncSeriesHook(["modules"]),
+			/** @type {AsyncSeriesHook<[Module]>} */
+			finishRebuildingModule: new AsyncSeriesHook(["module"]),
+			/** @type {SyncHook<[]>} */
+			unseal: new SyncHook([]),
+			/** @type {SyncHook<[]>} */
+			seal: new SyncHook([]),
+
+			/** @type {SyncHook<[]>} */
+			beforeChunks: new SyncHook([]),
+			/**
+			 * The `afterChunks` hook is called directly after the chunks and module graph have
+			 * been created and before the chunks and modules have been optimized. This hook is useful to
+			 * inspect, analyze, and/or modify the chunk graph.
+			 * @type {SyncHook<[Iterable<Chunk>]>}
+			 */
+			afterChunks: new SyncHook(["chunks"]),
+
+			/** @type {SyncBailHook<[Iterable<Module>], boolean | void>} */
+			optimizeDependencies: new SyncBailHook(["modules"]),
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			afterOptimizeDependencies: new SyncHook(["modules"]),
+
+			/** @type {SyncHook<[]>} */
+			optimize: new SyncHook([]),
+			/** @type {SyncBailHook<[Iterable<Module>], boolean | void>} */
+			optimizeModules: new SyncBailHook(["modules"]),
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			afterOptimizeModules: new SyncHook(["modules"]),
+
+			/** @type {SyncBailHook<[Iterable<Chunk>, ChunkGroup[]], boolean | void>} */
+			optimizeChunks: new SyncBailHook(["chunks", "chunkGroups"]),
+			/** @type {SyncHook<[Iterable<Chunk>, ChunkGroup[]]>} */
+			afterOptimizeChunks: new SyncHook(["chunks", "chunkGroups"]),
+
+			/** @type {AsyncSeriesHook<[Iterable<Chunk>, Iterable<Module>]>} */
+			optimizeTree: new AsyncSeriesHook(["chunks", "modules"]),
+			/** @type {SyncHook<[Iterable<Chunk>, Iterable<Module>]>} */
+			afterOptimizeTree: new SyncHook(["chunks", "modules"]),
+
+			/** @type {AsyncSeriesBailHook<[Iterable<Chunk>, Iterable<Module>], void>} */
+			optimizeChunkModules: new AsyncSeriesBailHook(["chunks", "modules"]),
+			/** @type {SyncHook<[Iterable<Chunk>, Iterable<Module>]>} */
+			afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]),
+			/** @type {SyncBailHook<[], boolean | void>} */
+			shouldRecord: new SyncBailHook([]),
+
+			/** @type {SyncHook<[Chunk, RuntimeRequirements, RuntimeRequirementsContext]>} */
+			additionalChunkRuntimeRequirements: new SyncHook([
+				"chunk",
+				"runtimeRequirements",
+				"context"
+			]),
+			/** @type {HookMap<SyncBailHook<[Chunk, RuntimeRequirements, RuntimeRequirementsContext], void>>} */
+			runtimeRequirementInChunk: new HookMap(
+				() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
+			),
+			/** @type {SyncHook<[Module, RuntimeRequirements, RuntimeRequirementsContext]>} */
+			additionalModuleRuntimeRequirements: new SyncHook([
+				"module",
+				"runtimeRequirements",
+				"context"
+			]),
+			/** @type {HookMap<SyncBailHook<[Module, RuntimeRequirements, RuntimeRequirementsContext], void>>} */
+			runtimeRequirementInModule: new HookMap(
+				() => new SyncBailHook(["module", "runtimeRequirements", "context"])
+			),
+			/** @type {SyncHook<[Chunk, RuntimeRequirements, RuntimeRequirementsContext]>} */
+			additionalTreeRuntimeRequirements: new SyncHook([
+				"chunk",
+				"runtimeRequirements",
+				"context"
+			]),
+			/** @type {HookMap<SyncBailHook<[Chunk, RuntimeRequirements, RuntimeRequirementsContext], void>>} */
+			runtimeRequirementInTree: new HookMap(
+				() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
+			),
+
+			/** @type {SyncHook<[RuntimeModule, Chunk]>} */
+			runtimeModule: new SyncHook(["module", "chunk"]),
+
+			/** @type {SyncHook<[Iterable<Module>, Records]>} */
+			reviveModules: new SyncHook(["modules", "records"]),
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			beforeModuleIds: new SyncHook(["modules"]),
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			moduleIds: new SyncHook(["modules"]),
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			optimizeModuleIds: new SyncHook(["modules"]),
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			afterOptimizeModuleIds: new SyncHook(["modules"]),
+
+			/** @type {SyncHook<[Iterable<Chunk>, Records]>} */
+			reviveChunks: new SyncHook(["chunks", "records"]),
+			/** @type {SyncHook<[Iterable<Chunk>]>} */
+			beforeChunkIds: new SyncHook(["chunks"]),
+			/** @type {SyncHook<[Iterable<Chunk>]>} */
+			chunkIds: new SyncHook(["chunks"]),
+			/** @type {SyncHook<[Iterable<Chunk>]>} */
+			optimizeChunkIds: new SyncHook(["chunks"]),
+			/** @type {SyncHook<[Iterable<Chunk>]>} */
+			afterOptimizeChunkIds: new SyncHook(["chunks"]),
+
+			/** @type {SyncHook<[Iterable<Module>, Records]>} */
+			recordModules: new SyncHook(["modules", "records"]),
+			/** @type {SyncHook<[Iterable<Chunk>, Records]>} */
+			recordChunks: new SyncHook(["chunks", "records"]),
+
+			/** @type {SyncHook<[Iterable<Module>]>} */
+			optimizeCodeGeneration: new SyncHook(["modules"]),
+
+			/** @type {SyncHook<[]>} */
+			beforeModuleHash: new SyncHook([]),
+			/** @type {SyncHook<[]>} */
+			afterModuleHash: new SyncHook([]),
+
+			/** @type {SyncHook<[]>} */
+			beforeCodeGeneration: new SyncHook([]),
+			/** @type {SyncHook<[]>} */
+			afterCodeGeneration: new SyncHook([]),
+
+			/** @type {SyncHook<[]>} */
+			beforeRuntimeRequirements: new SyncHook([]),
+			/** @type {SyncHook<[]>} */
+			afterRuntimeRequirements: new SyncHook([]),
+
+			/** @type {SyncHook<[]>} */
+			beforeHash: new SyncHook([]),
+			/** @type {SyncHook<[Chunk]>} */
+			contentHash: new SyncHook(["chunk"]),
+			/** @type {SyncHook<[]>} */
+			afterHash: new SyncHook([]),
+			/** @type {SyncHook<[Records]>} */
+			recordHash: new SyncHook(["records"]),
+			/** @type {SyncHook<[Compilation, Records]>} */
+			record: new SyncHook(["compilation", "records"]),
+
+			/** @type {SyncHook<[]>} */
+			beforeModuleAssets: new SyncHook([]),
+			/** @type {SyncBailHook<[], boolean | void>} */
+			shouldGenerateChunkAssets: new SyncBailHook([]),
+			/** @type {SyncHook<[]>} */
+			beforeChunkAssets: new SyncHook([]),
+			// TODO webpack 6 remove
+			/** @deprecated */
+			additionalChunkAssets:
+				/** @type {FakeHook<Pick<AsyncSeriesHook<[Chunks]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
+				(
+					createProcessAssetsHook(
+						"additionalChunkAssets",
+						Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
+						() => [this.chunks],
+						"DEP_WEBPACK_COMPILATION_ADDITIONAL_CHUNK_ASSETS"
+					)
+				),
+
+			// TODO webpack 6 deprecate
+			/** @deprecated */
+			additionalAssets:
+				/** @type {FakeHook<Pick<AsyncSeriesHook<[]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
+				(
+					createProcessAssetsHook(
+						"additionalAssets",
+						Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
+						() => []
+					)
+				),
+			// TODO webpack 6 remove
+			/** @deprecated */
+			optimizeChunkAssets:
+				/** @type {FakeHook<Pick<AsyncSeriesHook<[Chunks]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
+				(
+					createProcessAssetsHook(
+						"optimizeChunkAssets",
+						Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE,
+						() => [this.chunks],
+						"DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS"
+					)
+				),
+			// TODO webpack 6 remove
+			/** @deprecated */
+			afterOptimizeChunkAssets:
+				/** @type {FakeHook<Pick<AsyncSeriesHook<[Chunks]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
+				(
+					createProcessAssetsHook(
+						"afterOptimizeChunkAssets",
+						Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE + 1,
+						() => [this.chunks],
+						"DEP_WEBPACK_COMPILATION_AFTER_OPTIMIZE_CHUNK_ASSETS"
+					)
+				),
+			// TODO webpack 6 deprecate
+			/** @deprecated */
+			optimizeAssets: processAssetsHook,
+			// TODO webpack 6 deprecate
+			/** @deprecated */
+			afterOptimizeAssets: afterProcessAssetsHook,
+
+			processAssets: processAssetsHook,
+			afterProcessAssets: afterProcessAssetsHook,
+			/** @type {AsyncSeriesHook<[CompilationAssets]>} */
+			processAdditionalAssets: new AsyncSeriesHook(["assets"]),
+
+			/** @type {SyncBailHook<[], boolean | void>} */
+			needAdditionalSeal: new SyncBailHook([]),
+			/** @type {AsyncSeriesHook<[]>} */
+			afterSeal: new AsyncSeriesHook([]),
+
+			/** @type {SyncWaterfallHook<[RenderManifestEntry[], RenderManifestOptions]>} */
+			renderManifest: new SyncWaterfallHook(["result", "options"]),
+
+			/** @type {SyncHook<[Hash]>} */
+			fullHash: new SyncHook(["hash"]),
+			/** @type {SyncHook<[Chunk, Hash, ChunkHashContext]>} */
+			chunkHash: new SyncHook(["chunk", "chunkHash", "ChunkHashContext"]),
+
+			/** @type {SyncHook<[Module, string]>} */
+			moduleAsset: new SyncHook(["module", "filename"]),
+			/** @type {SyncHook<[Chunk, string]>} */
+			chunkAsset: new SyncHook(["chunk", "filename"]),
+
+			/** @type {SyncWaterfallHook<[string, PathData, AssetInfo | undefined]>} */
+			assetPath: new SyncWaterfallHook(["path", "options", "assetInfo"]),
+
+			/** @type {SyncBailHook<[], boolean | void>} */
+			needAdditionalPass: new SyncBailHook([]),
+
+			/** @type {SyncHook<[Compiler, string, number]>} */
+			childCompiler: new SyncHook([
+				"childCompiler",
+				"compilerName",
+				"compilerIndex"
+			]),
+
+			/** @type {SyncBailHook<[string, LogEntry], boolean | void>} */
+			log: new SyncBailHook(["origin", "logEntry"]),
+
+			/** @type {SyncWaterfallHook<[Error[]]>} */
+			processWarnings: new SyncWaterfallHook(["warnings"]),
+			/** @type {SyncWaterfallHook<[Error[]]>} */
+			processErrors: new SyncWaterfallHook(["errors"]),
+
+			/** @type {HookMap<SyncHook<[Partial<NormalizedStatsOptions>, CreateStatsOptionsContext]>>} */
+			statsPreset: new HookMap(() => new SyncHook(["options", "context"])),
+			/** @type {SyncHook<[Partial<NormalizedStatsOptions>, CreateStatsOptionsContext]>} */
+			statsNormalize: new SyncHook(["options", "context"]),
+			/** @type {SyncHook<[StatsFactory, NormalizedStatsOptions]>} */
+			statsFactory: new SyncHook(["statsFactory", "options"]),
+			/** @type {SyncHook<[StatsPrinter, NormalizedStatsOptions]>} */
+			statsPrinter: new SyncHook(["statsPrinter", "options"]),
+
+			/**
+			 * Gets normal module loader.
+			 * @deprecated
+			 * @returns {SyncHook<[AnyLoaderContext, NormalModule]>} normal module loader hook
+			 */
+			get normalModuleLoader() {
+				return getNormalModuleLoader();
+			}
+		});
+		/** @type {string=} */
+		this.name = undefined;
+		/** @type {number | undefined} */
+		this.startTime = undefined;
+		/** @type {number | undefined} */
+		this.endTime = undefined;
+		/** @type {Compiler} */
+		this.compiler = compiler;
+		this.resolverFactory = compiler.resolverFactory;
+		/** @type {InputFileSystem} */
+		this.inputFileSystem =
+			/** @type {InputFileSystem} */
+			(compiler.inputFileSystem);
+		this.fileSystemInfo = new FileSystemInfo(this.inputFileSystem, {
+			unmanagedPaths: compiler.unmanagedPaths,
+			managedPaths: compiler.managedPaths,
+			immutablePaths: compiler.immutablePaths,
+			logger: this.getLogger("webpack.FileSystemInfo"),
+			hashFunction: compiler.options.output.hashFunction
+		});
+		if (compiler.fileTimestamps) {
+			this.fileSystemInfo.addFileTimestamps(compiler.fileTimestamps, true);
+		}
+		if (compiler.contextTimestamps) {
+			this.fileSystemInfo.addContextTimestamps(
+				compiler.contextTimestamps,
+				true
+			);
+		}
+		/** @type {ValueCacheVersions} */
+		this.valueCacheVersions = new Map();
+		this.requestShortener = compiler.requestShortener;
+		this.compilerPath = compiler.compilerPath;
+
+		this.logger = this.getLogger("webpack.Compilation");
+
+		const options = /** @type {WebpackOptions} */ (compiler.options);
+		this.options = options;
+		this.outputOptions =
+			/** @type {OutputOptionsWithDefaults} */
+			(options && options.output);
+		/** @type {boolean} */
+		this.bail = (options && options.bail) || false;
+		/** @type {boolean} */
+		this.profile = (options && options.profile) || false;
+
+		this.params = params;
+		this.mainTemplate = new MainTemplate(this.outputOptions, this);
+		this.chunkTemplate = new ChunkTemplate(this.outputOptions, this);
+		this.runtimeTemplate = new RuntimeTemplate(
+			this,
+			this.outputOptions,
+			this.requestShortener
+		);
+		/** @type {ModuleTemplates} */
+		this.moduleTemplates = {
+			javascript: new ModuleTemplate(this.runtimeTemplate, this)
+		};
+		defineRemovedModuleTemplates(this.moduleTemplates);
+
+		// We need to think how implement types here
+		/** @type {ModuleMemCaches | undefined} */
+		this.moduleMemCaches = undefined;
+		/** @type {ModuleMemCaches | undefined} */
+		this.moduleMemCaches2 = undefined;
+		/** @type {ModuleGraph} */
+		this.moduleGraph = new ModuleGraph();
+		/** @type {ChunkGraph} */
+		this.chunkGraph = new ChunkGraph(
+			this.moduleGraph,
+			this.outputOptions.hashFunction
+		);
+		/** @type {CodeGenerationResults | undefined} */
+		this.codeGenerationResults = undefined;
+
+		/** @type {AsyncQueue<Module, Module, Module>} */
+		this.processDependenciesQueue = new AsyncQueue({
+			name: "processDependencies",
+			parallelism: options.parallelism || 100,
+			processor: this._processModuleDependencies.bind(this)
+		});
+		/** @type {AsyncQueue<Module, string, Module>} */
+		this.addModuleQueue = new AsyncQueue({
+			name: "addModule",
+			parent: this.processDependenciesQueue,
+			getKey: (module) => module.identifier(),
+			processor: this._addModule.bind(this)
+		});
+		/** @type {AsyncQueue<FactorizeModuleOptions, string, Module | ModuleFactoryResult>} */
+		this.factorizeQueue = new AsyncQueue({
+			name: "factorize",
+			parent: this.addModuleQueue,
+			processor: this._factorizeModule.bind(this)
+		});
+		/** @type {AsyncQueue<Module, Module, Module>} */
+		this.buildQueue = new AsyncQueue({
+			name: "build",
+			parent: this.factorizeQueue,
+			processor: this._buildModule.bind(this)
+		});
+		/** @type {AsyncQueue<Module, Module, Module>} */
+		this.rebuildQueue = new AsyncQueue({
+			name: "rebuild",
+			parallelism: options.parallelism || 100,
+			processor: this._rebuildModule.bind(this)
+		});
+
+		/**
+		 * Modules in value are building during the build of Module in key.
+		 * Means value blocking key from finishing.
+		 * Needed to detect build cycles.
+		 * @type {WeakMap<Module, Set<Module>>}
+		 */
+		this.creatingModuleDuringBuild = new WeakMap();
+
+		/** @type {Map<Exclude<ChunkName, null>, EntryData>} */
+		this.entries = new Map();
+		/** @type {EntryData} */
+		this.globalEntry = {
+			dependencies: [],
+			includeDependencies: [],
+			options: {
+				name: undefined
+			}
+		};
+		/** @type {Map<string, Entrypoint>} */
+		this.entrypoints = new Map();
+		/** @type {Entrypoint[]} */
+		this.asyncEntrypoints = [];
+		/** @type {Chunks} */
+		this.chunks = new Set();
+		/** @type {ChunkGroup[]} */
+		this.chunkGroups = [];
+		/** @type {Map<string, ChunkGroup>} */
+		this.namedChunkGroups = new Map();
+		/** @type {Map<string, Chunk>} */
+		this.namedChunks = new Map();
+		/** @type {Set<Module>} */
+		this.modules = new Set();
+		if (this._backCompat) {
+			arrayToSetDeprecation(this.chunks, "Compilation.chunks");
+			arrayToSetDeprecation(this.modules, "Compilation.modules");
+		}
+		/**
+		 * @private
+		 * @type {Map<string, Module>}
+		 */
+		this._modules = new Map();
+		/** @type {Records | null} */
+		this.records = null;
+		/** @type {string[]} */
+		this.additionalChunkAssets = [];
+		/** @type {CompilationAssets} */
+		this.assets = {};
+		/** @type {Map<string, AssetInfo>} */
+		this.assetsInfo = new Map();
+		/** @type {Map<string, Map<string, Set<string>>>} */
+		this._assetsRelatedIn = new Map();
+		/** @type {Error[]} */
+		this.errors = [];
+		/** @type {Error[]} */
+		this.warnings = [];
+		/** @type {Compilation[]} */
+		this.children = [];
+		/** @type {Map<string, LogEntry[]>} */
+		this.logging = new Map();
+		/** @type {Map<DependencyConstructor, ModuleFactory>} */
+		this.dependencyFactories = new Map();
+		/** @type {DependencyTemplates} */
+		this.dependencyTemplates = new DependencyTemplates(
+			this.outputOptions.hashFunction
+		);
+		/** @type {Record<string, number>} */
+		this.childrenCounters = {};
+		/** @type {Set<number> | null} */
+		this.usedChunkIds = null;
+		/** @type {Set<number> | null} */
+		this.usedModuleIds = null;
+		/** @type {boolean} */
+		this.needAdditionalPass = false;
+		/** @type {Set<ModuleWithRestoreFromUnsafeCache>} */
+		this._restoredUnsafeCacheModuleEntries = new Set();
+		/** @type {Map<string, ModuleWithRestoreFromUnsafeCache>} */
+		this._restoredUnsafeCacheEntries = new Map();
+		/** @type {WeakSet<Module>} */
+		this.builtModules = new WeakSet();
+		/** @type {WeakSet<Module>} */
+		this.codeGeneratedModules = new WeakSet();
+		/** @type {WeakSet<Module>} */
+		this.buildTimeExecutedModules = new WeakSet();
+		/** @type {Set<string>} */
+		this.emittedAssets = new Set();
+		/** @type {Set<string>} */
+		this.comparedForEmitAssets = new Set();
+		/** @type {FileSystemDependencies} */
+		this.fileDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		this.contextDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		this.missingDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		this.buildDependencies = new LazySet();
+		// TODO webpack 6 remove
+		/**
+		 * @deprecated
+		 * @type {{ add: (item: string) => FileSystemDependencies }}
+		 */
+		this.compilationDependencies = {
+			add: util.deprecate(
+				/**
+				 * Handles the add callback for this hook.
+				 * @param {string} item item
+				 * @returns {FileSystemDependencies} file dependencies
+				 */
+				(item) => this.fileDependencies.add(item),
+				"Compilation.compilationDependencies is deprecated (used Compilation.fileDependencies instead)",
+				"DEP_WEBPACK_COMPILATION_COMPILATION_DEPENDENCIES"
+			)
+		};
+
+		this._modulesCache = this.getCache("Compilation/modules");
+		this._assetsCache = this.getCache("Compilation/assets");
+		this._codeGenerationCache = this.getCache("Compilation/codeGeneration");
+
+		const unsafeCache = options.module.unsafeCache;
+		/** @type {boolean} */
+		this._unsafeCache = Boolean(unsafeCache);
+		/** @type {UnsafeCachePredicate} */
+		this._unsafeCachePredicate =
+			typeof unsafeCache === "function" ? unsafeCache : () => true;
+	}
+
+	getStats() {
+		return new Stats(this);
+	}
+
+	/**
+	 * Creates a stats options.
+	 * @param {string | boolean | StatsOptions | undefined} optionsOrPreset stats option value
+	 * @param {CreateStatsOptionsContext=} context context
+	 * @returns {NormalizedStatsOptions} normalized options
+	 */
+	createStatsOptions(optionsOrPreset, context = {}) {
+		if (typeof optionsOrPreset === "boolean") {
+			optionsOrPreset = {
+				preset: optionsOrPreset === false ? "none" : "normal"
+			};
+		} else if (typeof optionsOrPreset === "string") {
+			optionsOrPreset = { preset: optionsOrPreset };
+		}
+		if (typeof optionsOrPreset === "object" && optionsOrPreset !== null) {
+			// We use this method of shallow cloning this object to include
+			// properties in the prototype chain
+			/** @type {Partial<NormalizedStatsOptions>} */
+			const options = {};
+			for (const key in optionsOrPreset) {
+				options[key] = optionsOrPreset[/** @type {keyof StatsOptions} */ (key)];
+			}
+			if (options.preset !== undefined) {
+				this.hooks.statsPreset.for(options.preset).call(options, context);
+			}
+			this.hooks.statsNormalize.call(options, context);
+			return /** @type {NormalizedStatsOptions} */ (options);
+		}
+		/** @type {Partial<NormalizedStatsOptions>} */
+		const options = {};
+		this.hooks.statsNormalize.call(options, context);
+		return /** @type {NormalizedStatsOptions} */ (options);
+	}
+
+	/**
+	 * Creates a stats factory.
+	 * @param {NormalizedStatsOptions} options options
+	 * @returns {StatsFactory} the stats factory
+	 */
+	createStatsFactory(options) {
+		const statsFactory = new StatsFactory();
+		this.hooks.statsFactory.call(statsFactory, options);
+		return statsFactory;
+	}
+
+	/**
+	 * Creates a stats printer.
+	 * @param {NormalizedStatsOptions} options options
+	 * @returns {StatsPrinter} the stats printer
+	 */
+	createStatsPrinter(options) {
+		const statsPrinter = new StatsPrinter();
+		this.hooks.statsPrinter.call(statsPrinter, options);
+		return statsPrinter;
+	}
+
+	/**
+	 * Returns the cache facade instance.
+	 * @param {string} name cache name
+	 * @returns {CacheFacade} the cache facade instance
+	 */
+	getCache(name) {
+		return this.compiler.getCache(name);
+	}
+
+	/**
+	 * Returns a logger with that name.
+	 * @param {string | (() => string)} name name of the logger, or function called once to get the logger name
+	 * @returns {Logger} a logger with that name
+	 */
+	getLogger(name) {
+		if (!name) {
+			throw new TypeError("Compilation.getLogger(name) called without a name");
+		}
+		/** @type {LogEntry[] | undefined} */
+		let logEntries;
+		return new Logger(
+			(type, args) => {
+				if (typeof name === "function") {
+					name = name();
+					if (!name) {
+						throw new TypeError(
+							"Compilation.getLogger(name) called with a function not returning a name"
+						);
+					}
+				}
+				/** @type {LogEntry["trace"]} */
+				let trace;
+				switch (type) {
+					case LogType.warn:
+					case LogType.error:
+					case LogType.trace:
+						trace = ErrorHelpers.cutOffLoaderExecution(
+							/** @type {string} */ (new Error("Trace").stack)
+						)
+							.split("\n")
+							.slice(3);
+						break;
+				}
+				/** @type {LogEntry} */
+				const logEntry = {
+					time: Date.now(),
+					type,
+					args,
+					trace
+				};
+				/* eslint-disable no-console */
+				if (this.hooks.log.call(name, logEntry) === undefined) {
+					if (
+						logEntry.type === LogType.profileEnd &&
+						typeof console.profileEnd === "function"
+					) {
+						console.profileEnd(
+							`[${name}] ${/** @type {NonNullable<LogEntry["args"]>} */ (logEntry.args)[0]}`
+						);
+					}
+					if (logEntries === undefined) {
+						logEntries = this.logging.get(name);
+						if (logEntries === undefined) {
+							logEntries = [];
+							this.logging.set(name, logEntries);
+						}
+					}
+					logEntries.push(logEntry);
+					if (
+						logEntry.type === LogType.profile &&
+						typeof console.profile === "function"
+					) {
+						console.profile(
+							`[${name}] ${
+								/** @type {NonNullable<LogEntry["args"]>} */
+								(logEntry.args)[0]
+							}`
+						);
+					}
+					/* eslint-enable no-console */
+				}
+			},
+			(childName) => {
+				if (typeof name === "function") {
+					if (typeof childName === "function") {
+						return this.getLogger(() => {
+							if (typeof name === "function") {
+								name = name();
+								if (!name) {
+									throw new TypeError(
+										"Compilation.getLogger(name) called with a function not returning a name"
+									);
+								}
+							}
+							if (typeof childName === "function") {
+								childName = childName();
+								if (!childName) {
+									throw new TypeError(
+										"Logger.getChildLogger(name) called with a function not returning a name"
+									);
+								}
+							}
+							return `${name}/${childName}`;
+						});
+					}
+					return this.getLogger(() => {
+						if (typeof name === "function") {
+							name = name();
+							if (!name) {
+								throw new TypeError(
+									"Compilation.getLogger(name) called with a function not returning a name"
+								);
+							}
+						}
+						return `${name}/${childName}`;
+					});
+				}
+				if (typeof childName === "function") {
+					return this.getLogger(() => {
+						if (typeof childName === "function") {
+							childName = childName();
+							if (!childName) {
+								throw new TypeError(
+									"Logger.getChildLogger(name) called with a function not returning a name"
+								);
+							}
+						}
+						return `${name}/${childName}`;
+					});
+				}
+				return this.getLogger(`${name}/${childName}`);
+			}
+		);
+	}
+
+	/**
+	 * Adds the provided module to the compilation.
+	 * @param {Module} module module to be added that was created
+	 * @param {ModuleCallback} callback returns the module in the compilation,
+	 * it could be the passed one (if new), or an already existing in the compilation
+	 * @returns {void}
+	 */
+	addModule(module, callback) {
+		this.addModuleQueue.add(module, callback);
+	}
+
+	/**
+	 * Adds the provided module to the compilation.
+	 * @param {Module} module module to be added that was created
+	 * @param {ModuleCallback} callback returns the module in the compilation,
+	 * it could be the passed one (if new), or an already existing in the compilation
+	 * @returns {void}
+	 */
+	_addModule(module, callback) {
+		const identifier = module.identifier();
+		const alreadyAddedModule = this._modules.get(identifier);
+		if (alreadyAddedModule) {
+			return callback(null, alreadyAddedModule);
+		}
+
+		const currentProfile = this.profile
+			? this.moduleGraph.getProfile(module)
+			: undefined;
+		if (currentProfile !== undefined) {
+			currentProfile.markRestoringStart();
+		}
+
+		this._modulesCache.get(identifier, null, (err, cacheModule) => {
+			if (err) return callback(new ModuleRestoreError(module, err));
+
+			if (currentProfile !== undefined) {
+				currentProfile.markRestoringEnd();
+				currentProfile.markIntegrationStart();
+			}
+
+			if (cacheModule) {
+				cacheModule.updateCacheModule(module);
+
+				module = cacheModule;
+			}
+			this._modules.set(identifier, module);
+			this.modules.add(module);
+			if (this._backCompat) {
+				ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
+			}
+			if (currentProfile !== undefined) {
+				currentProfile.markIntegrationEnd();
+			}
+			callback(null, module);
+		});
+	}
+
+	/**
+	 * Fetches a module from a compilation by its identifier
+	 * @param {Module} module the module provided
+	 * @returns {Module} the module requested
+	 */
+	getModule(module) {
+		const identifier = module.identifier();
+		return /** @type {Module} */ (this._modules.get(identifier));
+	}
+
+	/**
+	 * Attempts to search for a module by its identifier
+	 * @param {string} identifier identifier (usually path) for module
+	 * @returns {Module | undefined} attempt to search for module and return it, else undefined
+	 */
+	findModule(identifier) {
+		return this._modules.get(identifier);
+	}
+
+	/**
+	 * Schedules a build of the module object
+	 * @param {Module} module module to be built
+	 * @param {ModuleCallback} callback the callback
+	 * @returns {void}
+	 */
+	buildModule(module, callback) {
+		this.buildQueue.add(module, callback);
+	}
+
+	/**
+	 * Builds the module object
+	 * @param {Module} module module to be built
+	 * @param {ModuleCallback} callback the callback
+	 * @returns {void}
+	 */
+	_buildModule(module, callback) {
+		const currentProfile = this.profile
+			? this.moduleGraph.getProfile(module)
+			: undefined;
+		if (currentProfile !== undefined) {
+			currentProfile.markBuildingStart();
+		}
+
+		module.needBuild(
+			{
+				compilation: this,
+				fileSystemInfo: this.fileSystemInfo,
+				valueCacheVersions: this.valueCacheVersions
+			},
+			(err, needBuild) => {
+				if (err) return callback(err);
+
+				if (!needBuild) {
+					if (currentProfile !== undefined) {
+						currentProfile.markBuildingEnd();
+					}
+					this.hooks.stillValidModule.call(module);
+					return callback();
+				}
+
+				this.hooks.buildModule.call(module);
+				this.builtModules.add(module);
+				module.build(
+					this.options,
+					this,
+					this.resolverFactory.get("normal", module.resolveOptions),
+					/** @type {InputFileSystem} */
+					(this.inputFileSystem),
+					(err) => {
+						if (currentProfile !== undefined) {
+							currentProfile.markBuildingEnd();
+						}
+						if (err) {
+							this.hooks.failedModule.call(module, err);
+							return callback(err);
+						}
+						if (currentProfile !== undefined) {
+							currentProfile.markStoringStart();
+						}
+						this._modulesCache.store(
+							module.identifier(),
+							null,
+							module,
+							(err) => {
+								if (currentProfile !== undefined) {
+									currentProfile.markStoringEnd();
+								}
+								if (err) {
+									this.hooks.failedModule.call(
+										module,
+										/** @type {WebpackError} */ (err)
+									);
+									return callback(new ModuleStoreError(module, err));
+								}
+								this.hooks.succeedModule.call(module);
+								return callback();
+							}
+						);
+					}
+				);
+			}
+		);
+	}
+
+	/**
+	 * Process module dependencies.
+	 * @param {Module} module to be processed for deps
+	 * @param {ModuleCallback} callback callback to be triggered
+	 * @returns {void}
+	 */
+	processModuleDependencies(module, callback) {
+		this.processDependenciesQueue.add(module, callback);
+	}
+
+	/**
+	 * Process module dependencies non recursive.
+	 * @param {Module} module to be processed for deps
+	 * @returns {void}
+	 */
+	processModuleDependenciesNonRecursive(module) {
+		/**
+		 * Process dependencies block.
+		 * @param {DependenciesBlock} block block
+		 */
+		const processDependenciesBlock = (block) => {
+			if (block.dependencies) {
+				let i = 0;
+				for (const dep of block.dependencies) {
+					this.moduleGraph.setParents(dep, block, module, i++);
+				}
+			}
+			if (block.blocks) {
+				for (const b of block.blocks) processDependenciesBlock(b);
+			}
+		};
+
+		processDependenciesBlock(module);
+	}
+
+	/**
+	 * Process module dependencies.
+	 * @param {Module} module to be processed for deps
+	 * @param {ModuleCallback} callback callback to be triggered
+	 * @returns {void}
+	 */
+	_processModuleDependencies(module, callback) {
+		/** @type {{ factory: ModuleFactory, dependencies: Dependency[], context: string | undefined, originModule: Module | null }[]} */
+		const sortedDependencies = [];
+		/** @type {boolean} */
+		const hasLowPriorityDependencies = module.dependencies.some(
+			Dependency.isLowPriorityDependency
+		);
+
+		/** @type {DependenciesBlock} */
+		let currentBlock;
+
+		/** @type {Map<ModuleFactory, Map<string, Dependency[]>>} */
+		let dependencies;
+		/** @type {DependencyConstructor} */
+		let factoryCacheKey;
+		/** @type {ModuleFactory} */
+		let factoryCacheKey2;
+		/** @typedef {Map<string, Dependency[]>} FactoryCacheValue */
+		/** @type {FactoryCacheValue | undefined} */
+		let factoryCacheValue;
+		/** @type {string} */
+		let listCacheKey1;
+		/** @type {string} */
+		let listCacheKey2;
+		/** @type {Dependency[]} */
+		let listCacheValue;
+
+		let inProgressSorting = 1;
+		let inProgressTransitive = 1;
+
+		/**
+		 * On dependencies sorted.
+		 * @param {WebpackError=} err error
+		 * @returns {void}
+		 */
+		const onDependenciesSorted = (err) => {
+			if (err) return callback(err);
+
+			// early exit without changing parallelism back and forth
+			if (sortedDependencies.length === 0 && inProgressTransitive === 1) {
+				return callback();
+			}
+
+			// This is nested so we need to allow one additional task
+			this.processDependenciesQueue.increaseParallelism();
+
+			for (const item of sortedDependencies) {
+				inProgressTransitive++;
+				// eslint-disable-next-line no-loop-func
+				this.handleModuleCreation(item, (err) => {
+					// In V8, the Error objects keep a reference to the functions on the stack. These warnings &
+					// errors are created inside closures that keep a reference to the Compilation, so errors are
+					// leaking the Compilation object.
+					if (err && this.bail) {
+						if (inProgressTransitive <= 0) return;
+						inProgressTransitive = -1;
+						// eslint-disable-next-line no-self-assign
+						err.stack = err.stack;
+						onTransitiveTasksFinished(err);
+						return;
+					}
+					if (--inProgressTransitive === 0) onTransitiveTasksFinished();
+				});
+			}
+			if (--inProgressTransitive === 0) onTransitiveTasksFinished();
+		};
+
+		/**
+		 * On transitive tasks finished.
+		 * @param {WebpackError=} err error
+		 * @returns {void}
+		 */
+		const onTransitiveTasksFinished = (err) => {
+			if (err) return callback(err);
+			this.processDependenciesQueue.decreaseParallelism();
+
+			return callback();
+		};
+
+		/**
+		 * Process dependency.
+		 * @param {Dependency} dep dependency
+		 * @param {number} index index in block
+		 * @returns {void}
+		 */
+		const processDependency = (dep, index) => {
+			this.moduleGraph.setParents(dep, currentBlock, module, index);
+			if (this._unsafeCache) {
+				try {
+					const unsafeCachedModule = unsafeCacheDependencies.get(dep);
+					if (unsafeCachedModule === null) return;
+					if (unsafeCachedModule !== undefined) {
+						if (
+							this._restoredUnsafeCacheModuleEntries.has(unsafeCachedModule)
+						) {
+							this._handleExistingModuleFromUnsafeCache(
+								module,
+								dep,
+								unsafeCachedModule
+							);
+							return;
+						}
+						const identifier = unsafeCachedModule.identifier();
+						const cachedModule =
+							this._restoredUnsafeCacheEntries.get(identifier);
+						if (cachedModule !== undefined) {
+							// update unsafe cache to new module
+							unsafeCacheDependencies.set(dep, cachedModule);
+							this._handleExistingModuleFromUnsafeCache(
+								module,
+								dep,
+								cachedModule
+							);
+							return;
+						}
+						inProgressSorting++;
+						this._modulesCache.get(identifier, null, (err, cachedModule) => {
+							if (err) {
+								if (inProgressSorting <= 0) return;
+								inProgressSorting = -1;
+								onDependenciesSorted(/** @type {WebpackError} */ (err));
+								return;
+							}
+							try {
+								if (!this._restoredUnsafeCacheEntries.has(identifier)) {
+									const data = unsafeCacheData.get(cachedModule);
+									if (data === undefined) {
+										processDependencyForResolving(dep);
+										if (--inProgressSorting === 0) onDependenciesSorted();
+										return;
+									}
+									if (cachedModule !== unsafeCachedModule) {
+										unsafeCacheDependencies.set(dep, cachedModule);
+									}
+									cachedModule.restoreFromUnsafeCache(
+										data,
+										this.params.normalModuleFactory,
+										this.params
+									);
+									this._restoredUnsafeCacheEntries.set(
+										identifier,
+										cachedModule
+									);
+									this._restoredUnsafeCacheModuleEntries.add(cachedModule);
+									if (!this.modules.has(cachedModule)) {
+										inProgressTransitive++;
+										this._handleNewModuleFromUnsafeCache(
+											module,
+											dep,
+											cachedModule,
+											(err) => {
+												if (err) {
+													if (inProgressTransitive <= 0) return;
+													inProgressTransitive = -1;
+													onTransitiveTasksFinished(err);
+												}
+												if (--inProgressTransitive === 0) {
+													return onTransitiveTasksFinished();
+												}
+											}
+										);
+										if (--inProgressSorting === 0) onDependenciesSorted();
+										return;
+									}
+								}
+								if (unsafeCachedModule !== cachedModule) {
+									unsafeCacheDependencies.set(dep, cachedModule);
+								}
+								this._handleExistingModuleFromUnsafeCache(
+									module,
+									dep,
+									cachedModule
+								); // a3
+							} catch (err) {
+								if (inProgressSorting <= 0) return;
+								inProgressSorting = -1;
+								onDependenciesSorted(/** @type {WebpackError} */ (err));
+								return;
+							}
+							if (--inProgressSorting === 0) onDependenciesSorted();
+						});
+						return;
+					}
+				} catch (err) {
+					// eslint-disable-next-line no-console
+					console.error(err);
+				}
+			}
+			processDependencyForResolving(dep);
+		};
+
+		/**
+		 * Process dependency for resolving.
+		 * @param {Dependency} dep dependency
+		 * @returns {void}
+		 */
+		const processDependencyForResolving = (dep) => {
+			const resourceIdent = dep.getResourceIdentifier();
+			if (resourceIdent !== undefined && resourceIdent !== null) {
+				const category = dep.category;
+				const constructor =
+					/** @type {DependencyConstructor} */
+					(dep.constructor);
+				if (factoryCacheKey === constructor) {
+					// Fast path 1: same constructor as prev item
+					if (listCacheKey1 === category && listCacheKey2 === resourceIdent) {
+						// Super fast path 1: also same resource
+						listCacheValue.push(dep);
+						return;
+					}
+				} else {
+					const factory = this.dependencyFactories.get(constructor);
+					if (factory === undefined) {
+						throw new Error(
+							`No module factory available for dependency type: ${constructor.name}`
+						);
+					}
+					if (factoryCacheKey2 === factory) {
+						// Fast path 2: same factory as prev item
+						factoryCacheKey = constructor;
+						if (listCacheKey1 === category && listCacheKey2 === resourceIdent) {
+							// Super fast path 2: also same resource
+							listCacheValue.push(dep);
+							return;
+						}
+					} else {
+						// Slow path
+						if (factoryCacheKey2 !== undefined) {
+							// Archive last cache entry
+							if (dependencies === undefined) dependencies = new Map();
+							dependencies.set(
+								factoryCacheKey2,
+								/** @type {FactoryCacheValue} */ (factoryCacheValue)
+							);
+							factoryCacheValue = dependencies.get(factory);
+							if (factoryCacheValue === undefined) {
+								factoryCacheValue = new Map();
+							}
+						} else {
+							factoryCacheValue = new Map();
+						}
+						factoryCacheKey = constructor;
+						factoryCacheKey2 = factory;
+					}
+				}
+				// Here webpack is using heuristic that assumes
+				// mostly esm dependencies would be used
+				// so we don't allocate extra string for them
+				const cacheKey =
+					category === esmDependencyCategory
+						? resourceIdent
+						: `${category}${resourceIdent}`;
+				let list = /** @type {FactoryCacheValue} */ (factoryCacheValue).get(
+					cacheKey
+				);
+				if (list === undefined) {
+					/** @type {FactoryCacheValue} */
+					(factoryCacheValue).set(cacheKey, (list = []));
+					const newItem = {
+						factory: factoryCacheKey2,
+						dependencies: list,
+						context: dep.getContext(),
+						originModule: module
+					};
+					if (hasLowPriorityDependencies) {
+						let insertIndex = sortedDependencies.length;
+						while (insertIndex > 0) {
+							const item = sortedDependencies[insertIndex - 1];
+							const isAllLowPriorityDependencies = item.dependencies.every(
+								Dependency.isLowPriorityDependency
+							);
+							if (isAllLowPriorityDependencies) {
+								insertIndex--;
+							} else {
+								break;
+							}
+						}
+						sortedDependencies.splice(insertIndex, 0, newItem);
+					} else {
+						sortedDependencies.push(newItem);
+					}
+				}
+				list.push(dep);
+				listCacheKey1 = category;
+				listCacheKey2 = resourceIdent;
+				listCacheValue = list;
+			}
+		};
+
+		try {
+			/** @type {DependenciesBlock[]} */
+			const queue = [module];
+			do {
+				const block = /** @type {DependenciesBlock} */ (queue.pop());
+				if (block.dependencies) {
+					currentBlock = block;
+					let i = 0;
+					for (const dep of block.dependencies) processDependency(dep, i++);
+				}
+				if (block.blocks) {
+					for (const b of block.blocks) queue.push(b);
+				}
+			} while (queue.length !== 0);
+		} catch (err) {
+			return callback(/** @type {WebpackError} */ (err));
+		}
+
+		if (--inProgressSorting === 0) onDependenciesSorted();
+	}
+
+	/**
+	 * Handle new module from unsafe cache.
+	 * @private
+	 * @param {Module} originModule original module
+	 * @param {Dependency} dependency dependency
+	 * @param {Module} module cached module
+	 * @param {Callback} callback callback
+	 */
+	_handleNewModuleFromUnsafeCache(originModule, dependency, module, callback) {
+		const moduleGraph = this.moduleGraph;
+
+		moduleGraph.setResolvedModule(originModule, dependency, module);
+
+		moduleGraph.setIssuerIfUnset(
+			module,
+			originModule !== undefined ? originModule : null
+		);
+
+		this._modules.set(module.identifier(), module);
+		this.modules.add(module);
+		if (this._backCompat) {
+			ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
+		}
+
+		this._handleModuleBuildAndDependencies(
+			originModule,
+			module,
+			true,
+			false,
+			callback
+		);
+	}
+
+	/**
+	 * Handle existing module from unsafe cache.
+	 * @private
+	 * @param {Module} originModule original modules
+	 * @param {Dependency} dependency dependency
+	 * @param {Module} module cached module
+	 */
+	_handleExistingModuleFromUnsafeCache(originModule, dependency, module) {
+		const moduleGraph = this.moduleGraph;
+
+		moduleGraph.setResolvedModule(originModule, dependency, module);
+	}
+
+	/**
+	 * Processes the provided factorize module option.
+	 * @param {FactorizeModuleOptions} options options
+	 * @param {ModuleOrModuleFactoryResultCallback} callback callback
+	 * @returns {void}
+	 */
+	_factorizeModule(
+		{
+			currentProfile,
+			factory,
+			dependencies,
+			originModule,
+			factoryResult,
+			contextInfo,
+			context
+		},
+		callback
+	) {
+		if (currentProfile !== undefined) {
+			currentProfile.markFactoryStart();
+		}
+		factory.create(
+			{
+				contextInfo: {
+					issuer: originModule
+						? /** @type {NameForCondition} */ (originModule.nameForCondition())
+						: "",
+					issuerLayer: originModule ? originModule.layer : null,
+					compiler: this.compiler.name,
+					...contextInfo
+				},
+				resolveOptions: originModule ? originModule.resolveOptions : undefined,
+				context:
+					context ||
+					(originModule
+						? /** @type {string} */ (originModule.context)
+						: this.compiler.context),
+				dependencies
+			},
+			(err, result) => {
+				if (result) {
+					// TODO webpack 6: remove
+					// For backward-compat
+					if (result.module === undefined && result instanceof Module) {
+						result = {
+							module: result
+						};
+					}
+					if (!factoryResult) {
+						const {
+							fileDependencies,
+							contextDependencies,
+							missingDependencies
+						} = result;
+						if (fileDependencies) {
+							this.fileDependencies.addAll(fileDependencies);
+						}
+						if (contextDependencies) {
+							this.contextDependencies.addAll(contextDependencies);
+						}
+						if (missingDependencies) {
+							this.missingDependencies.addAll(missingDependencies);
+						}
+					}
+				}
+				if (err) {
+					const notFoundError = new ModuleNotFoundError(
+						originModule,
+						err,
+						/** @type {DependencyLocation} */
+						(dependencies.map((d) => d.loc).find(Boolean))
+					);
+					return callback(notFoundError, factoryResult ? result : undefined);
+				}
+				if (!result) {
+					return callback();
+				}
+
+				if (currentProfile !== undefined) {
+					currentProfile.markFactoryEnd();
+				}
+
+				callback(null, factoryResult ? result : result.module);
+			}
+		);
+	}
+
+	/**
+	 * Processes the provided module callback.
+	 * @overload
+	 * @param {FactorizeModuleOptions & { factoryResult?: false }} options options
+	 * @param {ModuleCallback} callback callback
+	 * @returns {void}
+	 */
+	/**
+	 * Processes the provided module factory result callback.
+	 * @overload
+	 * @param {FactorizeModuleOptions & { factoryResult: true }} options options
+	 * @param {ModuleFactoryResultCallback} callback callback
+	 * @returns {void}
+	 */
+	/**
+	 * Processes the provided |.
+	 * @param {FactorizeModuleOptions & { factoryResult?: false } | FactorizeModuleOptions & { factoryResult: true }} options options
+	 * @param {ModuleCallback | ModuleFactoryResultCallback} callback callback
+	 */
+	factorizeModule(options, callback) {
+		this.factorizeQueue.add(
+			options,
+			/** @type {ModuleOrModuleFactoryResultCallback} */
+			(callback)
+		);
+	}
+
+	/**
+	 * Defines the handle module creation options type used by this module.
+	 * @typedef {object} HandleModuleCreationOptions
+	 * @property {ModuleFactory} factory
+	 * @property {Dependency[]} dependencies
+	 * @property {Module | null} originModule
+	 * @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
+	 * @property {string=} context
+	 * @property {boolean=} recursive recurse into dependencies of the created module
+	 * @property {boolean=} connectOrigin connect the resolved module with the origin module
+	 * @property {boolean=} checkCycle check the cycle dependencies of the created module
+	 */
+
+	/**
+	 * Handle module creation.
+	 * @param {HandleModuleCreationOptions} options options object
+	 * @param {ModuleCallback} callback callback
+	 * @returns {void}
+	 */
+	handleModuleCreation(
+		{
+			factory,
+			dependencies,
+			originModule,
+			contextInfo,
+			context,
+			recursive = true,
+			connectOrigin = recursive,
+			checkCycle = !recursive
+		},
+		callback
+	) {
+		const moduleGraph = this.moduleGraph;
+
+		const currentProfile = this.profile ? new ModuleProfile() : undefined;
+
+		this.factorizeModule(
+			{
+				currentProfile,
+				factory,
+				dependencies,
+				factoryResult: true,
+				originModule,
+				contextInfo,
+				context
+			},
+			(err, factoryResult) => {
+				const applyFactoryResultDependencies = () => {
+					const { fileDependencies, contextDependencies, missingDependencies } =
+						/** @type {ModuleFactoryResult} */ (factoryResult);
+					if (fileDependencies) {
+						this.fileDependencies.addAll(fileDependencies);
+					}
+					if (contextDependencies) {
+						this.contextDependencies.addAll(contextDependencies);
+					}
+					if (missingDependencies) {
+						this.missingDependencies.addAll(missingDependencies);
+					}
+				};
+				if (err) {
+					if (factoryResult) applyFactoryResultDependencies();
+					if (dependencies.every((d) => d.optional)) {
+						this.warnings.push(err);
+						return callback();
+					}
+					this.errors.push(err);
+					return callback(err);
+				}
+
+				const newModule =
+					/** @type {ModuleFactoryResult} */
+					(factoryResult).module;
+
+				if (!newModule) {
+					applyFactoryResultDependencies();
+					return callback();
+				}
+
+				if (currentProfile !== undefined) {
+					moduleGraph.setProfile(newModule, currentProfile);
+				}
+
+				this.addModule(newModule, (err, _module) => {
+					if (err) {
+						applyFactoryResultDependencies();
+						if (!err.module) {
+							err.module = _module;
+						}
+						this.errors.push(err);
+
+						return callback(err);
+					}
+
+					const module =
+						/** @type {ModuleWithRestoreFromUnsafeCache} */
+						(_module);
+
+					if (
+						this._unsafeCache &&
+						/** @type {ModuleFactoryResult} */
+						(factoryResult).cacheable !== false &&
+						module.restoreFromUnsafeCache &&
+						this._unsafeCachePredicate(module)
+					) {
+						const unsafeCacheableModule =
+							/** @type {ModuleWithRestoreFromUnsafeCache} */
+							(module);
+						for (const dependency of dependencies) {
+							moduleGraph.setResolvedModule(
+								connectOrigin ? originModule : null,
+								dependency,
+								unsafeCacheableModule
+							);
+							unsafeCacheDependencies.set(dependency, unsafeCacheableModule);
+						}
+						if (!unsafeCacheData.has(unsafeCacheableModule)) {
+							unsafeCacheData.set(
+								unsafeCacheableModule,
+								unsafeCacheableModule.getUnsafeCacheData()
+							);
+						}
+					} else {
+						applyFactoryResultDependencies();
+						for (const dependency of dependencies) {
+							moduleGraph.setResolvedModule(
+								connectOrigin ? originModule : null,
+								dependency,
+								module
+							);
+						}
+					}
+
+					moduleGraph.setIssuerIfUnset(
+						module,
+						originModule !== undefined ? originModule : null
+					);
+					if (module !== newModule && currentProfile !== undefined) {
+						const otherProfile = moduleGraph.getProfile(module);
+						if (otherProfile !== undefined) {
+							currentProfile.mergeInto(otherProfile);
+						} else {
+							moduleGraph.setProfile(module, currentProfile);
+						}
+					}
+
+					this._handleModuleBuildAndDependencies(
+						originModule,
+						module,
+						recursive,
+						checkCycle,
+						callback
+					);
+				});
+			}
+		);
+	}
+
+	/**
+	 * Handle module build and dependencies.
+	 * @private
+	 * @param {Module | null} originModule original module
+	 * @param {Module} module module
+	 * @param {boolean} recursive true if make it recursive, otherwise false
+	 * @param {boolean} checkCycle true if need to check cycle, otherwise false
+	 * @param {ModuleCallback} callback callback
+	 * @returns {void}
+	 */
+	_handleModuleBuildAndDependencies(
+		originModule,
+		module,
+		recursive,
+		checkCycle,
+		callback
+	) {
+		// Check for cycles when build is trigger inside another build
+		/** @type {Set<Module> | undefined} */
+		let creatingModuleDuringBuildSet;
+		if (
+			checkCycle &&
+			this.buildQueue.isProcessing(/** @type {Module} */ (originModule))
+		) {
+			// Track build dependency
+			creatingModuleDuringBuildSet = this.creatingModuleDuringBuild.get(
+				/** @type {Module} */
+				(originModule)
+			);
+			if (creatingModuleDuringBuildSet === undefined) {
+				/** @type {Set<Module>} */
+				creatingModuleDuringBuildSet = new Set();
+				this.creatingModuleDuringBuild.set(
+					/** @type {Module} */
+					(originModule),
+					creatingModuleDuringBuildSet
+				);
+			}
+			creatingModuleDuringBuildSet.add(module);
+
+			// When building is blocked by another module
+			// search for a cycle, cancel the cycle by throwing
+			// an error (otherwise this would deadlock)
+			const blockReasons = this.creatingModuleDuringBuild.get(module);
+			if (blockReasons !== undefined) {
+				const set = new Set(blockReasons);
+				for (const item of set) {
+					const blockReasons = this.creatingModuleDuringBuild.get(item);
+					if (blockReasons !== undefined) {
+						for (const m of blockReasons) {
+							if (m === module) {
+								return callback(new BuildCycleError(module));
+							}
+							set.add(m);
+						}
+					}
+				}
+			}
+		}
+
+		this.buildModule(module, (err) => {
+			if (creatingModuleDuringBuildSet !== undefined) {
+				creatingModuleDuringBuildSet.delete(module);
+			}
+			if (err) {
+				if (!err.module) {
+					err.module = module;
+				}
+				this.errors.push(err);
+
+				return callback(err);
+			}
+
+			if (!recursive) {
+				this.processModuleDependenciesNonRecursive(module);
+				callback(null, module);
+				return;
+			}
+
+			// This avoids deadlocks for circular dependencies
+			if (this.processDependenciesQueue.isProcessing(module)) {
+				return callback(null, module);
+			}
+
+			this.processModuleDependencies(module, (err) => {
+				if (err) {
+					return callback(err);
+				}
+				callback(null, module);
+			});
+		});
+	}
+
+	/**
+	 * Adds the provided string to the compilation.
+	 * @param {string} context context string path
+	 * @param {Dependency} dependency dependency used to create Module chain
+	 * @param {ModuleCallback} callback callback for when module chain is complete
+	 * @returns {void} will throw if dependency instance is not a valid Dependency
+	 */
+	addModuleChain(context, dependency, callback) {
+		return this.addModuleTree({ context, dependency }, callback);
+	}
+
+	/**
+	 * Adds the provided object to the compilation.
+	 * @param {object} options options
+	 * @param {string} options.context context string path
+	 * @param {Dependency} options.dependency dependency used to create Module chain
+	 * @param {Partial<ModuleFactoryCreateDataContextInfo>=} options.contextInfo additional context info for the root module
+	 * @param {ModuleCallback} callback callback for when module chain is complete
+	 * @returns {void} will throw if dependency instance is not a valid Dependency
+	 */
+	addModuleTree({ context, dependency, contextInfo }, callback) {
+		if (
+			typeof dependency !== "object" ||
+			dependency === null ||
+			!dependency.constructor
+		) {
+			return callback(
+				new WebpackError("Parameter 'dependency' must be a Dependency")
+			);
+		}
+		const Dep =
+			/** @type {DependencyConstructor} */
+			(dependency.constructor);
+		const moduleFactory = this.dependencyFactories.get(Dep);
+		if (!moduleFactory) {
+			return callback(
+				new WebpackError(
+					`No dependency factory available for this dependency type: ${dependency.constructor.name}`
+				)
+			);
+		}
+
+		this.handleModuleCreation(
+			{
+				factory: moduleFactory,
+				dependencies: [dependency],
+				originModule: null,
+				contextInfo,
+				context
+			},
+			(err, result) => {
+				if (err && this.bail) {
+					callback(err);
+					this.buildQueue.stop();
+					this.rebuildQueue.stop();
+					this.processDependenciesQueue.stop();
+					this.factorizeQueue.stop();
+				} else if (!err && result) {
+					callback(null, result);
+				} else {
+					callback();
+				}
+			}
+		);
+	}
+
+	/**
+	 * Adds the provided string to the compilation.
+	 * @param {string} context context path for entry
+	 * @param {Dependency} entry entry dependency that should be followed
+	 * @param {string | EntryOptions} optionsOrName options or deprecated name of entry
+	 * @param {ModuleCallback} callback callback function
+	 * @returns {void} returns
+	 */
+	addEntry(context, entry, optionsOrName, callback) {
+		// TODO webpack 6 remove
+		const options =
+			typeof optionsOrName === "object"
+				? optionsOrName
+				: { name: optionsOrName };
+
+		this._addEntryItem(context, entry, "dependencies", options, callback);
+	}
+
+	/**
+	 * Adds the provided string to the compilation.
+	 * @param {string} context context path for entry
+	 * @param {Dependency} dependency dependency that should be followed
+	 * @param {EntryOptions} options options
+	 * @param {ModuleCallback} callback callback function
+	 * @returns {void} returns
+	 */
+	addInclude(context, dependency, options, callback) {
+		this._addEntryItem(
+			context,
+			dependency,
+			"includeDependencies",
+			options,
+			callback
+		);
+	}
+
+	/**
+	 * Adds the provided string to the compilation.
+	 * @param {string} context context path for entry
+	 * @param {Dependency} entry entry dependency that should be followed
+	 * @param {"dependencies" | "includeDependencies"} target type of entry
+	 * @param {EntryOptions} options options
+	 * @param {ModuleCallback} callback callback function
+	 * @returns {void} returns
+	 */
+	_addEntryItem(context, entry, target, options, callback) {
+		const { name } = options;
+		/** @type {EntryData | undefined} */
+		let entryData =
+			name !== undefined ? this.entries.get(name) : this.globalEntry;
+		if (entryData === undefined) {
+			entryData = {
+				dependencies: [],
+				includeDependencies: [],
+				options: {
+					name: undefined,
+					...options
+				}
+			};
+			entryData[target].push(entry);
+			this.entries.set(
+				/** @type {NonNullable<EntryOptions["name"]>} */
+				(name),
+				entryData
+			);
+		} else {
+			entryData[target].push(entry);
+			for (const key_ of Object.keys(options)) {
+				const key = /** @type {keyof EntryOptions} */ (key_);
+				if (options[key] === undefined) continue;
+				if (entryData.options[key] === options[key]) continue;
+				if (
+					Array.isArray(entryData.options[key]) &&
+					Array.isArray(options[key]) &&
+					arrayEquals(entryData.options[key], options[key])
+				) {
+					continue;
+				}
+				if (entryData.options[key] === undefined) {
+					/** @type {EntryOptions[keyof EntryOptions]} */
+					(entryData.options[key]) = options[key];
+				} else {
+					return callback(
+						new WebpackError(
+							`Conflicting entry option ${key} = ${entryData.options[key]} vs ${options[key]}`
+						)
+					);
+				}
+			}
+		}
+
+		this.hooks.addEntry.call(entry, options);
+
+		this.addModuleTree(
+			{
+				context,
+				dependency: entry,
+				contextInfo: entryData.options.layer
+					? { issuerLayer: entryData.options.layer }
+					: undefined
+			},
+			(err, module) => {
+				if (err) {
+					this.hooks.failedEntry.call(entry, options, err);
+					return callback(err);
+				}
+				this.hooks.succeedEntry.call(
+					entry,
+					options,
+					/** @type {Module} */
+					(module)
+				);
+				return callback(null, module);
+			}
+		);
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module module to be rebuilt
+	 * @param {ModuleCallback} callback callback when module finishes rebuilding
+	 * @returns {void}
+	 */
+	rebuildModule(module, callback) {
+		this.rebuildQueue.add(module, callback);
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module module to be rebuilt
+	 * @param {ModuleCallback} callback callback when module finishes rebuilding
+	 * @returns {void}
+	 */
+	_rebuildModule(module, callback) {
+		this.hooks.rebuildModule.call(module);
+		const oldDependencies = [...module.dependencies];
+		const oldBlocks = [...module.blocks];
+		module.invalidateBuild();
+		this.buildQueue.invalidate(module);
+		this.buildModule(module, (err) => {
+			if (err) {
+				return this.hooks.finishRebuildingModule.callAsync(module, (err2) => {
+					if (err2) {
+						callback(
+							makeWebpackError(err2, "Compilation.hooks.finishRebuildingModule")
+						);
+						return;
+					}
+					callback(err);
+				});
+			}
+
+			this.processDependenciesQueue.invalidate(module);
+			this.moduleGraph.unfreeze();
+			this.processModuleDependencies(module, (err) => {
+				if (err) return callback(err);
+				this.removeReasonsOfDependencyBlock(module, {
+					dependencies: oldDependencies,
+					blocks: oldBlocks
+				});
+				this.hooks.finishRebuildingModule.callAsync(module, (err2) => {
+					if (err2) {
+						callback(
+							makeWebpackError(err2, "Compilation.hooks.finishRebuildingModule")
+						);
+						return;
+					}
+					callback(null, module);
+				});
+			});
+		});
+	}
+
+	/**
+	 * Compute affected modules.
+	 * @private
+	 * @param {Set<Module>} modules modules
+	 */
+	_computeAffectedModules(modules) {
+		const moduleMemCacheCache = this.compiler.moduleMemCaches;
+		if (!moduleMemCacheCache) return;
+		if (!this.moduleMemCaches) {
+			this.moduleMemCaches = new Map();
+			this.moduleGraph.setModuleMemCaches(this.moduleMemCaches);
+		}
+		const { moduleGraph, moduleMemCaches } = this;
+		/** @type {Set<Module>} */
+		const affectedModules = new Set();
+		/** @type {Set<Module>} */
+		const infectedModules = new Set();
+		let statNew = 0;
+		let statChanged = 0;
+		let statUnchanged = 0;
+		let statReferencesChanged = 0;
+		let statWithoutBuild = 0;
+
+		/**
+		 * Compute references.
+		 * @param {Module} module module
+		 * @returns {WeakReferences | undefined} references
+		 */
+		const computeReferences = (module) => {
+			/** @type {WeakReferences | undefined} */
+			let references;
+			for (const connection of moduleGraph.getOutgoingConnections(module)) {
+				const d = connection.dependency;
+				const m = connection.module;
+				if (!d || !m || unsafeCacheDependencies.has(d)) continue;
+				if (references === undefined) references = new WeakMap();
+				references.set(d, m);
+			}
+			return references;
+		};
+
+		/**
+		 * Compares references.
+		 * @param {Module} module the module
+		 * @param {WeakReferences | undefined} references references
+		 * @returns {boolean} true, when the references differ
+		 */
+		const compareReferences = (module, references) => {
+			if (references === undefined) return true;
+			for (const connection of moduleGraph.getOutgoingConnections(module)) {
+				const d = connection.dependency;
+				if (!d) continue;
+				const entry = references.get(d);
+				if (entry === undefined) continue;
+				if (entry !== connection.module) return false;
+			}
+			return true;
+		};
+
+		const modulesWithoutCache = new Set(modules);
+		for (const [module, cachedMemCache] of moduleMemCacheCache) {
+			if (modulesWithoutCache.has(module)) {
+				const buildInfo = module.buildInfo;
+				if (buildInfo) {
+					if (cachedMemCache.buildInfo !== buildInfo) {
+						// use a new one
+						/** @type {MemCache} */
+						const memCache = new WeakTupleMap();
+						moduleMemCaches.set(module, memCache);
+						affectedModules.add(module);
+						cachedMemCache.buildInfo = buildInfo;
+						cachedMemCache.references = computeReferences(module);
+						cachedMemCache.memCache = memCache;
+						statChanged++;
+					} else if (!compareReferences(module, cachedMemCache.references)) {
+						// use a new one
+						/** @type {MemCache} */
+						const memCache = new WeakTupleMap();
+						moduleMemCaches.set(module, memCache);
+						affectedModules.add(module);
+						cachedMemCache.references = computeReferences(module);
+						cachedMemCache.memCache = memCache;
+						statReferencesChanged++;
+					} else {
+						// keep the old mem cache
+						moduleMemCaches.set(module, cachedMemCache.memCache);
+						statUnchanged++;
+					}
+				} else {
+					infectedModules.add(module);
+					moduleMemCacheCache.delete(module);
+					statWithoutBuild++;
+				}
+				modulesWithoutCache.delete(module);
+			} else {
+				moduleMemCacheCache.delete(module);
+			}
+		}
+
+		for (const module of modulesWithoutCache) {
+			const buildInfo = module.buildInfo;
+			if (buildInfo) {
+				// create a new entry
+				const memCache = new WeakTupleMap();
+				moduleMemCacheCache.set(module, {
+					buildInfo,
+					references: computeReferences(module),
+					memCache
+				});
+				moduleMemCaches.set(module, memCache);
+				affectedModules.add(module);
+				statNew++;
+			} else {
+				infectedModules.add(module);
+				statWithoutBuild++;
+			}
+		}
+
+		/**
+		 * Reduce affect type.
+		 * @param {Readonly<ModuleGraphConnection[]>} connections connections
+		 * @returns {symbol | boolean} result
+		 */
+		const reduceAffectType = (connections) => {
+			let affected = false;
+			for (const { dependency } of connections) {
+				if (!dependency) continue;
+				const type = dependency.couldAffectReferencingModule();
+				if (type === Dependency.TRANSITIVE) return Dependency.TRANSITIVE;
+				if (type === false) continue;
+				affected = true;
+			}
+			return affected;
+		};
+		/** @type {Set<Module>} */
+		const directOnlyInfectedModules = new Set();
+		for (const module of infectedModules) {
+			for (const [
+				referencingModule,
+				connections
+			] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
+				if (!referencingModule) continue;
+				if (infectedModules.has(referencingModule)) continue;
+				const type = reduceAffectType(connections);
+				if (!type) continue;
+				if (type === true) {
+					directOnlyInfectedModules.add(referencingModule);
+				} else {
+					infectedModules.add(referencingModule);
+				}
+			}
+		}
+		for (const module of directOnlyInfectedModules) infectedModules.add(module);
+		/** @type {Set<Module>} */
+		const directOnlyAffectModules = new Set();
+		for (const module of affectedModules) {
+			for (const [
+				referencingModule,
+				connections
+			] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
+				if (!referencingModule) continue;
+				if (infectedModules.has(referencingModule)) continue;
+				if (affectedModules.has(referencingModule)) continue;
+				const type = reduceAffectType(connections);
+				if (!type) continue;
+				if (type === true) {
+					directOnlyAffectModules.add(referencingModule);
+				} else {
+					affectedModules.add(referencingModule);
+				}
+				/** @type {MemCache} */
+				const memCache = new WeakTupleMap();
+				const cache =
+					/** @type {ModuleMemCachesItem} */
+					(moduleMemCacheCache.get(referencingModule));
+				cache.memCache = memCache;
+				moduleMemCaches.set(referencingModule, memCache);
+			}
+		}
+		for (const module of directOnlyAffectModules) affectedModules.add(module);
+		this.logger.log(
+			`${Math.round(
+				(100 * (affectedModules.size + infectedModules.size)) /
+					this.modules.size
+			)}% (${affectedModules.size} affected + ${
+				infectedModules.size
+			} infected of ${
+				this.modules.size
+			}) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statReferencesChanged} references changed, ${statUnchanged} unchanged, ${statWithoutBuild} were not built)`
+		);
+	}
+
+	_computeAffectedModulesWithChunkGraph() {
+		const { moduleMemCaches } = this;
+		if (!moduleMemCaches) return;
+		const moduleMemCaches2 = (this.moduleMemCaches2 = new Map());
+		const { moduleGraph, chunkGraph } = this;
+		const key = "memCache2";
+		let statUnchanged = 0;
+		let statChanged = 0;
+		let statNew = 0;
+		/**
+		 * Compute references.
+		 * @param {Module} module module
+		 * @returns {References} references
+		 */
+		const computeReferences = (module) => {
+			const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+			/** @type {Map<Module, ModuleId> | undefined} */
+			let modules;
+			/** @type {(ChunkId | null)[] | undefined} */
+			let blocks;
+			const outgoing = moduleGraph.getOutgoingConnectionsByModule(module);
+			if (outgoing !== undefined) {
+				for (const m of outgoing.keys()) {
+					if (!m) continue;
+					if (modules === undefined) modules = new Map();
+					modules.set(m, /** @type {ModuleId} */ (chunkGraph.getModuleId(m)));
+				}
+			}
+			if (module.blocks.length > 0) {
+				blocks = [];
+				const queue = [...module.blocks];
+				for (const block of queue) {
+					const chunkGroup = chunkGraph.getBlockChunkGroup(block);
+					if (chunkGroup) {
+						for (const chunk of chunkGroup.chunks) {
+							blocks.push(chunk.id);
+						}
+					} else {
+						blocks.push(null);
+					}
+					// eslint-disable-next-line prefer-spread
+					queue.push.apply(queue, block.blocks);
+				}
+			}
+			return { id, modules, blocks };
+		};
+		/**
+		 * Compares references.
+		 * @param {Module} module module
+		 * @param {object} references references
+		 * @param {string | number} references.id id
+		 * @param {Map<Module, string | number | undefined>=} references.modules modules
+		 * @param {(string | number | null)[]=} references.blocks blocks
+		 * @returns {boolean} ok?
+		 */
+		const compareReferences = (module, { id, modules, blocks }) => {
+			if (id !== chunkGraph.getModuleId(module)) return false;
+			if (modules !== undefined) {
+				for (const [module, id] of modules) {
+					if (chunkGraph.getModuleId(module) !== id) return false;
+				}
+			}
+			if (blocks !== undefined) {
+				const queue = [...module.blocks];
+				let i = 0;
+				for (const block of queue) {
+					const chunkGroup = chunkGraph.getBlockChunkGroup(block);
+					if (chunkGroup) {
+						for (const chunk of chunkGroup.chunks) {
+							if (i >= blocks.length || blocks[i++] !== chunk.id) return false;
+						}
+					} else if (i >= blocks.length || blocks[i++] !== null) {
+						return false;
+					}
+					// eslint-disable-next-line prefer-spread
+					queue.push.apply(queue, block.blocks);
+				}
+				if (i !== blocks.length) return false;
+			}
+			return true;
+		};
+
+		for (const [module, memCache] of moduleMemCaches) {
+			/** @type {{ references: References, memCache: MemCache } | undefined} */
+			const cache = memCache.get(key);
+			if (cache === undefined) {
+				/** @type {WeakTupleMap<Module[], RuntimeRequirements | null> | undefined} */
+				const memCache2 = new WeakTupleMap();
+				memCache.set(key, {
+					references: computeReferences(module),
+					memCache: memCache2
+				});
+				moduleMemCaches2.set(module, memCache2);
+				statNew++;
+			} else if (!compareReferences(module, cache.references)) {
+				/** @type {WeakTupleMap<Module[], RuntimeRequirements | null> | undefined} */
+				const memCache = new WeakTupleMap();
+				cache.references = computeReferences(module);
+				cache.memCache = memCache;
+				moduleMemCaches2.set(module, memCache);
+				statChanged++;
+			} else {
+				moduleMemCaches2.set(module, cache.memCache);
+				statUnchanged++;
+			}
+		}
+
+		this.logger.log(
+			`${Math.round(
+				(100 * statChanged) / (statNew + statChanged + statUnchanged)
+			)}% modules flagged as affected by chunk graph (${statNew} new modules, ${statChanged} changed, ${statUnchanged} unchanged)`
+		);
+	}
+
+	/**
+	 * Processes the provided callback.
+	 * @param {Callback} callback callback
+	 */
+	finish(callback) {
+		this.factorizeQueue.clear();
+		if (this.profile) {
+			this.logger.time("finish module profiles");
+
+			const ParallelismFactorCalculator = require("./util/ParallelismFactorCalculator");
+
+			const p = new ParallelismFactorCalculator();
+			const moduleGraph = this.moduleGraph;
+			/** @type {Map<Module, ModuleProfile>} */
+			const modulesWithProfiles = new Map();
+			for (const module of this.modules) {
+				const profile = moduleGraph.getProfile(module);
+				if (!profile) continue;
+				modulesWithProfiles.set(module, profile);
+				p.range(
+					profile.buildingStartTime,
+					profile.buildingEndTime,
+					(f) => (profile.buildingParallelismFactor = f)
+				);
+				p.range(
+					profile.factoryStartTime,
+					profile.factoryEndTime,
+					(f) => (profile.factoryParallelismFactor = f)
+				);
+				p.range(
+					profile.integrationStartTime,
+					profile.integrationEndTime,
+					(f) => (profile.integrationParallelismFactor = f)
+				);
+				p.range(
+					profile.storingStartTime,
+					profile.storingEndTime,
+					(f) => (profile.storingParallelismFactor = f)
+				);
+				p.range(
+					profile.restoringStartTime,
+					profile.restoringEndTime,
+					(f) => (profile.restoringParallelismFactor = f)
+				);
+				if (profile.additionalFactoryTimes) {
+					for (const { start, end } of profile.additionalFactoryTimes) {
+						const influence = (end - start) / profile.additionalFactories;
+						p.range(
+							start,
+							end,
+							(f) =>
+								(profile.additionalFactoriesParallelismFactor += f * influence)
+						);
+					}
+				}
+			}
+			p.calculate();
+
+			const logger = this.getLogger("webpack.Compilation.ModuleProfile");
+			// Avoid coverage problems due indirect changes
+			/**
+			 * Processes the provided value.
+			 * @param {number} value value
+			 * @param {string} msg message
+			 */
+			/* istanbul ignore next */
+			const logByValue = (value, msg) => {
+				if (value > 1000) {
+					logger.error(msg);
+				} else if (value > 500) {
+					logger.warn(msg);
+				} else if (value > 200) {
+					logger.info(msg);
+				} else if (value > 30) {
+					logger.log(msg);
+				} else {
+					logger.debug(msg);
+				}
+			};
+			/**
+			 * Log normal summary.
+			 * @param {string} category a category
+			 * @param {(profile: ModuleProfile) => number} getDuration get duration callback
+			 * @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback
+			 */
+			const logNormalSummary = (category, getDuration, getParallelism) => {
+				let sum = 0;
+				let max = 0;
+				for (const [module, profile] of modulesWithProfiles) {
+					const p = getParallelism(profile);
+					const d = getDuration(profile);
+					if (d === 0 || p === 0) continue;
+					const t = d / p;
+					sum += t;
+					if (t <= 10) continue;
+					logByValue(
+						t,
+						` | ${Math.round(t)} ms${
+							p >= 1.1 ? ` (parallelism ${Math.round(p * 10) / 10})` : ""
+						} ${category} > ${module.readableIdentifier(this.requestShortener)}`
+					);
+					max = Math.max(max, t);
+				}
+				if (sum <= 10) return;
+				logByValue(
+					Math.max(sum / 10, max),
+					`${Math.round(sum)} ms ${category}`
+				);
+			};
+			/**
+			 * Log by loaders summary.
+			 * @param {string} category a category
+			 * @param {(profile: ModuleProfile) => number} getDuration get duration callback
+			 * @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback
+			 */
+			const logByLoadersSummary = (category, getDuration, getParallelism) => {
+				/** @type {Map<string, { module: Module, profile: ModuleProfile }[]>} */
+				const map = new Map();
+				for (const [module, profile] of modulesWithProfiles) {
+					const list = getOrInsert(
+						map,
+						`${module.type}!${module.identifier().replace(/(!|^)[^!]*$/, "")}`,
+						() => []
+					);
+					list.push({ module, profile });
+				}
+
+				let sum = 0;
+				let max = 0;
+				for (const [key, modules] of map) {
+					let innerSum = 0;
+					let innerMax = 0;
+					for (const { module, profile } of modules) {
+						const p = getParallelism(profile);
+						const d = getDuration(profile);
+						if (d === 0 || p === 0) continue;
+						const t = d / p;
+						innerSum += t;
+						if (t <= 10) continue;
+						logByValue(
+							t,
+							` |  | ${Math.round(t)} ms${
+								p >= 1.1 ? ` (parallelism ${Math.round(p * 10) / 10})` : ""
+							} ${category} > ${module.readableIdentifier(
+								this.requestShortener
+							)}`
+						);
+						innerMax = Math.max(innerMax, t);
+					}
+					sum += innerSum;
+					if (innerSum <= 10) continue;
+					const idx = key.indexOf("!");
+					const loaders = key.slice(idx + 1);
+					const moduleType = key.slice(0, idx);
+					const t = Math.max(innerSum / 10, innerMax);
+					logByValue(
+						t,
+						` | ${Math.round(innerSum)} ms ${category} > ${
+							loaders
+								? `${
+										modules.length
+									} x ${moduleType} with ${this.requestShortener.shorten(
+										loaders
+									)}`
+								: `${modules.length} x ${moduleType}`
+						}`
+					);
+					max = Math.max(max, t);
+				}
+				if (sum <= 10) return;
+				logByValue(
+					Math.max(sum / 10, max),
+					`${Math.round(sum)} ms ${category}`
+				);
+			};
+			logNormalSummary(
+				"resolve to new modules",
+				(p) => p.factory,
+				(p) => p.factoryParallelismFactor
+			);
+			logNormalSummary(
+				"resolve to existing modules",
+				(p) => p.additionalFactories,
+				(p) => p.additionalFactoriesParallelismFactor
+			);
+			logNormalSummary(
+				"integrate modules",
+				(p) => p.restoring,
+				(p) => p.restoringParallelismFactor
+			);
+			logByLoadersSummary(
+				"build modules",
+				(p) => p.building,
+				(p) => p.buildingParallelismFactor
+			);
+			logNormalSummary(
+				"store modules",
+				(p) => p.storing,
+				(p) => p.storingParallelismFactor
+			);
+			logNormalSummary(
+				"restore modules",
+				(p) => p.restoring,
+				(p) => p.restoringParallelismFactor
+			);
+			this.logger.timeEnd("finish module profiles");
+		}
+		this.logger.time("compute affected modules");
+		this._computeAffectedModules(this.modules);
+		this.logger.timeEnd("compute affected modules");
+		this.logger.time("finish modules");
+		const { modules, moduleMemCaches } = this;
+		this.hooks.finishModules.callAsync(modules, (err) => {
+			this.logger.timeEnd("finish modules");
+			if (err) return callback(/** @type {WebpackError} */ (err));
+
+			// extract warnings and errors from modules
+			this.moduleGraph.freeze("dependency errors");
+			// TODO keep a cacheToken (= {}) for each module in the graph
+			// create a new one per compilation and flag all updated files
+			// and parents with it
+			this.logger.time("report dependency errors and warnings");
+			for (const module of modules) {
+				// TODO only run for modules with changed cacheToken
+				// global WeakMap<CacheToken, WeakSet<Module>> to keep modules without errors/warnings
+				const memCache = moduleMemCaches && moduleMemCaches.get(module);
+				if (memCache && memCache.get("noWarningsOrErrors")) continue;
+				let hasProblems = this.reportDependencyErrorsAndWarnings(module, [
+					module
+				]);
+				const errors = /** @type {WebpackError[]} */ (module.getErrors());
+				if (errors !== undefined) {
+					for (const error of errors) {
+						if (!error.module) {
+							error.module = module;
+						}
+						this.errors.push(error);
+						hasProblems = true;
+					}
+				}
+				const warnings = /** @type {WebpackError[]} */ (module.getWarnings());
+				if (warnings !== undefined) {
+					for (const warning of warnings) {
+						if (!warning.module) {
+							warning.module = module;
+						}
+						this.warnings.push(warning);
+						hasProblems = true;
+					}
+				}
+				if (!hasProblems && memCache) memCache.set("noWarningsOrErrors", true);
+			}
+			this.moduleGraph.unfreeze();
+			this.logger.timeEnd("report dependency errors and warnings");
+
+			callback();
+		});
+	}
+
+	unseal() {
+		this.hooks.unseal.call();
+		this.chunks.clear();
+		this.chunkGroups.length = 0;
+		this.namedChunks.clear();
+		this.namedChunkGroups.clear();
+		this.entrypoints.clear();
+		this.additionalChunkAssets.length = 0;
+		this.assets = {};
+		this.assetsInfo.clear();
+		this.moduleGraph.removeAllModuleAttributes();
+		this.moduleGraph.unfreeze();
+		this.moduleMemCaches2 = undefined;
+	}
+
+	/**
+	 * Processes the provided callback.
+	 * @param {Callback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	seal(callback) {
+		/**
+		 * Processes the provided err.
+		 * @param {WebpackError=} err err
+		 * @returns {void}
+		 */
+		const finalCallback = (err) => {
+			this.factorizeQueue.clear();
+			this.buildQueue.clear();
+			this.rebuildQueue.clear();
+			this.processDependenciesQueue.clear();
+			this.addModuleQueue.clear();
+			return callback(err);
+		};
+
+		if (this._backCompat) {
+			for (const module of this.modules) {
+				ChunkGraph.setChunkGraphForModule(module, this.chunkGraph);
+			}
+		}
+
+		this.hooks.seal.call();
+
+		this.logger.time("optimize dependencies");
+		while (this.hooks.optimizeDependencies.call(this.modules)) {
+			/* empty */
+		}
+		this.hooks.afterOptimizeDependencies.call(this.modules);
+		this.logger.timeEnd("optimize dependencies");
+
+		this.logger.time("create chunks");
+		this.hooks.beforeChunks.call();
+		this.moduleGraph.freeze("seal");
+		/** @type {Map<Entrypoint, Module[]>} */
+		const chunkGraphInit = new Map();
+		for (const [name, { dependencies, includeDependencies, options }] of this
+			.entries) {
+			const chunk = this.addChunk(name);
+			if (options.filename) {
+				chunk.filenameTemplate = options.filename;
+			}
+			const entrypoint = new Entrypoint(options);
+			if (!options.dependOn && !options.runtime) {
+				entrypoint.setRuntimeChunk(chunk);
+			}
+			entrypoint.setEntrypointChunk(chunk);
+			this.namedChunkGroups.set(name, entrypoint);
+			this.entrypoints.set(name, entrypoint);
+			this.chunkGroups.push(entrypoint);
+
+			if (entrypoint.pushChunk(chunk)) {
+				chunk.addGroup(entrypoint);
+			}
+
+			/** @type {Set<Module>} */
+			const entryModules = new Set();
+			for (const dep of [...this.globalEntry.dependencies, ...dependencies]) {
+				entrypoint.addOrigin(
+					null,
+					{ name },
+					/** @type {Dependency & { request: string }} */
+					(dep).request
+				);
+
+				const module = this.moduleGraph.getModule(dep);
+				if (module) {
+					this.chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint);
+					entryModules.add(module);
+					const modulesList = chunkGraphInit.get(entrypoint);
+					if (modulesList === undefined) {
+						chunkGraphInit.set(entrypoint, [module]);
+					} else {
+						modulesList.push(module);
+					}
+				}
+			}
+
+			this.assignDepths(entryModules);
+
+			/**
+			 * Returns sorted deps.
+			 * @param {Dependency[]} deps deps
+			 * @returns {Module[]} sorted deps
+			 */
+			const mapAndSort = (deps) =>
+				/** @type {Module[]} */
+				(
+					deps.map((dep) => this.moduleGraph.getModule(dep)).filter(Boolean)
+				).sort(compareModulesByIdentifier);
+			const includedModules = [
+				...mapAndSort(this.globalEntry.includeDependencies),
+				...mapAndSort(includeDependencies)
+			];
+
+			let modulesList = chunkGraphInit.get(entrypoint);
+			if (modulesList === undefined) {
+				chunkGraphInit.set(entrypoint, (modulesList = []));
+			}
+			for (const module of includedModules) {
+				this.assignDepths([module]);
+				modulesList.push(module);
+			}
+		}
+		/** @type {Set<Chunk>} */
+		const runtimeChunks = new Set();
+		outer: for (const [
+			name,
+			{
+				options: { dependOn, runtime }
+			}
+		] of this.entries) {
+			if (dependOn && runtime) {
+				const err =
+					new WebpackError(`Entrypoint '${name}' has 'dependOn' and 'runtime' specified. This is not valid.
+Entrypoints that depend on other entrypoints do not have their own runtime.
+They will use the runtime(s) from referenced entrypoints instead.
+Remove the 'runtime' option from the entrypoint.`);
+				const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
+				err.chunk = entry.getEntrypointChunk();
+				this.errors.push(err);
+			}
+			if (dependOn) {
+				const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
+				const referencedChunks = entry
+					.getEntrypointChunk()
+					.getAllReferencedChunks();
+				for (const dep of dependOn) {
+					const dependency = this.entrypoints.get(dep);
+					if (!dependency) {
+						throw new Error(
+							`Entry ${name} depends on ${dep}, but this entry was not found`
+						);
+					}
+					if (referencedChunks.has(dependency.getEntrypointChunk())) {
+						const err = new WebpackError(
+							`Entrypoints '${name}' and '${dep}' use 'dependOn' to depend on each other in a circular way.`
+						);
+						const entryChunk = entry.getEntrypointChunk();
+						err.chunk = entryChunk;
+						this.errors.push(err);
+						entry.setRuntimeChunk(entryChunk);
+						continue outer;
+					}
+
+					entry.addDependOn(dependency);
+
+					if (dependency.addChild(entry)) {
+						entry.addParent(dependency);
+					}
+				}
+			} else if (runtime) {
+				const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
+				let chunk = this.namedChunks.get(runtime);
+				if (chunk) {
+					if (!runtimeChunks.has(chunk)) {
+						const err =
+							new WebpackError(`Entrypoint '${name}' has a 'runtime' option which points to another entrypoint named '${runtime}'.
+It's not valid to use other entrypoints as runtime chunk.
+Did you mean to use 'dependOn: ${JSON.stringify(
+								runtime
+							)}' instead to allow using entrypoint '${name}' within the runtime of entrypoint '${runtime}'? For this '${runtime}' must always be loaded when '${name}' is used.
+Or do you want to use the entrypoints '${name}' and '${runtime}' independently on the same page with a shared runtime? In this case give them both the same value for the 'runtime' option. It must be a name not already used by an entrypoint.`);
+						const entryChunk =
+							/** @type {Chunk} */
+							(entry.getEntrypointChunk());
+						err.chunk = entryChunk;
+						this.errors.push(err);
+						entry.setRuntimeChunk(entryChunk);
+						continue;
+					}
+				} else {
+					chunk = this.addChunk(runtime);
+					chunk.preventIntegration = true;
+					runtimeChunks.add(chunk);
+				}
+				entry.unshiftChunk(chunk);
+				chunk.addGroup(entry);
+				entry.setRuntimeChunk(chunk);
+			}
+		}
+
+		buildChunkGraph(this, chunkGraphInit);
+		this.hooks.afterChunks.call(this.chunks);
+		this.logger.timeEnd("create chunks");
+
+		this.logger.time("optimize");
+		this.hooks.optimize.call();
+
+		while (this.hooks.optimizeModules.call(this.modules)) {
+			/* empty */
+		}
+		this.hooks.afterOptimizeModules.call(this.modules);
+
+		while (this.hooks.optimizeChunks.call(this.chunks, this.chunkGroups)) {
+			/* empty */
+		}
+		this.hooks.afterOptimizeChunks.call(this.chunks, this.chunkGroups);
+
+		this.hooks.optimizeTree.callAsync(this.chunks, this.modules, (err) => {
+			if (err) {
+				return finalCallback(
+					makeWebpackError(err, "Compilation.hooks.optimizeTree")
+				);
+			}
+
+			this.hooks.afterOptimizeTree.call(this.chunks, this.modules);
+
+			this.hooks.optimizeChunkModules.callAsync(
+				this.chunks,
+				this.modules,
+				(err) => {
+					if (err) {
+						return finalCallback(
+							makeWebpackError(err, "Compilation.hooks.optimizeChunkModules")
+						);
+					}
+
+					this.hooks.afterOptimizeChunkModules.call(this.chunks, this.modules);
+
+					const shouldRecord = this.hooks.shouldRecord.call() !== false;
+
+					this.hooks.reviveModules.call(
+						this.modules,
+						/** @type {Records} */
+						(this.records)
+					);
+					this.hooks.beforeModuleIds.call(this.modules);
+					this.hooks.moduleIds.call(this.modules);
+					this.hooks.optimizeModuleIds.call(this.modules);
+					this.hooks.afterOptimizeModuleIds.call(this.modules);
+
+					this.hooks.reviveChunks.call(
+						this.chunks,
+						/** @type {Records} */
+						(this.records)
+					);
+					this.hooks.beforeChunkIds.call(this.chunks);
+					this.hooks.chunkIds.call(this.chunks);
+					this.hooks.optimizeChunkIds.call(this.chunks);
+					this.hooks.afterOptimizeChunkIds.call(this.chunks);
+
+					this.assignRuntimeIds();
+
+					this.logger.time("compute affected modules with chunk graph");
+					this._computeAffectedModulesWithChunkGraph();
+					this.logger.timeEnd("compute affected modules with chunk graph");
+
+					this.sortItemsWithChunkIds();
+
+					if (shouldRecord) {
+						this.hooks.recordModules.call(
+							this.modules,
+							/** @type {Records} */
+							(this.records)
+						);
+						this.hooks.recordChunks.call(
+							this.chunks,
+							/** @type {Records} */
+							(this.records)
+						);
+					}
+
+					this.hooks.optimizeCodeGeneration.call(this.modules);
+					this.logger.timeEnd("optimize");
+
+					this.logger.time("module hashing");
+					this.hooks.beforeModuleHash.call();
+					this.createModuleHashes();
+					this.hooks.afterModuleHash.call();
+					this.logger.timeEnd("module hashing");
+
+					this.logger.time("code generation");
+					this.hooks.beforeCodeGeneration.call();
+					this.codeGeneration((err) => {
+						if (err) {
+							return finalCallback(err);
+						}
+						this.hooks.afterCodeGeneration.call();
+						this.logger.timeEnd("code generation");
+
+						this.logger.time("runtime requirements");
+						this.hooks.beforeRuntimeRequirements.call();
+						this.processRuntimeRequirements();
+						this.hooks.afterRuntimeRequirements.call();
+						this.logger.timeEnd("runtime requirements");
+
+						this.logger.time("hashing");
+						this.hooks.beforeHash.call();
+						const codeGenerationJobs = this.createHash();
+						this.hooks.afterHash.call();
+						this.logger.timeEnd("hashing");
+
+						this._runCodeGenerationJobs(codeGenerationJobs, (err) => {
+							if (err) {
+								return finalCallback(err);
+							}
+
+							if (shouldRecord) {
+								this.logger.time("record hash");
+								this.hooks.recordHash.call(
+									/** @type {Records} */
+									(this.records)
+								);
+								this.logger.timeEnd("record hash");
+							}
+
+							this.logger.time("module assets");
+							this.clearAssets();
+
+							this.hooks.beforeModuleAssets.call();
+							this.createModuleAssets();
+							this.logger.timeEnd("module assets");
+
+							const cont = () => {
+								this.logger.time("process assets");
+								this.hooks.processAssets.callAsync(this.assets, (err) => {
+									if (err) {
+										return finalCallback(
+											makeWebpackError(err, "Compilation.hooks.processAssets")
+										);
+									}
+									this.hooks.afterProcessAssets.call(this.assets);
+									this.logger.timeEnd("process assets");
+									this.assets =
+										/** @type {CompilationAssets} */
+										(
+											this._backCompat
+												? soonFrozenObjectDeprecation(
+														this.assets,
+														"Compilation.assets",
+														"DEP_WEBPACK_COMPILATION_ASSETS",
+														`BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
+	Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
+	Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.`
+													)
+												: Object.freeze(this.assets)
+										);
+
+									this.summarizeDependencies();
+									if (shouldRecord) {
+										this.hooks.record.call(
+											this,
+											/** @type {Records} */
+											(this.records)
+										);
+									}
+
+									if (this.hooks.needAdditionalSeal.call()) {
+										this.unseal();
+										return this.seal(callback);
+									}
+									return this.hooks.afterSeal.callAsync((err) => {
+										if (err) {
+											return finalCallback(
+												makeWebpackError(err, "Compilation.hooks.afterSeal")
+											);
+										}
+										this.fileSystemInfo.logStatistics();
+										finalCallback();
+									});
+								});
+							};
+
+							this.logger.time("create chunk assets");
+							if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
+								this.hooks.beforeChunkAssets.call();
+								this.createChunkAssets((err) => {
+									this.logger.timeEnd("create chunk assets");
+									if (err) {
+										return finalCallback(err);
+									}
+									cont();
+								});
+							} else {
+								this.logger.timeEnd("create chunk assets");
+								cont();
+							}
+						});
+					});
+				}
+			);
+		});
+	}
+
+	/**
+	 * Report dependency errors and warnings.
+	 * @param {Module} module module to report from
+	 * @param {DependenciesBlock[]} blocks blocks to report from
+	 * @returns {boolean} true, when it has warnings or errors
+	 */
+	reportDependencyErrorsAndWarnings(module, blocks) {
+		let hasProblems = false;
+		for (const block of blocks) {
+			const dependencies = block.dependencies;
+
+			for (const d of dependencies) {
+				const warnings = d.getWarnings(this.moduleGraph);
+				if (warnings) {
+					for (const w of warnings) {
+						const warning = new ModuleDependencyWarning(module, w, d.loc);
+						this.warnings.push(warning);
+						hasProblems = true;
+					}
+				}
+				const errors = d.getErrors(this.moduleGraph);
+				if (errors) {
+					for (const e of errors) {
+						const error = new ModuleDependencyError(module, e, d.loc);
+						this.errors.push(error);
+						hasProblems = true;
+					}
+				}
+			}
+
+			if (this.reportDependencyErrorsAndWarnings(module, block.blocks)) {
+				hasProblems = true;
+			}
+		}
+		return hasProblems;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {Callback} callback callback
+	 */
+	codeGeneration(callback) {
+		const { chunkGraph } = this;
+		this.codeGenerationResults = new CodeGenerationResults(
+			this.outputOptions.hashFunction
+		);
+		/** @type {CodeGenerationJobs} */
+		const jobs = [];
+		for (const module of this.modules) {
+			const runtimes = chunkGraph.getModuleRuntimes(module);
+			if (runtimes.size === 1) {
+				for (const runtime of runtimes) {
+					const hash = chunkGraph.getModuleHash(module, runtime);
+					jobs.push({ module, hash, runtime, runtimes: [runtime] });
+				}
+			} else if (runtimes.size > 1) {
+				/** @type {Map<string, { runtimes: RuntimeSpec[] }>} */
+				const map = new Map();
+				for (const runtime of runtimes) {
+					const hash = chunkGraph.getModuleHash(module, runtime);
+					const job = map.get(hash);
+					if (job === undefined) {
+						const newJob = { module, hash, runtime, runtimes: [runtime] };
+						jobs.push(newJob);
+						map.set(hash, newJob);
+					} else {
+						job.runtimes.push(runtime);
+					}
+				}
+			}
+		}
+
+		this._runCodeGenerationJobs(jobs, callback);
+	}
+
+	/**
+	 * Run code generation jobs.
+	 * @private
+	 * @param {CodeGenerationJobs} jobs code generation jobs
+	 * @param {Callback} callback callback
+	 * @returns {void}
+	 */
+	_runCodeGenerationJobs(jobs, callback) {
+		if (jobs.length === 0) {
+			return callback();
+		}
+		let statModulesFromCache = 0;
+		let statModulesGenerated = 0;
+		const { chunkGraph, moduleGraph, dependencyTemplates, runtimeTemplate } =
+			this;
+		const results =
+			/** @type {CodeGenerationResults} */
+			(this.codeGenerationResults);
+		/** @type {WebpackError[]} */
+		const errors = [];
+		/** @type {NotCodeGeneratedModules | undefined} */
+		let notCodeGeneratedModules;
+		const runIteration = () => {
+			/** @type {CodeGenerationJobs} */
+			let delayedJobs = [];
+			/** @type {Set<Module>} */
+			let delayedModules = new Set();
+			asyncLib.eachLimit(
+				jobs,
+				this.options.parallelism,
+				(job, callback) => {
+					const { module } = job;
+					const { codeGenerationDependencies } = module;
+					if (
+						codeGenerationDependencies !== undefined &&
+						(notCodeGeneratedModules === undefined ||
+							codeGenerationDependencies.some((dep) => {
+								const referencedModule = /** @type {Module} */ (
+									moduleGraph.getModule(dep)
+								);
+								return /** @type {NotCodeGeneratedModules} */ (
+									notCodeGeneratedModules
+								).has(referencedModule);
+							}))
+					) {
+						delayedJobs.push(job);
+						delayedModules.add(module);
+						return callback();
+					}
+					const { hash, runtime, runtimes } = job;
+					this._codeGenerationModule(
+						module,
+						runtime,
+						runtimes,
+						hash,
+						dependencyTemplates,
+						chunkGraph,
+						moduleGraph,
+						runtimeTemplate,
+						errors,
+						results,
+						(err, codeGenerated) => {
+							if (codeGenerated) statModulesGenerated++;
+							else statModulesFromCache++;
+							callback(err);
+						}
+					);
+				},
+				(err) => {
+					if (err) return callback(/** @type {WebpackError} */ (err));
+					if (delayedJobs.length > 0) {
+						if (delayedJobs.length === jobs.length) {
+							return callback(
+								/** @type {WebpackError} */ (
+									new Error(
+										`Unable to make progress during code generation because of circular code generation dependency: ${Array.from(
+											delayedModules,
+											(m) => m.identifier()
+										).join(", ")}`
+									)
+								)
+							);
+						}
+						jobs = delayedJobs;
+						delayedJobs = [];
+						notCodeGeneratedModules = delayedModules;
+						delayedModules = new Set();
+						return runIteration();
+					}
+					if (errors.length > 0) {
+						errors.sort(
+							compareSelect((err) => err.module, compareModulesByIdentifier)
+						);
+						for (const error of errors) {
+							this.errors.push(error);
+						}
+					}
+					this.logger.log(
+						`${Math.round(
+							(100 * statModulesGenerated) /
+								(statModulesGenerated + statModulesFromCache)
+						)}% code generated (${statModulesGenerated} generated, ${statModulesFromCache} from cache)`
+					);
+					callback();
+				}
+			);
+		};
+		runIteration();
+	}
+
+	/**
+	 * Code generation module.
+	 * @param {Module} module module
+	 * @param {RuntimeSpec} runtime runtime
+	 * @param {RuntimeSpec[]} runtimes runtimes
+	 * @param {string} hash hash
+	 * @param {DependencyTemplates} dependencyTemplates dependencyTemplates
+	 * @param {ChunkGraph} chunkGraph chunkGraph
+	 * @param {ModuleGraph} moduleGraph moduleGraph
+	 * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate
+	 * @param {WebpackError[]} errors errors
+	 * @param {CodeGenerationResults} results results
+	 * @param {(err?: WebpackError | null, result?: boolean) => void} callback callback
+	 */
+	_codeGenerationModule(
+		module,
+		runtime,
+		runtimes,
+		hash,
+		dependencyTemplates,
+		chunkGraph,
+		moduleGraph,
+		runtimeTemplate,
+		errors,
+		results,
+		callback
+	) {
+		let codeGenerated = false;
+		const cache = new MultiItemCache(
+			runtimes.map((runtime) =>
+				this._codeGenerationCache.getItemCache(
+					`${module.identifier()}|${getRuntimeKey(runtime)}`,
+					`${hash}|${dependencyTemplates.getHash()}`
+				)
+			)
+		);
+		cache.get((err, cachedResult) => {
+			if (err) return callback(/** @type {WebpackError} */ (err));
+			/** @type {CodeGenerationResult} */
+			let result;
+			if (!cachedResult) {
+				try {
+					codeGenerated = true;
+					this.codeGeneratedModules.add(module);
+					result = module.codeGeneration({
+						chunkGraph,
+						moduleGraph,
+						dependencyTemplates,
+						runtimeTemplate,
+						runtime,
+						runtimes,
+						codeGenerationResults: results,
+						compilation: this
+					});
+				} catch (err) {
+					errors.push(
+						new CodeGenerationError(module, /** @type {Error} */ (err))
+					);
+					result = cachedResult = {
+						sources: new Map(),
+						runtimeRequirements: null
+					};
+				}
+			} else {
+				result = cachedResult;
+			}
+			for (const runtime of runtimes) {
+				results.add(module, runtime, result);
+			}
+			if (!cachedResult) {
+				cache.store(result, (err) =>
+					callback(/** @type {WebpackError} */ (err), codeGenerated)
+				);
+			} else {
+				callback(null, codeGenerated);
+			}
+		});
+	}
+
+	_getChunkGraphEntries() {
+		/** @type {Set<Chunk>} */
+		const treeEntries = new Set();
+		for (const ep of this.entrypoints.values()) {
+			const chunk = ep.getRuntimeChunk();
+			if (chunk) treeEntries.add(chunk);
+		}
+		for (const ep of this.asyncEntrypoints) {
+			const chunk = ep.getRuntimeChunk();
+			if (chunk) treeEntries.add(chunk);
+		}
+		return treeEntries;
+	}
+
+	/**
+	 * Process runtime requirements.
+	 * @param {object} options options
+	 * @param {ChunkGraph=} options.chunkGraph the chunk graph
+	 * @param {Iterable<Module>=} options.modules modules
+	 * @param {Iterable<Chunk>=} options.chunks chunks
+	 * @param {CodeGenerationResults=} options.codeGenerationResults codeGenerationResults
+	 * @param {Iterable<Chunk>=} options.chunkGraphEntries chunkGraphEntries
+	 * @returns {void}
+	 */
+	processRuntimeRequirements({
+		chunkGraph = this.chunkGraph,
+		modules = this.modules,
+		chunks = this.chunks,
+		codeGenerationResults = /** @type {CodeGenerationResults} */ (
+			this.codeGenerationResults
+		),
+		chunkGraphEntries = this._getChunkGraphEntries()
+	} = {}) {
+		const context = { chunkGraph, codeGenerationResults };
+		const { moduleMemCaches2 } = this;
+		this.logger.time("runtime requirements.modules");
+		const additionalModuleRuntimeRequirements =
+			this.hooks.additionalModuleRuntimeRequirements;
+		const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
+		for (const module of modules) {
+			if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
+				const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
+				for (const runtime of chunkGraph.getModuleRuntimes(module)) {
+					if (memCache) {
+						const cached = memCache.get(
+							`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`
+						);
+						if (cached !== undefined) {
+							if (cached !== null) {
+								chunkGraph.addModuleRuntimeRequirements(
+									module,
+									runtime,
+									/** @type {RuntimeRequirements} */
+									(cached),
+									false
+								);
+							}
+							continue;
+						}
+					}
+					/** @type {RuntimeRequirements} */
+					let set;
+					const runtimeRequirements =
+						codeGenerationResults.getRuntimeRequirements(module, runtime);
+					if (runtimeRequirements && runtimeRequirements.size > 0) {
+						set = new Set(runtimeRequirements);
+					} else if (additionalModuleRuntimeRequirements.isUsed()) {
+						set = new Set();
+					} else {
+						if (memCache) {
+							memCache.set(
+								`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
+								null
+							);
+						}
+						continue;
+					}
+					additionalModuleRuntimeRequirements.call(module, set, context);
+
+					for (const r of set) {
+						const hook = runtimeRequirementInModule.get(r);
+						if (hook !== undefined) hook.call(module, set, context);
+					}
+					if (set.size === 0) {
+						if (memCache) {
+							memCache.set(
+								`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
+								null
+							);
+						}
+					} else if (memCache) {
+						memCache.set(
+							`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
+							set
+						);
+						chunkGraph.addModuleRuntimeRequirements(
+							module,
+							runtime,
+							set,
+							false
+						);
+					} else {
+						chunkGraph.addModuleRuntimeRequirements(module, runtime, set);
+					}
+				}
+			}
+		}
+		this.logger.timeEnd("runtime requirements.modules");
+
+		this.logger.time("runtime requirements.chunks");
+		for (const chunk of chunks) {
+			/** @type {RuntimeRequirements} */
+			const set = new Set();
+			for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+				const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
+					module,
+					chunk.runtime
+				);
+				for (const r of runtimeRequirements) set.add(r);
+			}
+			this.hooks.additionalChunkRuntimeRequirements.call(chunk, set, context);
+
+			for (const r of set) {
+				this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set, context);
+			}
+
+			chunkGraph.addChunkRuntimeRequirements(chunk, set);
+		}
+		this.logger.timeEnd("runtime requirements.chunks");
+
+		this.logger.time("runtime requirements.entries");
+		for (const treeEntry of chunkGraphEntries) {
+			/** @type {RuntimeRequirements} */
+			const set = new Set();
+			for (const chunk of treeEntry.getAllReferencedChunks()) {
+				const runtimeRequirements =
+					chunkGraph.getChunkRuntimeRequirements(chunk);
+				for (const r of runtimeRequirements) set.add(r);
+			}
+
+			this.hooks.additionalTreeRuntimeRequirements.call(
+				treeEntry,
+				set,
+				context
+			);
+
+			for (const r of set) {
+				this.hooks.runtimeRequirementInTree
+					.for(r)
+					.call(treeEntry, set, context);
+			}
+
+			chunkGraph.addTreeRuntimeRequirements(treeEntry, set);
+		}
+		this.logger.timeEnd("runtime requirements.entries");
+	}
+
+	// TODO webpack 6 make chunkGraph argument non-optional
+	/**
+	 * Adds runtime module.
+	 * @param {Chunk} chunk target chunk
+	 * @param {RuntimeModule} module runtime module
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {void}
+	 */
+	addRuntimeModule(chunk, module, chunkGraph = this.chunkGraph) {
+		// Deprecated ModuleGraph association
+		if (this._backCompat) {
+			ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
+		}
+
+		// add it to the list
+		this.modules.add(module);
+		this._modules.set(module.identifier(), module);
+
+		// connect to the chunk graph
+		chunkGraph.connectChunkAndModule(chunk, module);
+		chunkGraph.connectChunkAndRuntimeModule(chunk, module);
+		if (module.fullHash) {
+			chunkGraph.addFullHashModuleToChunk(chunk, module);
+		} else if (module.dependentHash) {
+			chunkGraph.addDependentHashModuleToChunk(chunk, module);
+		}
+
+		// attach runtime module
+		module.attach(this, chunk, chunkGraph);
+
+		// Setup internals
+		const exportsInfo = this.moduleGraph.getExportsInfo(module);
+		exportsInfo.setHasProvideInfo();
+		if (typeof chunk.runtime === "string") {
+			exportsInfo.setUsedForSideEffectsOnly(chunk.runtime);
+		} else if (chunk.runtime === undefined) {
+			exportsInfo.setUsedForSideEffectsOnly(undefined);
+		} else {
+			for (const runtime of chunk.runtime) {
+				exportsInfo.setUsedForSideEffectsOnly(runtime);
+			}
+		}
+		chunkGraph.addModuleRuntimeRequirements(
+			module,
+			chunk.runtime,
+			new Set([RuntimeGlobals.requireScope])
+		);
+
+		// runtime modules don't need ids
+		chunkGraph.setModuleId(module, "");
+
+		// Call hook
+		this.hooks.runtimeModule.call(module, chunk);
+	}
+
+	/**
+	 * If `module` is passed, `loc` and `request` must also be passed.
+	 * @param {string | ChunkGroupOptions} groupOptions options for the chunk group
+	 * @param {Module=} module the module the references the chunk group
+	 * @param {DependencyLocation=} loc the location from with the chunk group is referenced (inside of module)
+	 * @param {string=} request the request from which the chunk group is referenced
+	 * @returns {ChunkGroup} the new or existing chunk group
+	 */
+	addChunkInGroup(groupOptions, module, loc, request) {
+		if (typeof groupOptions === "string") {
+			groupOptions = { name: groupOptions };
+		}
+		const name = groupOptions.name;
+		if (name) {
+			const chunkGroup = this.namedChunkGroups.get(name);
+			if (chunkGroup !== undefined) {
+				if (module) {
+					chunkGroup.addOrigin(
+						module,
+						/** @type {DependencyLocation} */
+						(loc),
+						/** @type {string} */
+						(request)
+					);
+				}
+				return chunkGroup;
+			}
+		}
+		const chunkGroup = new ChunkGroup(groupOptions);
+		if (module) {
+			chunkGroup.addOrigin(
+				module,
+				/** @type {DependencyLocation} */
+				(loc),
+				/** @type {string} */
+				(request)
+			);
+		}
+		const chunk = this.addChunk(name);
+
+		if (chunkGroup.pushChunk(chunk)) {
+			chunk.addGroup(chunkGroup);
+		}
+
+		this.chunkGroups.push(chunkGroup);
+		if (name) {
+			this.namedChunkGroups.set(name, chunkGroup);
+		}
+		return chunkGroup;
+	}
+
+	/**
+	 * Adds the provided async entrypoint to this chunk group.
+	 * @param {EntryOptions} options options for the entrypoint
+	 * @param {Module} module the module the references the chunk group
+	 * @param {DependencyLocation} loc the location from with the chunk group is referenced (inside of module)
+	 * @param {string} request the request from which the chunk group is referenced
+	 * @returns {Entrypoint} the new or existing entrypoint
+	 */
+	addAsyncEntrypoint(options, module, loc, request) {
+		const name = options.name;
+		if (name) {
+			const entrypoint = this.namedChunkGroups.get(name);
+			if (entrypoint instanceof Entrypoint) {
+				if (module) {
+					entrypoint.addOrigin(module, loc, request);
+				}
+				return entrypoint;
+			} else if (entrypoint) {
+				throw new Error(
+					`Cannot add an async entrypoint with the name '${name}', because there is already an chunk group with this name`
+				);
+			}
+		}
+		const chunk = this.addChunk(name);
+		if (options.filename) {
+			chunk.filenameTemplate = options.filename;
+		}
+		const entrypoint = new Entrypoint(options, false);
+		entrypoint.setRuntimeChunk(chunk);
+		entrypoint.setEntrypointChunk(chunk);
+		if (name) {
+			this.namedChunkGroups.set(name, entrypoint);
+		}
+		this.chunkGroups.push(entrypoint);
+		this.asyncEntrypoints.push(entrypoint);
+		if (entrypoint.pushChunk(chunk)) {
+			chunk.addGroup(entrypoint);
+		}
+		if (module) {
+			entrypoint.addOrigin(module, loc, request);
+		}
+		return entrypoint;
+	}
+
+	/**
+	 * This method first looks to see if a name is provided for a new chunk,
+	 * and first looks to see if any named chunks already exist and reuse that chunk instead.
+	 * @param {ChunkName=} name optional chunk name to be provided
+	 * @returns {Chunk} create a chunk (invoked during seal event)
+	 */
+	addChunk(name) {
+		if (name) {
+			const chunk = this.namedChunks.get(name);
+			if (chunk !== undefined) {
+				return chunk;
+			}
+		}
+		const chunk = new Chunk(name, this._backCompat);
+		this.chunks.add(chunk);
+		if (this._backCompat) {
+			ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph);
+		}
+		if (name) {
+			this.namedChunks.set(name, chunk);
+		}
+		return chunk;
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @deprecated
+	 * @param {Module} module module to assign depth
+	 * @returns {void}
+	 */
+	assignDepth(module) {
+		const moduleGraph = this.moduleGraph;
+
+		const queue = new Set([module]);
+		/** @type {number} */
+		let depth;
+
+		moduleGraph.setDepth(module, 0);
+
+		/**
+		 * Processes the provided module.
+		 * @param {Module} module module for processing
+		 * @returns {void}
+		 */
+		const processModule = (module) => {
+			if (!moduleGraph.setDepthIfLower(module, depth)) return;
+			queue.add(module);
+		};
+
+		for (module of queue) {
+			queue.delete(module);
+			depth = /** @type {number} */ (moduleGraph.getDepth(module)) + 1;
+
+			for (const connection of moduleGraph.getOutgoingConnections(module)) {
+				const refModule = connection.module;
+				if (refModule) {
+					processModule(refModule);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Assigns depth values to the provided modules.
+	 * @param {Module[] | Set<Module>} modules modules to assign depth
+	 * @returns {void}
+	 */
+	assignDepths(modules) {
+		const moduleGraph = this.moduleGraph;
+
+		/** @type {Set<Module>} */
+		const queue = new Set(modules);
+		// Track these in local variables so that queue only has one data type
+		let nextDepthAt = queue.size;
+		let depth = 0;
+
+		let i = 0;
+		for (const module of queue) {
+			moduleGraph.setDepth(module, depth);
+			// Some of these results come from cache, which speeds this up
+			const connections = moduleGraph.getOutgoingConnectionsByModule(module);
+			// connections will be undefined if there are no outgoing connections
+			if (connections) {
+				for (const refModule of connections.keys()) {
+					if (refModule) queue.add(refModule);
+				}
+			}
+			i++;
+			// Since this is a breadth-first search, all modules added to the queue
+			// while at depth N will be depth N+1
+			if (i >= nextDepthAt) {
+				depth++;
+				nextDepthAt = queue.size;
+			}
+		}
+	}
+
+	/**
+	 * Gets dependency referenced exports.
+	 * @param {Dependency} dependency the dependency
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getDependencyReferencedExports(dependency, runtime) {
+		const referencedExports = dependency.getReferencedExports(
+			this.moduleGraph,
+			runtime
+		);
+		return this.hooks.dependencyReferencedExports.call(
+			referencedExports,
+			dependency,
+			runtime
+		);
+	}
+
+	/**
+	 * Removes reasons of dependency block.
+	 * @param {Module} module module relationship for removal
+	 * @param {DependenciesBlockLike} block dependencies block
+	 * @returns {void}
+	 */
+	removeReasonsOfDependencyBlock(module, block) {
+		if (block.blocks) {
+			for (const b of block.blocks) {
+				this.removeReasonsOfDependencyBlock(module, b);
+			}
+		}
+
+		if (block.dependencies) {
+			for (const dep of block.dependencies) {
+				const originalModule = this.moduleGraph.getModule(dep);
+				if (originalModule) {
+					this.moduleGraph.removeConnection(dep);
+
+					if (this.chunkGraph) {
+						for (const chunk of this.chunkGraph.getModuleChunks(
+							originalModule
+						)) {
+							this.patchChunksAfterReasonRemoval(originalModule, chunk);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Patch chunks after reason removal.
+	 * @param {Module} module module to patch tie
+	 * @param {Chunk} chunk chunk to patch tie
+	 * @returns {void}
+	 */
+	patchChunksAfterReasonRemoval(module, chunk) {
+		if (!module.hasReasons(this.moduleGraph, chunk.runtime)) {
+			this.removeReasonsOfDependencyBlock(module, module);
+		}
+		if (
+			!module.hasReasonForChunk(chunk, this.moduleGraph, this.chunkGraph) &&
+			this.chunkGraph.isModuleInChunk(module, chunk)
+		) {
+			this.chunkGraph.disconnectChunkAndModule(chunk, module);
+			this.removeChunkFromDependencies(module, chunk);
+		}
+	}
+
+	/**
+	 * Removes chunk from dependencies.
+	 * @param {DependenciesBlock} block block tie for Chunk
+	 * @param {Chunk} chunk chunk to remove from dep
+	 * @returns {void}
+	 */
+	removeChunkFromDependencies(block, chunk) {
+		/**
+		 * Iterator dependency.
+		 * @param {Dependency} d dependency to (maybe) patch up
+		 */
+		const iteratorDependency = (d) => {
+			const depModule = this.moduleGraph.getModule(d);
+			if (!depModule) {
+				return;
+			}
+			this.patchChunksAfterReasonRemoval(depModule, chunk);
+		};
+
+		const blocks = block.blocks;
+		for (const asyncBlock of blocks) {
+			const chunkGroup =
+				/** @type {ChunkGroup} */
+				(this.chunkGraph.getBlockChunkGroup(asyncBlock));
+			// Grab all chunks from the first Block's AsyncDepBlock
+			const chunks = chunkGroup.chunks;
+			// For each chunk in chunkGroup
+			for (const iteratedChunk of chunks) {
+				chunkGroup.removeChunk(iteratedChunk);
+				// Recurse
+				this.removeChunkFromDependencies(block, iteratedChunk);
+			}
+		}
+
+		if (block.dependencies) {
+			for (const dep of block.dependencies) iteratorDependency(dep);
+		}
+	}
+
+	assignRuntimeIds() {
+		const { chunkGraph } = this;
+		/**
+		 * Process entrypoint.
+		 * @param {Entrypoint} ep an entrypoint
+		 */
+		const processEntrypoint = (ep) => {
+			const runtime = /** @type {string} */ (ep.options.runtime || ep.name);
+			const chunk = /** @type {Chunk} */ (ep.getRuntimeChunk());
+			chunkGraph.setRuntimeId(runtime, /** @type {ChunkId} */ (chunk.id));
+		};
+		for (const ep of this.entrypoints.values()) {
+			processEntrypoint(ep);
+		}
+		for (const ep of this.asyncEntrypoints) {
+			processEntrypoint(ep);
+		}
+	}
+
+	sortItemsWithChunkIds() {
+		for (const chunkGroup of this.chunkGroups) {
+			chunkGroup.sortItems();
+		}
+
+		this.errors.sort(compareErrors);
+		this.warnings.sort(compareErrors);
+		this.children.sort(byNameOrHash);
+	}
+
+	summarizeDependencies() {
+		for (const child of this.children) {
+			this.fileDependencies.addAll(child.fileDependencies);
+			this.contextDependencies.addAll(child.contextDependencies);
+			this.missingDependencies.addAll(child.missingDependencies);
+			this.buildDependencies.addAll(child.buildDependencies);
+		}
+
+		for (const module of this.modules) {
+			module.addCacheDependencies(
+				this.fileDependencies,
+				this.contextDependencies,
+				this.missingDependencies,
+				this.buildDependencies
+			);
+		}
+	}
+
+	createModuleHashes() {
+		let statModulesHashed = 0;
+		let statModulesFromCache = 0;
+		const { chunkGraph, runtimeTemplate, moduleMemCaches2 } = this;
+		const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
+		/** @type {WebpackError[]} */
+		const errors = [];
+		for (const module of this.modules) {
+			const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
+			for (const runtime of chunkGraph.getModuleRuntimes(module)) {
+				if (memCache) {
+					const digest =
+						/** @type {string} */
+						(memCache.get(`moduleHash-${getRuntimeKey(runtime)}`));
+					if (digest !== undefined) {
+						chunkGraph.setModuleHashes(
+							module,
+							runtime,
+							digest,
+							digest.slice(0, hashDigestLength)
+						);
+						statModulesFromCache++;
+						continue;
+					}
+				}
+				statModulesHashed++;
+				const digest = this._createModuleHash(
+					module,
+					chunkGraph,
+					runtime,
+					hashFunction,
+					runtimeTemplate,
+					hashDigest,
+					hashDigestLength,
+					errors
+				);
+				if (memCache) {
+					memCache.set(`moduleHash-${getRuntimeKey(runtime)}`, digest);
+				}
+			}
+		}
+		if (errors.length > 0) {
+			errors.sort(
+				compareSelect((err) => err.module, compareModulesByIdentifier)
+			);
+			for (const error of errors) {
+				this.errors.push(error);
+			}
+		}
+		this.logger.log(
+			`${statModulesHashed} modules hashed, ${statModulesFromCache} from cache (${
+				Math.round(
+					(100 * (statModulesHashed + statModulesFromCache)) / this.modules.size
+				) / 100
+			} variants per module in average)`
+		);
+	}
+
+	/**
+	 * Create module hash.
+	 * @private
+	 * @param {Module} module module
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {RuntimeSpec} runtime runtime
+	 * @param {HashFunction} hashFunction hash function
+	 * @param {RuntimeTemplate} runtimeTemplate runtime template
+	 * @param {HashDigest} hashDigest hash digest
+	 * @param {HashDigestLength} hashDigestLength hash digest length
+	 * @param {WebpackError[]} errors errors
+	 * @returns {string} module hash digest
+	 */
+	_createModuleHash(
+		module,
+		chunkGraph,
+		runtime,
+		hashFunction,
+		runtimeTemplate,
+		hashDigest,
+		hashDigestLength,
+		errors
+	) {
+		/** @type {string} */
+		let moduleHashDigest;
+		try {
+			const moduleHash = createHash(hashFunction);
+			module.updateHash(moduleHash, {
+				chunkGraph,
+				runtime,
+				runtimeTemplate
+			});
+			moduleHashDigest = moduleHash.digest(hashDigest);
+		} catch (err) {
+			errors.push(new ModuleHashingError(module, /** @type {Error} */ (err)));
+			moduleHashDigest = "XXXXXX";
+		}
+		chunkGraph.setModuleHashes(
+			module,
+			runtime,
+			moduleHashDigest,
+			moduleHashDigest.slice(0, hashDigestLength)
+		);
+		return moduleHashDigest;
+	}
+
+	createHash() {
+		this.logger.time("hashing: initialize hash");
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const runtimeTemplate = this.runtimeTemplate;
+		const outputOptions = this.outputOptions;
+		const hashFunction = outputOptions.hashFunction;
+		const hashDigest = outputOptions.hashDigest;
+		const hashDigestLength = outputOptions.hashDigestLength;
+		const hash = createHash(hashFunction);
+		if (outputOptions.hashSalt) {
+			hash.update(outputOptions.hashSalt);
+		}
+		this.logger.timeEnd("hashing: initialize hash");
+		if (this.children.length > 0) {
+			this.logger.time("hashing: hash child compilations");
+			for (const child of this.children) {
+				hash.update(/** @type {string} */ (child.hash));
+			}
+			this.logger.timeEnd("hashing: hash child compilations");
+		}
+		if (this.warnings.length > 0) {
+			this.logger.time("hashing: hash warnings");
+			for (const warning of this.warnings) {
+				hash.update(`${warning.message}`);
+			}
+			this.logger.timeEnd("hashing: hash warnings");
+		}
+		if (this.errors.length > 0) {
+			this.logger.time("hashing: hash errors");
+			for (const error of this.errors) {
+				hash.update(`${error.message}`);
+			}
+			this.logger.timeEnd("hashing: hash errors");
+		}
+
+		this.logger.time("hashing: sort chunks");
+		/*
+		 * Chunks are hashed in 4 categories, in this order:
+		 * 1. Async chunks - no hash dependencies on other chunks
+		 * 2. Non-entry initial chunks (e.g. shared split chunks) - no hash
+		 *    dependencies on other chunks, but runtime chunks may read their
+		 *    hashes via GetChunkFilenameRuntimeModule (dependentHash)
+		 * 3. Runtime chunks - may use hashes of async and non-entry initial
+		 *    chunks (via GetChunkFilenameRuntimeModule). Ordered by references
+		 *    between each other (for async entrypoints)
+		 * 4. Entry chunks - may depend on runtimeChunk.hash (via
+		 *    createChunkHashHandler for ESM/CJS entry importing runtime)
+		 *
+		 * This ordering ensures all hash dependencies flow in one direction:
+		 * async/initial → runtime → entry, with no circular dependencies.
+		 * Chunks within each category are sorted by id for determinism.
+		 */
+		/** @type {Chunk[]} */
+		const unorderedRuntimeChunks = [];
+		/** @type {Chunk[]} */
+		const initialChunks = [];
+		/** @type {Chunk[]} */
+		const entryChunks = [];
+		/** @type {Chunk[]} */
+		const asyncChunks = [];
+		for (const c of this.chunks) {
+			if (c.hasRuntime()) {
+				unorderedRuntimeChunks.push(c);
+			} else if (chunkGraph.getNumberOfEntryModules(c) > 0) {
+				entryChunks.push(c);
+			} else if (c.canBeInitial()) {
+				initialChunks.push(c);
+			} else {
+				asyncChunks.push(c);
+			}
+		}
+		unorderedRuntimeChunks.sort(byId);
+		entryChunks.sort(byId);
+		initialChunks.sort(byId);
+		asyncChunks.sort(byId);
+
+		/** @typedef {{ chunk: Chunk, referencedBy: RuntimeChunkInfo[], remaining: number }} RuntimeChunkInfo */
+		/** @type {Map<Chunk, RuntimeChunkInfo>} */
+		const runtimeChunksMap = new Map();
+		for (const chunk of unorderedRuntimeChunks) {
+			runtimeChunksMap.set(chunk, {
+				chunk,
+				referencedBy: [],
+				remaining: 0
+			});
+		}
+		let remaining = 0;
+		for (const info of runtimeChunksMap.values()) {
+			for (const other of new Set(
+				[...info.chunk.getAllReferencedAsyncEntrypoints()].map(
+					(e) => e.chunks[e.chunks.length - 1]
+				)
+			)) {
+				const otherInfo = runtimeChunksMap.get(other);
+				// other may be a non-runtime chunk (e.g. worker chunk)
+				// when you have a worker chunk in your app.js (new Worker(...)) and as a separate entry point
+				if (otherInfo) {
+					otherInfo.referencedBy.push(info);
+					info.remaining++;
+					remaining++;
+				}
+			}
+		}
+		/** @type {Chunk[]} */
+		const runtimeChunks = [];
+		for (const info of runtimeChunksMap.values()) {
+			if (info.remaining === 0) {
+				runtimeChunks.push(info.chunk);
+			}
+		}
+		// If there are any references between chunks
+		// make sure to follow these chains
+		if (remaining > 0) {
+			/** @type {Chunk[]} */
+			const readyChunks = [];
+			for (const chunk of runtimeChunks) {
+				const hasFullHashModules =
+					chunkGraph.getNumberOfChunkFullHashModules(chunk) !== 0;
+				const info =
+					/** @type {RuntimeChunkInfo} */
+					(runtimeChunksMap.get(chunk));
+				for (const otherInfo of info.referencedBy) {
+					if (hasFullHashModules) {
+						chunkGraph.upgradeDependentToFullHashModules(otherInfo.chunk);
+					}
+					remaining--;
+					if (--otherInfo.remaining === 0) {
+						readyChunks.push(otherInfo.chunk);
+					}
+				}
+				if (readyChunks.length > 0) {
+					// This ensures deterministic ordering, since referencedBy is non-deterministic
+					readyChunks.sort(byId);
+					for (const c of readyChunks) runtimeChunks.push(c);
+					readyChunks.length = 0;
+				}
+			}
+		}
+		// If there are still remaining references we have cycles and want to create a warning
+		if (remaining > 0) {
+			/** @type {RuntimeChunkInfo[]} */
+			const circularRuntimeChunkInfo = [];
+			for (const info of runtimeChunksMap.values()) {
+				if (info.remaining !== 0) {
+					circularRuntimeChunkInfo.push(info);
+				}
+			}
+			circularRuntimeChunkInfo.sort(compareSelect((i) => i.chunk, byId));
+			const err =
+				new WebpackError(`Circular dependency between chunks with runtime (${Array.from(
+					circularRuntimeChunkInfo,
+					(c) => c.chunk.name || c.chunk.id
+				).join(", ")})
+This prevents using hashes of each other and should be avoided.`);
+			err.chunk = circularRuntimeChunkInfo[0].chunk;
+			this.warnings.push(err);
+			for (const i of circularRuntimeChunkInfo) runtimeChunks.push(i.chunk);
+		}
+		this.logger.timeEnd("hashing: sort chunks");
+
+		/** @type {Set<Chunk>} */
+		const fullHashChunks = new Set();
+		/** @type {CodeGenerationJobs} */
+		const codeGenerationJobs = [];
+		/** @type {Map<string, Map<Module, CodeGenerationJob>>} */
+		const codeGenerationJobsMap = new Map();
+		/** @type {WebpackError[]} */
+		const errors = [];
+
+		/**
+		 * Processes the provided chunk.
+		 * @param {Chunk} chunk chunk
+		 */
+		const processChunk = (chunk) => {
+			// Last minute module hash generation for modules that depend on chunk hashes
+			this.logger.time("hashing: hash runtime modules");
+			const runtime = chunk.runtime;
+			for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+				if (!chunkGraph.hasModuleHashes(module, runtime)) {
+					const hash = this._createModuleHash(
+						module,
+						chunkGraph,
+						runtime,
+						hashFunction,
+						runtimeTemplate,
+						hashDigest,
+						hashDigestLength,
+						errors
+					);
+					let hashMap = codeGenerationJobsMap.get(hash);
+					if (hashMap) {
+						const moduleJob = hashMap.get(module);
+						if (moduleJob) {
+							moduleJob.runtimes.push(runtime);
+							continue;
+						}
+					} else {
+						hashMap = new Map();
+						codeGenerationJobsMap.set(hash, hashMap);
+					}
+					const job = {
+						module,
+						hash,
+						runtime,
+						runtimes: [runtime]
+					};
+					hashMap.set(module, job);
+					codeGenerationJobs.push(job);
+				}
+			}
+			this.logger.timeAggregate("hashing: hash runtime modules");
+			try {
+				this.logger.time("hashing: hash chunks");
+				const chunkHash = createHash(hashFunction);
+				if (outputOptions.hashSalt) {
+					chunkHash.update(outputOptions.hashSalt);
+				}
+				chunk.updateHash(chunkHash, chunkGraph);
+				this.hooks.chunkHash.call(chunk, chunkHash, {
+					chunkGraph,
+					codeGenerationResults:
+						/** @type {CodeGenerationResults} */
+						(this.codeGenerationResults),
+					moduleGraph: this.moduleGraph,
+					runtimeTemplate: this.runtimeTemplate
+				});
+				const chunkHashDigest = chunkHash.digest(hashDigest);
+				hash.update(chunkHashDigest);
+				chunk.hash = chunkHashDigest;
+				chunk.renderedHash = chunk.hash.slice(0, hashDigestLength);
+				const fullHashModules =
+					chunkGraph.getChunkFullHashModulesIterable(chunk);
+				if (fullHashModules) {
+					fullHashChunks.add(chunk);
+				} else {
+					this.hooks.contentHash.call(chunk);
+				}
+			} catch (err) {
+				this.errors.push(
+					new ChunkRenderError(chunk, "", /** @type {Error} */ (err))
+				);
+			}
+			this.logger.timeAggregate("hashing: hash chunks");
+		};
+		for (const chunk of asyncChunks) processChunk(chunk);
+		for (const chunk of initialChunks) processChunk(chunk);
+		for (const chunk of runtimeChunks) processChunk(chunk);
+		for (const chunk of entryChunks) processChunk(chunk);
+		if (errors.length > 0) {
+			errors.sort(
+				compareSelect((err) => err.module, compareModulesByIdentifier)
+			);
+			for (const error of errors) {
+				this.errors.push(error);
+			}
+		}
+
+		this.logger.timeAggregateEnd("hashing: hash runtime modules");
+		this.logger.timeAggregateEnd("hashing: hash chunks");
+		this.logger.time("hashing: hash digest");
+		this.hooks.fullHash.call(hash);
+		this.fullHash = hash.digest(hashDigest);
+		this.hash = this.fullHash.slice(0, hashDigestLength);
+		this.logger.timeEnd("hashing: hash digest");
+
+		this.logger.time("hashing: process full hash modules");
+		for (const chunk of fullHashChunks) {
+			for (const module of /** @type {Iterable<RuntimeModule>} */ (
+				chunkGraph.getChunkFullHashModulesIterable(chunk)
+			)) {
+				const moduleHash = createHash(hashFunction);
+				module.updateHash(moduleHash, {
+					chunkGraph,
+					runtime: chunk.runtime,
+					runtimeTemplate
+				});
+				const moduleHashDigest = moduleHash.digest(hashDigest);
+				const oldHash = chunkGraph.getModuleHash(module, chunk.runtime);
+				chunkGraph.setModuleHashes(
+					module,
+					chunk.runtime,
+					moduleHashDigest,
+					moduleHashDigest.slice(0, hashDigestLength)
+				);
+				/** @type {CodeGenerationJob} */
+				(
+					/** @type {Map<Module, CodeGenerationJob>} */
+					(codeGenerationJobsMap.get(oldHash)).get(module)
+				).hash = moduleHashDigest;
+			}
+			const chunkHash = createHash(hashFunction);
+			chunkHash.update(/** @type {string} */ (chunk.hash));
+			chunkHash.update(this.hash);
+			const chunkHashDigest = chunkHash.digest(hashDigest);
+			chunk.hash = chunkHashDigest;
+			chunk.renderedHash = chunk.hash.slice(0, hashDigestLength);
+			this.hooks.contentHash.call(chunk);
+		}
+		this.logger.timeEnd("hashing: process full hash modules");
+		return codeGenerationJobs;
+	}
+
+	/**
+	 * Processes the provided file.
+	 * @param {string} file file name
+	 * @param {Source} source asset source
+	 * @param {AssetInfo} assetInfo extra asset information
+	 * @returns {void}
+	 */
+	emitAsset(file, source, assetInfo = {}) {
+		if (this.assets[file]) {
+			if (!isSourceEqual(this.assets[file], source)) {
+				this.errors.push(
+					new WebpackError(
+						`Conflict: Multiple assets emit different content to the same filename ${file}${
+							assetInfo.sourceFilename
+								? `. Original source ${assetInfo.sourceFilename}`
+								: ""
+						}`
+					)
+				);
+				this.assets[file] = source;
+				this._setAssetInfo(file, assetInfo);
+				return;
+			}
+			const oldInfo = this.assetsInfo.get(file);
+			const newInfo = { ...oldInfo, ...assetInfo };
+			this._setAssetInfo(file, newInfo, oldInfo);
+			return;
+		}
+		this.assets[file] = source;
+		this._setAssetInfo(file, assetInfo, undefined);
+	}
+
+	/**
+	 * Processes the provided file.
+	 * @private
+	 * @param {string} file file name
+	 * @param {AssetInfo=} newInfo new asset information
+	 * @param {AssetInfo=} oldInfo old asset information
+	 */
+	_setAssetInfo(file, newInfo, oldInfo = this.assetsInfo.get(file)) {
+		if (newInfo === undefined) {
+			this.assetsInfo.delete(file);
+		} else {
+			this.assetsInfo.set(file, newInfo);
+		}
+		const oldRelated = oldInfo && oldInfo.related;
+		const newRelated = newInfo && newInfo.related;
+		if (oldRelated) {
+			for (const key of Object.keys(oldRelated)) {
+				/**
+				 * Processes the provided name.
+				 * @param {string} name name
+				 */
+				const remove = (name) => {
+					const relatedIn = this._assetsRelatedIn.get(name);
+					if (relatedIn === undefined) return;
+					const entry = relatedIn.get(key);
+					if (entry === undefined) return;
+					entry.delete(file);
+					if (entry.size !== 0) return;
+					relatedIn.delete(key);
+					if (relatedIn.size === 0) this._assetsRelatedIn.delete(name);
+				};
+				const entry = oldRelated[key];
+				if (Array.isArray(entry)) {
+					for (const name of entry) {
+						remove(name);
+					}
+				} else if (entry) {
+					remove(entry);
+				}
+			}
+		}
+		if (newRelated) {
+			for (const key of Object.keys(newRelated)) {
+				/**
+				 * Processes the provided name.
+				 * @param {string} name name
+				 */
+				const add = (name) => {
+					let relatedIn = this._assetsRelatedIn.get(name);
+					if (relatedIn === undefined) {
+						this._assetsRelatedIn.set(name, (relatedIn = new Map()));
+					}
+					let entry = relatedIn.get(key);
+					if (entry === undefined) {
+						relatedIn.set(key, (entry = new Set()));
+					}
+					entry.add(file);
+				};
+				const entry = newRelated[key];
+				if (Array.isArray(entry)) {
+					for (const name of entry) {
+						add(name);
+					}
+				} else if (entry) {
+					add(entry);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Updates asset using the provided file.
+	 * @param {string} file file name
+	 * @param {Source | ((source: Source) => Source)} newSourceOrFunction new asset source or function converting old to new
+	 * @param {(AssetInfo | ((assetInfo?: AssetInfo) => AssetInfo | undefined)) | undefined} assetInfoUpdateOrFunction new asset info or function converting old to new
+	 */
+	updateAsset(
+		file,
+		newSourceOrFunction,
+		assetInfoUpdateOrFunction = undefined
+	) {
+		if (!this.assets[file]) {
+			throw new Error(
+				`Called Compilation.updateAsset for not existing filename ${file}`
+			);
+		}
+		this.assets[file] =
+			typeof newSourceOrFunction === "function"
+				? newSourceOrFunction(this.assets[file])
+				: newSourceOrFunction;
+		if (assetInfoUpdateOrFunction !== undefined) {
+			const oldInfo = this.assetsInfo.get(file) || EMPTY_ASSET_INFO;
+			if (typeof assetInfoUpdateOrFunction === "function") {
+				this._setAssetInfo(file, assetInfoUpdateOrFunction(oldInfo), oldInfo);
+			} else {
+				this._setAssetInfo(
+					file,
+					cachedCleverMerge(oldInfo, assetInfoUpdateOrFunction),
+					oldInfo
+				);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided file.
+	 * @param {string} file file name
+	 * @param {string} newFile the new name of file
+	 */
+	renameAsset(file, newFile) {
+		const source = this.assets[file];
+		if (!source) {
+			throw new Error(
+				`Called Compilation.renameAsset for not existing filename ${file}`
+			);
+		}
+		if (this.assets[newFile] && !isSourceEqual(this.assets[file], source)) {
+			this.errors.push(
+				new WebpackError(
+					`Conflict: Called Compilation.renameAsset for already existing filename ${newFile} with different content`
+				)
+			);
+		}
+		const assetInfo = this.assetsInfo.get(file);
+		// Update related in all other assets
+		const relatedInInfo = this._assetsRelatedIn.get(file);
+		if (relatedInInfo) {
+			for (const [key, assets] of relatedInInfo) {
+				for (const name of assets) {
+					const info = this.assetsInfo.get(name);
+					if (!info) continue;
+					const related = info.related;
+					if (!related) continue;
+					const entry = related[key];
+					/** @type {string | string[]} */
+					let newEntry;
+					if (Array.isArray(entry)) {
+						newEntry = entry.map((x) => (x === file ? newFile : x));
+					} else if (entry === file) {
+						newEntry = newFile;
+					} else {
+						continue;
+					}
+					this.assetsInfo.set(name, {
+						...info,
+						related: {
+							...related,
+							[key]: newEntry
+						}
+					});
+				}
+			}
+		}
+		this._setAssetInfo(file, undefined, assetInfo);
+		this._setAssetInfo(newFile, assetInfo);
+		delete this.assets[file];
+		this.assets[newFile] = source;
+		for (const chunk of this.chunks) {
+			{
+				const size = chunk.files.size;
+				chunk.files.delete(file);
+				if (size !== chunk.files.size) {
+					chunk.files.add(newFile);
+				}
+			}
+			{
+				const size = chunk.auxiliaryFiles.size;
+				chunk.auxiliaryFiles.delete(file);
+				if (size !== chunk.auxiliaryFiles.size) {
+					chunk.auxiliaryFiles.add(newFile);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided file.
+	 * @param {string} file file name
+	 */
+	deleteAsset(file) {
+		if (!this.assets[file]) {
+			return;
+		}
+		delete this.assets[file];
+		const assetInfo = this.assetsInfo.get(file);
+		this._setAssetInfo(file, undefined, assetInfo);
+		const related = assetInfo && assetInfo.related;
+		if (related) {
+			for (const key of Object.keys(related)) {
+				/**
+				 * Checks used and delete.
+				 * @param {string} file file
+				 */
+				const checkUsedAndDelete = (file) => {
+					if (!this._assetsRelatedIn.has(file)) {
+						this.deleteAsset(file);
+					}
+				};
+				const items = related[key];
+				if (Array.isArray(items)) {
+					for (const file of items) {
+						checkUsedAndDelete(file);
+					}
+				} else if (items) {
+					checkUsedAndDelete(items);
+				}
+			}
+		}
+		// TODO If this becomes a performance problem
+		// store a reverse mapping from asset to chunk
+		for (const chunk of this.chunks) {
+			chunk.files.delete(file);
+			chunk.auxiliaryFiles.delete(file);
+		}
+	}
+
+	getAssets() {
+		/** @type {Readonly<Asset>[]} */
+		const array = [];
+		for (const assetName of Object.keys(this.assets)) {
+			if (Object.prototype.hasOwnProperty.call(this.assets, assetName)) {
+				array.push({
+					name: assetName,
+					source: this.assets[assetName],
+					info: this.assetsInfo.get(assetName) || EMPTY_ASSET_INFO
+				});
+			}
+		}
+		return array;
+	}
+
+	/**
+	 * Returns the asset or undefined when not found.
+	 * @param {string} name the name of the asset
+	 * @returns {Readonly<Asset> | undefined} the asset or undefined when not found
+	 */
+	getAsset(name) {
+		if (!Object.prototype.hasOwnProperty.call(this.assets, name)) return;
+		return {
+			name,
+			source: this.assets[name],
+			info: this.assetsInfo.get(name) || EMPTY_ASSET_INFO
+		};
+	}
+
+	clearAssets() {
+		for (const chunk of this.chunks) {
+			chunk.files.clear();
+			chunk.auxiliaryFiles.clear();
+		}
+	}
+
+	createModuleAssets() {
+		const { chunkGraph } = this;
+		for (const module of this.modules) {
+			const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
+			if (buildInfo.assets) {
+				const assetsInfo = buildInfo.assetsInfo;
+				for (const assetName of Object.keys(buildInfo.assets)) {
+					const fileName = this.getPath(assetName, {
+						chunkGraph: this.chunkGraph,
+						module
+					});
+					for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
+						chunk.auxiliaryFiles.add(fileName);
+					}
+					this.emitAsset(
+						fileName,
+						buildInfo.assets[assetName],
+						assetsInfo ? assetsInfo.get(assetName) : undefined
+					);
+					this.hooks.moduleAsset.call(module, fileName);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Gets render manifest.
+	 * @param {RenderManifestOptions} options options object
+	 * @returns {RenderManifestEntry[]} manifest entries
+	 */
+	getRenderManifest(options) {
+		return this.hooks.renderManifest.call([], options);
+	}
+
+	/**
+	 * Creates a chunk assets.
+	 * @param {Callback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	createChunkAssets(callback) {
+		const outputOptions = this.outputOptions;
+		/** @type {WeakMap<Source, CachedSource>} */
+		const cachedSourceMap = new WeakMap();
+		/** @type {Map<string, { hash: string, source: Source, chunk: Chunk }>} */
+		const alreadyWrittenFiles = new Map();
+
+		asyncLib.forEachLimit(
+			this.chunks,
+			15,
+			(chunk, callback) => {
+				/** @type {RenderManifestEntry[]} */
+				let manifest;
+				try {
+					manifest = this.getRenderManifest({
+						chunk,
+						hash: /** @type {string} */ (this.hash),
+						fullHash: /** @type {string} */ (this.fullHash),
+						outputOptions,
+						codeGenerationResults:
+							/** @type {CodeGenerationResults} */
+							(this.codeGenerationResults),
+						moduleTemplates: this.moduleTemplates,
+						dependencyTemplates: this.dependencyTemplates,
+						chunkGraph: this.chunkGraph,
+						moduleGraph: this.moduleGraph,
+						runtimeTemplate: this.runtimeTemplate
+					});
+				} catch (err) {
+					this.errors.push(
+						new ChunkRenderError(chunk, "", /** @type {Error} */ (err))
+					);
+					return callback();
+				}
+				asyncLib.each(
+					manifest,
+					(fileManifest, callback) => {
+						const ident = fileManifest.identifier;
+						const usedHash = /** @type {string} */ (fileManifest.hash);
+
+						const assetCacheItem = this._assetsCache.getItemCache(
+							ident,
+							usedHash
+						);
+
+						assetCacheItem.get((err, sourceFromCache) => {
+							/** @type {string | import("./TemplatedPathPlugin").TemplatePathFn<EXPECTED_ANY>} */
+							let filenameTemplate;
+							/** @type {string} */
+							let file;
+							/** @type {AssetInfo} */
+							let assetInfo;
+
+							let inTry = true;
+							/**
+							 * Error and callback.
+							 * @param {Error} err error
+							 * @returns {void}
+							 */
+							const errorAndCallback = (err) => {
+								const filename =
+									file ||
+									(typeof file === "string"
+										? file
+										: typeof filenameTemplate === "string"
+											? filenameTemplate
+											: "");
+
+								this.errors.push(new ChunkRenderError(chunk, filename, err));
+								inTry = false;
+								return callback();
+							};
+
+							try {
+								if ("filename" in fileManifest) {
+									file = fileManifest.filename;
+									assetInfo = fileManifest.info;
+								} else {
+									filenameTemplate = fileManifest.filenameTemplate;
+									const pathAndInfo = this.getPathWithInfo(
+										filenameTemplate,
+										fileManifest.pathOptions
+									);
+									file = pathAndInfo.path;
+									assetInfo = fileManifest.info
+										? {
+												...pathAndInfo.info,
+												...fileManifest.info
+											}
+										: pathAndInfo.info;
+								}
+
+								if (err) {
+									return errorAndCallback(err);
+								}
+
+								let source = sourceFromCache;
+
+								// check if the same filename was already written by another chunk
+								const alreadyWritten = alreadyWrittenFiles.get(file);
+								if (alreadyWritten !== undefined) {
+									if (alreadyWritten.hash !== usedHash) {
+										inTry = false;
+										return callback(
+											new WebpackError(
+												`Conflict: Multiple chunks emit assets to the same filename ${file}` +
+													` (chunks ${alreadyWritten.chunk.id} and ${chunk.id})`
+											)
+										);
+									}
+									source = alreadyWritten.source;
+								} else if (!source) {
+									// render the asset
+									source = fileManifest.render();
+
+									// Ensure that source is a cached source to avoid additional cost because of repeated access
+									if (!(source instanceof CachedSource)) {
+										const cacheEntry = cachedSourceMap.get(source);
+										if (cacheEntry) {
+											source = cacheEntry;
+										} else {
+											const cachedSource = new CachedSource(source);
+											cachedSourceMap.set(source, cachedSource);
+											source = cachedSource;
+										}
+									}
+								}
+								this.emitAsset(file, source, assetInfo);
+								if (fileManifest.auxiliary) {
+									chunk.auxiliaryFiles.add(file);
+								} else {
+									chunk.files.add(file);
+								}
+								this.hooks.chunkAsset.call(chunk, file);
+								alreadyWrittenFiles.set(file, {
+									hash: usedHash,
+									source,
+									chunk
+								});
+								if (source !== sourceFromCache) {
+									assetCacheItem.store(source, (err) => {
+										if (err) return errorAndCallback(err);
+										inTry = false;
+										return callback();
+									});
+								} else {
+									inTry = false;
+									callback();
+								}
+							} catch (err) {
+								if (!inTry) throw err;
+								errorAndCallback(/** @type {Error} */ (err));
+							}
+						});
+					},
+					callback
+				);
+			},
+			callback
+		);
+	}
+
+	/**
+	 * Returns interpolated path.
+	 * @template {PathData} [T=PathData]
+	 * @param {string | import("./TemplatedPathPlugin").TemplatePathFn<T>} filename used to get asset path with hash
+	 * @param {T=} data context data
+	 * @returns {string} interpolated path
+	 */
+	getPath(filename, data = /** @type {T} */ ({})) {
+		if (!data.hash) {
+			data = {
+				hash: this.hash,
+				...data
+			};
+		}
+		return this.getAssetPath(filename, data);
+	}
+
+	/**
+	 * Gets path with info.
+	 * @template {PathData} [T=PathData]
+	 * @param {string | import("./TemplatedPathPlugin").TemplatePathFn<T>} filename used to get asset path with hash
+	 * @param {T=} data context data
+	 * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info
+	 */
+	getPathWithInfo(filename, data = /** @type {T} */ ({})) {
+		if (!data.hash) {
+			data = {
+				hash: this.hash,
+				...data
+			};
+		}
+		return this.getAssetPathWithInfo(filename, data);
+	}
+
+	/**
+	 * Returns interpolated path.
+	 * @template {PathData} [T=PathData]
+	 * @param {string | import("./TemplatedPathPlugin").TemplatePathFn<T>} filename used to get asset path with hash
+	 * @param {T} data context data
+	 * @returns {string} interpolated path
+	 */
+	getAssetPath(filename, data) {
+		return this.hooks.assetPath.call(
+			typeof filename === "function" ? filename(data) : filename,
+			data,
+			undefined
+		);
+	}
+
+	/**
+	 * Gets asset path with info.
+	 * @template {PathData} [T=PathData]
+	 * @param {string | import("./TemplatedPathPlugin").TemplatePathFn<T>} filename used to get asset path with hash
+	 * @param {T} data context data
+	 * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info
+	 */
+	getAssetPathWithInfo(filename, data) {
+		const assetInfo = {};
+		// TODO webpack 5: refactor assetPath hook to receive { path, info } object
+		const newPath = this.hooks.assetPath.call(
+			typeof filename === "function" ? filename(data, assetInfo) : filename,
+			data,
+			assetInfo
+		);
+		return { path: newPath, info: assetInfo };
+	}
+
+	getWarnings() {
+		return this.hooks.processWarnings.call(this.warnings);
+	}
+
+	getErrors() {
+		return this.hooks.processErrors.call(this.errors);
+	}
+
+	/**
+	 * This function allows you to run another instance of webpack inside of webpack however as
+	 * a child with different settings and configurations (if desired) applied. It copies all hooks, plugins
+	 * from parent (or top level compiler) and creates a child Compilation
+	 * @param {string} name name of the child compiler
+	 * @param {Partial<OutputOptions>=} outputOptions // Need to convert config schema to types for this
+	 * @param {Plugins=} plugins webpack plugins that will be applied
+	 * @returns {Compiler} creates a child Compiler instance
+	 */
+	createChildCompiler(name, outputOptions, plugins) {
+		const idx = this.childrenCounters[name] || 0;
+		this.childrenCounters[name] = idx + 1;
+		return this.compiler.createChildCompiler(
+			this,
+			name,
+			idx,
+			outputOptions,
+			plugins
+		);
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module the module
+	 * @param {ExecuteModuleOptions} options options
+	 * @param {ExecuteModuleCallback} callback callback
+	 */
+	executeModule(module, options, callback) {
+		// Aggregate all referenced modules and ensure they are ready
+		const modules = new Set([module]);
+		processAsyncTree(
+			modules,
+			10,
+			(module, push, callback) => {
+				this.buildQueue.waitFor(module, (err) => {
+					if (err) return callback(err);
+					this.processDependenciesQueue.waitFor(module, (err) => {
+						if (err) return callback(err);
+						for (const { module: m } of this.moduleGraph.getOutgoingConnections(
+							module
+						)) {
+							const size = modules.size;
+							modules.add(m);
+							if (modules.size !== size) push(m);
+						}
+						callback();
+					});
+				});
+			},
+			(err) => {
+				if (err) return callback(/** @type {WebpackError} */ (err));
+
+				// Create new chunk graph, chunk and entrypoint for the build time execution
+				const chunkGraph = new ChunkGraph(
+					this.moduleGraph,
+					this.outputOptions.hashFunction
+				);
+				const runtime = "build time";
+				const { hashFunction, hashDigest, hashDigestLength } =
+					this.outputOptions;
+				const runtimeTemplate = this.runtimeTemplate;
+
+				const chunk = new Chunk("build time chunk", this._backCompat);
+				chunk.id = /** @type {ChunkId} */ (chunk.name);
+				chunk.ids = [chunk.id];
+				chunk.runtime = runtime;
+
+				const entrypoint = new Entrypoint({
+					runtime,
+					chunkLoading: false,
+					...options.entryOptions
+				});
+				chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint);
+				if (entrypoint.pushChunk(chunk)) {
+					chunk.addGroup(entrypoint);
+				}
+				entrypoint.setRuntimeChunk(chunk);
+				entrypoint.setEntrypointChunk(chunk);
+
+				const chunks = new Set([chunk]);
+
+				// Assign ids to modules and modules to the chunk
+				for (const module of modules) {
+					const id = module.identifier();
+					chunkGraph.setModuleId(module, id);
+					chunkGraph.connectChunkAndModule(chunk, module);
+				}
+
+				/** @type {WebpackError[]} */
+				const errors = [];
+
+				// Hash modules
+				for (const module of modules) {
+					this._createModuleHash(
+						module,
+						chunkGraph,
+						runtime,
+						hashFunction,
+						runtimeTemplate,
+						hashDigest,
+						hashDigestLength,
+						errors
+					);
+				}
+
+				const codeGenerationResults = new CodeGenerationResults(
+					this.outputOptions.hashFunction
+				);
+				/**
+				 * Processes the provided module.
+				 * @param {Module} module the module
+				 * @param {Callback} callback callback
+				 * @returns {void}
+				 */
+				const codeGen = (module, callback) => {
+					this._codeGenerationModule(
+						module,
+						runtime,
+						[runtime],
+						chunkGraph.getModuleHash(module, runtime),
+						this.dependencyTemplates,
+						chunkGraph,
+						this.moduleGraph,
+						runtimeTemplate,
+						errors,
+						codeGenerationResults,
+						(err, _codeGenerated) => {
+							callback(err);
+						}
+					);
+				};
+
+				const reportErrors = () => {
+					if (errors.length > 0) {
+						errors.sort(
+							compareSelect((err) => err.module, compareModulesByIdentifier)
+						);
+						for (const error of errors) {
+							this.errors.push(error);
+						}
+						errors.length = 0;
+					}
+				};
+
+				// Generate code for all aggregated modules
+				asyncLib.eachLimit(
+					/** @type {import("neo-async").IterableCollection<Module>} */ (
+						/** @type {unknown} */ (modules)
+					),
+					10,
+					codeGen,
+					(err) => {
+						if (err) return callback(err);
+						reportErrors();
+
+						// for backward-compat temporary set the chunk graph
+						// TODO webpack 6
+						const old = this.chunkGraph;
+						this.chunkGraph = chunkGraph;
+						this.processRuntimeRequirements({
+							chunkGraph,
+							modules,
+							chunks,
+							codeGenerationResults,
+							chunkGraphEntries: chunks
+						});
+						this.chunkGraph = old;
+
+						const runtimeModules =
+							chunkGraph.getChunkRuntimeModulesIterable(chunk);
+
+						// Hash runtime modules
+						for (const module of runtimeModules) {
+							modules.add(module);
+							this._createModuleHash(
+								module,
+								chunkGraph,
+								runtime,
+								hashFunction,
+								runtimeTemplate,
+								hashDigest,
+								hashDigestLength,
+								errors
+							);
+						}
+
+						// Generate code for all runtime modules
+						asyncLib.eachLimit(
+							/** @type {import("neo-async").IterableCollection<RuntimeModule>} */ (
+								runtimeModules
+							),
+							10,
+							codeGen,
+							(err) => {
+								if (err) return callback(err);
+								reportErrors();
+
+								/** @type {Map<Module, ExecuteModuleArgument>} */
+								const moduleArgumentsMap = new Map();
+								/** @type {Map<string, ExecuteModuleArgument>} */
+								const moduleArgumentsById = new Map();
+
+								/** @type {ExecuteModuleResult["fileDependencies"]} */
+								const fileDependencies = new LazySet();
+								/** @type {ExecuteModuleResult["contextDependencies"]} */
+								const contextDependencies = new LazySet();
+								/** @type {ExecuteModuleResult["missingDependencies"]} */
+								const missingDependencies = new LazySet();
+								/** @type {ExecuteModuleResult["buildDependencies"]} */
+								const buildDependencies = new LazySet();
+
+								/** @type {ExecuteModuleResult["assets"]} */
+								const assets = new Map();
+
+								let cacheable = true;
+
+								/** @type {ExecuteModuleContext} */
+								const context = {
+									assets,
+									__webpack_require__: undefined,
+									chunk,
+									chunkGraph
+								};
+
+								// Prepare execution
+								asyncLib.eachLimit(
+									modules,
+									10,
+									(module, callback) => {
+										const codeGenerationResult = codeGenerationResults.get(
+											module,
+											runtime
+										);
+										/** @type {ExecuteModuleArgument} */
+										const moduleArgument = {
+											module,
+											codeGenerationResult,
+											moduleObject: undefined
+										};
+										moduleArgumentsMap.set(module, moduleArgument);
+										moduleArgumentsById.set(
+											module.identifier(),
+											moduleArgument
+										);
+										module.addCacheDependencies(
+											fileDependencies,
+											contextDependencies,
+											missingDependencies,
+											buildDependencies
+										);
+										if (
+											/** @type {BuildInfo} */ (module.buildInfo).cacheable ===
+											false
+										) {
+											cacheable = false;
+										}
+										if (module.buildInfo && module.buildInfo.assets) {
+											const { assets: moduleAssets, assetsInfo } =
+												module.buildInfo;
+											for (const assetName of Object.keys(moduleAssets)) {
+												assets.set(assetName, {
+													source: moduleAssets[assetName],
+													info: assetsInfo
+														? assetsInfo.get(assetName)
+														: undefined
+												});
+											}
+										}
+										this.hooks.prepareModuleExecution.callAsync(
+											moduleArgument,
+											context,
+											callback
+										);
+									},
+									(err) => {
+										if (err) return callback(/** @type {WebpackError} */ (err));
+
+										/** @type {ExecuteModuleExports | undefined} */
+										let exports;
+										try {
+											const {
+												strictModuleErrorHandling,
+												strictModuleExceptionHandling
+											} = this.outputOptions;
+
+											/** @type {WebpackRequire} */
+											const __webpack_require__ = (id) => {
+												const cached = moduleCache[id];
+												if (cached !== undefined) {
+													if (cached.error) throw cached.error;
+													return cached.exports;
+												}
+												const moduleArgument = moduleArgumentsById.get(id);
+												return __webpack_require_module__(
+													/** @type {ExecuteModuleArgument} */
+													(moduleArgument),
+													id
+												);
+											};
+											const interceptModuleExecution = (__webpack_require__[
+												/** @type {"i"} */
+												(
+													RuntimeGlobals.interceptModuleExecution.replace(
+														`${RuntimeGlobals.require}.`,
+														""
+													)
+												)
+											] = /** @type {NonNullable<WebpackRequire["i"]>} */ ([]));
+											const moduleCache = (__webpack_require__[
+												/** @type {"c"} */ (
+													RuntimeGlobals.moduleCache.replace(
+														`${RuntimeGlobals.require}.`,
+														""
+													)
+												)
+											] = /** @type {NonNullable<WebpackRequire["c"]>} */ ({}));
+
+											context.__webpack_require__ = __webpack_require__;
+
+											/**
+											 * Webpack require module.
+											 * @param {ExecuteModuleArgument} moduleArgument the module argument
+											 * @param {string=} id id
+											 * @returns {ExecuteModuleExports} exports
+											 */
+											const __webpack_require_module__ = (
+												moduleArgument,
+												id
+											) => {
+												/** @type {ExecuteOptions} */
+												const execOptions = {
+													id,
+													module: {
+														id,
+														exports: {},
+														loaded: false,
+														error: undefined
+													},
+													require: __webpack_require__
+												};
+												for (const handler of interceptModuleExecution) {
+													handler(execOptions);
+												}
+												const module = moduleArgument.module;
+												this.buildTimeExecutedModules.add(module);
+												const moduleObject = execOptions.module;
+												moduleArgument.moduleObject = moduleObject;
+												try {
+													if (id) moduleCache[id] = moduleObject;
+
+													tryRunOrWebpackError(
+														() =>
+															this.hooks.executeModule.call(
+																moduleArgument,
+																context
+															),
+														"Compilation.hooks.executeModule"
+													);
+													moduleObject.loaded = true;
+													return moduleObject.exports;
+												} catch (execErr) {
+													if (strictModuleExceptionHandling) {
+														if (id) delete moduleCache[id];
+													} else if (strictModuleErrorHandling) {
+														moduleObject.error =
+															/** @type {WebpackError} */
+															(execErr);
+													}
+													if (!(/** @type {WebpackError} */ (execErr).module)) {
+														/** @type {WebpackError} */
+														(execErr).module = module;
+													}
+													throw execErr;
+												}
+											};
+
+											for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder(
+												chunk
+											)) {
+												__webpack_require_module__(
+													/** @type {ExecuteModuleArgument} */
+													(moduleArgumentsMap.get(runtimeModule))
+												);
+											}
+
+											exports = __webpack_require__(module.identifier());
+										} catch (execErr) {
+											const { message, stack, module } =
+												/** @type {WebpackError} */
+												(execErr);
+											const err = new WebpackError(
+												`Execution of module code from module graph (${
+													/** @type {Module} */
+													(module).readableIdentifier(this.requestShortener)
+												}) failed: ${message}`,
+												{ cause: execErr }
+											);
+											err.stack = stack;
+											err.module = module;
+											return callback(err);
+										}
+
+										callback(null, {
+											exports,
+											assets,
+											cacheable,
+											fileDependencies,
+											contextDependencies,
+											missingDependencies,
+											buildDependencies
+										});
+									}
+								);
+							}
+						);
+					}
+				);
+			}
+		);
+	}
+
+	checkConstraints() {
+		const chunkGraph = this.chunkGraph;
+
+		/** @type {Set<ModuleId>} */
+		const usedIds = new Set();
+
+		for (const module of this.modules) {
+			if (module.type === WEBPACK_MODULE_TYPE_RUNTIME) continue;
+			const moduleId = chunkGraph.getModuleId(module);
+			if (moduleId === null) continue;
+			if (usedIds.has(moduleId)) {
+				throw new Error(`checkConstraints: duplicate module id ${moduleId}`);
+			}
+			usedIds.add(moduleId);
+		}
+
+		for (const chunk of this.chunks) {
+			for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+				if (!this.modules.has(module)) {
+					throw new Error(
+						"checkConstraints: module in chunk but not in compilation " +
+							` ${chunk.debugId} ${module.debugId}`
+					);
+				}
+			}
+			for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
+				if (!this.modules.has(module)) {
+					throw new Error(
+						"checkConstraints: entry module in chunk but not in compilation " +
+							` ${chunk.debugId} ${module.debugId}`
+					);
+				}
+			}
+		}
+
+		for (const chunkGroup of this.chunkGroups) {
+			chunkGroup.checkConstraints();
+		}
+	}
+}
+
+/**
+ * Defines the factorize module options type used by this module.
+ * @typedef {object} FactorizeModuleOptions
+ * @property {ModuleProfile=} currentProfile
+ * @property {ModuleFactory} factory
+ * @property {Dependency[]} dependencies
+ * @property {boolean=} factoryResult return full ModuleFactoryResult instead of only module
+ * @property {Module | null} originModule
+ * @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
+ * @property {string=} context
+ */
+
+/**
+ * Processes the provided factorize module option.
+ * @param {FactorizeModuleOptions} options options object
+ * @param {ModuleCallback | ModuleFactoryResultCallback} callback callback
+ * @returns {void}
+ */
+
+// Hide from typescript
+const compilationPrototype = Compilation.prototype;
+
+// TODO webpack 6 remove
+Object.defineProperty(compilationPrototype, "modifyHash", {
+	writable: false,
+	enumerable: false,
+	configurable: false,
+	value: () => {
+		throw new Error(
+			"Compilation.modifyHash was removed in favor of Compilation.hooks.fullHash"
+		);
+	}
+});
+
+// TODO webpack 6 remove
+Object.defineProperty(compilationPrototype, "cache", {
+	enumerable: false,
+	configurable: false,
+	get: util.deprecate(
+		/**
+		 * Returns the cache.
+		 * @this {Compilation} the compilation
+		 * @returns {Cache} the cache
+		 */
+		function cache() {
+			return this.compiler.cache;
+		},
+		"Compilation.cache was removed in favor of Compilation.getCache()",
+		"DEP_WEBPACK_COMPILATION_CACHE"
+	),
+	set: util.deprecate(
+		/**
+		 * Handles the value callback for this hook.
+		 * @param {EXPECTED_ANY} _v value
+		 */
+		(_v) => {},
+		"Compilation.cache was removed in favor of Compilation.getCache()",
+		"DEP_WEBPACK_COMPILATION_CACHE"
+	)
+});
+
+/**
+ * Add additional assets to the compilation.
+ */
+Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL = -2000;
+
+/**
+ * Basic preprocessing of assets.
+ */
+Compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS = -1000;
+
+/**
+ * Derive new assets from existing assets.
+ * Existing assets should not be treated as complete.
+ */
+Compilation.PROCESS_ASSETS_STAGE_DERIVED = -200;
+
+/**
+ * Add additional sections to existing assets, like a banner or initialization code.
+ */
+Compilation.PROCESS_ASSETS_STAGE_ADDITIONS = -100;
+
+/**
+ * Optimize existing assets in a general way.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE = 100;
+
+/**
+ * Optimize the count of existing assets, e. g. by merging them.
+ * Only assets of the same type should be merged.
+ * For assets of different types see PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT = 200;
+
+/**
+ * Optimize the compatibility of existing assets, e. g. add polyfills or vendor-prefixes.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY = 300;
+
+/**
+ * Optimize the size of existing assets, e. g. by minimizing or omitting whitespace.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE = 400;
+
+/**
+ * Add development tooling to assets, e. g. by extracting a SourceMap.
+ */
+Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING = 500;
+
+/**
+ * Optimize the count of existing assets, e. g. by inlining assets of into other assets.
+ * Only assets of different types should be inlined.
+ * For assets of the same type see PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE = 700;
+
+/**
+ * Summarize the list of existing assets
+ * e. g. creating an assets manifest of Service Workers.
+ */
+Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE = 1000;
+
+/**
+ * Optimize the hashes of the assets, e. g. by generating real hashes of the asset content.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH = 2500;
+
+/**
+ * Optimize the transfer of existing assets, e. g. by preparing a compressed (gzip) file as separate asset.
+ */
+Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER = 3000;
+
+/**
+ * Analyse existing assets.
+ */
+Compilation.PROCESS_ASSETS_STAGE_ANALYSE = 4000;
+
+/**
+ * Creating assets for reporting purposes.
+ */
+Compilation.PROCESS_ASSETS_STAGE_REPORT = 5000;
+
+module.exports = Compilation;
Index: frontend/node_modules/webpack/lib/Compiler.js
===================================================================
--- frontend/node_modules/webpack/lib/Compiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Compiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1495 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const {
+	AsyncParallelHook,
+	AsyncSeriesHook,
+	SyncBailHook,
+	SyncHook
+} = require("tapable");
+const { SizeOnlySource } = require("webpack-sources");
+const Cache = require("./Cache");
+const CacheFacade = require("./CacheFacade");
+const ChunkGraph = require("./ChunkGraph");
+const Compilation = require("./Compilation");
+const ContextModuleFactory = require("./ContextModuleFactory");
+const ModuleGraph = require("./ModuleGraph");
+const NormalModuleFactory = require("./NormalModuleFactory");
+const RequestShortener = require("./RequestShortener");
+const ResolverFactory = require("./ResolverFactory");
+const Stats = require("./Stats");
+const Watching = require("./Watching");
+const ConcurrentCompilationError = require("./errors/ConcurrentCompilationError");
+const WebpackError = require("./errors/WebpackError");
+const { Logger } = require("./logging/Logger");
+const { dirname, join, mkdirp } = require("./util/fs");
+const { makePathsRelative } = require("./util/identifier");
+const memoize = require("./util/memoize");
+const parseJson = require("./util/parseJson");
+const { isSourceEqual } = require("./util/source");
+const webpack = require(".");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").EntryNormalized} Entry */
+/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
+/** @typedef {import("../declarations/WebpackOptions").WatchOptions} WatchOptions */
+/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
+/** @typedef {import("../declarations/WebpackOptions").Plugins} Plugins */
+/** @typedef {import("./webpack").WebpackPluginFunction} WebpackPluginFunction */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./HotModuleReplacementPlugin").ChunkHashes} ChunkHashes */
+/** @typedef {import("./HotModuleReplacementPlugin").ChunkModuleHashes} ChunkModuleHashes */
+/** @typedef {import("./HotModuleReplacementPlugin").ChunkModuleIds} ChunkModuleIds */
+/** @typedef {import("./HotModuleReplacementPlugin").ChunkRuntime} ChunkRuntime */
+/** @typedef {import("./HotModuleReplacementPlugin").FullHashChunkModuleHashes} FullHashChunkModuleHashes */
+/** @typedef {import("./HotModuleReplacementPlugin").HotIndex} HotIndex */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./RecordIdsPlugin").RecordsChunks} RecordsChunks */
+/** @typedef {import("./RecordIdsPlugin").RecordsModules} RecordsModules */
+/** @typedef {import("./config/target").PlatformTargetProperties} PlatformTargetProperties */
+/** @typedef {import("./logging/createConsoleLogger").LoggingFunction} LoggingFunction */
+/** @typedef {import("./optimize/AggressiveSplittingPlugin").SplitData} SplitData */
+/** @typedef {import("./util/fs").IStats} IStats */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
+/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
+/** @typedef {import("./util/fs").TimeInfoEntries} TimeInfoEntries */
+/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
+/** @typedef {import("schema-utils").validate} Validate */
+/** @typedef {import("schema-utils").Schema} Schema */
+/** @typedef {import("schema-utils").ValidationErrorConfiguration} ValidationErrorConfiguration */
+
+/**
+ * Defines the compilation params type used by this module.
+ * @typedef {object} CompilationParams
+ * @property {NormalModuleFactory} normalModuleFactory
+ * @property {ContextModuleFactory} contextModuleFactory
+ */
+
+/**
+ * Defines the callback type used by this module.
+ * @template T
+ * @template [R=void]
+ * @typedef {import("./webpack").Callback<T, R>} Callback
+ */
+
+/** @typedef {import("./webpack").ErrorCallback} ErrorCallback */
+
+/**
+ * Defines the run as child callback callback.
+ * @callback RunAsChildCallback
+ * @param {Error | null} err
+ * @param {Chunk[]=} entries
+ * @param {Compilation=} compilation
+ * @returns {void}
+ */
+
+/**
+ * Defines the known records type used by this module.
+ * @typedef {object} KnownRecords
+ * @property {SplitData[]=} aggressiveSplits
+ * @property {RecordsChunks=} chunks
+ * @property {RecordsModules=} modules
+ * @property {string=} hash
+ * @property {HotIndex=} hotIndex
+ * @property {FullHashChunkModuleHashes=} fullHashChunkModuleHashes
+ * @property {ChunkModuleHashes=} chunkModuleHashes
+ * @property {ChunkHashes=} chunkHashes
+ * @property {ChunkRuntime=} chunkRuntime
+ * @property {ChunkModuleIds=} chunkModuleIds
+ */
+
+/** @typedef {KnownRecords & Record<string, KnownRecords[]> & Record<string, EXPECTED_ANY>} Records */
+
+/**
+ * Defines the asset emitted info type used by this module.
+ * @typedef {object} AssetEmittedInfo
+ * @property {Buffer} content
+ * @property {Source} source
+ * @property {Compilation} compilation
+ * @property {string} outputPath
+ * @property {string} targetPath
+ */
+
+/** @typedef {{ sizeOnlySource: SizeOnlySource | undefined, writtenTo: Map<string, number> }} CacheEntry */
+/** @typedef {{ path: string, source: Source, size: number | undefined, waiting: ({ cacheEntry: CacheEntry, file: string }[] | undefined) }} SimilarEntry */
+
+/** @typedef {WeakMap<Dependency, Module>} WeakReferences */
+/** @typedef {import("./util/WeakTupleMap")<EXPECTED_ANY[], EXPECTED_ANY>} MemCache */
+/** @typedef {{ buildInfo: BuildInfo, references: WeakReferences | undefined, memCache: MemCache }} ModuleMemCachesItem */
+
+/**
+ * Checks whether this object is sorted.
+ * @template T
+ * @param {T[]} array an array
+ * @returns {boolean} true, if the array is sorted
+ */
+const isSorted = (array) => {
+	for (let i = 1; i < array.length; i++) {
+		if (array[i - 1] > array[i]) return false;
+	}
+	return true;
+};
+
+/**
+ * Returns the object with properties sorted by property name.
+ * @template {object} T
+ * @param {T} obj an object
+ * @param {(keyof T)[]} keys the keys of the object
+ * @returns {T} the object with properties sorted by property name
+ */
+const sortObject = (obj, keys) => {
+	const o = /** @type {T} */ ({});
+	for (const k of keys.sort()) {
+		o[k] = obj[k];
+	}
+	return o;
+};
+
+/**
+ * Returns true, if the filename contains any hash.
+ * @param {string} filename filename
+ * @param {string | string[] | undefined} hashes list of hashes
+ * @returns {boolean} true, if the filename contains any hash
+ */
+const includesHash = (filename, hashes) => {
+	if (!hashes) return false;
+	if (Array.isArray(hashes)) {
+		return hashes.some((hash) => filename.includes(hash));
+	}
+	return filename.includes(hashes);
+};
+
+const getValidate = memoize(() => require("schema-utils").validate);
+
+class Compiler {
+	/**
+	 * Creates an instance of Compiler.
+	 * @param {string} context the compilation path
+	 * @param {WebpackOptions} options options
+	 */
+	constructor(context, options = /** @type {WebpackOptions} */ ({})) {
+		this.hooks = Object.freeze({
+			/** @type {SyncHook<[]>} */
+			initialize: new SyncHook([]),
+
+			/** @type {SyncBailHook<[Compilation], boolean | void>} */
+			shouldEmit: new SyncBailHook(["compilation"]),
+			/** @type {AsyncSeriesHook<[Stats]>} */
+			done: new AsyncSeriesHook(["stats"]),
+			/** @type {SyncHook<[Stats]>} */
+			afterDone: new SyncHook(["stats"]),
+			/** @type {AsyncSeriesHook<[]>} */
+			additionalPass: new AsyncSeriesHook([]),
+			/** @type {AsyncSeriesHook<[Compiler]>} */
+			beforeRun: new AsyncSeriesHook(["compiler"]),
+			/** @type {AsyncSeriesHook<[Compiler]>} */
+			run: new AsyncSeriesHook(["compiler"]),
+			/** @type {AsyncSeriesHook<[Compilation]>} */
+			emit: new AsyncSeriesHook(["compilation"]),
+			/** @type {AsyncSeriesHook<[string, AssetEmittedInfo]>} */
+			assetEmitted: new AsyncSeriesHook(["file", "info"]),
+			/** @type {AsyncSeriesHook<[Compilation]>} */
+			afterEmit: new AsyncSeriesHook(["compilation"]),
+
+			/** @type {SyncHook<[Compilation, CompilationParams]>} */
+			thisCompilation: new SyncHook(["compilation", "params"]),
+			/** @type {SyncHook<[Compilation, CompilationParams]>} */
+			compilation: new SyncHook(["compilation", "params"]),
+			/** @type {SyncHook<[NormalModuleFactory]>} */
+			normalModuleFactory: new SyncHook(["normalModuleFactory"]),
+			/** @type {SyncHook<[ContextModuleFactory]>}  */
+			contextModuleFactory: new SyncHook(["contextModuleFactory"]),
+
+			/** @type {AsyncSeriesHook<[CompilationParams]>} */
+			beforeCompile: new AsyncSeriesHook(["params"]),
+			/** @type {SyncHook<[CompilationParams]>} */
+			compile: new SyncHook(["params"]),
+			/** @type {AsyncParallelHook<[Compilation]>} */
+			make: new AsyncParallelHook(["compilation"]),
+			/** @type {AsyncParallelHook<[Compilation]>} */
+			finishMake: new AsyncSeriesHook(["compilation"]),
+			/** @type {AsyncSeriesHook<[Compilation]>} */
+			afterCompile: new AsyncSeriesHook(["compilation"]),
+
+			/** @type {AsyncSeriesHook<[]>} */
+			readRecords: new AsyncSeriesHook([]),
+			/** @type {AsyncSeriesHook<[]>} */
+			emitRecords: new AsyncSeriesHook([]),
+
+			/** @type {AsyncSeriesHook<[Compiler]>} */
+			watchRun: new AsyncSeriesHook(["compiler"]),
+			/** @type {SyncHook<[Error]>} */
+			failed: new SyncHook(["error"]),
+			/** @type {SyncHook<[string | null, number]>} */
+			invalid: new SyncHook(["filename", "changeTime"]),
+			/** @type {SyncHook<[]>} */
+			watchClose: new SyncHook([]),
+			/** @type {AsyncSeriesHook<[]>} */
+			shutdown: new AsyncSeriesHook([]),
+
+			/** @type {SyncBailHook<[string, string, EXPECTED_ANY[] | undefined], true | void>} */
+			infrastructureLog: new SyncBailHook(["origin", "type", "args"]),
+
+			// TODO the following hooks are weirdly located here
+			// TODO move them for webpack 5
+			/** @type {SyncHook<[]>} */
+			validate: new SyncHook([]),
+			/** @type {SyncHook<[]>} */
+			environment: new SyncHook([]),
+			/** @type {SyncHook<[]>} */
+			afterEnvironment: new SyncHook([]),
+			/** @type {SyncHook<[Compiler]>} */
+			afterPlugins: new SyncHook(["compiler"]),
+			/** @type {SyncHook<[Compiler]>} */
+			afterResolvers: new SyncHook(["compiler"]),
+			/** @type {SyncBailHook<[string, Entry], boolean | void>} */
+			entryOption: new SyncBailHook(["context", "entry"])
+		});
+
+		this.webpack = webpack;
+
+		/** @type {string | undefined} */
+		this.name = undefined;
+		/** @type {Compilation | undefined} */
+		this.parentCompilation = undefined;
+		/** @type {Compiler} */
+		this.root = this;
+		/** @type {string} */
+		this.outputPath = "";
+		/** @type {Watching | undefined} */
+		this.watching = undefined;
+
+		/** @type {OutputFileSystem | null} */
+		this.outputFileSystem = null;
+		/** @type {IntermediateFileSystem | null} */
+		this.intermediateFileSystem = null;
+		/** @type {InputFileSystem | null} */
+		this.inputFileSystem = null;
+		/** @type {WatchFileSystem | null} */
+		this.watchFileSystem = null;
+
+		/** @type {string | null} */
+		this.recordsInputPath = null;
+		/** @type {string | null} */
+		this.recordsOutputPath = null;
+		/** @type {Records} */
+		this.records = {};
+		/** @type {Set<string | RegExp>} */
+		this.managedPaths = new Set();
+		/** @type {Set<string | RegExp>} */
+		this.unmanagedPaths = new Set();
+		/** @type {Set<string | RegExp>} */
+		this.immutablePaths = new Set();
+
+		/** @type {ReadonlySet<string> | undefined} */
+		this.modifiedFiles = undefined;
+		/** @type {ReadonlySet<string> | undefined} */
+		this.removedFiles = undefined;
+		/** @type {TimeInfoEntries | undefined} */
+		this.fileTimestamps = undefined;
+		/** @type {TimeInfoEntries | undefined} */
+		this.contextTimestamps = undefined;
+		/** @type {number | undefined} */
+		this.fsStartTime = undefined;
+
+		/** @type {ResolverFactory} */
+		this.resolverFactory = new ResolverFactory();
+
+		/** @type {LoggingFunction | undefined} */
+		this.infrastructureLogger = undefined;
+
+		/** @type {Readonly<PlatformTargetProperties>} */
+		this.platform = {
+			web: null,
+			browser: null,
+			webworker: null,
+			node: null,
+			nwjs: null,
+			electron: null
+		};
+
+		this.options = options;
+
+		this.context = context;
+
+		this.requestShortener = new RequestShortener(context, this.root);
+
+		this.cache = new Cache();
+
+		/** @type {Map<Module, ModuleMemCachesItem> | undefined} */
+		this.moduleMemCaches = undefined;
+
+		this.compilerPath = "";
+
+		/** @type {boolean} */
+		this.running = false;
+
+		/** @type {boolean} */
+		this.idle = false;
+
+		/** @type {boolean} */
+		this.watchMode = false;
+
+		this._backCompat = this.options.experiments.backCompat !== false;
+
+		/** @type {Compilation | undefined} */
+		this._lastCompilation = undefined;
+		/** @type {NormalModuleFactory | undefined} */
+		this._lastNormalModuleFactory = undefined;
+
+		/**
+		 * @private
+		 * @type {WeakMap<Source, CacheEntry>}
+		 */
+		this._assetEmittingSourceCache = new WeakMap();
+		/**
+		 * @private
+		 * @type {Map<string, number>}
+		 */
+		this._assetEmittingWrittenFiles = new Map();
+		/**
+		 * @private
+		 * @type {Set<string>}
+		 */
+		this._assetEmittingPreviousFiles = new Set();
+	}
+
+	/**
+	 * Returns the cache facade instance.
+	 * @param {string} name cache name
+	 * @returns {CacheFacade} the cache facade instance
+	 */
+	getCache(name) {
+		return new CacheFacade(
+			this.cache,
+			`${this.compilerPath}${name}`,
+			this.options.output.hashFunction
+		);
+	}
+
+	/**
+	 * Gets infrastructure logger.
+	 * @param {string | (() => string)} name name of the logger, or function called once to get the logger name
+	 * @returns {Logger} a logger with that name
+	 */
+	getInfrastructureLogger(name) {
+		if (!name) {
+			throw new TypeError(
+				"Compiler.getInfrastructureLogger(name) called without a name"
+			);
+		}
+		return new Logger(
+			(type, args) => {
+				if (typeof name === "function") {
+					name = name();
+					if (!name) {
+						throw new TypeError(
+							"Compiler.getInfrastructureLogger(name) called with a function not returning a name"
+						);
+					}
+				}
+				if (
+					this.hooks.infrastructureLog.call(name, type, args) === undefined &&
+					this.infrastructureLogger !== undefined
+				) {
+					this.infrastructureLogger(name, type, args);
+				}
+			},
+			(childName) => {
+				if (typeof name === "function") {
+					if (typeof childName === "function") {
+						return this.getInfrastructureLogger(() => {
+							if (typeof name === "function") {
+								name = name();
+								if (!name) {
+									throw new TypeError(
+										"Compiler.getInfrastructureLogger(name) called with a function not returning a name"
+									);
+								}
+							}
+							if (typeof childName === "function") {
+								childName = childName();
+								if (!childName) {
+									throw new TypeError(
+										"Logger.getChildLogger(name) called with a function not returning a name"
+									);
+								}
+							}
+							return `${name}/${childName}`;
+						});
+					}
+					return this.getInfrastructureLogger(() => {
+						if (typeof name === "function") {
+							name = name();
+							if (!name) {
+								throw new TypeError(
+									"Compiler.getInfrastructureLogger(name) called with a function not returning a name"
+								);
+							}
+						}
+						return `${name}/${childName}`;
+					});
+				}
+				if (typeof childName === "function") {
+					return this.getInfrastructureLogger(() => {
+						if (typeof childName === "function") {
+							childName = childName();
+							if (!childName) {
+								throw new TypeError(
+									"Logger.getChildLogger(name) called with a function not returning a name"
+								);
+							}
+						}
+						return `${name}/${childName}`;
+					});
+				}
+				return this.getInfrastructureLogger(`${name}/${childName}`);
+			}
+		);
+	}
+
+	// TODO webpack 6: solve this in a better way
+	// e.g. move compilation specific info from Modules into ModuleGraph
+	_cleanupLastCompilation() {
+		if (this._lastCompilation !== undefined) {
+			for (const childCompilation of this._lastCompilation.children) {
+				for (const module of childCompilation.modules) {
+					ChunkGraph.clearChunkGraphForModule(module);
+					ModuleGraph.clearModuleGraphForModule(module);
+					module.cleanupForCache();
+				}
+				for (const chunk of childCompilation.chunks) {
+					ChunkGraph.clearChunkGraphForChunk(chunk);
+				}
+			}
+
+			for (const module of this._lastCompilation.modules) {
+				ChunkGraph.clearChunkGraphForModule(module);
+				ModuleGraph.clearModuleGraphForModule(module);
+				module.cleanupForCache();
+			}
+			for (const chunk of this._lastCompilation.chunks) {
+				ChunkGraph.clearChunkGraphForChunk(chunk);
+			}
+			this._lastCompilation = undefined;
+		}
+	}
+
+	// TODO webpack 6: solve this in a better way
+	_cleanupLastNormalModuleFactory() {
+		if (this._lastNormalModuleFactory !== undefined) {
+			this._lastNormalModuleFactory.cleanupForCache();
+			this._lastNormalModuleFactory = undefined;
+		}
+	}
+
+	/**
+	 * Returns a compiler watcher.
+	 * @param {WatchOptions} watchOptions the watcher's options
+	 * @param {Callback<Stats>} handler signals when the call finishes
+	 * @returns {Watching | undefined} a compiler watcher
+	 */
+	watch(watchOptions, handler) {
+		if (this.running) {
+			handler(new ConcurrentCompilationError());
+			return;
+		}
+
+		this.running = true;
+		this.watchMode = true;
+		this.watching = new Watching(this, watchOptions, handler);
+		return this.watching;
+	}
+
+	/**
+	 * Processes the provided stat.
+	 * @param {Callback<Stats>} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	run(callback) {
+		if (this.running) {
+			callback(new ConcurrentCompilationError());
+			return;
+		}
+
+		/** @type {Logger | undefined} */
+		let logger;
+
+		/**
+		 * Processes the provided err.
+		 * @param {Error | null} err error
+		 * @param {Stats=} stats stats
+		 */
+		const finalCallback = (err, stats) => {
+			if (logger) logger.time("beginIdle");
+			this.idle = true;
+			this.cache.beginIdle();
+			if (logger) logger.timeEnd("beginIdle");
+			this.running = false;
+			if (err) {
+				this.hooks.failed.call(err);
+			}
+			if (callback !== undefined) callback(err, stats);
+			this.hooks.afterDone.call(/** @type {Stats} */ (stats));
+		};
+
+		const startTime = Date.now();
+
+		this.running = true;
+
+		/**
+		 * Processes the provided err.
+		 * @param {Error | null} err error
+		 * @param {Compilation=} _compilation compilation
+		 * @returns {void}
+		 */
+		const onCompiled = (err, _compilation) => {
+			if (err) return finalCallback(err);
+
+			const compilation = /** @type {Compilation} */ (_compilation);
+
+			if (this.hooks.shouldEmit.call(compilation) === false) {
+				compilation.startTime = startTime;
+				compilation.endTime = Date.now();
+				const stats = new Stats(compilation);
+				this.hooks.done.callAsync(stats, (err) => {
+					if (err) return finalCallback(err);
+					return finalCallback(null, stats);
+				});
+				return;
+			}
+
+			process.nextTick(() => {
+				logger = compilation.getLogger("webpack.Compiler");
+				logger.time("emitAssets");
+				this.emitAssets(compilation, (err) => {
+					/** @type {Logger} */
+					(logger).timeEnd("emitAssets");
+					if (err) return finalCallback(err);
+
+					if (compilation.hooks.needAdditionalPass.call()) {
+						compilation.needAdditionalPass = true;
+
+						compilation.startTime = startTime;
+						compilation.endTime = Date.now();
+						/** @type {Logger} */
+						(logger).time("done hook");
+						const stats = new Stats(compilation);
+						this.hooks.done.callAsync(stats, (err) => {
+							/** @type {Logger} */
+							(logger).timeEnd("done hook");
+							if (err) return finalCallback(err);
+
+							this.hooks.additionalPass.callAsync((err) => {
+								if (err) return finalCallback(err);
+								this.compile(onCompiled);
+							});
+						});
+						return;
+					}
+
+					/** @type {Logger} */
+					(logger).time("emitRecords");
+					this.emitRecords((err) => {
+						/** @type {Logger} */
+						(logger).timeEnd("emitRecords");
+						if (err) return finalCallback(err);
+
+						compilation.startTime = startTime;
+						compilation.endTime = Date.now();
+						/** @type {Logger} */
+						(logger).time("done hook");
+						const stats = new Stats(compilation);
+						this.hooks.done.callAsync(stats, (err) => {
+							/** @type {Logger} */
+							(logger).timeEnd("done hook");
+							if (err) return finalCallback(err);
+							this.cache.storeBuildDependencies(
+								compilation.buildDependencies,
+								(err) => {
+									if (err) return finalCallback(err);
+									return finalCallback(null, stats);
+								}
+							);
+						});
+					});
+				});
+			});
+		};
+
+		const run = () => {
+			this.hooks.beforeRun.callAsync(this, (err) => {
+				if (err) return finalCallback(err);
+
+				this.hooks.run.callAsync(this, (err) => {
+					if (err) return finalCallback(err);
+
+					this.readRecords((err) => {
+						if (err) return finalCallback(err);
+
+						this.compile(onCompiled);
+					});
+				});
+			});
+		};
+
+		if (this.idle) {
+			this.cache.endIdle((err) => {
+				if (err) return finalCallback(err);
+
+				this.idle = false;
+				run();
+			});
+		} else {
+			run();
+		}
+	}
+
+	/**
+	 * Processes the provided run as child callback.
+	 * @param {RunAsChildCallback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	runAsChild(callback) {
+		const startTime = Date.now();
+
+		/**
+		 * Processes the provided err.
+		 * @param {Error | null} err error
+		 * @param {Chunk[]=} entries entries
+		 * @param {Compilation=} compilation compilation
+		 */
+		const finalCallback = (err, entries, compilation) => {
+			try {
+				callback(err, entries, compilation);
+			} catch (runAsChildErr) {
+				const err = new WebpackError(
+					`compiler.runAsChild callback error: ${runAsChildErr}`,
+					{ cause: runAsChildErr }
+				);
+				err.details = /** @type {Error} */ (runAsChildErr).stack;
+				/** @type {Compilation} */
+				(this.parentCompilation).errors.push(err);
+			}
+		};
+
+		this.compile((err, _compilation) => {
+			if (err) return finalCallback(err);
+
+			const compilation = /** @type {Compilation} */ (_compilation);
+			const parentCompilation = /** @type {Compilation} */ (
+				this.parentCompilation
+			);
+
+			parentCompilation.children.push(compilation);
+
+			for (const { name, source, info } of compilation.getAssets()) {
+				parentCompilation.emitAsset(name, source, info);
+			}
+
+			/** @type {Chunk[]} */
+			const entries = [];
+
+			for (const ep of compilation.entrypoints.values()) {
+				entries.push(...ep.chunks);
+			}
+
+			compilation.startTime = startTime;
+			compilation.endTime = Date.now();
+
+			return finalCallback(null, entries, compilation);
+		});
+	}
+
+	purgeInputFileSystem() {
+		if (this.inputFileSystem && this.inputFileSystem.purge) {
+			this.inputFileSystem.purge();
+		}
+	}
+
+	/**
+	 * Processes the provided compilation.
+	 * @param {Compilation} compilation the compilation
+	 * @param {ErrorCallback} callback signals when the assets are emitted
+	 * @returns {void}
+	 */
+	emitAssets(compilation, callback) {
+		/** @type {string} */
+		let outputPath;
+
+		/**
+		 * Processes the provided err.
+		 * @param {Error=} err error
+		 * @returns {void}
+		 */
+		const emitFiles = (err) => {
+			if (err) return callback(err);
+
+			const assets = compilation.getAssets();
+			compilation.assets = { ...compilation.assets };
+			/** @type {Map<string, SimilarEntry>} */
+			const caseInsensitiveMap = new Map();
+			/** @type {Set<string>} */
+			const allTargetPaths = new Set();
+			asyncLib.forEachLimit(
+				assets,
+				15,
+				({ name: file, source, info }, callback) => {
+					let targetFile = file;
+					let immutable = info.immutable;
+					const queryOrHashStringIdx = targetFile.search(/[?#]/);
+					if (queryOrHashStringIdx >= 0) {
+						targetFile = targetFile.slice(0, queryOrHashStringIdx);
+						// We may remove the hash, which is in the query string
+						// So we recheck if the file is immutable
+						// This doesn't cover all cases, but immutable is only a performance optimization anyway
+						immutable =
+							immutable &&
+							(includesHash(targetFile, info.contenthash) ||
+								includesHash(targetFile, info.chunkhash) ||
+								includesHash(targetFile, info.modulehash) ||
+								includesHash(targetFile, info.fullhash));
+					}
+
+					/**
+					 * Processes the provided err.
+					 * @param {Error=} err error
+					 * @returns {void}
+					 */
+					const writeOut = (err) => {
+						if (err) return callback(err);
+						const targetPath = join(
+							/** @type {OutputFileSystem} */
+							(this.outputFileSystem),
+							outputPath,
+							targetFile
+						);
+						allTargetPaths.add(targetPath);
+
+						// check if the target file has already been written by this Compiler
+						const targetFileGeneration =
+							this._assetEmittingWrittenFiles.get(targetPath);
+
+						// create an cache entry for this Source if not already existing
+						let cacheEntry = this._assetEmittingSourceCache.get(source);
+						if (cacheEntry === undefined) {
+							cacheEntry = {
+								sizeOnlySource: undefined,
+								/** @type {CacheEntry["writtenTo"]} */
+								writtenTo: new Map()
+							};
+							this._assetEmittingSourceCache.set(source, cacheEntry);
+						}
+
+						/** @type {SimilarEntry | undefined} */
+						let similarEntry;
+
+						const checkSimilarFile = () => {
+							const caseInsensitiveTargetPath = targetPath.toLowerCase();
+							similarEntry = caseInsensitiveMap.get(caseInsensitiveTargetPath);
+							if (similarEntry !== undefined) {
+								const { path: other, source: otherSource } = similarEntry;
+								if (isSourceEqual(otherSource, source)) {
+									// Size may or may not be available at this point.
+									// If it's not available add to "waiting" list and it will be updated once available
+									if (similarEntry.size !== undefined) {
+										updateWithReplacementSource(similarEntry.size);
+									} else {
+										if (!similarEntry.waiting) similarEntry.waiting = [];
+										similarEntry.waiting.push({ file, cacheEntry });
+									}
+									alreadyWritten();
+								} else {
+									const err =
+										new WebpackError(`Prevent writing to file that only differs in casing or query string from already written file.
+This will lead to a race-condition and corrupted files on case-insensitive file systems.
+${targetPath}
+${other}`);
+									err.file = file;
+									callback(err);
+								}
+								return true;
+							}
+							caseInsensitiveMap.set(
+								caseInsensitiveTargetPath,
+								(similarEntry = /** @type {SimilarEntry} */ ({
+									path: targetPath,
+									source,
+									size: undefined,
+									waiting: undefined
+								}))
+							);
+							return false;
+						};
+
+						/**
+						 * get the binary (Buffer) content from the Source
+						 * @returns {Buffer} content for the source
+						 */
+						const getContent = () => {
+							if (typeof source.buffer === "function") {
+								return source.buffer();
+							}
+							const bufferOrString = source.source();
+							if (Buffer.isBuffer(bufferOrString)) {
+								return bufferOrString;
+							}
+							return Buffer.from(bufferOrString, "utf8");
+						};
+
+						const alreadyWritten = () => {
+							// cache the information that the Source has been already been written to that location
+							if (targetFileGeneration === undefined) {
+								const newGeneration = 1;
+								this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
+								/** @type {CacheEntry} */
+								(cacheEntry).writtenTo.set(targetPath, newGeneration);
+							} else {
+								/** @type {CacheEntry} */
+								(cacheEntry).writtenTo.set(targetPath, targetFileGeneration);
+							}
+							callback();
+						};
+
+						/**
+						 * Write the file to output file system
+						 * @param {Buffer} content content to be written
+						 * @returns {void}
+						 */
+						const doWrite = (content) => {
+							/** @type {OutputFileSystem} */
+							(this.outputFileSystem).writeFile(targetPath, content, (err) => {
+								if (err) return callback(err);
+
+								// information marker that the asset has been emitted
+								compilation.emittedAssets.add(file);
+
+								// cache the information that the Source has been written to that location
+								const newGeneration =
+									targetFileGeneration === undefined
+										? 1
+										: targetFileGeneration + 1;
+								/** @type {CacheEntry} */
+								(cacheEntry).writtenTo.set(targetPath, newGeneration);
+								this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
+								this.hooks.assetEmitted.callAsync(
+									file,
+									{
+										content,
+										source,
+										outputPath,
+										compilation,
+										targetPath
+									},
+									callback
+								);
+							});
+						};
+
+						/**
+						 * Updates with replacement source.
+						 * @param {number} size size
+						 */
+						const updateWithReplacementSource = (size) => {
+							updateFileWithReplacementSource(
+								file,
+								/** @type {CacheEntry} */ (cacheEntry),
+								size
+							);
+							/** @type {SimilarEntry} */
+							(similarEntry).size = size;
+							if (
+								/** @type {SimilarEntry} */ (similarEntry).waiting !== undefined
+							) {
+								for (const { file, cacheEntry } of /** @type {SimilarEntry} */ (
+									similarEntry
+								).waiting) {
+									updateFileWithReplacementSource(file, cacheEntry, size);
+								}
+							}
+						};
+
+						/**
+						 * Updates file with replacement source.
+						 * @param {string} file file
+						 * @param {CacheEntry} cacheEntry cache entry
+						 * @param {number} size size
+						 */
+						const updateFileWithReplacementSource = (
+							file,
+							cacheEntry,
+							size
+						) => {
+							// Create a replacement resource which only allows to ask for size
+							// This allows to GC all memory allocated by the Source
+							// (expect when the Source is stored in any other cache)
+							if (!cacheEntry.sizeOnlySource) {
+								cacheEntry.sizeOnlySource = new SizeOnlySource(size);
+							}
+							compilation.updateAsset(file, cacheEntry.sizeOnlySource, {
+								size
+							});
+						};
+
+						/**
+						 * Process existing file.
+						 * @param {IStats} stats stats
+						 * @returns {void}
+						 */
+						const processExistingFile = (stats) => {
+							// skip emitting if it's already there and an immutable file
+							if (immutable) {
+								updateWithReplacementSource(/** @type {number} */ (stats.size));
+								return alreadyWritten();
+							}
+
+							const content = getContent();
+
+							updateWithReplacementSource(content.length);
+
+							// if it exists and content on disk matches content
+							// skip writing the same content again
+							// (to keep mtime and don't trigger watchers)
+							// for a fast negative match file size is compared first
+							if (content.length === stats.size) {
+								compilation.comparedForEmitAssets.add(file);
+								return /** @type {OutputFileSystem} */ (
+									this.outputFileSystem
+								).readFile(targetPath, (err, existingContent) => {
+									if (
+										err ||
+										!content.equals(/** @type {Buffer} */ (existingContent))
+									) {
+										return doWrite(content);
+									}
+									return alreadyWritten();
+								});
+							}
+
+							return doWrite(content);
+						};
+
+						const processMissingFile = () => {
+							const content = getContent();
+
+							updateWithReplacementSource(content.length);
+
+							return doWrite(content);
+						};
+
+						// if the target file has already been written
+						if (targetFileGeneration !== undefined) {
+							// check if the Source has been written to this target file
+							const writtenGeneration = /** @type {CacheEntry} */ (
+								cacheEntry
+							).writtenTo.get(targetPath);
+							if (writtenGeneration === targetFileGeneration) {
+								// if yes, we may skip writing the file
+								// if it's already there
+								// (we assume one doesn't modify files while the Compiler is running, other then removing them)
+
+								if (this._assetEmittingPreviousFiles.has(targetPath)) {
+									const sizeOnlySource = /** @type {SizeOnlySource} */ (
+										/** @type {CacheEntry} */ (cacheEntry).sizeOnlySource
+									);
+
+									// We assume that assets from the last compilation say intact on disk (they are not removed)
+									compilation.updateAsset(file, sizeOnlySource, {
+										size: sizeOnlySource.size()
+									});
+
+									return callback();
+								}
+								// Settings immutable will make it accept file content without comparing when file exist
+								immutable = true;
+							} else if (!immutable) {
+								if (checkSimilarFile()) return;
+								// We wrote to this file before which has very likely a different content
+								// skip comparing and assume content is different for performance
+								// This case happens often during watch mode.
+								return processMissingFile();
+							}
+						}
+
+						if (checkSimilarFile()) return;
+						if (this.options.output.compareBeforeEmit) {
+							/** @type {OutputFileSystem} */
+							(this.outputFileSystem).stat(targetPath, (err, stats) => {
+								const exists = !err && /** @type {IStats} */ (stats).isFile();
+
+								if (exists) {
+									processExistingFile(/** @type {IStats} */ (stats));
+								} else {
+									processMissingFile();
+								}
+							});
+						} else {
+							processMissingFile();
+						}
+					};
+
+					if (/\/|\\/.test(targetFile)) {
+						const fs = /** @type {OutputFileSystem} */ (this.outputFileSystem);
+						const dir = dirname(fs, join(fs, outputPath, targetFile));
+						mkdirp(fs, dir, writeOut);
+					} else {
+						writeOut();
+					}
+				},
+				(err) => {
+					// Clear map to free up memory
+					caseInsensitiveMap.clear();
+					if (err) {
+						this._assetEmittingPreviousFiles.clear();
+						return callback(err);
+					}
+
+					this._assetEmittingPreviousFiles = allTargetPaths;
+
+					this.hooks.afterEmit.callAsync(compilation, (err) => {
+						if (err) return callback(err);
+
+						return callback(null);
+					});
+				}
+			);
+		};
+
+		this.hooks.emit.callAsync(compilation, (err) => {
+			if (err) return callback(err);
+			outputPath = compilation.getPath(this.outputPath, {});
+			mkdirp(
+				/** @type {OutputFileSystem} */ (this.outputFileSystem),
+				outputPath,
+				emitFiles
+			);
+		});
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	emitRecords(callback) {
+		if (this.hooks.emitRecords.isUsed()) {
+			if (this.recordsOutputPath) {
+				asyncLib.parallel(
+					[
+						(cb) => this.hooks.emitRecords.callAsync(cb),
+						this._emitRecords.bind(this)
+					],
+					(err) => callback(/** @type {Error | null} */ (err))
+				);
+			} else {
+				this.hooks.emitRecords.callAsync(callback);
+			}
+		} else if (this.recordsOutputPath) {
+			this._emitRecords(callback);
+		} else {
+			callback(null);
+		}
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	_emitRecords(callback) {
+		const writeFile = () => {
+			/** @type {OutputFileSystem} */
+			(this.outputFileSystem).writeFile(
+				/** @type {string} */ (this.recordsOutputPath),
+				JSON.stringify(
+					this.records,
+					(n, value) => {
+						if (
+							typeof value === "object" &&
+							value !== null &&
+							!Array.isArray(value)
+						) {
+							const keys = Object.keys(value);
+							if (!isSorted(keys)) {
+								return sortObject(value, keys);
+							}
+						}
+						return value;
+					},
+					2
+				),
+				callback
+			);
+		};
+
+		const recordsOutputPathDirectory = dirname(
+			/** @type {OutputFileSystem} */
+			(this.outputFileSystem),
+			/** @type {string} */
+			(this.recordsOutputPath)
+		);
+		if (!recordsOutputPathDirectory) {
+			return writeFile();
+		}
+		mkdirp(
+			/** @type {OutputFileSystem} */ (this.outputFileSystem),
+			recordsOutputPathDirectory,
+			(err) => {
+				if (err) return callback(err);
+				writeFile();
+			}
+		);
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	readRecords(callback) {
+		if (this.hooks.readRecords.isUsed()) {
+			if (this.recordsInputPath) {
+				asyncLib.parallel(
+					[
+						(cb) => this.hooks.readRecords.callAsync(cb),
+						this._readRecords.bind(this)
+					],
+					(err) => callback(/** @type {Error | null} */ (err))
+				);
+			} else {
+				this.records = {};
+				this.hooks.readRecords.callAsync(callback);
+			}
+		} else if (this.recordsInputPath) {
+			this._readRecords(callback);
+		} else {
+			this.records = {};
+			callback(null);
+		}
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	_readRecords(callback) {
+		if (!this.recordsInputPath) {
+			this.records = {};
+			return callback(null);
+		}
+		/** @type {InputFileSystem} */
+		(this.inputFileSystem).stat(this.recordsInputPath, (err) => {
+			// It doesn't exist
+			// We can ignore this.
+			if (err) return callback(null);
+
+			/** @type {InputFileSystem} */
+			(this.inputFileSystem).readFile(
+				/** @type {string} */
+				(this.recordsInputPath),
+				(err, content) => {
+					if (err) return callback(err);
+
+					try {
+						this.records =
+							/** @type {Records} */
+							(parseJson(/** @type {Buffer} */ (content).toString("utf8")));
+					} catch (parseErr) {
+						return callback(
+							new Error(
+								`Cannot parse records: ${/** @type {Error} */ (parseErr).message}`
+							)
+						);
+					}
+
+					return callback(null);
+				}
+			);
+		});
+	}
+
+	/**
+	 * Creates a child compiler.
+	 * @param {Compilation} compilation the compilation
+	 * @param {string} compilerName the compiler's name
+	 * @param {number} compilerIndex the compiler's index
+	 * @param {Partial<OutputOptions>=} outputOptions the output options
+	 * @param {Plugins=} plugins the plugins to apply
+	 * @returns {Compiler} a child compiler
+	 */
+	createChildCompiler(
+		compilation,
+		compilerName,
+		compilerIndex,
+		outputOptions,
+		plugins
+	) {
+		const childCompiler = new Compiler(this.context, {
+			...this.options,
+			output: {
+				...this.options.output,
+				...outputOptions
+			}
+		});
+		childCompiler.name = compilerName;
+		childCompiler.outputPath = this.outputPath;
+		childCompiler.inputFileSystem = this.inputFileSystem;
+		childCompiler.outputFileSystem = null;
+		childCompiler.resolverFactory = this.resolverFactory;
+		childCompiler.modifiedFiles = this.modifiedFiles;
+		childCompiler.removedFiles = this.removedFiles;
+		childCompiler.fileTimestamps = this.fileTimestamps;
+		childCompiler.contextTimestamps = this.contextTimestamps;
+		childCompiler.fsStartTime = this.fsStartTime;
+		childCompiler.cache = this.cache;
+		childCompiler.compilerPath = `${this.compilerPath}${compilerName}|${compilerIndex}|`;
+		childCompiler._backCompat = this._backCompat;
+
+		const relativeCompilerName = makePathsRelative(
+			this.context,
+			compilerName,
+			this.root
+		);
+		if (!this.records[relativeCompilerName]) {
+			this.records[relativeCompilerName] = [];
+		}
+		if (this.records[relativeCompilerName][compilerIndex]) {
+			childCompiler.records =
+				/** @type {Records} */
+				(this.records[relativeCompilerName][compilerIndex]);
+		} else {
+			this.records[relativeCompilerName].push((childCompiler.records = {}));
+		}
+
+		childCompiler.parentCompilation = compilation;
+		childCompiler.root = this.root;
+		if (Array.isArray(plugins)) {
+			for (const plugin of plugins) {
+				if (typeof plugin === "function") {
+					/** @type {WebpackPluginFunction} */
+					(plugin).call(childCompiler, childCompiler);
+				} else if (plugin) {
+					plugin.apply(childCompiler);
+				}
+			}
+		}
+		for (const name in this.hooks) {
+			if (
+				![
+					"make",
+					"compile",
+					"emit",
+					"afterEmit",
+					"invalid",
+					"done",
+					"thisCompilation"
+				].includes(name) &&
+				childCompiler.hooks[/** @type {keyof Compiler["hooks"]} */ (name)]
+			) {
+				childCompiler.hooks[
+					/** @type {keyof Compiler["hooks"]} */
+					(name)
+				].taps = [
+					...this.hooks[
+						/** @type {keyof Compiler["hooks"]} */
+						(name)
+					].taps
+				];
+			}
+		}
+
+		compilation.hooks.childCompiler.call(
+			childCompiler,
+			compilerName,
+			compilerIndex
+		);
+
+		return childCompiler;
+	}
+
+	isChild() {
+		return Boolean(this.parentCompilation);
+	}
+
+	/**
+	 * Creates a compilation.
+	 * @param {CompilationParams} params the compilation parameters
+	 * @returns {Compilation} compilation
+	 */
+	createCompilation(params) {
+		this._cleanupLastCompilation();
+		return (this._lastCompilation = new Compilation(this, params));
+	}
+
+	/**
+	 * Returns the created compilation.
+	 * @param {CompilationParams} params the compilation parameters
+	 * @returns {Compilation} the created compilation
+	 */
+	newCompilation(params) {
+		const compilation = this.createCompilation(params);
+		compilation.name = this.name;
+		compilation.records = this.records;
+		this.hooks.thisCompilation.call(compilation, params);
+		this.hooks.compilation.call(compilation, params);
+		return compilation;
+	}
+
+	createNormalModuleFactory() {
+		this._cleanupLastNormalModuleFactory();
+		const normalModuleFactory = new NormalModuleFactory({
+			context: this.options.context,
+			fs: /** @type {InputFileSystem} */ (this.inputFileSystem),
+			resolverFactory: this.resolverFactory,
+			options: this.options.module,
+			associatedObjectForCache: this.root
+		});
+		this._lastNormalModuleFactory = normalModuleFactory;
+		this.hooks.normalModuleFactory.call(normalModuleFactory);
+		return normalModuleFactory;
+	}
+
+	createContextModuleFactory() {
+		const contextModuleFactory = new ContextModuleFactory(this.resolverFactory);
+		this.hooks.contextModuleFactory.call(contextModuleFactory);
+		return contextModuleFactory;
+	}
+
+	newCompilationParams() {
+		const params = {
+			normalModuleFactory: this.createNormalModuleFactory(),
+			contextModuleFactory: this.createContextModuleFactory()
+		};
+		return params;
+	}
+
+	/**
+	 * Processes the provided compilation.
+	 * @param {Callback<Compilation>} callback signals when the compilation finishes
+	 * @returns {void}
+	 */
+	compile(callback) {
+		const params = this.newCompilationParams();
+		this.hooks.beforeCompile.callAsync(params, (err) => {
+			if (err) return callback(err);
+
+			this.hooks.compile.call(params);
+
+			const compilation = this.newCompilation(params);
+
+			const logger = compilation.getLogger("webpack.Compiler");
+
+			logger.time("make hook");
+			this.hooks.make.callAsync(compilation, (err) => {
+				logger.timeEnd("make hook");
+				if (err) return callback(err);
+
+				logger.time("finish make hook");
+				this.hooks.finishMake.callAsync(compilation, (err) => {
+					logger.timeEnd("finish make hook");
+					if (err) return callback(err);
+
+					process.nextTick(() => {
+						logger.time("finish compilation");
+						compilation.finish((err) => {
+							logger.timeEnd("finish compilation");
+							if (err) return callback(err);
+
+							logger.time("seal compilation");
+							compilation.seal((err) => {
+								logger.timeEnd("seal compilation");
+								if (err) return callback(err);
+
+								logger.time("afterCompile hook");
+								this.hooks.afterCompile.callAsync(compilation, (err) => {
+									logger.timeEnd("afterCompile hook");
+									if (err) return callback(err);
+
+									return callback(null, compilation);
+								});
+							});
+						});
+					});
+				});
+			});
+		});
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the compiler closes
+	 * @returns {void}
+	 */
+	close(callback) {
+		if (this.watching) {
+			// When there is still an active watching, close this first
+			this.watching.close((_err) => {
+				this.close(callback);
+			});
+			return;
+		}
+		this.hooks.shutdown.callAsync((err) => {
+			if (err) return callback(err);
+			// Get rid of reference to last compilation to avoid leaking memory
+			// We can't run this._cleanupLastCompilation() as the Stats to this compilation
+			// might be still in use. We try to get rid of the reference to the cache instead.
+			this._lastCompilation = undefined;
+			this._lastNormalModuleFactory = undefined;
+			this.cache.shutdown(callback);
+		});
+	}
+
+	/**
+	 * Schema validation function with optional pre-compiled check
+	 * @template {EXPECTED_OBJECT | EXPECTED_OBJECT[]} [T=EXPECTED_OBJECT]
+	 * @param {Schema | (() => Schema)} schema schema
+	 * @param {T} value value
+	 * @param {ValidationErrorConfiguration=} options options
+	 * @param {((value: T) => boolean)=} check options
+	 */
+	validate(schema, value, options, check) {
+		// Avoid validation at all when disabled
+		if (this.options.validate === false) {
+			return;
+		}
+
+		/**
+		 * Returns schema.
+		 * @returns {Schema} schema
+		 */
+		const getSchema = () => {
+			if (typeof schema === "function") {
+				return schema();
+			}
+
+			return schema;
+		};
+
+		// // If we have precompiled schema let's use it
+		if (check) {
+			if (!check(value)) {
+				getValidate()(getSchema(), value, options);
+				require("util").deprecate(
+					() => {},
+					"webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.",
+					"DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID"
+				)();
+			}
+			return;
+		}
+
+		// Otherwise let's standard validation
+		getValidate()(getSchema(), value, options);
+	}
+}
+
+module.exports = Compiler;
Index: frontend/node_modules/webpack/lib/ConcatenationScope.js
===================================================================
--- frontend/node_modules/webpack/lib/ConcatenationScope.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ConcatenationScope.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,204 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	DEFAULT_EXPORT,
+	NAMESPACE_OBJECT_EXPORT
+} = require("./util/concatenate");
+
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./optimize/ConcatenatedModule").ConcatenatedModuleInfo} ConcatenatedModuleInfo */
+/** @typedef {import("./optimize/ConcatenatedModule").ModuleInfo} ModuleInfo */
+/** @typedef {import("./optimize/ConcatenatedModule").ExportName} Ids */
+
+const MODULE_REFERENCE_REGEXP =
+	/^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_directImport)?(_deferredImport)?(?:_asiSafe(\d))?__$/;
+
+/**
+ * Encodes how a concatenated module reference should be interpreted when it is
+ * later reconstructed from its placeholder identifier.
+ * @typedef {object} ModuleReferenceOptions
+ * @property {Ids} ids the properties or exports selected from the referenced module
+ * @property {boolean} call true, when this referenced export is called
+ * @property {boolean} directImport true, when this referenced export is directly imported (not via property access)
+ * @property {boolean} deferredImport true, when this referenced export is deferred
+ * @property {boolean | undefined} asiSafe if the position is ASI safe or unknown
+ */
+
+/**
+ * Tracks the symbols and cross-module references needed while rendering a
+ * concatenated module.
+ */
+class ConcatenationScope {
+	/**
+	 * Creates the mutable scope object used while rendering a concatenated
+	 * module and its cross-module references.
+	 * @param {ModuleInfo[] | Map<Module, ModuleInfo>} modulesMap all module info by module
+	 * @param {ConcatenatedModuleInfo} currentModule the current module info
+	 * @param {Set<string>} usedNames all used names
+	 */
+	constructor(modulesMap, currentModule, usedNames) {
+		this._currentModule = currentModule;
+		if (Array.isArray(modulesMap)) {
+			/** @type {Map<Module, ConcatenatedModuleInfo>} */
+			const map = new Map();
+			for (const info of modulesMap) {
+				map.set(info.module, /** @type {ConcatenatedModuleInfo} */ (info));
+			}
+			modulesMap = map;
+		}
+		this.usedNames = usedNames;
+		this._modulesMap = modulesMap;
+	}
+
+	/**
+	 * Checks whether a module participates in the current concatenation scope.
+	 * @param {Module} module the referenced module
+	 * @returns {boolean} true, when it's in the scope
+	 */
+	isModuleInScope(module) {
+		return this._modulesMap.has(module);
+	}
+
+	/**
+	 * Records the symbol that should be used when the current module exports a
+	 * named binding.
+	 * @param {string} exportName name of the export
+	 * @param {string} symbol identifier of the export in source code
+	 */
+	registerExport(exportName, symbol) {
+		if (!this._currentModule.exportMap) {
+			this._currentModule.exportMap = new Map();
+		}
+		if (!this._currentModule.exportMap.has(exportName)) {
+			this._currentModule.exportMap.set(exportName, symbol);
+		}
+	}
+
+	/**
+	 * Records a raw expression that can be used to reference an export without
+	 * going through the normal symbol map.
+	 * @param {string} exportName name of the export
+	 * @param {string} expression expression to be used
+	 */
+	registerRawExport(exportName, expression) {
+		if (!this._currentModule.rawExportMap) {
+			this._currentModule.rawExportMap = new Map();
+		}
+		if (!this._currentModule.rawExportMap.has(exportName)) {
+			this._currentModule.rawExportMap.set(exportName, expression);
+		}
+	}
+
+	/**
+	 * Returns the raw expression registered for an export, if one exists.
+	 * @param {string} exportName name of the export
+	 * @returns {string | undefined} the expression of the export
+	 */
+	getRawExport(exportName) {
+		if (!this._currentModule.rawExportMap) {
+			return undefined;
+		}
+		return this._currentModule.rawExportMap.get(exportName);
+	}
+
+	/**
+	 * Replaces the raw expression for an export only when that export already
+	 * has an entry in the raw export map.
+	 * @param {string} exportName name of the export
+	 * @param {string} expression expression to be used
+	 */
+	setRawExportMap(exportName, expression) {
+		if (!this._currentModule.rawExportMap) {
+			this._currentModule.rawExportMap = new Map();
+		}
+		if (this._currentModule.rawExportMap.has(exportName)) {
+			this._currentModule.rawExportMap.set(exportName, expression);
+		}
+	}
+
+	/**
+	 * Records the symbol that should be used for the synthetic namespace export.
+	 * @param {string} symbol identifier of the export in source code
+	 */
+	registerNamespaceExport(symbol) {
+		this._currentModule.namespaceExportSymbol = symbol;
+	}
+
+	/**
+	 * Encodes a reference to another concatenated module as a placeholder
+	 * identifier that can be parsed later during code generation.
+	 * @param {Module} module the referenced module
+	 * @param {Partial<ModuleReferenceOptions>} options options
+	 * @returns {string} the reference as identifier
+	 */
+	createModuleReference(
+		module,
+		{
+			ids = undefined,
+			call = false,
+			directImport = false,
+			deferredImport = false,
+			asiSafe = false
+		}
+	) {
+		const info = /** @type {ModuleInfo} */ (this._modulesMap.get(module));
+		const callFlag = call ? "_call" : "";
+		const directImportFlag = directImport ? "_directImport" : "";
+		const deferredImportFlag = deferredImport ? "_deferredImport" : "";
+		const asiSafeFlag = asiSafe
+			? "_asiSafe1"
+			: asiSafe === false
+				? "_asiSafe0"
+				: "";
+		const exportData = ids
+			? Buffer.from(JSON.stringify(ids), "utf8").toString("hex")
+			: "ns";
+		// a "._" is appended to allow "delete ...", which would cause a SyntaxError in strict mode
+		return `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportData}${callFlag}${directImportFlag}${deferredImportFlag}${asiSafeFlag}__._`;
+	}
+
+	/**
+	 * Checks whether an identifier is one of webpack's encoded concatenation
+	 * module references.
+	 * @param {string} name the identifier
+	 * @returns {boolean} true, when it's an module reference
+	 */
+	static isModuleReference(name) {
+		return MODULE_REFERENCE_REGEXP.test(name);
+	}
+
+	/**
+	 * Parses an encoded module reference back into its module index and
+	 * reference flags.
+	 * @param {string} name the identifier
+	 * @returns {ModuleReferenceOptions & { index: number } | null} parsed options and index
+	 */
+	static matchModuleReference(name) {
+		const match = MODULE_REFERENCE_REGEXP.exec(name);
+		if (!match) return null;
+		const index = Number(match[1]);
+		const asiSafe = match[6];
+		return {
+			index,
+			ids:
+				match[2] === "ns"
+					? []
+					: JSON.parse(Buffer.from(match[2], "hex").toString("utf8")),
+			call: Boolean(match[3]),
+			directImport: Boolean(match[4]),
+			deferredImport: Boolean(match[5]),
+			asiSafe: asiSafe ? asiSafe === "1" : undefined
+		};
+	}
+}
+
+ConcatenationScope.DEFAULT_EXPORT = DEFAULT_EXPORT;
+ConcatenationScope.NAMESPACE_OBJECT_EXPORT = NAMESPACE_OBJECT_EXPORT;
+
+module.exports = ConcatenationScope;
Index: frontend/node_modules/webpack/lib/ConditionalInitFragment.js
===================================================================
--- frontend/node_modules/webpack/lib/ConditionalInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ConditionalInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,126 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, PrefixSource } = require("webpack-sources");
+const InitFragment = require("./InitFragment");
+const Template = require("./Template");
+const { mergeRuntime } = require("./util/runtime");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./Generator").GenerateContext} GenerateContext */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Returns wrapped source.
+ * @param {string} condition condition
+ * @param {string | Source} source source
+ * @returns {string | Source} wrapped source
+ */
+const wrapInCondition = (condition, source) => {
+	if (typeof source === "string") {
+		return Template.asString([
+			`if (${condition}) {`,
+			Template.indent(source),
+			"}",
+			""
+		]);
+	}
+	return new ConcatSource(
+		`if (${condition}) {\n`,
+		new PrefixSource("\t", source),
+		"}\n"
+	);
+};
+
+/**
+ * Represents ConditionalInitFragment.
+ * @extends {InitFragment<GenerateContext>}
+ */
+class ConditionalInitFragment extends InitFragment {
+	/**
+	 * Creates an instance of ConditionalInitFragment.
+	 * @param {string | Source | undefined} content the source code that will be included as initialization code
+	 * @param {number} stage category of initialization code (contribute to order)
+	 * @param {number} position position in the category (contribute to order)
+	 * @param {string | undefined} key unique key to avoid emitting the same initialization code twice
+	 * @param {RuntimeSpec | boolean} runtimeCondition in which runtime this fragment should be executed
+	 * @param {string | Source=} endContent the source code that will be included at the end of the module
+	 */
+	constructor(
+		content,
+		stage,
+		position,
+		key,
+		runtimeCondition = true,
+		endContent = undefined
+	) {
+		super(content, stage, position, key, endContent);
+		this.runtimeCondition = runtimeCondition;
+	}
+
+	/**
+	 * Returns the source code that will be included as initialization code.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included as initialization code
+	 */
+	getContent(context) {
+		if (this.runtimeCondition === false || !this.content) return "";
+		if (this.runtimeCondition === true) return this.content;
+		const expr = context.runtimeTemplate.runtimeConditionExpression({
+			chunkGraph: context.chunkGraph,
+			runtimeRequirements: context.runtimeRequirements,
+			runtime: context.runtime,
+			runtimeCondition: this.runtimeCondition
+		});
+		if (expr === "true") return this.content;
+		return wrapInCondition(expr, this.content);
+	}
+
+	/**
+	 * Returns the source code that will be included at the end of the module.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included at the end of the module
+	 */
+	getEndContent(context) {
+		if (this.runtimeCondition === false || !this.endContent) return "";
+		if (this.runtimeCondition === true) return this.endContent;
+		const expr = context.runtimeTemplate.runtimeConditionExpression({
+			chunkGraph: context.chunkGraph,
+			runtimeRequirements: context.runtimeRequirements,
+			runtime: context.runtime,
+			runtimeCondition: this.runtimeCondition
+		});
+		if (expr === "true") return this.endContent;
+		return wrapInCondition(expr, this.endContent);
+	}
+
+	/**
+	 * Returns merged fragment.
+	 * @param {ConditionalInitFragment} other fragment to merge with
+	 * @returns {ConditionalInitFragment} merged fragment
+	 */
+	merge(other) {
+		if (this.runtimeCondition === true) return this;
+		if (other.runtimeCondition === true) return other;
+		if (this.runtimeCondition === false) return other;
+		if (other.runtimeCondition === false) return this;
+		const runtimeCondition = mergeRuntime(
+			this.runtimeCondition,
+			other.runtimeCondition
+		);
+		return new ConditionalInitFragment(
+			this.content,
+			this.stage,
+			this.position,
+			this.key,
+			runtimeCondition,
+			this.endContent
+		);
+	}
+}
+
+module.exports = ConditionalInitFragment;
Index: frontend/node_modules/webpack/lib/ConstPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ConstPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ConstPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,570 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const CachedConstDependency = require("./dependencies/CachedConstDependency");
+const ConstDependency = require("./dependencies/ConstDependency");
+const { evaluateToString } = require("./javascript/JavascriptParserHelpers");
+const { parseResource } = require("./util/identifier");
+
+/** @typedef {import("estree").AssignmentProperty} AssignmentProperty */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("estree").Pattern} Pattern */
+/** @typedef {import("estree").SourceLocation} SourceLocation */
+/** @typedef {import("estree").Statement} Statement */
+/** @typedef {import("estree").Super} Super */
+/** @typedef {import("estree").VariableDeclaration} VariableDeclaration */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+/** @typedef {Set<string>} Declarations */
+
+/**
+ * Collect declaration.
+ * @param {Declarations} declarations set of declarations
+ * @param {Identifier | Pattern} pattern pattern to collect declarations from
+ */
+const collectDeclaration = (declarations, pattern) => {
+	const stack = [pattern];
+	while (stack.length > 0) {
+		const node = /** @type {Pattern} */ (stack.pop());
+		switch (node.type) {
+			case "Identifier":
+				declarations.add(node.name);
+				break;
+			case "ArrayPattern":
+				for (const element of node.elements) {
+					if (element) {
+						stack.push(element);
+					}
+				}
+				break;
+			case "AssignmentPattern":
+				stack.push(node.left);
+				break;
+			case "ObjectPattern":
+				for (const property of node.properties) {
+					stack.push(/** @type {AssignmentProperty} */ (property).value);
+				}
+				break;
+			case "RestElement":
+				stack.push(node.argument);
+				break;
+		}
+	}
+};
+
+/**
+ * Gets hoisted declarations.
+ * @param {Statement} branch branch to get hoisted declarations from
+ * @param {boolean} includeFunctionDeclarations whether to include function declarations
+ * @returns {string[]} hoisted declarations
+ */
+const getHoistedDeclarations = (branch, includeFunctionDeclarations) => {
+	/** @type {Declarations} */
+	const declarations = new Set();
+	/** @type {(Statement | null | undefined)[]} */
+	const stack = [branch];
+	while (stack.length > 0) {
+		const node = stack.pop();
+		// Some node could be `null` or `undefined`.
+		if (!node) continue;
+		switch (node.type) {
+			// Walk through control statements to look for hoisted declarations.
+			// Some branches are skipped since they do not allow declarations.
+			case "BlockStatement":
+				for (const stmt of node.body) {
+					stack.push(stmt);
+				}
+				break;
+			case "IfStatement":
+				stack.push(node.consequent);
+				stack.push(node.alternate);
+				break;
+			case "ForStatement":
+				stack.push(/** @type {VariableDeclaration} */ (node.init));
+				stack.push(node.body);
+				break;
+			case "ForInStatement":
+			case "ForOfStatement":
+				stack.push(/** @type {VariableDeclaration} */ (node.left));
+				stack.push(node.body);
+				break;
+			case "DoWhileStatement":
+			case "WhileStatement":
+			case "LabeledStatement":
+				stack.push(node.body);
+				break;
+			case "SwitchStatement":
+				for (const cs of node.cases) {
+					for (const consequent of cs.consequent) {
+						stack.push(consequent);
+					}
+				}
+				break;
+			case "TryStatement":
+				stack.push(node.block);
+				if (node.handler) {
+					stack.push(node.handler.body);
+				}
+				stack.push(node.finalizer);
+				break;
+			case "FunctionDeclaration":
+				if (includeFunctionDeclarations) {
+					collectDeclaration(declarations, /** @type {Identifier} */ (node.id));
+				}
+				break;
+			case "VariableDeclaration":
+				if (node.kind === "var") {
+					for (const decl of node.declarations) {
+						collectDeclaration(declarations, decl.id);
+					}
+				}
+				break;
+		}
+	}
+	return [...declarations];
+};
+
+const PLUGIN_NAME = "ConstPlugin";
+
+class ConstPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const cachedParseResource = parseResource.bindCache(compiler.root);
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					ConstDependency,
+					new ConstDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					CachedConstDependency,
+					new CachedConstDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 */
+				const handler = (parser) => {
+					parser.hooks.terminate.tap(PLUGIN_NAME, (_statement) => true);
+					parser.hooks.statementIf.tap(PLUGIN_NAME, (statement) => {
+						if (parser.scope.isAsmJs) return;
+						const param = parser.evaluateExpression(statement.test);
+						const bool = param.asBool();
+						if (typeof bool === "boolean") {
+							if (!param.couldHaveSideEffects()) {
+								const dep = new ConstDependency(
+									`${bool}`,
+									/** @type {Range} */ (param.range)
+								);
+								dep.loc = /** @type {SourceLocation} */ (statement.loc);
+								parser.state.module.addPresentationalDependency(dep);
+							} else {
+								parser.walkExpression(statement.test);
+							}
+							const branchToRemove = bool
+								? statement.alternate
+								: statement.consequent;
+							if (branchToRemove) {
+								this.eliminateUnusedStatement(parser, branchToRemove, true);
+							}
+							return bool;
+						}
+					});
+					parser.hooks.unusedStatement.tap(PLUGIN_NAME, (statement) => {
+						if (
+							parser.scope.isAsmJs ||
+							// Check top level scope here again
+							parser.scope.topLevelScope === true
+						) {
+							return;
+						}
+						this.eliminateUnusedStatement(parser, statement, false);
+						return true;
+					});
+					parser.hooks.expressionConditionalOperator.tap(
+						PLUGIN_NAME,
+						(expression) => {
+							if (parser.scope.isAsmJs) return;
+							const param = parser.evaluateExpression(expression.test);
+							const bool = param.asBool();
+							if (typeof bool === "boolean") {
+								if (!param.couldHaveSideEffects()) {
+									const dep = new ConstDependency(
+										` ${bool}`,
+										/** @type {Range} */ (param.range)
+									);
+									dep.loc = /** @type {SourceLocation} */ (expression.loc);
+									parser.state.module.addPresentationalDependency(dep);
+								} else {
+									parser.walkExpression(expression.test);
+								}
+								// Expressions do not hoist.
+								// It is safe to remove the dead branch.
+								//
+								// Given the following code:
+								//
+								//   false ? someExpression() : otherExpression();
+								//
+								// the generated code is:
+								//
+								//   false ? 0 : otherExpression();
+								//
+								const branchToRemove = bool
+									? expression.alternate
+									: expression.consequent;
+								const dep = new ConstDependency(
+									"0",
+									/** @type {Range} */ (branchToRemove.range)
+								);
+								dep.loc = /** @type {SourceLocation} */ (branchToRemove.loc);
+								parser.state.module.addPresentationalDependency(dep);
+								return bool;
+							}
+						}
+					);
+					parser.hooks.expressionLogicalOperator.tap(
+						PLUGIN_NAME,
+						(expression) => {
+							if (parser.scope.isAsmJs) return;
+							if (
+								expression.operator === "&&" ||
+								expression.operator === "||"
+							) {
+								const param = parser.evaluateExpression(expression.left);
+								const bool = param.asBool();
+								if (typeof bool === "boolean") {
+									// Expressions do not hoist.
+									// It is safe to remove the dead branch.
+									//
+									// ------------------------------------------
+									//
+									// Given the following code:
+									//
+									//   falsyExpression() && someExpression();
+									//
+									// the generated code is:
+									//
+									//   falsyExpression() && false;
+									//
+									// ------------------------------------------
+									//
+									// Given the following code:
+									//
+									//   truthyExpression() && someExpression();
+									//
+									// the generated code is:
+									//
+									//   true && someExpression();
+									//
+									// ------------------------------------------
+									//
+									// Given the following code:
+									//
+									//   truthyExpression() || someExpression();
+									//
+									// the generated code is:
+									//
+									//   truthyExpression() || false;
+									//
+									// ------------------------------------------
+									//
+									// Given the following code:
+									//
+									//   falsyExpression() || someExpression();
+									//
+									// the generated code is:
+									//
+									//   false && someExpression();
+									//
+									const keepRight =
+										(expression.operator === "&&" && bool) ||
+										(expression.operator === "||" && !bool);
+
+									if (
+										!param.couldHaveSideEffects() &&
+										(param.isBoolean() || keepRight)
+									) {
+										// for case like
+										//
+										//   return'development'===process.env.NODE_ENV&&'foo'
+										//
+										// we need a space before the bool to prevent result like
+										//
+										//   returnfalse&&'foo'
+										//
+										const dep = new ConstDependency(
+											` ${bool}`,
+											/** @type {Range} */ (param.range)
+										);
+										dep.loc = /** @type {SourceLocation} */ (expression.loc);
+										parser.state.module.addPresentationalDependency(dep);
+									} else {
+										parser.walkExpression(expression.left);
+									}
+									if (!keepRight) {
+										const dep = new ConstDependency(
+											"0",
+											/** @type {Range} */ (expression.right.range)
+										);
+										dep.loc = /** @type {SourceLocation} */ (expression.loc);
+										parser.state.module.addPresentationalDependency(dep);
+									}
+									return keepRight;
+								}
+							} else if (expression.operator === "??") {
+								const param = parser.evaluateExpression(expression.left);
+								const keepRight = param.asNullish();
+								if (typeof keepRight === "boolean") {
+									// ------------------------------------------
+									//
+									// Given the following code:
+									//
+									//   nonNullish ?? someExpression();
+									//
+									// the generated code is:
+									//
+									//   nonNullish ?? 0;
+									//
+									// ------------------------------------------
+									//
+									// Given the following code:
+									//
+									//   nullish ?? someExpression();
+									//
+									// the generated code is:
+									//
+									//   null ?? someExpression();
+									//
+									if (!param.couldHaveSideEffects() && keepRight) {
+										// cspell:word returnnull
+										// for case like
+										//
+										//   return('development'===process.env.NODE_ENV&&null)??'foo'
+										//
+										// we need a space before the bool to prevent result like
+										//
+										//   returnnull??'foo'
+										//
+										const dep = new ConstDependency(
+											" null",
+											/** @type {Range} */ (param.range)
+										);
+										dep.loc = /** @type {SourceLocation} */ (expression.loc);
+										parser.state.module.addPresentationalDependency(dep);
+									} else {
+										const dep = new ConstDependency(
+											"0",
+											/** @type {Range} */ (expression.right.range)
+										);
+										dep.loc = /** @type {SourceLocation} */ (expression.loc);
+										parser.state.module.addPresentationalDependency(dep);
+										parser.walkExpression(expression.left);
+									}
+
+									return keepRight;
+								}
+							}
+						}
+					);
+					parser.hooks.optionalChaining.tap(PLUGIN_NAME, (expr) => {
+						/** @type {Expression[]} */
+						const optionalExpressionsStack = [];
+						/** @type {Expression | Super} */
+						let next = expr.expression;
+
+						while (
+							next.type === "MemberExpression" ||
+							next.type === "CallExpression"
+						) {
+							if (next.type === "MemberExpression") {
+								if (next.optional) {
+									// SuperNode can not be optional
+									optionalExpressionsStack.push(
+										/** @type {Expression} */ (next.object)
+									);
+								}
+								next = next.object;
+							} else {
+								if (next.optional) {
+									// SuperNode can not be optional
+									optionalExpressionsStack.push(
+										/** @type {Expression} */ (next.callee)
+									);
+								}
+								next = next.callee;
+							}
+						}
+
+						while (optionalExpressionsStack.length) {
+							const expression = optionalExpressionsStack.pop();
+							const evaluated = parser.evaluateExpression(
+								/** @type {Expression} */ (expression)
+							);
+
+							if (evaluated.asNullish()) {
+								// ------------------------------------------
+								//
+								// Given the following code:
+								//
+								//   nullishMemberChain?.a.b();
+								//
+								// the generated code is:
+								//
+								//   undefined;
+								//
+								// ------------------------------------------
+								//
+								const dep = new ConstDependency(
+									" undefined",
+									/** @type {Range} */ (expr.range)
+								);
+								dep.loc = /** @type {SourceLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+								return true;
+							}
+						}
+					});
+					parser.hooks.evaluateIdentifier
+						.for("__resourceQuery")
+						.tap(PLUGIN_NAME, (expr) => {
+							if (parser.scope.isAsmJs) return;
+							if (!parser.state.module) return;
+							return evaluateToString(
+								cachedParseResource(parser.state.module.resource).query
+							)(expr);
+						});
+					parser.hooks.expression
+						.for("__resourceQuery")
+						.tap(PLUGIN_NAME, (expr) => {
+							if (parser.scope.isAsmJs) return;
+							if (!parser.state.module) return;
+							const dep = new CachedConstDependency(
+								JSON.stringify(
+									cachedParseResource(parser.state.module.resource).query
+								),
+								/** @type {Range} */ (expr.range),
+								"__resourceQuery"
+							);
+							dep.loc = /** @type {SourceLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+
+					parser.hooks.evaluateIdentifier
+						.for("__resourceFragment")
+						.tap(PLUGIN_NAME, (expr) => {
+							if (parser.scope.isAsmJs) return;
+							if (!parser.state.module) return;
+							return evaluateToString(
+								cachedParseResource(parser.state.module.resource).fragment
+							)(expr);
+						});
+					parser.hooks.expression
+						.for("__resourceFragment")
+						.tap(PLUGIN_NAME, (expr) => {
+							if (parser.scope.isAsmJs) return;
+							if (!parser.state.module) return;
+							const dep = new CachedConstDependency(
+								JSON.stringify(
+									cachedParseResource(parser.state.module.resource).fragment
+								),
+								/** @type {Range} */ (expr.range),
+								"__resourceFragment"
+							);
+							dep.loc = /** @type {SourceLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+				};
+
+				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);
+			}
+		);
+	}
+
+	/**
+	 * Eliminate an unused statement.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {Statement} statement the statement to remove
+	 * @param {boolean} alwaysInBlock whether to always generate curly brackets
+	 * @returns {void}
+	 */
+	eliminateUnusedStatement(parser, statement, alwaysInBlock) {
+		// Before removing the unused branch, the hoisted declarations
+		// must be collected.
+		//
+		// Given the following code:
+		//
+		//     if (true) f() else g()
+		//     if (false) {
+		//       function f() {}
+		//       const g = function g() {}
+		//       if (someTest) {
+		//         let a = 1
+		//         var x, {y, z} = obj
+		//       }
+		//     } else {
+		//       …
+		//     }
+		//
+		// the generated code is:
+		//
+		//     if (true) f() else {}
+		//     if (false) {
+		//       var f, x, y, z;   (in loose mode)
+		//       var x, y, z;      (in strict mode)
+		//     } else {
+		//       …
+		//     }
+		//
+		// NOTE: When code runs in strict mode, `var` declarations
+		// are hoisted but `function` declarations don't.
+		//
+		const declarations = parser.scope.isStrict
+			? getHoistedDeclarations(statement, false)
+			: getHoistedDeclarations(statement, true);
+
+		const inBlock = alwaysInBlock || statement.type === "BlockStatement";
+
+		let replacement = inBlock ? "{" : "";
+		replacement +=
+			declarations.length > 0 ? ` var ${declarations.join(", ")}; ` : "";
+		replacement += inBlock ? "}" : "";
+
+		const dep = new ConstDependency(
+			`// removed by dead control flow\n${replacement}`,
+			/** @type {Range} */ (statement.range)
+		);
+		dep.loc = /** @type {SourceLocation} */ (statement.loc);
+		parser.state.module.addPresentationalDependency(dep);
+	}
+}
+
+module.exports = ConstPlugin;
Index: frontend/node_modules/webpack/lib/ContextExclusionPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ContextExclusionPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ContextExclusionPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "ContextExclusionPlugin";
+
+class ContextExclusionPlugin {
+	/**
+	 * Creates an instance of ContextExclusionPlugin.
+	 * @param {RegExp} negativeMatcher Matcher regular expression
+	 */
+	constructor(negativeMatcher) {
+		this.negativeMatcher = negativeMatcher;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.contextModuleFactory.tap(PLUGIN_NAME, (cmf) => {
+			cmf.hooks.contextModuleFiles.tap(PLUGIN_NAME, (files) =>
+				files.filter((filePath) => !this.negativeMatcher.test(filePath))
+			);
+		});
+	}
+}
+
+module.exports = ContextExclusionPlugin;
Index: frontend/node_modules/webpack/lib/ContextModule.js
===================================================================
--- frontend/node_modules/webpack/lib/ContextModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ContextModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1423 @@
+/*
+	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 Module = require("./Module");
+const {
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("./ModuleSourceTypeConstants");
+const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const Template = require("./Template");
+const {
+	getOutgoingAsyncModules
+} = require("./async-modules/AsyncModuleHelpers");
+const { ImportPhase, ImportPhaseUtils } = require("./dependencies/ImportPhase");
+const { makeWebpackError } = require("./errors/HookWebpackError");
+const WebpackError = require("./errors/WebpackError");
+const {
+	compareLocations,
+	compareModulesById,
+	compareSelect,
+	concatComparators,
+	keepOriginalOrder
+} = require("./util/comparators");
+const {
+	contextify,
+	makePathsRelative,
+	parseResource
+} = require("./util/identifier");
+const makeSerializable = require("./util/makeSerializable");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Chunk").ChunkId} ChunkId */
+/** @typedef {import("./Chunk").ChunkName} ChunkName */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("./Generator").SourceTypes} SourceTypes */
+/** @typedef {import("./Module").BuildCallback} BuildCallback */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./Module").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("./Module").BuildMeta} BuildMeta */
+/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("./Module").LibIdent} LibIdent */
+/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./Module").Sources} Sources */
+/** @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 */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
+
+/** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */
+
+/**
+ * @typedef {object} ContextOptions
+ * @property {ContextMode} mode
+ * @property {boolean} recursive
+ * @property {RegExp | false | null} regExp
+ * @property {"strict" | boolean=} namespaceObject
+ * @property {string=} addon
+ * @property {ChunkName=} chunkName
+ * @property {RegExp | null=} include
+ * @property {RegExp | null=} exclude
+ * @property {RawChunkGroupOptions=} groupOptions
+ * @property {string=} typePrefix
+ * @property {string=} category
+ * @property {RawReferencedExports | null=} referencedExports exports referenced from modules (won't be mangled)
+ * @property {string | null=} layer
+ * @property {ImportAttributes=} attributes
+ * @property {ImportPhaseType=} phase
+ */
+
+/**
+ * @typedef {object} ContextModuleOptionsExtras
+ * @property {false | string | string[]} resource
+ * @property {string=} resourceQuery
+ * @property {string=} resourceFragment
+ * @property {ResolveOptions=} resolveOptions
+ */
+
+/** @typedef {ContextOptions & ContextModuleOptionsExtras} ContextModuleOptions */
+
+/**
+ * @callback ResolveDependenciesCallback
+ * @param {Error | null} err
+ * @param {ContextElementDependency[]=} dependencies
+ * @returns {void}
+ */
+
+/**
+ * @callback ResolveDependencies
+ * @param {InputFileSystem} fs
+ * @param {ContextModuleOptions} options
+ * @param {ResolveDependenciesCallback} callback
+ */
+
+/** @typedef {1 | 3 | 7 | 9} FakeMapType */
+
+/** @typedef {Record<ModuleId, FakeMapType>} FakeMap */
+/** @typedef {Record<string, ModuleId>} UserRequestMap */
+/** @typedef {Record<ModuleId, ModuleId[]>} UserRequestsMap */
+
+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 the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_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 = stripSlash
+			? regexString.source + regexString.flags
+			: `${regexString}`;
+		return str.replace(/!/g, "%21").replace(/\|/g, "%7C");
+	}
+
+	_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.options.attributes) {
+			identifier += `|importAttributes: ${JSON.stringify(this.options.attributes)}`;
+		}
+		if (this.options.phase) {
+			identifier += `|importPhase: ${this.options.phase}`;
+		}
+		if (this.layer) {
+			identifier += `|layer: ${this.layer}`;
+		}
+		return identifier;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this._identifier;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		/** @type {string} */
+		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;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		/** @type {string} */
+		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;
+	}
+
+	/**
+	 * Invalidates the cached state associated with this value.
+	 * @returns {void}
+	 */
+	invalidateBuild() {
+		this._forceBuild = true;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} 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);
+		});
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} 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();
+
+			const snapshotOptions = compilation.options.snapshot.contextModule;
+
+			compilation.fileSystemInfo.createSnapshot(
+				startTime,
+				null,
+				this.context
+					? [this.context]
+					: typeof this.options.resource === "string"
+						? [this.options.resource]
+						: /** @type {string[]} */ (this.options.resource),
+				null,
+				snapshotOptions,
+				(err, snapshot) => {
+					if (err) return callback(err);
+					/** @type {BuildInfo} */
+					(this.buildInfo).snapshot = snapshot;
+					callback();
+				}
+			);
+		});
+	}
+
+	/**
+	 * Adds the provided file dependencies to the module.
+	 * @param {FileSystemDependencies} fileDependencies set where file dependencies are added to
+	 * @param {FileSystemDependencies} contextDependencies set where context dependencies are added to
+	 * @param {FileSystemDependencies} missingDependencies set where missing dependencies are added to
+	 * @param {FileSystemDependencies} 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) {
+			// Do nothing
+		} else {
+			for (const res of this.options.resource) contextDependencies.add(res);
+		}
+	}
+
+	/**
+	 * @param {Dependency[]} dependencies all dependencies
+	 * @param {ChunkGraph} chunkGraph chunk graph
+	 * @returns {UserRequestMap} 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;
+				});
+		/** @type {UserRequestMap} */
+		const map = Object.create(null);
+		for (const dep of sortedDependencies) {
+			const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+			map[dep.userRequest] =
+				/** @type {ModuleId} */
+				(chunkGraph.getModuleId(module));
+		}
+		return map;
+	}
+
+	/**
+	 * @param {Dependency[]} dependencies all dependencies
+	 * @param {ChunkGraph} chunkGraph chunk graph
+	 * @returns {FakeMap | FakeMapType} 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);
+		/** @type {FakeMap} */
+		const fakeMap = Object.create(null);
+		for (const module of sortedModules) {
+			const exportsType = module.getExportsType(
+				moduleGraph,
+				this.options.namespaceObject === "strict"
+			);
+			const id = /** @type {ModuleId} */ (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 | FakeMapType} fakeMap fake map
+	 * @returns {string} fake map init statement
+	 */
+	getFakeMapInitStatement(fakeMap) {
+		return typeof fakeMap === "object"
+			? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};`
+			: "";
+	}
+
+	/**
+	 * @param {Dependency[]} dependencies all dependencies
+	 * @param {ChunkGraph} chunkGraph chunk graph
+	 * @returns {UserRequestsMap} map with user requests
+	 */
+	getModuleDeferredAsyncDepsMap(dependencies, chunkGraph) {
+		const moduleGraph = chunkGraph.moduleGraph;
+		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);
+		/** @type {UserRequestsMap} */
+		const map = Object.create(null);
+		for (const module of sortedModules) {
+			if (!(/** @type {BuildMeta} */ (module.buildMeta).async)) {
+				const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+				map[id] = Array.from(
+					getOutgoingAsyncModules(chunkGraph.moduleGraph, module),
+					(m) => chunkGraph.getModuleId(m)
+				).filter((id) => id !== null);
+			}
+		}
+		return map;
+	}
+
+	/**
+	 * @param {false | UserRequestsMap} asyncDepsMap fake map
+	 * @returns {string} async deps map init statement
+	 */
+	getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap) {
+		return typeof asyncDepsMap === "object"
+			? `var asyncDepsMap = ${JSON.stringify(asyncDepsMap, 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 | FakeMapType} fakeMap fake map
+	 * @param {boolean=} asyncModule is async module
+	 * @param {string=} asyncDeps async deps for deferred module
+	 * @param {string=} fakeMapDataExpression fake map data expression
+	 * @returns {string} module object source
+	 */
+	getReturnModuleObjectSource(
+		fakeMap,
+		asyncModule,
+		asyncDeps,
+		fakeMapDataExpression = "fakeMap[id]"
+	) {
+		const source =
+			typeof fakeMap === "number"
+				? this.getReturn(fakeMap, asyncModule)
+				: `${RuntimeGlobals.createFakeNamespaceObject}(id, ${fakeMapDataExpression}${asyncModule ? " | 16" : ""})`;
+		if (asyncDeps) {
+			if (!asyncModule) {
+				throw new Error("Must be async when module is deferred");
+			}
+			const type =
+				typeof fakeMap === "number" ? fakeMap : fakeMapDataExpression;
+			return `${asyncDeps} ? ${asyncDeps}.length ? ${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies}(${asyncDeps}).then(${RuntimeGlobals.makeDeferredNamespaceObject}.bind(${RuntimeGlobals.require}, id, ${type} ^ 1, true)) : ${RuntimeGlobals.makeDeferredNamespaceObject}(id, ${type} ^ 1 | 16) : ${source}`;
+		}
+		return source;
+	}
+
+	/**
+	 * @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);
+	return ${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;
+	}
+	return ${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 {ImportPhaseType} phase import phase
+	 * @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, phase, { chunkGraph, runtimeTemplate }) {
+		const map = this.getUserRequestMap(dependencies, chunkGraph);
+		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
+		const asyncDepsMap =
+			ImportPhaseUtils.isDefer(phase) &&
+			this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
+		const returnModuleObject = this.getReturnModuleObjectSource(
+			fakeMap,
+			true,
+			asyncDepsMap ? "asyncDepsMap[id]" : undefined
+		);
+
+		return `var map = ${JSON.stringify(map, null, "\t")};
+${this.getFakeMapInitStatement(fakeMap)}
+${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
+
+function webpackAsyncContext(req) {
+	return webpackAsyncContextResolve(req).then(${runtimeTemplate.basicFunction(
+		"id",
+		[
+			`if(!${RuntimeGlobals.moduleFactories}[id]) {`,
+			Template.indent([
+				'var e = new Error("Module \'" + req + "\' (\'" + id + "\') is not available (weak dependency)");',
+				"e.code = 'MODULE_NOT_FOUND';",
+				"throw e;"
+			]),
+			"}",
+			`return ${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(${runtimeTemplate.basicFunction("", [
+		`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
+		Template.indent([
+			'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 {ImportPhaseType} phase import phase
+	 * @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, phase, { chunkGraph, runtimeTemplate }) {
+		const map = this.getUserRequestMap(dependencies, chunkGraph);
+		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
+		const asyncDepsMap =
+			ImportPhaseUtils.isDefer(phase) &&
+			this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
+		const thenFunction = runtimeTemplate.returningFunction(
+			this.getReturnModuleObjectSource(
+				fakeMap,
+				true,
+				asyncDepsMap ? "asyncDepsMap[id]" : undefined
+			),
+			"id"
+		);
+
+		return `var map = ${JSON.stringify(map, null, "\t")};
+${this.getFakeMapInitStatement(fakeMap)}
+${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
+
+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(${runtimeTemplate.basicFunction("", [
+		`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
+		Template.indent([
+			'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 {ImportPhaseType} phase import phase
+	 * @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,
+		phase,
+		{ runtimeTemplate, chunkGraph }
+	) {
+		const promise = runtimeTemplate.blockPromise({
+			chunkGraph,
+			block,
+			message: "lazy-once context",
+			/** @type {RuntimeRequirements} */
+			runtimeRequirements: new Set()
+		});
+		const map = this.getUserRequestMap(dependencies, chunkGraph);
+		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
+		const asyncDepsMap =
+			ImportPhaseUtils.isDefer(phase) &&
+			this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
+		const thenFunction = runtimeTemplate.returningFunction(
+			this.getReturnModuleObjectSource(
+				fakeMap,
+				true,
+				asyncDepsMap ? "asyncDepsMap[id]" : undefined
+			),
+			"id"
+		);
+
+		return `var map = ${JSON.stringify(map, null, "\t")};
+${this.getFakeMapInitStatement(fakeMap)}
+${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
+
+function webpackAsyncContext(req) {
+	return webpackAsyncContextResolve(req).then(${thenFunction});
+}
+function webpackAsyncContextResolve(req) {
+	return ${promise}.then(${runtimeTemplate.basicFunction("", [
+		`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
+		Template.indent([
+			'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 {ImportPhaseType} phase import phase
+	 * @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, phase, { chunkGraph, runtimeTemplate }) {
+		const moduleGraph = chunkGraph.moduleGraph;
+		let hasMultipleOrNoChunks = false;
+		let hasNoChunk = true;
+		let hasNoModuleDeferred = true;
+		const fakeMap = this.getFakeMap(
+			blocks.map((b) => b.dependencies[0]),
+			chunkGraph
+		);
+		const hasFakeMap = typeof fakeMap === "object";
+		/** @typedef {{ userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock, asyncDeps: undefined | ModuleId[] }} Item */
+		/**
+		 * @type {Item[]}
+		 */
+		const items = blocks
+			.map((block) => {
+				const dependency =
+					/** @type {ContextElementDependency} */
+					(block.dependencies[0]);
+				return {
+					dependency,
+					module: /** @type {Module} */ (moduleGraph.getModule(dependency)),
+					block,
+					userRequest: dependency.userRequest,
+					chunks: undefined,
+					asyncDeps: 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 isModuleDeferred =
+				ImportPhaseUtils.isDefer(phase) &&
+				!(/** @type {BuildMeta} */ (item.module.buildMeta).async);
+			if (isModuleDeferred) {
+				const asyncDeps = Array.from(
+					getOutgoingAsyncModules(chunkGraph.moduleGraph, item.module),
+					(m) => chunkGraph.getModuleId(m)
+				).filter((id) => id !== null);
+				item.asyncDeps = asyncDeps;
+				hasNoModuleDeferred = false;
+			}
+		}
+		const shortMode = hasNoChunk && hasNoModuleDeferred && !hasFakeMap;
+		const sortedItems = items.sort((a, b) => {
+			if (a.userRequest === b.userRequest) return 0;
+			return a.userRequest < b.userRequest ? -1 : 1;
+		});
+		/** @type {Record<string, ModuleId | (ModuleId | FakeMapType | ChunkId[] | (ModuleId[] | undefined))[]>} */
+		const map = Object.create(null);
+		for (const item of sortedItems) {
+			const moduleId =
+				/** @type {ModuleId} */
+				(chunkGraph.getModuleId(item.module));
+			if (shortMode) {
+				map[item.userRequest] = moduleId;
+			} else {
+				/** @type {(ModuleId | FakeMapType | ChunkId[] | (ModuleId[] | undefined))[]} */
+				const array = [moduleId];
+				if (hasFakeMap) {
+					array.push(fakeMap[moduleId]);
+				}
+				if (!hasNoChunk) {
+					array.push(
+						/** @type {Chunk[]} */ (item.chunks).map(
+							(chunk) => /** @type {ChunkId} */ (chunk.id)
+						)
+					);
+				}
+				if (!hasNoModuleDeferred) {
+					array.push(item.asyncDeps);
+				}
+				map[item.userRequest] = array;
+			}
+		}
+
+		const chunksPosition = hasFakeMap ? 2 : 1;
+		const asyncDepsPosition = chunksPosition + 1;
+		const requestPrefix = hasNoChunk
+			? "Promise.resolve()"
+			: hasMultipleOrNoChunks
+				? `Promise.all(ids[${chunksPosition}].map(${RuntimeGlobals.ensureChunk}))`
+				: `${RuntimeGlobals.ensureChunk}(ids[${chunksPosition}][0])`;
+		const returnModuleObject = this.getReturnModuleObjectSource(
+			fakeMap,
+			true,
+			hasNoModuleDeferred ? undefined : `ids[${asyncDepsPosition}]`,
+			shortMode ? "invalid" : "ids[1]"
+		);
+
+		const webpackAsyncContext =
+			requestPrefix === "Promise.resolve()"
+				? `
+function webpackAsyncContext(req) {
+	return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
+		`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
+		Template.indent([
+			'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];",
+		`return ${returnModuleObject};`
+	])});
+}`
+				: `function webpackAsyncContext(req) {
+	try {
+		if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
+			return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
+				'var e = new Error("Cannot find module \'" + req + "\'");',
+				"e.code = 'MODULE_NOT_FOUND';",
+				"throw e;"
+			])});
+		}
+	} catch(err) {
+		return Promise.reject(err);
+	}
+
+	var ids = map[req], id = ids[0];
+	return ${requestPrefix}.then(${runtimeTemplate.returningFunction(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) {
+		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(${runtimeTemplate.basicFunction("", [
+		'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 {ImportPhaseType} phase import phase
+	 * @param {CodeGenerationContext} context context info
+	 * @returns {string} the source code
+	 */
+	getSourceString(asyncMode, phase, { runtimeTemplate, chunkGraph }) {
+		const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(this));
+		if (asyncMode === "lazy") {
+			if (this.blocks && this.blocks.length > 0) {
+				return this.getLazySource(this.blocks, id, phase, {
+					runtimeTemplate,
+					chunkGraph
+				});
+			}
+			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
+		}
+		if (asyncMode === "eager") {
+			if (this.dependencies && this.dependencies.length > 0) {
+				return this.getEagerSource(this.dependencies, id, phase, {
+					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, phase, {
+					runtimeTemplate,
+					chunkGraph
+				});
+			}
+			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
+		}
+		if (asyncMode === "async-weak") {
+			if (this.dependencies && this.dependencies.length > 0) {
+				return this.getAsyncWeakSource(this.dependencies, id, phase, {
+					chunkGraph,
+					runtimeTemplate
+				});
+			}
+			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
+		}
+		if (
+			asyncMode === "weak" &&
+			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);
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration(context) {
+		const { chunkGraph, compilation } = context;
+
+		/** @type {Sources} */
+		const sources = new Map();
+		sources.set(
+			JAVASCRIPT_TYPE,
+			this.getSource(
+				this.getSourceString(
+					this.options.mode,
+					this.options.phase || ImportPhase.Evaluation,
+					context
+				),
+				compilation
+			)
+		);
+		/** @type {RuntimeRequirements} */
+		const set = new Set();
+		const allDeps =
+			this.dependencies.length > 0
+				? /** @type {ContextElementDependency[]} */ [...this.dependencies]
+				: [];
+		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);
+			}
+			if (
+				ImportPhaseUtils.isDefer(this.options.phase || ImportPhase.Evaluation)
+			) {
+				set.add(RuntimeGlobals.makeDeferredNamespaceObject);
+			}
+		}
+		return {
+			sources,
+			runtimeRequirements: set
+		};
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this._identifier);
+		write(this._forceBuild);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer 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;
Index: frontend/node_modules/webpack/lib/ContextModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/ContextModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ContextModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,524 @@
+/*
+	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("enhanced-resolve").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Compilation").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("./ContextModule").ContextModuleOptions} ContextModuleOptions */
+/** @typedef {import("./ContextModule").ResolveDependenciesCallback} ResolveDependenciesCallback */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("./ResolverFactory")} ResolverFactory */
+/** @typedef {import("./dependencies/ContextDependency")} ContextDependency */
+/** @typedef {import("./dependencies/ContextDependency").ContextOptions} ContextOptions */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T>
+ */
+/** @typedef {import("./util/fs").IStats} IStats */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {{ context: string, request: string }} ContextAlternativeRequest */
+
+/**
+ * Defines the context resolve data type used by this module.
+ * @typedef {object} ContextResolveData
+ * @property {string} context
+ * @property {string} request
+ * @property {ModuleFactoryCreateData["resolveOptions"]} resolveOptions
+ * @property {FileSystemDependencies} fileDependencies
+ * @property {FileSystemDependencies} missingDependencies
+ * @property {FileSystemDependencies} contextDependencies
+ * @property {ContextDependency[]} dependencies
+ */
+
+/** @typedef {ContextResolveData & ContextOptions} BeforeContextResolveData */
+/** @typedef {BeforeContextResolveData & { resource: string | string[], resourceQuery: string | undefined, resourceFragment: string | undefined, resolveDependencies: ContextModuleFactory["resolveDependencies"] }} AfterContextResolveData */
+
+const EMPTY_RESOLVE_OPTIONS = {};
+
+class ContextModuleFactory extends ModuleFactory {
+	/**
+	 * Creates an instance of ContextModuleFactory.
+	 * @param {ResolverFactory} resolverFactory resolverFactory
+	 */
+	constructor(resolverFactory) {
+		super();
+		/** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[], ContextModuleOptions]>} */
+		const alternativeRequests = new AsyncSeriesWaterfallHook([
+			"modules",
+			"options"
+		]);
+		this.hooks = Object.freeze({
+			/** @type {AsyncSeriesWaterfallHook<[BeforeContextResolveData], BeforeContextResolveData | false | void>} */
+			beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
+			/** @type {AsyncSeriesWaterfallHook<[AfterContextResolveData], AfterContextResolveData | false | void>} */
+			afterResolve: new AsyncSeriesWaterfallHook(["data"]),
+			/** @type {SyncWaterfallHook<[string[]]>} */
+			contextModuleFiles: new SyncWaterfallHook(["files"]),
+			/** @type {FakeHook<Pick<AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
+			alternatives: createFakeHook(
+				{
+					name: "alternatives",
+					/** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["intercept"]} */
+					intercept: (interceptor) => {
+						throw new Error(
+							"Intercepting fake hook ContextModuleFactory.hooks.alternatives is not possible, use ContextModuleFactory.hooks.alternativeRequests instead"
+						);
+					},
+					/** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tap"]} */
+					tap: (options, fn) => {
+						alternativeRequests.tap(options, fn);
+					},
+					/** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tapAsync"]} */
+					tapAsync: (options, fn) => {
+						alternativeRequests.tapAsync(options, (items, _options, callback) =>
+							fn(items, callback)
+						);
+					},
+					/** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["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
+		});
+		/** @type {ResolverFactory} */
+		this.resolverFactory = resolverFactory;
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const context = data.context;
+		const dependencies = /** @type {ContextDependency[]} */ (data.dependencies);
+		const resolveOptions = data.resolveOptions;
+		const dependency = dependencies[0];
+		/** @type {FileSystemDependencies} */
+		const fileDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		const missingDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		const contextDependencies = new LazySet();
+		this.hooks.beforeResolve.callAsync(
+			{
+				context,
+				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;
+
+				/** @type {undefined | string[]} */
+				let loaders;
+				/** @type {undefined | string} */
+				let resource;
+				let loadersPrefix = "";
+				const idx = request.lastIndexOf("!");
+				if (idx >= 0) {
+					let loadersRequest = request.slice(0, idx + 1);
+					/** @type {number} */
+					let i;
+					for (
+						i = 0;
+						i < loadersRequest.length && loadersRequest[i] === "!";
+						i++
+					) {
+						loadersPrefix += "!";
+					}
+					loadersRequest = loadersRequest
+						.slice(i)
+						.replace(/!+$/, "")
+						.replace(/!{2,}/g, "!");
+					loaders = loadersRequest === "" ? [] : 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 = /** @type {ResolveRequest[]} */ ([]);
+							/**
+							 * Processes the provided obj.
+							 * @param {ResolveRequest} obj obj
+							 * @returns {void}
+							 */
+							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] =
+							/** @type {[ResolveRequest[], string[]]} */ (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
+										? /** @type {string[]} */ (contextResult.map((r) => r.path))
+										: /** @type {string} */ (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
+								});
+							}
+						);
+					}
+				);
+			}
+		);
+	}
+
+	/**
+	 * Resolves dependencies.
+	 * @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, []);
+
+		/**
+		 * Adds directory checked.
+		 * @param {string} ctx context
+		 * @param {string} directory directory
+		 * @param {Set<string>} visited visited
+		 * @param {ResolveDependenciesCallback} callback callback
+		 */
+		const addDirectoryChecked = (ctx, directory, visited, callback) => {
+			/** @type {NonNullable<InputFileSystem["realpath"]>} */
+			(fs.realpath)(directory, (err, _realPath) => {
+				if (err) return callback(err);
+				const realPath = /** @type {string} */ (_realPath);
+				if (visited.has(realPath)) return callback(null, []);
+				/** @type {Set<string> | undefined} */
+				let recursionStack;
+				addDirectory(
+					ctx,
+					directory,
+					(_, dir, callback) => {
+						if (recursionStack === undefined) {
+							recursionStack = new Set(visited);
+							recursionStack.add(realPath);
+						}
+						addDirectoryChecked(ctx, dir, recursionStack, callback);
+					},
+					callback
+				);
+			});
+		};
+
+		/**
+		 * Adds the provided ctx to the context module factory.
+		 * @param {string} ctx context
+		 * @param {string} directory directory
+		 * @param {(context: string, subResource: string, callback: () => void) => void} addSubDirectory addSubDirectoryFn
+		 * @param {ResolveDependenciesCallback} callback callback
+		 * @returns {void}
+		 */
+		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 || !exclude.test(subResource)) {
+							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();
+									}
+									return callback(err);
+								}
+
+								const stat = /** @type {IStats} */ (_stat);
+
+								if (stat.isDirectory()) {
+									if (!recursive) return callback();
+									addSubDirectory(ctx, subResource, callback);
+								} else if (
+									stat.isFile() &&
+									(!include || include.test(subResource))
+								) {
+									/** @type {{ context: string, request: string }} */
+									const obj = {
+										context: ctx,
+										request: `.${subResource.slice(ctx.length).replace(/\\/g, "/")}`
+									};
+
+									this.hooks.alternativeRequests.callAsync(
+										[obj],
+										options,
+										(err, alternatives) => {
+											if (err) return callback(err);
+											callback(
+												null,
+												/** @type {ContextAlternativeRequest[]} */
+												(alternatives)
+													.filter((obj) =>
+														regExp.test(/** @type {string} */ (obj.request))
+													)
+													.map((obj) => {
+														const dep = new ContextElementDependency(
+															`${obj.request}${resourceQuery}${resourceFragment}`,
+															obj.request,
+															typePrefix,
+															/** @type {string} */
+															(category),
+															referencedExports,
+															obj.context,
+															attributes
+														);
+														dep.optional = true;
+														return dep;
+													})
+											);
+										}
+									);
+								} else {
+									callback();
+								}
+							});
+						} else {
+							callback();
+						}
+					},
+					(err, result) => {
+						if (err) return callback(err);
+
+						if (!result) return callback(null, []);
+
+						/** @type {ContextElementDependency[]} */
+						const flattenedResult = [];
+
+						for (const item of result) {
+							if (item) flattenedResult.push(...item);
+						}
+
+						callback(null, flattenedResult);
+					}
+				);
+			});
+		};
+
+		/**
+		 * Adds sub directory.
+		 * @param {string} ctx context
+		 * @param {string} dir dir
+		 * @param {ResolveDependenciesCallback} callback callback
+		 * @returns {void}
+		 */
+		const addSubDirectory = (ctx, dir, callback) =>
+			addDirectory(ctx, dir, addSubDirectory, callback);
+
+		/**
+		 * Processes the provided resource.
+		 * @param {string} resource resource
+		 * @param {ResolveDependenciesCallback} callback callback
+		 */
+		const visitResource = (resource, callback) => {
+			if (typeof fs.realpath === "function") {
+				addDirectoryChecked(
+					resource,
+					resource,
+					/** @type {Set<string>} */
+					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);
+				const result = /** @type {ContextElementDependency[][]} */ (_result);
+
+				// result dependencies should have unique userRequest
+				// ordered by resolve result
+				/** @type {Set<string>} */
+				const temp = new Set();
+				/** @type {ContextElementDependency[]} */
+				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);
+			});
+		}
+	}
+}
+
+module.exports = ContextModuleFactory;
Index: frontend/node_modules/webpack/lib/ContextReplacementPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ContextReplacementPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ContextReplacementPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,230 @@
+/*
+	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("./ContextModule").ContextModuleOptions} ContextModuleOptions */
+/** @typedef {import("./ContextModuleFactory").BeforeContextResolveData} BeforeContextResolveData */
+/** @typedef {import("./ContextModuleFactory").AfterContextResolveData} AfterContextResolveData */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+
+/** @typedef {Record<string, string>} NewContentCreateContextMap */
+
+const PLUGIN_NAME = "ContextReplacementPlugin";
+
+class ContextReplacementPlugin {
+	/**
+	 * Creates an instance of ContextReplacementPlugin.
+	 * @param {RegExp} resourceRegExp A regular expression that determines which files will be selected
+	 * @param {(string | ((context: BeforeContextResolveData | AfterContextResolveData) => void) | RegExp | boolean)=} newContentResource A new resource to replace the match
+	 * @param {(boolean | NewContentCreateContextMap | RegExp)=} newContentRecursive If true, all subdirectories are searched for matches
+	 * @param {RegExp=} newContentRegExp A regular expression that determines which files will be selected
+	 */
+	constructor(
+		resourceRegExp,
+		newContentResource,
+		newContentRecursive,
+		newContentRegExp
+	) {
+		this.resourceRegExp = resourceRegExp;
+
+		// new webpack.ContextReplacementPlugin(/selector/, (context) => { /* Logic */ });
+		if (typeof newContentResource === "function") {
+			this.newContentCallback = newContentResource;
+		}
+		// new ContextReplacementPlugin(/selector/, './folder', { './request': './request' });
+		else if (
+			typeof newContentResource === "string" &&
+			typeof newContentRecursive === "object"
+		) {
+			this.newContentResource = newContentResource;
+			/**
+			 * Stores new content create context map.
+			 * @param {InputFileSystem} fs input file system
+			 * @param {(err: null | Error, newContentRecursive: NewContentCreateContextMap) => void} callback callback
+			 */
+			this.newContentCreateContextMap = (fs, callback) => {
+				callback(
+					null,
+					/** @type {NewContentCreateContextMap} */ (newContentRecursive)
+				);
+			};
+		}
+		// new ContextReplacementPlugin(/selector/, './folder', (context) => { /* Logic */ });
+		else if (
+			typeof newContentResource === "string" &&
+			typeof newContentRecursive === "function"
+		) {
+			this.newContentResource = newContentResource;
+			this.newContentCreateContextMap = newContentRecursive;
+		} else {
+			// new webpack.ContextReplacementPlugin(/selector/, false, /reg-exp/);
+			if (typeof newContentResource !== "string") {
+				newContentRegExp = /** @type {RegExp} */ (newContentRecursive);
+				newContentRecursive = /** @type {boolean} */ (newContentResource);
+				newContentResource = undefined;
+			}
+			// new webpack.ContextReplacementPlugin(/selector/, /de|fr|hu/);
+			if (typeof newContentRecursive !== "boolean") {
+				newContentRegExp = /** @type {RegExp} */ (newContentRecursive);
+				newContentRecursive = undefined;
+			}
+			// new webpack.ContextReplacementPlugin(/selector/, './folder', false, /selector/);
+			this.newContentResource =
+				/** @type {string | undefined} */
+				(newContentResource);
+			this.newContentRecursive =
+				/** @type {boolean | undefined} */
+				(newContentRecursive);
+			this.newContentRegExp =
+				/** @type {RegExp | undefined} */
+				(newContentRegExp);
+		}
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @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(PLUGIN_NAME, (cmf) => {
+			cmf.hooks.beforeResolve.tap(PLUGIN_NAME, (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(PLUGIN_NAME, (result) => {
+				if (!result) return;
+				const isMatchResourceRegExp = () => {
+					if (Array.isArray(result.resource)) {
+						return result.resource.some((item) => resourceRegExp.test(item));
+					}
+
+					return resourceRegExp.test(result.resource);
+				};
+				if (isMatchResourceRegExp()) {
+					if (newContentResource !== undefined) {
+						if (
+							newContentResource.startsWith("/") ||
+							(newContentResource.length > 1 && newContentResource[1] === ":")
+						) {
+							result.resource = newContentResource;
+						} else {
+							const rootPath =
+								typeof result.resource === "string"
+									? result.resource
+									: /** @type {string} */
+										(result.resource.find((item) => resourceRegExp.test(item)));
+							result.resource = join(
+								/** @type {InputFileSystem} */
+								(compiler.inputFileSystem),
+								rootPath,
+								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) {
+							const newResource = Array.isArray(result.resource)
+								? result.resource
+								: [result.resource];
+
+							for (let i = 0; i < newResource.length; i++) {
+								if (
+									!newResource[i].startsWith("/") &&
+									(newResource[i].length <= 1 || newResource[i][1] !== ":")
+								) {
+									// When the function changed it to an relative path
+									newResource[i] = join(
+										/** @type {InputFileSystem} */
+										(compiler.inputFileSystem),
+										origResource[i],
+										newResource[i]
+									);
+								}
+							}
+
+							result.resource = newResource;
+						}
+					} else {
+						for (const d of result.dependencies) {
+							if (d.critical) d.critical = false;
+						}
+					}
+				}
+				return result;
+			});
+		});
+	}
+}
+
+/**
+ * Creates a resolve dependencies from context map.
+ * @param {(fs: InputFileSystem, callback: (err: null | Error, map: NewContentCreateContextMap) => void) => void} createContextMap create context map function
+ * @returns {(fs: InputFileSystem, options: ContextModuleOptions, callback: (err: null | Error, dependencies?: ContextElementDependency[]) => void) => void} resolve resolve dependencies from context map function
+ */
+const createResolveDependenciesFromContextMap =
+	(createContextMap) => (fs, options, callback) => {
+		createContextMap(fs, (err, map) => {
+			if (err) return callback(err);
+			const dependencies = Object.keys(map).map(
+				(key) =>
+					new ContextElementDependency(
+						map[key] + options.resourceQuery + options.resourceFragment,
+						key,
+						options.typePrefix,
+						/** @type {string} */
+						(options.category),
+						options.referencedExports
+					)
+			);
+			callback(null, dependencies);
+		});
+	};
+
+module.exports = ContextReplacementPlugin;
Index: frontend/node_modules/webpack/lib/DefinePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/DefinePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/DefinePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,891 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const ConstDependency = require("./dependencies/ConstDependency");
+const WebpackError = require("./errors/WebpackError");
+const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression");
+const { VariableInfo } = require("./javascript/JavascriptParser");
+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("./Module").ValueCacheVersion} ValueCacheVersion */
+/** @typedef {import("./Module").ValueCacheVersions} ValueCacheVersions */
+/** @typedef {import("./NormalModule")} NormalModule */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").DestructuringAssignmentProperties} DestructuringAssignmentProperties */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./Compilation")} Compilation */
+
+/** @typedef {null | undefined | RegExp | EXPECTED_FUNCTION | string | number | boolean | bigint | undefined} CodeValuePrimitive */
+/** @typedef {RecursiveArrayOrRecord<CodeValuePrimitive | RuntimeValue>} CodeValue */
+
+/**
+ * Defines the runtime value options type used by this module.
+ * @typedef {object} RuntimeValueOptions
+ * @property {string[]=} fileDependencies
+ * @property {string[]=} contextDependencies
+ * @property {string[]=} missingDependencies
+ * @property {string[]=} buildDependencies
+ * @property {string | (() => string)=} version
+ */
+
+/** @typedef {(value: { module: NormalModule, key: string, readonly version: ValueCacheVersion }) => CodeValuePrimitive} GeneratorFn */
+
+class RuntimeValue {
+	/**
+	 * Creates an instance of RuntimeValue.
+	 * @param {GeneratorFn} fn generator function
+	 * @param {true | string[] | RuntimeValueOptions=} options options
+	 */
+	constructor(fn, options) {
+		/** @type {GeneratorFn} */
+		this.fn = fn;
+		if (Array.isArray(options)) {
+			options = {
+				fileDependencies: options
+			};
+		}
+		/** @type {true | RuntimeValueOptions} */
+		this.options = options || {};
+	}
+
+	get fileDependencies() {
+		return this.options === true ? true : this.options.fileDependencies;
+	}
+
+	/**
+	 * Returns code.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {ValueCacheVersions} 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) {
+					/** @type {NonNullable<BuildInfo["fileDependencies"]>} */
+					(buildInfo.fileDependencies).add(dep);
+				}
+			}
+			if (this.options.contextDependencies) {
+				for (const dep of this.options.contextDependencies) {
+					/** @type {NonNullable<BuildInfo["contextDependencies"]>} */
+					(buildInfo.contextDependencies).add(dep);
+				}
+			}
+			if (this.options.missingDependencies) {
+				for (const dep of this.options.missingDependencies) {
+					/** @type {NonNullable<BuildInfo["missingDependencies"]>} */
+					(buildInfo.missingDependencies).add(dep);
+				}
+			}
+			if (this.options.buildDependencies) {
+				for (const dep of this.options.buildDependencies) {
+					/** @type {NonNullable<BuildInfo["buildDependencies"]>} */
+					(buildInfo.buildDependencies).add(dep);
+				}
+			}
+		}
+
+		return this.fn({
+			module: parser.state.module,
+			key,
+			get version() {
+				return /** @type {ValueCacheVersion} */ (
+					valueCacheVersions.get(VALUE_DEP_PREFIX + key)
+				);
+			}
+		});
+	}
+
+	getCacheVersion() {
+		return this.options === true
+			? undefined
+			: (typeof this.options.version === "function"
+					? this.options.version()
+					: this.options.version) || "unset";
+	}
+}
+
+/**
+ * Returns used keys.
+ * @param {DestructuringAssignmentProperties | undefined} properties properties
+ * @returns {Set<string> | undefined} used keys
+ */
+function getObjKeys(properties) {
+	if (!properties) return;
+	return new Set([...properties].map((p) => p.id));
+}
+
+/** @typedef {Set<string> | null} ObjKeys */
+/** @typedef {boolean | undefined | null} AsiSafe */
+
+/**
+ * Returns code converted to string that evaluates.
+ * @param {EXPECTED_ANY[] | { [k: string]: EXPECTED_ANY }} obj obj
+ * @param {JavascriptParser} parser Parser
+ * @param {ValueCacheVersions} valueCacheVersions valueCacheVersions
+ * @param {string} key the defined key
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Logger} logger the logger object
+ * @param {AsiSafe=} asiSafe asi safe (undefined: unknown, null: unneeded)
+ * @param {ObjKeys=} objKeys used keys
+ * @returns {string} code converted to string that evaluates
+ */
+const stringifyObj = (
+	obj,
+	parser,
+	valueCacheVersions,
+	key,
+	runtimeTemplate,
+	logger,
+	asiSafe,
+	objKeys
+) => {
+	/** @type {string} */
+	let code;
+	const arr = Array.isArray(obj);
+	if (arr) {
+		code = `[${obj
+			.map((code) =>
+				toCode(
+					code,
+					parser,
+					valueCacheVersions,
+					key,
+					runtimeTemplate,
+					logger,
+					null
+				)
+			)
+			.join(",")}]`;
+	} else {
+		let keys = Object.keys(obj);
+		if (objKeys) {
+			keys = objKeys.size === 0 ? [] : keys.filter((k) => objKeys.has(k));
+		}
+		code = `{${keys
+			.map((key) => {
+				const code = obj[key];
+				return `${key === "__proto__" ? '["__proto__"]' : 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 {ValueCacheVersions} 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 {ObjKeys=} 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.debug(`Replaced "${key}" with "${strCode}"`);
+
+	return strCode;
+};
+
+/**
+ * Returns result.
+ * @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, CodeValue>} */
+				(code)[key]
+			)
+		}));
+		if (items.some(({ value }) => value === undefined)) return;
+		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);
+
+/**
+ * Defines the define plugin hooks type used by this module.
+ * @typedef {object} DefinePluginHooks
+ * @property {SyncWaterfallHook<[Record<string, CodeValue>]>} definitions
+ */
+
+/** @typedef {Record<string, CodeValue>} Definitions */
+
+/** @type {WeakMap<Compilation, DefinePluginHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class DefinePlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {DefinePluginHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				definitions: new SyncWaterfallHook(["definitions"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Create a new define plugin
+	 * @param {Definitions} definitions A map of global object definitions
+	 */
+	constructor(definitions) {
+		/** @type {Definitions} */
+		this.definitions = definitions;
+	}
+
+	/**
+	 * Returns runtime value.
+	 * @param {GeneratorFn} fn generator function
+	 * @param {true | string[] | RuntimeValueOptions=} options options
+	 * @returns {RuntimeValue} runtime value
+	 */
+	static runtimeValue(fn, options) {
+		return new RuntimeValue(fn, options);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const definitions = this.definitions;
+				const hooks = DefinePlugin.getCompilationHooks(compilation);
+
+				hooks.definitions.tap(PLUGIN_NAME, (previousDefinitions) => ({
+					...previousDefinitions,
+					...definitions
+				}));
+
+				/**
+				 * @type {Map<string, Set<string>>}
+				 */
+				const finalByNestedKey = new Map();
+				/**
+				 * @type {Map<string, Set<string>>}
+				 */
+				const nestedByFinalKey = new Map();
+
+				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)) || ""
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser Parser
+				 * @returns {void}
+				 */
+				const handler = (parser) => {
+					/** @type {Set<string>} */
+					const hooked = new Set();
+					const mainValue =
+						/** @type {ValueCacheVersion} */
+						(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);
+					});
+
+					/**
+					 * Adds value dependency.
+					 * @param {string} key key
+					 */
+					const addValueDependency = (key) => {
+						const buildInfo =
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo);
+						/** @type {NonNullable<BuildInfo["valueDependencies"]>} */
+						(buildInfo.valueDependencies).set(
+							VALUE_DEP_PREFIX + key,
+							/** @type {ValueCacheVersion} */
+							(compilation.valueCacheVersions.get(VALUE_DEP_PREFIX + key))
+						);
+					};
+
+					/**
+					 * With value dependency.
+					 * @template T
+					 * @param {string} key key
+					 * @param {(expression: Expression) => T} fn fn
+					 * @returns {(expression: Expression) => T} result
+					 */
+					const withValueDependency =
+						(key, fn) =>
+						(...args) => {
+							addValueDependency(key);
+							return fn(...args);
+						};
+
+					/**
+					 * Processes the provided definition.
+					 * @param {Definitions} definitions Definitions map
+					 * @param {string} prefix Prefix string
+					 * @returns {void}
+					 */
+					const walkDefinitions = (definitions, prefix) => {
+						for (const key of Object.keys(definitions)) {
+							const code = definitions[key];
+							if (
+								code &&
+								typeof code === "object" &&
+								!(code instanceof RuntimeValue) &&
+								!(code instanceof RegExp)
+							) {
+								walkDefinitions(
+									/** @type {Definitions} */ (code),
+									`${prefix + key}.`
+								);
+								applyObjectDefine(prefix + key, code);
+								continue;
+							}
+							applyDefineKey(prefix, key);
+							applyDefine(prefix + key, code);
+						}
+					};
+
+					/**
+					 * Processes the provided prefix.
+					 * @param {string} prefix Prefix
+					 * @param {string} key Key
+					 * @returns {void}
+					 */
+					const applyDefineKey = (prefix, key) => {
+						const splittedKey = key.split(".");
+						const firstKey = splittedKey[0];
+						for (const [i, _] of splittedKey.slice(1).entries()) {
+							const fullKey = prefix + splittedKey.slice(0, i + 1).join(".");
+							parser.hooks.canRename.for(fullKey).tap(PLUGIN_NAME, () => {
+								addValueDependency(key);
+								if (
+									parser.scope.definitions.get(firstKey) instanceof VariableInfo
+								) {
+									return false;
+								}
+								return true;
+							});
+						}
+						if (prefix === "") {
+							const final = splittedKey[splittedKey.length - 1];
+							const nestedSet = nestedByFinalKey.get(final);
+							if (!nestedSet || nestedSet.size <= 0) return;
+							for (const nested of /** @type {Set<string>} */ (nestedSet)) {
+								if (nested && !hooked.has(nested)) {
+									// only detect the same nested key once
+									hooked.add(nested);
+									parser.hooks.collectDestructuringAssignmentProperties.tap(
+										PLUGIN_NAME,
+										(expr) => {
+											const nameInfo = parser.getNameForExpression(expr);
+											if (nameInfo && nameInfo.name === nested) return true;
+										}
+									);
+									parser.hooks.expression.for(nested).tap(
+										{
+											name: PLUGIN_NAME,
+											// why 100? Ensures it runs after object define
+											stage: 100
+										},
+										(expr) => {
+											const destructed =
+												parser.destructuringAssignmentPropertiesFor(expr);
+											if (destructed === undefined) {
+												return;
+											}
+											/** @type {Definitions} */
+											const obj = Object.create(null);
+											const finalSet = finalByNestedKey.get(nested);
+											for (const { id } of destructed) {
+												const fullKey = `${nested}.${id}`;
+												if (
+													!finalSet ||
+													!finalSet.has(id) ||
+													!definitions[fullKey]
+												) {
+													return;
+												}
+												obj[id] = definitions[fullKey];
+											}
+											let strCode = stringifyObj(
+												obj,
+												parser,
+												compilation.valueCacheVersions,
+												key,
+												runtimeTemplate,
+												logger,
+												!parser.isAsiPosition(
+													/** @type {Range} */ (expr.range)[0]
+												),
+												getObjKeys(destructed)
+											);
+											if (parser.scope.inShorthand) {
+												strCode = `${parser.scope.inShorthand}:${strCode}`;
+											}
+											return toConstantDependency(parser, strCode)(expr);
+										}
+									);
+								}
+							}
+						}
+					};
+
+					/**
+					 * Processes the provided key.
+					 * @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);
+								}
+								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);
+						});
+					};
+
+					/**
+					 * Processes the provided key.
+					 * @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.collectDestructuringAssignmentProperties.tap(
+							PLUGIN_NAME,
+							(expr) => {
+								const nameInfo = parser.getNameForExpression(expr);
+								if (nameInfo && nameInfo.name === key) return true;
+							}
+						);
+						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);
+							}
+							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);
+
+				/**
+				 * Processes the provided definition.
+				 * @param {Definitions} definitions Definitions map
+				 * @param {string} prefix Prefix string
+				 * @returns {void}
+				 */
+				const walkDefinitionsForValues = (definitions, prefix) => {
+					for (const key of Object.keys(definitions)) {
+						const code = definitions[key];
+						const version = /** @type {string} */ (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 {Definitions} */ (code),
+								`${prefix + key}.`
+							);
+						}
+					}
+				};
+
+				/**
+				 * Walk definitions for keys.
+				 * @param {Definitions} definitions Definitions map
+				 * @returns {void}
+				 */
+				const walkDefinitionsForKeys = (definitions) => {
+					/**
+					 * Adds the provided map to the define plugin.
+					 * @param {Map<string, Set<string>>} map Map
+					 * @param {string} key key
+					 * @param {string} value v
+					 * @returns {void}
+					 */
+					const addToMap = (map, key, value) => {
+						if (map.has(key)) {
+							/** @type {Set<string>} */
+							(map.get(key)).add(value);
+						} else {
+							map.set(key, new Set([value]));
+						}
+					};
+					for (const key of Object.keys(definitions)) {
+						const code = definitions[key];
+						if (
+							!code ||
+							typeof code === "object" ||
+							TYPEOF_OPERATOR_REGEXP.test(key)
+						) {
+							continue;
+						}
+						const idx = key.lastIndexOf(".");
+						if (idx <= 0 || idx >= key.length - 1) {
+							continue;
+						}
+						const nested = key.slice(0, idx);
+						const final = key.slice(idx + 1);
+						addToMap(finalByNestedKey, nested, final);
+						addToMap(nestedByFinalKey, final, nested);
+					}
+				};
+
+				walkDefinitionsForKeys(definitions);
+				walkDefinitionsForValues(definitions, "");
+
+				compilation.valueCacheVersions.set(
+					VALUE_DEP_MAIN,
+					mainHash.digest("hex").slice(0, 8)
+				);
+			}
+		);
+	}
+}
+
+module.exports = DefinePlugin;
Index: frontend/node_modules/webpack/lib/DependenciesBlock.js
===================================================================
--- frontend/node_modules/webpack/lib/DependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/DependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,125 @@
+/*
+	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("./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;
+	}
+
+	/**
+	 * Adds the provided dependency to the dependencies block.
+	 * @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);
+	}
+
+	/**
+	 * Removes 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);
+		}
+	}
+
+	/**
+	 * Clear dependencies and blocks.
+	 * @returns {void}
+	 */
+	clearDependenciesAndBlocks() {
+		this.dependencies.length = 0;
+		this.blocks.length = 0;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @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);
+		}
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this.dependencies);
+		write(this.blocks);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @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;
Index: frontend/node_modules/webpack/lib/Dependency.js
===================================================================
--- frontend/node_modules/webpack/lib/Dependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Dependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,434 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const memoize = require("./util/memoize");
+
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./errors/WebpackError")} WebpackError */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
+/**
+ * Defines the update hash context type used by this module.
+ * @typedef {object} UpdateHashContext
+ * @property {ChunkGraph} chunkGraph
+ * @property {RuntimeSpec} runtime
+ * @property {RuntimeTemplate=} runtimeTemplate
+ */
+
+/**
+ * Defines the source position type used by this module.
+ * @typedef {object} SourcePosition
+ * @property {number} line
+ * @property {number=} column
+ */
+
+/**
+ * Defines the real dependency location type used by this module.
+ * @typedef {object} RealDependencyLocation
+ * @property {SourcePosition} start
+ * @property {SourcePosition=} end
+ * @property {number=} index
+ */
+
+/**
+ * Defines the synthetic dependency location type used by this module.
+ * @typedef {object} SyntheticDependencyLocation
+ * @property {string} name
+ * @property {number=} index
+ */
+
+/** @typedef {SyntheticDependencyLocation | RealDependencyLocation} DependencyLocation */
+
+/** @typedef {string} ExportInfoName */
+
+/**
+ * Defines the export spec type used by this module.
+ * @typedef {object} ExportSpec
+ * @property {ExportInfoName} name the name of the export
+ * @property {boolean=} canMangle can the export be renamed (defaults to true)
+ * @property {boolean=} terminalBinding is the export a terminal binding that should be checked for export star conflicts
+ * @property {(string | ExportSpec)[]=} exports nested exports
+ * @property {ModuleGraphConnection=} from when reexported: from which module
+ * @property {string[] | null=} export when reexported: from which export
+ * @property {number=} priority when reexported: with which priority
+ * @property {boolean=} hidden export is not visible, because another export blends over it
+ */
+
+/** @typedef {Set<string>} ExportsSpecExcludeExports */
+
+/**
+ * Defines the exports spec type used by this module.
+ * @typedef {object} ExportsSpec
+ * @property {(string | ExportSpec)[] | true | null} exports exported names, true for unknown exports or null for no exports
+ * @property {ExportsSpecExcludeExports=} excludeExports when exports = true, list of unaffected exports
+ * @property {(Set<string> | null)=} hideExports list of maybe prior exposed, but now hidden exports
+ * @property {ModuleGraphConnection=} from when reexported: from which module
+ * @property {number=} priority when reexported: with which priority
+ * @property {boolean=} canMangle can the export be renamed (defaults to true)
+ * @property {boolean=} terminalBinding are the exports terminal bindings that should be checked for export star conflicts
+ * @property {Module[]=} dependencies module on which the result depends on
+ */
+
+/**
+ * Defines the referenced export type used by this module.
+ * @typedef {object} ReferencedExport
+ * @property {string[]} name name of the referenced export
+ * @property {boolean=} canMangle when false, referenced export can not be mangled, defaults to true
+ */
+
+/** @typedef {string[][]} RawReferencedExports */
+/** @typedef {(string[] | ReferencedExport)[]} ReferencedExports */
+
+/** @typedef {(moduleGraphConnection: ModuleGraphConnection, runtime: RuntimeSpec) => ConnectionState} GetConditionFn */
+
+const TRANSITIVE = /** @type {symbol} */ (Symbol("transitive"));
+
+const getIgnoredModule = memoize(() => {
+	const RawModule = require("./RawModule");
+
+	const module = new RawModule("/* (ignored) */", "ignored", "(ignored)");
+	module.factoryMeta = { sideEffectFree: true };
+	return module;
+});
+
+class Dependency {
+	constructor() {
+		/** @type {Module | undefined} */
+		this._parentModule = undefined;
+		/** @type {DependenciesBlock | undefined} */
+		this._parentDependenciesBlock = undefined;
+		/** @type {number} */
+		this._parentDependenciesBlockIndex = -1;
+		// TODO check if this can be moved into ModuleDependency
+		/** @type {boolean} */
+		this.weak = false;
+		// TODO check if this can be moved into ModuleDependency
+		/** @type {boolean | undefined} */
+		this.optional = false;
+		this._locSL = 0;
+		this._locSC = 0;
+		this._locEL = 0;
+		this._locEC = 0;
+		/** @type {undefined | number} */
+		this._locI = undefined;
+		/** @type {undefined | string} */
+		this._locN = undefined;
+		/** @type {undefined | DependencyLocation} */
+		this._loc = undefined;
+	}
+
+	/**
+	 * Returns a display name for the type of dependency.
+	 * @returns {string} a display name for the type of dependency
+	 */
+	get type() {
+		return "unknown";
+	}
+
+	/**
+	 * Returns a dependency category, typical categories are "commonjs", "amd", "esm".
+	 * @returns {string} a dependency category, typical categories are "commonjs", "amd", "esm"
+	 */
+	get category() {
+		return "unknown";
+	}
+
+	/**
+	 * Returns location.
+	 * @returns {DependencyLocation} location
+	 */
+	get loc() {
+		if (this._loc !== undefined) return this._loc;
+
+		/** @type {SyntheticDependencyLocation & RealDependencyLocation} */
+		const loc = {};
+
+		if (this._locSL > 0) {
+			loc.start = { line: this._locSL, column: this._locSC };
+		}
+		if (this._locEL > 0) {
+			loc.end = { line: this._locEL, column: this._locEC };
+		}
+		if (this._locN !== undefined) {
+			loc.name = this._locN;
+		}
+		if (this._locI !== undefined) {
+			loc.index = this._locI;
+		}
+
+		return (this._loc = loc);
+	}
+
+	set loc(loc) {
+		if ("start" in loc && typeof loc.start === "object") {
+			this._locSL = loc.start.line || 0;
+			this._locSC = loc.start.column || 0;
+		} else {
+			this._locSL = 0;
+			this._locSC = 0;
+		}
+		if ("end" in loc && typeof loc.end === "object") {
+			this._locEL = loc.end.line || 0;
+			this._locEC = loc.end.column || 0;
+		} else {
+			this._locEL = 0;
+			this._locEC = 0;
+		}
+		this._locI = "index" in loc ? loc.index : undefined;
+		this._locN = "name" in loc ? loc.name : undefined;
+		this._loc = loc;
+	}
+
+	/**
+	 * Updates loc using the provided start line.
+	 * @param {number} startLine start line
+	 * @param {number} startColumn start column
+	 * @param {number} endLine end line
+	 * @param {number} endColumn end column
+	 */
+	setLoc(startLine, startColumn, endLine, endColumn) {
+		this._locSL = startLine;
+		this._locSC = startColumn;
+		this._locEL = endLine;
+		this._locEC = endColumn;
+		this._locI = undefined;
+		this._locN = undefined;
+		this._loc = undefined;
+	}
+
+	/**
+	 * Returns a request context.
+	 * @returns {string | undefined} a request context
+	 */
+	getContext() {
+		return undefined;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return null;
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return TRANSITIVE;
+	}
+
+	/**
+	 * Returns the referenced module and export
+	 * @deprecated
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {never} throws error
+	 */
+	getReference(moduleGraph) {
+		throw new Error(
+			"Dependency.getReference was removed in favor of Dependency.getReferencedExports, ModuleGraph.getModule, ModuleGraph.getConnection(), and ModuleGraphConnection.getActiveState(runtime)"
+		);
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return Dependency.EXPORTS_OBJECT_REFERENCED;
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return null;
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		return undefined;
+	}
+
+	/**
+	 * Returns warnings.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} warnings
+	 */
+	getWarnings(moduleGraph) {
+		return null;
+	}
+
+	/**
+	 * Returns errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} errors
+	 */
+	getErrors(moduleGraph) {
+		return null;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {}
+
+	/**
+	 * implement this method to allow the occurrence order plugin to count correctly
+	 * @returns {number} count how often the id is used in this dependency
+	 */
+	getNumberOfIdOccurrences() {
+		return 1;
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		return true;
+	}
+
+	/**
+	 * Creates an ignored module.
+	 * @param {string} context context directory
+	 * @returns {Module} ignored module
+	 */
+	createIgnoredModule(context) {
+		return getIgnoredModule();
+	}
+
+	/**
+	 * Returns true if this dependency can be concatenated
+	 * @returns {boolean} true if this dependency can be concatenated
+	 */
+	canConcatenate() {
+		return false;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this.weak);
+		write(this.optional);
+		write(this._locSL);
+		write(this._locSC);
+		write(this._locEL);
+		write(this._locEC);
+		write(this._locI);
+		write(this._locN);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize({ read }) {
+		this.weak = read();
+		this.optional = read();
+		this._locSL = read();
+		this._locSC = read();
+		this._locEL = read();
+		this._locEC = read();
+		this._locI = read();
+		this._locN = read();
+	}
+}
+
+/** @type {RawReferencedExports} */
+Dependency.NO_EXPORTS_REFERENCED = [];
+/** @type {RawReferencedExports} */
+Dependency.EXPORTS_OBJECT_REFERENCED = [[]];
+
+// TODO remove in webpack 6
+Object.defineProperty(Dependency.prototype, "module", {
+	/**
+	 * Returns throws.
+	 * @deprecated
+	 * @returns {EXPECTED_ANY} throws
+	 */
+	get() {
+		throw new Error(
+			"module property was removed from Dependency (use compilation.moduleGraph.getModule(dependency) instead)"
+		);
+	},
+
+	/**
+	 * Updates module.
+	 * @deprecated
+	 * @returns {never} throws
+	 */
+	set() {
+		throw new Error(
+			"module property was removed from Dependency (use compilation.moduleGraph.updateModule(dependency, module) instead)"
+		);
+	}
+});
+
+/**
+ * Returns true if the dependency is a low priority dependency.
+ * @param {Dependency} dependency dep
+ * @returns {boolean} true if the dependency is a low priority dependency
+ */
+Dependency.isLowPriorityDependency = (dependency) =>
+	/** @type {ModuleDependency} */ (dependency).sourceOrder === Infinity;
+
+// TODO in webpack 6, call canConcatenate() directly on the dependency instance instead of using this static method.
+/**
+ * Returns true if the dependency can be concatenated (scope hoisting).
+ * @param {Dependency} dependency dep
+ * @returns {boolean} true if this dependency supports concatenation
+ */
+Dependency.canConcatenate = (dependency) => {
+	if (typeof dependency.canConcatenate === "function") {
+		return dependency.canConcatenate();
+	}
+	return false;
+};
+
+// TODO remove in webpack 6
+Object.defineProperty(Dependency.prototype, "disconnect", {
+	/**
+	 * Returns throws.
+	 * @deprecated
+	 * @returns {EXPECTED_ANY} throws
+	 */
+	get() {
+		throw new Error(
+			"disconnect was removed from Dependency (Dependency no longer carries graph specific information)"
+		);
+	}
+});
+
+Dependency.TRANSITIVE = TRANSITIVE;
+
+module.exports = Dependency;
Index: frontend/node_modules/webpack/lib/DependencyTemplate.js
===================================================================
--- frontend/node_modules/webpack/lib/DependencyTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/DependencyTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,77 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("./Generator").GenerateContext} GenerateContext */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+
+/**
+ * Defines the init fragment type used by this module.
+ * @template T
+ * @typedef {import("./InitFragment")<T>} InitFragment
+ */
+
+/**
+ * Defines the dependency template context type used by this module.
+ * @typedef {object} DependencyTemplateContext
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {RuntimeRequirements} runtimeRequirements the requirements for runtime
+ * @property {Module} module current module
+ * @property {RuntimeSpec} runtime current runtimes, for which code is generated
+ * @property {InitFragment<GenerateContext>[]} initFragments mutable array of init fragments for the current module
+ * @property {ConcatenationScope=} concatenationScope when in a concatenated module, information about other concatenated modules
+ * @property {CodeGenerationResults} codeGenerationResults the code generation results
+ * @property {InitFragment<GenerateContext>[]} chunkInitFragments chunkInitFragments
+ */
+
+/**
+ * Defines the css dependency template context extras type used by this module.
+ * @typedef {object} CssDependencyTemplateContextExtras
+ * @property {CssData} cssData the css exports data
+ * @property {string} type the css exports data
+ */
+
+/**
+ * Defines the css data type used by this module.
+ * @typedef {object} CssData
+ * @property {boolean} esModule whether export __esModule
+ * @property {Map<string, string>} exports the css exports
+ * @property {Map<string, { line: number, column: number }>=} exportLocs source position (line is 1-based, column is 0-based) of each export's defining identifier in the original CSS, used to emit fine-grained JS-to-CSS source mappings
+ */
+
+/** @typedef {DependencyTemplateContext & CssDependencyTemplateContextExtras} CssDependencyTemplateContext */
+
+class DependencyTemplate {
+	/* istanbul ignore next */
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @abstract
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+}
+
+module.exports = DependencyTemplate;
Index: frontend/node_modules/webpack/lib/DependencyTemplates.js
===================================================================
--- frontend/node_modules/webpack/lib/DependencyTemplates.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/DependencyTemplates.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { DEFAULTS } = require("./config/defaults");
+const createHash = require("./util/createHash");
+
+/** @typedef {import("./Compilation").DependencyConstructor} DependencyConstructor */
+/** @typedef {import("./DependencyTemplate")} DependencyTemplate */
+/** @typedef {import("./util/Hash").HashFunction} HashFunction */
+
+class DependencyTemplates {
+	/**
+	 * Creates an instance of DependencyTemplates.
+	 * @param {HashFunction} hashFunction the hash function to use
+	 */
+	constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
+		/** @type {Map<DependencyConstructor, DependencyTemplate>} */
+		this._map = new Map();
+		/** @type {string} */
+		this._hash = "31d6cfe0d16ae931b73c59d7e0c089c0";
+		/** @type {HashFunction} */
+		this._hashFunction = hashFunction;
+	}
+
+	/**
+	 * Returns template for this dependency.
+	 * @param {DependencyConstructor} dependency Constructor of Dependency
+	 * @returns {DependencyTemplate | undefined} template for this dependency
+	 */
+	get(dependency) {
+		return this._map.get(dependency);
+	}
+
+	/**
+	 * Updates value using the provided dependency.
+	 * @param {DependencyConstructor} dependency Constructor of Dependency
+	 * @param {DependencyTemplate} dependencyTemplate template for this dependency
+	 * @returns {void}
+	 */
+	set(dependency, dependencyTemplate) {
+		this._map.set(dependency, dependencyTemplate);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {string} part additional hash contributor
+	 * @returns {void}
+	 */
+	updateHash(part) {
+		const hash = createHash(this._hashFunction);
+		hash.update(`${this._hash}${part}`);
+		this._hash = hash.digest("hex");
+	}
+
+	getHash() {
+		return this._hash;
+	}
+
+	clone() {
+		const newInstance = new DependencyTemplates(this._hashFunction);
+		newInstance._map = new Map(this._map);
+		newInstance._hash = this._hash;
+		return newInstance;
+	}
+}
+
+module.exports = DependencyTemplates;
Index: frontend/node_modules/webpack/lib/DotenvPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/DotenvPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/DotenvPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,473 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+const FileSystemInfo = require("./FileSystemInfo");
+const { join } = require("./util/fs");
+
+/** @typedef {import("../declarations/WebpackOptions").DotenvPluginOptions} DotenvPluginOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./CacheFacade").ItemCacheFacade} ItemCacheFacade */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./FileSystemInfo").Snapshot} Snapshot */
+
+/** @typedef {Exclude<DotenvPluginOptions["prefix"], string | undefined>} Prefix */
+/** @typedef {Record<string, string>} Env */
+
+const DEFAULT_TEMPLATE = [
+	".env",
+	".env.local",
+	".env.[mode]",
+	".env.[mode].local"
+];
+
+// Regex for parsing .env files
+// ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L49
+const LINE =
+	/^\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?$/gm;
+
+const PLUGIN_NAME = "DotenvPlugin";
+
+/**
+ * Parse .env file content
+ * ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L49
+ * @param {string | Buffer} src the source content to parse
+ * @returns {Env} parsed environment variables object
+ */
+function parse(src) {
+	const obj = /** @type {Env} */ (Object.create(null));
+
+	// Convert buffer to string
+	let lines = src.toString();
+
+	// Convert line breaks to same format
+	lines = lines.replace(/\r\n?/g, "\n");
+
+	/** @type {null | RegExpExecArray} */
+	let match;
+
+	while ((match = LINE.exec(lines)) !== null) {
+		const key = match[1];
+
+		// Default undefined or null to empty string
+		let value = match[2] || "";
+
+		// Remove whitespace
+		value = value.trim();
+
+		// Check if double quoted
+		const maybeQuote = value[0];
+
+		// Remove surrounding quotes
+		value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
+
+		// Expand newlines if double quoted
+		if (maybeQuote === '"') {
+			value = value.replace(/\\n/g, "\n");
+			value = value.replace(/\\r/g, "\r");
+		}
+
+		// Add to object
+		obj[key] = value;
+	}
+
+	return obj;
+}
+
+/**
+ * Resolve escape sequences
+ * ported from https://github.com/motdotla/dotenv-expand
+ * @param {string} value value to resolve
+ * @returns {string} resolved value
+ */
+function _resolveEscapeSequences(value) {
+	return value.replace(/\\\$/g, "$");
+}
+
+/**
+ * Expand environment variable value
+ * ported from https://github.com/motdotla/dotenv-expand
+ * @param {string} value value to expand
+ * @param {Record<string, string | undefined>} processEnv process.env object
+ * @param {Env} runningParsed running parsed object
+ * @returns {string} expanded value
+ */
+function expandValue(value, processEnv, runningParsed) {
+	const env = { ...runningParsed, ...processEnv }; // process.env wins
+
+	const regex = /(?<!\\)\$\{([^{}]+)\}|(?<!\\)\$([a-z_]\w*)/gi;
+
+	let result = value;
+	/** @type {null | RegExpExecArray} */
+	let match;
+	/** @type {Set<string>} */
+	const seen = new Set(); // self-referential checker
+
+	while ((match = regex.exec(result)) !== null) {
+		seen.add(result);
+
+		const [template, bracedExpression, unbracedExpression] = match;
+		const expression = bracedExpression || unbracedExpression;
+
+		// match the operators `:+`, `+`, `:-`, and `-`
+		const opRegex = /(:\+|\+|:-|-)/;
+		// find first match
+		const opMatch = expression.match(opRegex);
+		const splitter = opMatch ? opMatch[0] : null;
+
+		const r = expression.split(/** @type {string} */ (splitter));
+		// const r = splitter ? expression.split(splitter) : [expression];
+
+		/** @type {string} */
+		let defaultValue;
+		/** @type {undefined | null | string} */
+		let value;
+
+		const key = r.shift();
+
+		if ([":+", "+"].includes(splitter || "")) {
+			defaultValue = env[key || ""] ? r.join(splitter || "") : "";
+			value = null;
+		} else {
+			defaultValue = r.join(splitter || "");
+			value = env[key || ""];
+		}
+
+		if (value) {
+			// self-referential check
+			result = seen.has(value)
+				? result.replace(template, defaultValue)
+				: result.replace(template, value);
+		} else {
+			result = result.replace(template, defaultValue);
+		}
+
+		// if the result equaled what was in process.env and runningParsed then stop expanding
+		if (result === runningParsed[key || ""]) {
+			break;
+		}
+
+		regex.lastIndex = 0; // reset regex search position to re-evaluate after each replacement
+	}
+
+	return result;
+}
+
+/**
+ * Expand environment variables in parsed object
+ * ported from https://github.com/motdotla/dotenv-expand
+ * @param {{ parsed: Env, processEnv: Record<string, string | undefined> }} options expand options
+ * @returns {{ parsed: Env }} expanded options
+ */
+function expand(options) {
+	// for use with progressive expansion
+	const runningParsed = /** @type {Env} */ (Object.create(null));
+	const processEnv = options.processEnv;
+
+	// dotenv.config() ran before this so the assumption is process.env has already been set
+	for (const key in options.parsed) {
+		let value = options.parsed[key];
+
+		// short-circuit scenario: process.env was already set prior to the file value
+		value =
+			Object.prototype.hasOwnProperty.call(processEnv, key) &&
+			processEnv[key] !== value
+				? /** @type {string} */ (processEnv[key])
+				: expandValue(value, processEnv, runningParsed);
+
+		const resolvedValue = _resolveEscapeSequences(value);
+
+		options.parsed[key] = resolvedValue;
+		// for use with progressive expansion
+		runningParsed[key] = resolvedValue;
+	}
+
+	// Part of `dotenv-expand` code, but we don't need it because of we don't modify `process.env`
+	// for (const processKey in options.parsed) {
+	// 	if (processEnv) {
+	// 		processEnv[processKey] = options.parsed[processKey];
+	// 	}
+	// }
+
+	return options;
+}
+
+/**
+ * Format environment variables as DefinePlugin definitions
+ * @param {Env} env environment variables
+ * @returns {Record<string, string>} formatted definitions
+ */
+const envToDefinitions = (env) => {
+	const definitions = /** @type {Record<string, string>} */ ({});
+
+	for (const [key, value] of Object.entries(env)) {
+		const defValue = JSON.stringify(value);
+		definitions[`process.env.${key}`] = defValue;
+		definitions[`import.meta.env.${key}`] = defValue;
+	}
+
+	return definitions;
+};
+
+class DotenvPlugin {
+	/**
+	 * Creates an instance of DotenvPlugin.
+	 * @param {DotenvPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {DotenvPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => {
+					const { definitions } = require("../schemas/WebpackOptions.json");
+
+					return {
+						definitions,
+						oneOf: [{ $ref: "#/definitions/DotenvPluginOptions" }]
+					};
+				},
+				this.options,
+				{
+					name: "Dotenv Plugin",
+					baseDataPath: "options"
+				}
+			);
+		});
+		const definePlugin = new compiler.webpack.DefinePlugin({});
+		const prefixes = Array.isArray(this.options.prefix)
+			? this.options.prefix
+			: [this.options.prefix || "WEBPACK_"];
+		/** @type {string | false} */
+		const dir =
+			typeof this.options.dir === "string"
+				? this.options.dir
+				: typeof this.options.dir === "undefined"
+					? compiler.context
+					: this.options.dir;
+
+		/** @type {undefined | Snapshot} */
+		let snapshot;
+
+		const cache = compiler.getCache(PLUGIN_NAME);
+		const identifier = JSON.stringify(
+			this.options.template || DEFAULT_TEMPLATE
+		);
+		const itemCache = cache.getItemCache(identifier, null);
+
+		compiler.hooks.beforeCompile.tapPromise(PLUGIN_NAME, async () => {
+			const { parsed, snapshot: newSnapshot } = dir
+				? await this._loadEnv(compiler, itemCache, dir)
+				: { parsed: {} };
+			const env = this._getEnv(prefixes, parsed);
+
+			definePlugin.definitions = envToDefinitions(env || {});
+			snapshot = newSnapshot;
+		});
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			if (snapshot) {
+				compilation.fileDependencies.addAll(snapshot.getFileIterable());
+				compilation.missingDependencies.addAll(snapshot.getMissingIterable());
+			}
+		});
+
+		definePlugin.apply(compiler);
+	}
+
+	/**
+	 * Get list of env files to load based on mode and template
+	 * Similar to Vite's getEnvFilesForMode
+	 * @private
+	 * @param {InputFileSystem} inputFileSystem the input file system
+	 * @param {string | false} dir the directory containing .env files
+	 * @param {string | undefined} mode the mode (e.g., 'production', 'development')
+	 * @returns {string[]} array of file paths to load
+	 */
+	_getEnvFilesForMode(inputFileSystem, dir, mode) {
+		if (!dir) {
+			return [];
+		}
+
+		const templates = this.options.template || DEFAULT_TEMPLATE;
+
+		return templates
+			.map((pattern) => pattern.replace(/\[mode\]/g, mode || "development"))
+			.map((file) => join(inputFileSystem, dir, file));
+	}
+
+	/**
+	 * Get parsed env variables from `.env` files
+	 * @private
+	 * @param {InputFileSystem} fs input file system
+	 * @param {string} dir dir to load `.env` files
+	 * @param {string} mode mode
+	 * @returns {Promise<{ parsed: Env, fileDependencies: string[], missingDependencies: string[] }>} parsed env variables and dependencies
+	 */
+	async _getParsed(fs, dir, mode) {
+		/** @type {string[]} */
+		const fileDependencies = [];
+		/** @type {string[]} */
+		const missingDependencies = [];
+
+		// Get env files to load
+		const envFiles = this._getEnvFilesForMode(fs, dir, mode);
+
+		// Read all files
+		const contents = await Promise.all(
+			envFiles.map((filePath) =>
+				this._loadFile(fs, filePath).then(
+					(content) => {
+						fileDependencies.push(filePath);
+						return content;
+					},
+					() => {
+						// File doesn't exist, add to missingDependencies (this is normal)
+						missingDependencies.push(filePath);
+						return "";
+					}
+				)
+			)
+		);
+
+		// Parse all files and merge (later files override earlier ones)
+		// Similar to Vite's implementation
+		const parsed = /** @type {Env} */ (Object.create(null));
+
+		for (const content of contents) {
+			if (!content) continue;
+			const entries = parse(content);
+			for (const key in entries) {
+				parsed[key] = entries[key];
+			}
+		}
+
+		return { parsed, fileDependencies, missingDependencies };
+	}
+
+	/**
+	 * Loads the provided compiler.
+	 * @private
+	 * @param {Compiler} compiler compiler
+	 * @param {ItemCacheFacade} itemCache item cache facade
+	 * @param {string} dir directory to read
+	 * @returns {Promise<{ parsed: Env, snapshot: Snapshot }>} parsed result and snapshot
+	 */
+	async _loadEnv(compiler, itemCache, dir) {
+		const fs = /** @type {InputFileSystem} */ (compiler.inputFileSystem);
+		const fileSystemInfo = new FileSystemInfo(fs, {
+			unmanagedPaths: compiler.unmanagedPaths,
+			managedPaths: compiler.managedPaths,
+			immutablePaths: compiler.immutablePaths,
+			hashFunction: compiler.options.output.hashFunction
+		});
+
+		const result = await itemCache.getPromise();
+
+		if (result) {
+			const isSnapshotValid = await new Promise((resolve, reject) => {
+				fileSystemInfo.checkSnapshotValid(result.snapshot, (error, isValid) => {
+					if (error) {
+						reject(error);
+
+						return;
+					}
+
+					resolve(isValid);
+				});
+			});
+
+			if (isSnapshotValid) {
+				return { parsed: result.parsed, snapshot: result.snapshot };
+			}
+		}
+
+		const { parsed, fileDependencies, missingDependencies } =
+			await this._getParsed(
+				fs,
+				dir,
+				/** @type {string} */
+				(compiler.options.mode)
+			);
+
+		const startTime = Date.now();
+		const newSnapshot = await new Promise((resolve, reject) => {
+			fileSystemInfo.createSnapshot(
+				startTime,
+				fileDependencies,
+				null,
+				missingDependencies,
+				// `.env` files are build dependencies
+				compiler.options.snapshot.buildDependencies,
+				(err, snapshot) => {
+					if (err) return reject(err);
+					resolve(snapshot);
+				}
+			);
+		});
+
+		await itemCache.storePromise({ parsed, snapshot: newSnapshot });
+
+		return { parsed, snapshot: newSnapshot };
+	}
+
+	/**
+	 * Generate env variables
+	 * @private
+	 * @param {Prefix} prefixes expose only environment variables that start with these prefixes
+	 * @param {Env} parsed parsed env variables
+	 * @returns {Env} env variables
+	 */
+	_getEnv(prefixes, parsed) {
+		// Always expand environment variables (like Vite does)
+		// Make a copy of process.env so that dotenv-expand doesn't modify global process.env
+		const processEnv = { ...process.env };
+		expand({ parsed, processEnv });
+		const env = /** @type {Env} */ (Object.create(null));
+
+		// Get all keys from parser and process.env
+		const keys = [...Object.keys(parsed), ...Object.keys(process.env)];
+
+		// Prioritize actual env variables from `process.env`, fallback to parsed
+		for (const key of keys) {
+			if (prefixes.some((prefix) => key.startsWith(prefix))) {
+				env[key] =
+					Object.prototype.hasOwnProperty.call(process.env, key) &&
+					process.env[key]
+						? process.env[key]
+						: parsed[key];
+			}
+		}
+
+		return env;
+	}
+
+	/**
+	 * Load a file with proper path resolution
+	 * @private
+	 * @param {InputFileSystem} fs the input file system
+	 * @param {string} file the file to load
+	 * @returns {Promise<string>} the content of the file
+	 */
+	_loadFile(fs, file) {
+		return new Promise((resolve, reject) => {
+			fs.readFile(file, (err, content) => {
+				if (err) reject(err);
+				else resolve(/** @type {Buffer} */ (content).toString() || "");
+			});
+		});
+	}
+}
+
+module.exports = DotenvPlugin;
Index: frontend/node_modules/webpack/lib/DynamicEntryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/DynamicEntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/DynamicEntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,95 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Naoyuki Kanezawa @nkzawa
+*/
+
+"use strict";
+
+const EntryOptionPlugin = require("./EntryOptionPlugin");
+const EntryPlugin = require("./EntryPlugin");
+const EntryDependency = require("./dependencies/EntryDependency");
+
+/** @typedef {import("../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */
+/** @typedef {import("../declarations/WebpackOptions").EntryStatic} EntryStatic */
+/** @typedef {import("../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "DynamicEntryPlugin";
+
+/** @typedef {() => EntryStatic | Promise<EntryStatic>} RawEntryDynamic */
+/** @typedef {() => Promise<EntryStaticNormalized>} EntryDynamic */
+
+class DynamicEntryPlugin {
+	/**
+	 * Creates an instance of DynamicEntryPlugin.
+	 * @param {string} context the context path
+	 * @param {EntryDynamic} entry the entry value
+	 */
+	constructor(context, entry) {
+		/** @type {string} */
+		this.context = context;
+		/** @type {EntryDynamic} */
+		this.entry = entry;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					EntryDependency,
+					normalModuleFactory
+				);
+			}
+		);
+
+		compiler.hooks.make.tapPromise(PLUGIN_NAME, (compilation) =>
+			Promise.resolve(this.entry())
+				.then((entry) => {
+					/** @type {Promise<void>[]} */
+					const promises = [];
+					for (const name of Object.keys(entry)) {
+						const desc = entry[name];
+						const options = EntryOptionPlugin.entryDescriptionToOptions(
+							compiler,
+							name,
+							desc
+						);
+						for (const entry of /** @type {NonNullable<EntryDescriptionNormalized["import"]>} */ (
+							desc.import
+						)) {
+							promises.push(
+								new Promise(
+									/**
+									 * Handles the callback logic for this hook.
+									 * @param {(value?: undefined) => void} resolve resolve
+									 * @param {(reason?: Error) => void} reject reject
+									 */
+									(resolve, reject) => {
+										compilation.addEntry(
+											this.context,
+											EntryPlugin.createDependency(entry, options),
+											options,
+											(err) => {
+												if (err) return reject(err);
+												resolve();
+											}
+										);
+									}
+								)
+							);
+						}
+					}
+					return Promise.all(promises);
+				})
+				.then(() => {})
+		);
+	}
+}
+
+module.exports = DynamicEntryPlugin;
Index: frontend/node_modules/webpack/lib/EntryOptionPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/EntryOptionPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/EntryOptionPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,101 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescription */
+/** @typedef {import("../declarations/WebpackOptions").EntryNormalized} Entry */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
+
+const PLUGIN_NAME = "EntryOptionPlugin";
+
+class EntryOptionPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance one is tapping into
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.entryOption.tap(PLUGIN_NAME, (context, entry) => {
+			EntryOptionPlugin.applyEntryOption(compiler, context, entry);
+			return true;
+		});
+	}
+
+	/**
+	 * Apply entry option.
+	 * @param {Compiler} compiler the compiler
+	 * @param {string} context context directory
+	 * @param {Entry} entry request
+	 * @returns {void}
+	 */
+	static applyEntryOption(compiler, context, entry) {
+		if (typeof entry === "function") {
+			const DynamicEntryPlugin = require("./DynamicEntryPlugin");
+
+			new DynamicEntryPlugin(context, entry).apply(compiler);
+		} else {
+			const EntryPlugin = require("./EntryPlugin");
+
+			for (const name of Object.keys(entry)) {
+				const desc = entry[name];
+				const options = EntryOptionPlugin.entryDescriptionToOptions(
+					compiler,
+					name,
+					desc
+				);
+				const descImport =
+					/** @type {Exclude<EntryDescription["import"], undefined>} */
+					(desc.import);
+				for (const entry of descImport) {
+					new EntryPlugin(context, entry, options).apply(compiler);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Entry description to options.
+	 * @param {Compiler} compiler the compiler
+	 * @param {string} name entry name
+	 * @param {EntryDescription} desc entry description
+	 * @returns {EntryOptions} options for the entry
+	 */
+	static entryDescriptionToOptions(compiler, name, desc) {
+		/** @type {EntryOptions} */
+		const options = {
+			name,
+			filename: desc.filename,
+			runtime: desc.runtime,
+			layer: desc.layer,
+			dependOn: desc.dependOn,
+			baseUri: desc.baseUri,
+			publicPath: desc.publicPath,
+			chunkLoading: desc.chunkLoading,
+			asyncChunks: desc.asyncChunks,
+			wasmLoading: desc.wasmLoading,
+			library: desc.library
+		};
+		if (desc.chunkLoading) {
+			const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin");
+
+			EnableChunkLoadingPlugin.checkEnabled(compiler, desc.chunkLoading);
+		}
+		if (desc.wasmLoading) {
+			const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin");
+
+			EnableWasmLoadingPlugin.checkEnabled(compiler, desc.wasmLoading);
+		}
+		if (desc.library) {
+			const EnableLibraryPlugin = require("./library/EnableLibraryPlugin");
+
+			EnableLibraryPlugin.checkEnabled(compiler, desc.library.type);
+		}
+		return options;
+	}
+}
+
+module.exports = EntryOptionPlugin;
Index: frontend/node_modules/webpack/lib/EntryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/EntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/EntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,73 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const EntryDependency = require("./dependencies/EntryDependency");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
+
+const PLUGIN_NAME = "EntryPlugin";
+
+class EntryPlugin {
+	/**
+	 * An entry plugin which will handle creation of the EntryDependency
+	 * @param {string} context context path
+	 * @param {string} entry entry path
+	 * @param {EntryOptions | string=} options entry options (passing a string is deprecated)
+	 */
+	constructor(context, entry, options) {
+		this.context = context;
+		this.entry = entry;
+		this.options = options || "";
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					EntryDependency,
+					normalModuleFactory
+				);
+			}
+		);
+
+		const { entry, options, context } = this;
+		const dep = EntryPlugin.createDependency(entry, options);
+
+		compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
+			compilation.addEntry(context, dep, options, (err) => {
+				callback(err);
+			});
+		});
+	}
+
+	/**
+	 * Creates a dependency.
+	 * @param {string} entry entry request
+	 * @param {EntryOptions | string} options entry options (passing string is deprecated)
+	 * @returns {EntryDependency} the dependency
+	 */
+	static createDependency(entry, options) {
+		const dep = new EntryDependency(entry);
+		// TODO webpack 6 remove string option
+		dep.loc = {
+			name:
+				typeof options === "object"
+					? /** @type {string} */ (options.name)
+					: options
+		};
+		return dep;
+	}
+}
+
+module.exports = EntryPlugin;
Index: frontend/node_modules/webpack/lib/Entrypoint.js
===================================================================
--- frontend/node_modules/webpack/lib/Entrypoint.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Entrypoint.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,124 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ChunkGroup = require("./ChunkGroup");
+const SortableSet = require("./util/SortableSet");
+
+/** @typedef {import("../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescription */
+/** @typedef {import("./Chunk")} Chunk */
+
+/** @typedef {{ name?: string } & Omit<EntryDescription, "import">} EntryOptions */
+
+/**
+ * Entrypoint serves as an encapsulation primitive for chunks that are
+ * a part of a single ChunkGroup. They represent all bundles that need to be loaded for a
+ * single instance of a page. Multi-page application architectures will typically yield multiple Entrypoint objects
+ * inside of the compilation, whereas a Single Page App may only contain one with many lazy-loaded chunks.
+ */
+class Entrypoint extends ChunkGroup {
+	/**
+	 * Creates an instance of Entrypoint.
+	 * @param {EntryOptions | string} entryOptions the options for the entrypoint (or name)
+	 * @param {boolean=} initial false, when the entrypoint is not initial loaded
+	 */
+	constructor(entryOptions, initial = true) {
+		if (typeof entryOptions === "string") {
+			entryOptions = { name: entryOptions };
+		}
+		super({
+			name: entryOptions.name
+		});
+		this.options = entryOptions;
+		/** @type {Chunk=} */
+		this._runtimeChunk = undefined;
+		/** @type {Chunk=} */
+		this._entrypointChunk = undefined;
+		/** @type {boolean} */
+		this._initial = initial;
+		/** @type {SortableSet<Entrypoint>} */
+		this._dependOn = new SortableSet();
+	}
+
+	/**
+	 * Indicates whether this chunk group is loaded as part of the initial page
+	 * load instead of being created lazily.
+	 * @returns {boolean} true, when this chunk group will be loaded on initial page load
+	 */
+	isInitial() {
+		return this._initial;
+	}
+
+	/**
+	 * Sets the runtimeChunk for an entrypoint.
+	 * @param {Chunk} chunk the chunk being set as the runtime chunk.
+	 * @returns {void}
+	 */
+	setRuntimeChunk(chunk) {
+		this._runtimeChunk = chunk;
+	}
+
+	/**
+	 * Fetches the chunk reference containing the webpack bootstrap code
+	 * @returns {Chunk | null} returns the runtime chunk or null if there is none
+	 */
+	getRuntimeChunk() {
+		if (this._runtimeChunk) return this._runtimeChunk;
+		for (const parent of this.parentsIterable) {
+			if (parent instanceof Entrypoint) return parent.getRuntimeChunk();
+		}
+		return null;
+	}
+
+	/**
+	 * Sets the chunk with the entrypoint modules for an entrypoint.
+	 * @param {Chunk} chunk the chunk being set as the entrypoint chunk.
+	 * @returns {void}
+	 */
+	setEntrypointChunk(chunk) {
+		this._entrypointChunk = chunk;
+	}
+
+	/**
+	 * Returns the chunk which contains the entrypoint modules
+	 * (or at least the execution of them)
+	 * @returns {Chunk} chunk
+	 */
+	getEntrypointChunk() {
+		return /** @type {Chunk} */ (this._entrypointChunk);
+	}
+
+	/**
+	 * Replaces one member chunk with another while preserving the group's
+	 * ordering and avoiding duplicates.
+	 * @param {Chunk} oldChunk chunk to be replaced
+	 * @param {Chunk} newChunk New chunk that will be replaced with
+	 * @returns {boolean | undefined} returns true if the replacement was successful
+	 */
+	replaceChunk(oldChunk, newChunk) {
+		if (this._runtimeChunk === oldChunk) this._runtimeChunk = newChunk;
+		if (this._entrypointChunk === oldChunk) this._entrypointChunk = newChunk;
+		return super.replaceChunk(oldChunk, newChunk);
+	}
+
+	/**
+	 * @param {Entrypoint} entrypoint the entrypoint
+	 * @returns {void}
+	 */
+	addDependOn(entrypoint) {
+		this._dependOn.add(entrypoint);
+	}
+
+	/**
+	 * @param {Entrypoint} entrypoint the entrypoint
+	 * @returns {boolean} true if the entrypoint is in the dependOn set
+	 */
+	dependOn(entrypoint) {
+		return this._dependOn.has(entrypoint);
+	}
+}
+
+module.exports = Entrypoint;
Index: frontend/node_modules/webpack/lib/EnvironmentPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/EnvironmentPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/EnvironmentPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Authors Simen Brekken @simenbrekken, Einar Löve @einarlove
+*/
+
+"use strict";
+
+const DefinePlugin = require("./DefinePlugin");
+const WebpackError = require("./errors/WebpackError");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./DefinePlugin").CodeValue} CodeValue */
+
+const PLUGIN_NAME = "EnvironmentPlugin";
+
+class EnvironmentPlugin {
+	/**
+	 * Creates an instance of EnvironmentPlugin.
+	 * @param {(string | string[] | Record<string, EXPECTED_ANY>)[]} keys keys
+	 */
+	constructor(...keys) {
+		if (keys.length === 1 && Array.isArray(keys[0])) {
+			/** @type {string[]} */
+			this.keys = keys[0];
+			this.defaultValues = {};
+		} else if (keys.length === 1 && keys[0] && typeof keys[0] === "object") {
+			this.keys = Object.keys(keys[0]);
+			this.defaultValues =
+				/** @type {Record<string, EXPECTED_ANY>} */
+				(keys[0]);
+		} else {
+			this.keys = /** @type {string[]} */ (keys);
+			this.defaultValues = {};
+		}
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const definePlugin = new DefinePlugin({});
+
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			/** @type {Record<string, CodeValue>} */
+			const definitions = {};
+			for (const key of this.keys) {
+				const value =
+					process.env[key] !== undefined
+						? process.env[key]
+						: this.defaultValues[key];
+
+				if (value === undefined) {
+					const error = new WebpackError(
+						`${PLUGIN_NAME} - ${key} environment variable is undefined.\n\n` +
+							"You can pass an object with default values to suppress this warning.\n" +
+							"See https://webpack.js.org/plugins/environment-plugin for example."
+					);
+
+					error.name = "EnvVariableNotDefinedError";
+					compilation.errors.push(error);
+				}
+				const defValue =
+					value === undefined ? "undefined" : JSON.stringify(value);
+				definitions[`process.env.${key}`] = defValue;
+				definitions[`import.meta.env.${key}`] = defValue;
+			}
+			definePlugin.definitions = definitions;
+		});
+		definePlugin.apply(compiler);
+	}
+}
+
+module.exports = EnvironmentPlugin;
Index: frontend/node_modules/webpack/lib/ErrorHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/ErrorHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ErrorHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,107 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const loaderFlag = "LOADER_EXECUTION";
+
+const webpackOptionsFlag = "WEBPACK_OPTIONS";
+
+/**
+ * Returns stack trace without the specified flag included.
+ * @param {string} stack stack trace
+ * @param {string} flag flag to cut off
+ * @returns {string} stack trace without the specified flag included
+ */
+const cutOffByFlag = (stack, flag) => {
+	const errorStack = stack.split("\n");
+	for (let i = 0; i < errorStack.length; i++) {
+		if (errorStack[i].includes(flag)) {
+			errorStack.length = i;
+		}
+	}
+	return errorStack.join("\n");
+};
+
+/**
+ * Cut off loader execution.
+ * @param {string} stack stack trace
+ * @returns {string} stack trace without the loader execution flag included
+ */
+const cutOffLoaderExecution = (stack) => cutOffByFlag(stack, loaderFlag);
+
+/**
+ * Cut off webpack options.
+ * @param {string} stack stack trace
+ * @returns {string} stack trace without the webpack options flag included
+ */
+const cutOffWebpackOptions = (stack) => cutOffByFlag(stack, webpackOptionsFlag);
+
+/**
+ * Cut off multiline message.
+ * @param {string} stack stack trace
+ * @param {string} message error message
+ * @returns {string} stack trace without the message included
+ */
+const cutOffMultilineMessage = (stack, message) => {
+	const stackSplitByLines = stack.split("\n");
+	const messageSplitByLines = message.split("\n");
+
+	/** @type {string[]} */
+	const result = [];
+
+	for (const [idx, line] of stackSplitByLines.entries()) {
+		if (!line.includes(messageSplitByLines[idx])) result.push(line);
+	}
+
+	return result.join("\n");
+};
+
+/**
+ * Returns stack trace without the message included.
+ * @param {string} stack stack trace
+ * @param {string} message error message
+ * @returns {string} stack trace without the message included
+ */
+const cutOffMessage = (stack, message) => {
+	const nextLine = stack.indexOf("\n");
+	if (nextLine === -1) {
+		return stack === message ? "" : stack;
+	}
+	const firstLine = stack.slice(0, nextLine);
+	return firstLine === message ? stack.slice(nextLine + 1) : stack;
+};
+
+/**
+ * Returns stack trace without the loader execution flag and message included.
+ * @param {string} stack stack trace
+ * @param {string} message error message
+ * @returns {string} stack trace without the loader execution flag and message included
+ */
+const cleanUp = (stack, message) => {
+	stack = cutOffLoaderExecution(stack);
+	stack = cutOffMessage(stack, message);
+	return stack;
+};
+
+/**
+ * Clean up webpack options.
+ * @param {string} stack stack trace
+ * @param {string} message error message
+ * @returns {string} stack trace without the webpack options flag and message included
+ */
+const cleanUpWebpackOptions = (stack, message) => {
+	stack = cutOffWebpackOptions(stack);
+	stack = cutOffMultilineMessage(stack, message);
+	return stack;
+};
+
+module.exports.cleanUp = cleanUp;
+module.exports.cleanUpWebpackOptions = cleanUpWebpackOptions;
+module.exports.cutOffByFlag = cutOffByFlag;
+module.exports.cutOffLoaderExecution = cutOffLoaderExecution;
+module.exports.cutOffMessage = cutOffMessage;
+module.exports.cutOffMultilineMessage = cutOffMultilineMessage;
+module.exports.cutOffWebpackOptions = cutOffWebpackOptions;
Index: frontend/node_modules/webpack/lib/EvalDevToolModulePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/EvalDevToolModulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/EvalDevToolModulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,137 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, RawSource } = require("webpack-sources");
+const ExternalModule = require("./ExternalModule");
+const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolNamespace} DevtoolNamespace */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolModuleFilenameTemplate} DevtoolModuleFilenameTemplate */
+/** @typedef {import("./Compiler")} Compiler */
+
+/** @type {WeakMap<Source, Source>} */
+const cache = new WeakMap();
+
+const devtoolWarning = new RawSource(`/*
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
+ * This devtool is neither made for production nor for readable output files.
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
+ * or disable the default devtool with "devtool: false".
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
+ */
+`);
+
+/**
+ * Defines the eval dev tool module plugin options type used by this module.
+ * @typedef {object} EvalDevToolModulePluginOptions
+ * @property {DevtoolNamespace=} namespace namespace
+ * @property {string=} sourceUrlComment source url comment
+ * @property {DevtoolModuleFilenameTemplate=} moduleFilenameTemplate module filename template
+ */
+
+const PLUGIN_NAME = "EvalDevToolModulePlugin";
+
+class EvalDevToolModulePlugin {
+	/**
+	 * Creates an instance of EvalDevToolModulePlugin.
+	 * @param {EvalDevToolModulePluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {DevtoolNamespace} */
+		this.namespace = options.namespace || "";
+		/** @type {string} */
+		this.sourceUrlComment = options.sourceUrlComment || "\n//# sourceURL=[url]";
+		/** @type {DevtoolModuleFilenameTemplate} */
+		this.moduleFilenameTemplate =
+			options.moduleFilenameTemplate ||
+			"webpack://[namespace]/[resourcePath]?[loaders]";
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
+			hooks.renderModuleContent.tap(
+				PLUGIN_NAME,
+				(source, module, { chunk, runtimeTemplate, chunkGraph }) => {
+					const cacheEntry = cache.get(source);
+					if (cacheEntry !== undefined) return cacheEntry;
+					if (module instanceof ExternalModule) {
+						cache.set(source, source);
+						return source;
+					}
+					const content = source.source();
+					const namespace = compilation.getPath(this.namespace, {
+						chunk
+					});
+					const str = ModuleFilenameHelpers.createFilename(
+						module,
+						{
+							moduleFilenameTemplate: this.moduleFilenameTemplate,
+							namespace
+						},
+						{
+							requestShortener: runtimeTemplate.requestShortener,
+							chunkGraph,
+							hashFunction: compilation.outputOptions.hashFunction
+						}
+					);
+					const footer = `\n${this.sourceUrlComment.replace(
+						/\[url\]/g,
+						encodeURI(str)
+							.replace(/%2F/g, "/")
+							.replace(/%20/g, "_")
+							.replace(/%5E/g, "^")
+							.replace(/%5C/g, "\\")
+							.replace(/^\//, "")
+					)}`;
+					const result = new RawSource(
+						`eval(${
+							compilation.outputOptions.trustedTypes
+								? `${RuntimeGlobals.createScript}(${JSON.stringify(
+										`{${content + footer}\n}`
+									)})`
+								: JSON.stringify(`{${content + footer}\n}`)
+						});`
+					);
+					cache.set(source, result);
+					return result;
+				}
+			);
+			hooks.inlineInRuntimeBailout.tap(
+				PLUGIN_NAME,
+				() => "the eval devtool is used."
+			);
+			hooks.render.tap(
+				PLUGIN_NAME,
+				(source) => new ConcatSource(devtoolWarning, source)
+			);
+			hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash) => {
+				hash.update(PLUGIN_NAME);
+				hash.update("2");
+			});
+			if (compilation.outputOptions.trustedTypes) {
+				compilation.hooks.additionalModuleRuntimeRequirements.tap(
+					PLUGIN_NAME,
+					(module, set, _context) => {
+						set.add(RuntimeGlobals.createScript);
+					}
+				);
+			}
+		});
+	}
+}
+
+module.exports = EvalDevToolModulePlugin;
Index: frontend/node_modules/webpack/lib/EvalSourceMapDevToolPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/EvalSourceMapDevToolPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/EvalSourceMapDevToolPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,252 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, RawSource } = require("webpack-sources");
+const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
+const NormalModule = require("./NormalModule");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin");
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+const ConcatenatedModule = require("./optimize/ConcatenatedModule");
+const generateDebugId = require("./util/generateDebugId");
+const { makePathsAbsolute } = require("./util/identifier");
+
+/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolNamespace} DevtoolNamespace */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolModuleFilenameTemplate} DevtoolModuleFilenameTemplate */
+/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
+/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").Rules} Rules */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+
+/** @type {WeakMap<Source, Source>} */
+const cache = new WeakMap();
+
+const devtoolWarning = new RawSource(`/*
+ * ATTENTION: An "eval-source-map" devtool has been used.
+ * This devtool is neither made for production nor for readable output files.
+ * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
+ * or disable the default devtool with "devtool: false".
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
+ */
+`);
+
+const PLUGIN_NAME = "EvalSourceMapDevToolPlugin";
+
+class EvalSourceMapDevToolPlugin {
+	/**
+	 * Creates an instance of EvalSourceMapDevToolPlugin.
+	 * @param {SourceMapDevToolPluginOptions | string=} inputOptions Options object
+	 */
+	constructor(inputOptions = {}) {
+		/** @type {SourceMapDevToolPluginOptions} */
+		let options;
+		if (typeof inputOptions === "string") {
+			options = {
+				append: inputOptions
+			};
+		} else {
+			options = inputOptions;
+		}
+		/** @type {string} */
+		this.sourceMapComment =
+			options.append && typeof options.append !== "function"
+				? options.append
+				: "//# sourceURL=[module]\n//# sourceMappingURL=[url]";
+		/** @type {DevtoolModuleFilenameTemplate} */
+		this.moduleFilenameTemplate =
+			options.moduleFilenameTemplate ||
+			"webpack://[namespace]/[resource-path]?[hash]";
+		/** @type {DevtoolNamespace} */
+		this.namespace = options.namespace || "";
+		/** @type {SourceMapDevToolPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const options = this.options;
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
+			new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation);
+			const matchModule = ModuleFilenameHelpers.matchObject.bind(
+				ModuleFilenameHelpers,
+				options
+			);
+			hooks.renderModuleContent.tap(
+				PLUGIN_NAME,
+				(source, m, { chunk, runtimeTemplate, chunkGraph }) => {
+					const cachedSource = cache.get(source);
+					if (cachedSource !== undefined) {
+						return cachedSource;
+					}
+
+					/**
+					 * Returns result.
+					 * @param {Source} r result
+					 * @returns {Source} result
+					 */
+					const result = (r) => {
+						cache.set(source, r);
+						return r;
+					};
+
+					if (m instanceof NormalModule) {
+						if (!matchModule(m.resource)) {
+							return result(source);
+						}
+					} else if (m instanceof ConcatenatedModule) {
+						if (m.rootModule instanceof NormalModule) {
+							if (!matchModule(m.rootModule.resource)) {
+								return result(source);
+							}
+						} else {
+							return result(source);
+						}
+					} else {
+						return result(source);
+					}
+
+					const namespace = compilation.getPath(this.namespace, {
+						chunk
+					});
+					/** @type {RawSourceMap} */
+					let sourceMap;
+					/** @type {string | Buffer} */
+					let content;
+					if (source.sourceAndMap) {
+						const sourceAndMap = source.sourceAndMap(options);
+						sourceMap = /** @type {RawSourceMap} */ (sourceAndMap.map);
+						content = sourceAndMap.source;
+					} else {
+						sourceMap = /** @type {RawSourceMap} */ (source.map(options));
+						content = source.source();
+					}
+					if (!sourceMap) {
+						return result(source);
+					}
+
+					// Clone (flat) the sourcemap to ensure that the mutations below do not persist.
+					sourceMap = { ...sourceMap };
+					const context = compiler.context;
+					const root = compiler.root;
+					const cachedAbsolutify = makePathsAbsolute.bindContextCache(
+						context,
+						root
+					);
+					const modules = sourceMap.sources.map((source) => {
+						if (!source.startsWith("webpack://")) return source;
+						source = cachedAbsolutify(source.slice(10));
+						const module = compilation.findModule(source);
+						return module || source;
+					});
+					let moduleFilenames = modules.map((module) =>
+						ModuleFilenameHelpers.createFilename(
+							module,
+							{
+								moduleFilenameTemplate: this.moduleFilenameTemplate,
+								namespace
+							},
+							{
+								requestShortener: runtimeTemplate.requestShortener,
+								chunkGraph,
+								hashFunction: compilation.outputOptions.hashFunction
+							}
+						)
+					);
+					moduleFilenames = ModuleFilenameHelpers.replaceDuplicates(
+						moduleFilenames,
+						(filename, i, n) => {
+							for (let j = 0; j < n; j++) filename += "*";
+							return filename;
+						}
+					);
+					sourceMap.sources = moduleFilenames;
+					if (options.ignoreList) {
+						const ignoreList = sourceMap.sources.reduce(
+							/** @type {(acc: number[], sourceName: string, idx: number) => number[]} */ (
+								(acc, sourceName, idx) => {
+									const rule = /** @type {Rules} */ (options.ignoreList);
+									if (ModuleFilenameHelpers.matchPart(sourceName, rule)) {
+										acc.push(idx);
+									}
+									return acc;
+								}
+							),
+							[]
+						);
+						if (ignoreList.length > 0) {
+							sourceMap.ignoreList = ignoreList;
+						}
+					}
+
+					if (options.noSources) {
+						sourceMap.sourcesContent = undefined;
+					}
+					sourceMap.sourceRoot = options.sourceRoot || "";
+					const moduleId =
+						/** @type {ModuleId} */
+						(chunkGraph.getModuleId(m));
+					sourceMap.file =
+						typeof moduleId === "number" ? `${moduleId}.js` : moduleId;
+
+					if (options.debugIds) {
+						sourceMap.debugId = generateDebugId(content, sourceMap.file);
+					}
+
+					const footer = `${this.sourceMapComment.replace(
+						/\[url\]/g,
+						`data:application/json;charset=utf-8;base64,${Buffer.from(
+							JSON.stringify(sourceMap),
+							"utf8"
+						).toString("base64")}`
+					)}\n//# sourceURL=webpack-internal:///${moduleId}\n`; // workaround for chrome bug
+
+					return result(
+						new RawSource(
+							`eval(${
+								compilation.outputOptions.trustedTypes
+									? `${RuntimeGlobals.createScript}(${JSON.stringify(
+											`{${content + footer}\n}`
+										)})`
+									: JSON.stringify(`{${content + footer}\n}`)
+							});`
+						)
+					);
+				}
+			);
+			hooks.inlineInRuntimeBailout.tap(
+				PLUGIN_NAME,
+				() => "the eval-source-map devtool is used."
+			);
+			hooks.render.tap(
+				PLUGIN_NAME,
+				(source) => new ConcatSource(devtoolWarning, source)
+			);
+			hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash) => {
+				hash.update(PLUGIN_NAME);
+				hash.update("2");
+			});
+			if (compilation.outputOptions.trustedTypes) {
+				compilation.hooks.additionalModuleRuntimeRequirements.tap(
+					PLUGIN_NAME,
+					(module, set, context) => {
+						set.add(RuntimeGlobals.createScript);
+					}
+				);
+			}
+		});
+	}
+}
+
+module.exports = EvalSourceMapDevToolPlugin;
Index: frontend/node_modules/webpack/lib/ExportsInfo.js
===================================================================
--- frontend/node_modules/webpack/lib/ExportsInfo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ExportsInfo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1713 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
+const { equals } = require("./util/ArrayHelpers");
+const SortableSet = require("./util/SortableSet");
+const makeSerializable = require("./util/makeSerializable");
+const { forEachRuntime } = require("./util/runtime");
+
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./Dependency").ExportInfoName} ExportInfoName */
+/** @typedef {import("./Dependency").ExportsSpecExcludeExports} ExportsSpecExcludeExports */
+/** @typedef {import("./dependencies/HarmonyImportDependency")} HarmonyImportDependency */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+
+/** @typedef {typeof UsageState.OnlyPropertiesUsed | typeof UsageState.NoInfo | typeof UsageState.Unknown | typeof UsageState.Used} RuntimeUsageStateType */
+/** @typedef {typeof UsageState.Unused | RuntimeUsageStateType} UsageStateType */
+
+/** @typedef {Map<string, RuntimeUsageStateType>} UsedInRuntime */
+/** @typedef {{ module: Module, export: ExportInfoName[], deferred: boolean }} TargetItemWithoutConnection */
+/** @typedef {{ module: Module, connection: ModuleGraphConnection, export: ExportInfoName[] | undefined }} TargetItemWithConnection */
+/** @typedef {(target: TargetItemWithConnection) => boolean} ResolveTargetFilter */
+/** @typedef {(module: Module) => boolean} ValidTargetModuleFilter */
+/** @typedef {{ connection: ModuleGraphConnection, export: ExportInfoName[], priority: number }} TargetItem */
+/** @typedef {Map<Dependency | undefined, TargetItem>} Target */
+
+/** @typedef {string | null} ExportInfoUsedName */
+/** @typedef {boolean | null} ExportInfoProvided */
+
+/** @typedef {Map<ExportInfoName, ExportInfo>} Exports */
+/** @typedef {string | string[] | false} UsedName */
+/** @typedef {Set<ExportInfo>} AlreadyVisitedExportInfo */
+
+/**
+ * Defines the restore provided data exports type used by this module.
+ * @typedef {object} RestoreProvidedDataExports
+ * @property {ExportInfoName} name
+ * @property {ExportInfo["provided"]} provided
+ * @property {ExportInfo["canMangleProvide"]} canMangleProvide
+ * @property {ExportInfo["terminalBinding"]} terminalBinding
+ * @property {RestoreProvidedData | undefined} exportsInfo
+ */
+
+const UsageState = Object.freeze({
+	Unused: /** @type {0} */ (0),
+	OnlyPropertiesUsed: /** @type {1} */ (1),
+	NoInfo: /** @type {2} */ (2),
+	Unknown: /** @type {3} */ (3),
+	Used: /** @type {4} */ (4)
+});
+
+const RETURNS_TRUE = () => true;
+
+const CIRCULAR = Symbol("circular target");
+
+class RestoreProvidedData {
+	/**
+	 * Creates an instance of RestoreProvidedData.
+	 * @param {RestoreProvidedDataExports[]} exports exports
+	 * @param {ExportInfo["provided"]} otherProvided other provided
+	 * @param {ExportInfo["canMangleProvide"]} otherCanMangleProvide other can mangle provide
+	 * @param {ExportInfo["terminalBinding"]} otherTerminalBinding other terminal binding
+	 */
+	constructor(
+		exports,
+		otherProvided,
+		otherCanMangleProvide,
+		otherTerminalBinding
+	) {
+		this.exports = exports;
+		this.otherProvided = otherProvided;
+		this.otherCanMangleProvide = otherCanMangleProvide;
+		this.otherTerminalBinding = otherTerminalBinding;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this.exports);
+		write(this.otherProvided);
+		write(this.otherCanMangleProvide);
+		write(this.otherTerminalBinding);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {RestoreProvidedData} RestoreProvidedData
+	 */
+	static deserialize({ read }) {
+		return new RestoreProvidedData(read(), read(), read(), read());
+	}
+}
+
+makeSerializable(
+	RestoreProvidedData,
+	"webpack/lib/ModuleGraph",
+	"RestoreProvidedData"
+);
+
+class ExportsInfo {
+	constructor() {
+		/** @type {Exports} */
+		this._exports = new Map();
+
+		// `_otherExportsInfo` is a fallback entry for unlisted exports. Two roles:
+		// 1. factory template — `getExportInfo` creates `new ExportInfo(name, this)`,
+		//    so created export info extends its properties.
+		// 2. flags whether the whole exportsInfo can be statically analyzed.
+		// Its `used` reachable values:
+		// 	- NoInfo: no use analysis yet (`optimization#usedExports` off), or used without info
+		// 	- Unused: analyzed, no unlisted export needed
+		// 	- Unknown: used in unknown way
+		// 	- Used/OnlyPropertiesUsed: never reached
+		// Its `provided` reachable values:
+		// 	- undefined: provision not determined yet
+		// 	- false: determined, no unlisted export is provided
+		// 	- null: only runtime knows (dynamic/unknown exports)
+		// 	- true: never reached
+		/** @type {ExportInfo} */
+		this._otherExportsInfo = new ExportInfo(null);
+		/** @type {ExportInfo} */
+		this._sideEffectsOnlyInfo = new ExportInfo("*side effects only*");
+		/** @type {boolean} */
+		this._exportsAreOrdered = false;
+		/** @type {ExportsInfo=} */
+		this._redirectTo = undefined;
+	}
+
+	/**
+	 * Gets owned exports.
+	 * @returns {Iterable<ExportInfo>} all owned exports in any order
+	 */
+	get ownedExports() {
+		return this._exports.values();
+	}
+
+	/**
+	 * Gets ordered owned exports.
+	 * @returns {Iterable<ExportInfo>} all owned exports in order
+	 */
+	get orderedOwnedExports() {
+		if (!this._exportsAreOrdered) {
+			this._sortExports();
+		}
+		return this._exports.values();
+	}
+
+	/**
+	 * Returns all exports in any order.
+	 * @returns {Iterable<ExportInfo>} all exports in any order
+	 */
+	get exports() {
+		if (this._redirectTo !== undefined) {
+			const map = new Map(this._redirectTo._exports);
+			for (const [key, value] of this._exports) {
+				map.set(key, value);
+			}
+			return map.values();
+		}
+		return this._exports.values();
+	}
+
+	/**
+	 * Gets ordered exports.
+	 * @returns {Iterable<ExportInfo>} all exports in order
+	 */
+	get orderedExports() {
+		if (!this._exportsAreOrdered) {
+			this._sortExports();
+		}
+		if (this._redirectTo !== undefined) {
+			/** @type {Exports} */
+			const map = new Map(
+				Array.from(this._redirectTo.orderedExports, (item) => [item.name, item])
+			);
+			for (const [key, value] of this._exports) {
+				map.set(key, value);
+			}
+			// sorting should be pretty fast as map contains
+			// a lot of presorted items
+			this._sortExportsMap(map);
+			return map.values();
+		}
+		return this._exports.values();
+	}
+
+	/**
+	 * Gets other exports info.
+	 * @returns {ExportInfo} the export info of unlisted exports
+	 */
+	get otherExportsInfo() {
+		if (this._redirectTo !== undefined) {
+			return this._redirectTo.otherExportsInfo;
+		}
+		return this._otherExportsInfo;
+	}
+
+	/**
+	 * Processes the provided export.
+	 * @param {Exports} exports exports
+	 * @private
+	 */
+	_sortExportsMap(exports) {
+		if (exports.size > 1) {
+			/** @type {ExportInfoName[]} */
+			const namesInOrder = [];
+			for (const entry of exports.values()) {
+				namesInOrder.push(entry.name);
+			}
+			namesInOrder.sort();
+			let i = 0;
+			for (const entry of exports.values()) {
+				const name = namesInOrder[i];
+				if (entry.name !== name) break;
+				i++;
+			}
+			for (; i < namesInOrder.length; i++) {
+				const name = namesInOrder[i];
+				const correctEntry = /** @type {ExportInfo} */ (exports.get(name));
+				exports.delete(name);
+				exports.set(name, correctEntry);
+			}
+		}
+	}
+
+	_sortExports() {
+		this._sortExportsMap(this._exports);
+		this._exportsAreOrdered = true;
+	}
+
+	/**
+	 * Sets redirect named to.
+	 * @param {ExportsInfo | undefined} exportsInfo exports info
+	 * @returns {boolean} result
+	 */
+	setRedirectNamedTo(exportsInfo) {
+		if (this._redirectTo === exportsInfo) return false;
+		this._redirectTo = exportsInfo;
+		return true;
+	}
+
+	setHasProvideInfo() {
+		for (const exportInfo of this._exports.values()) {
+			exportInfo.setHasProvideInfo();
+		}
+		if (this._redirectTo !== undefined) {
+			this._redirectTo.setHasProvideInfo();
+		} else {
+			this._otherExportsInfo.setHasProvideInfo();
+		}
+	}
+
+	setHasUseInfo() {
+		for (const exportInfo of this._exports.values()) {
+			exportInfo.setHasUseInfo();
+		}
+		this._sideEffectsOnlyInfo.setHasUseInfo();
+		if (this._redirectTo !== undefined) {
+			this._redirectTo.setHasUseInfo();
+		} else {
+			this._otherExportsInfo.setHasUseInfo();
+		}
+	}
+
+	/**
+	 * Gets own export info.
+	 * @param {ExportInfoName} name export name
+	 * @returns {ExportInfo} export info for this name
+	 */
+	getOwnExportInfo(name) {
+		const info = this._exports.get(name);
+		if (info !== undefined) return info;
+		const newInfo = new ExportInfo(name, this._otherExportsInfo);
+		this._exports.set(name, newInfo);
+		this._exportsAreOrdered = false;
+		return newInfo;
+	}
+
+	/**
+	 * Returns export info for this name.
+	 * @param {ExportInfoName} name export name
+	 * @returns {ExportInfo} export info for this name
+	 */
+	getExportInfo(name) {
+		const info = this._exports.get(name);
+		if (info !== undefined) return info;
+		if (this._redirectTo !== undefined) {
+			return this._redirectTo.getExportInfo(name);
+		}
+		const newInfo = new ExportInfo(name, this._otherExportsInfo);
+		this._exports.set(name, newInfo);
+		this._exportsAreOrdered = false;
+		return newInfo;
+	}
+
+	/**
+	 * Gets read only export info.
+	 * @param {ExportInfoName} name export name
+	 * @returns {ExportInfo} export info for this name
+	 */
+	getReadOnlyExportInfo(name) {
+		const info = this._exports.get(name);
+		if (info !== undefined) return info;
+		if (this._redirectTo !== undefined) {
+			return this._redirectTo.getReadOnlyExportInfo(name);
+		}
+		return this._otherExportsInfo;
+	}
+
+	/**
+	 * Gets read only export info recursive.
+	 * @param {ExportInfoName[]} name export name
+	 * @returns {ExportInfo | undefined} export info for this name
+	 */
+	getReadOnlyExportInfoRecursive(name) {
+		const exportInfo = this.getReadOnlyExportInfo(name[0]);
+		if (name.length === 1) return exportInfo;
+		if (!exportInfo.exportsInfo) return;
+		return exportInfo.exportsInfo.getReadOnlyExportInfoRecursive(name.slice(1));
+	}
+
+	/**
+	 * Gets nested exports info.
+	 * @param {ExportInfoName[]=} name the export name
+	 * @returns {ExportsInfo | undefined} the nested exports info
+	 */
+	getNestedExportsInfo(name) {
+		if (Array.isArray(name) && name.length > 0) {
+			const info = this.getReadOnlyExportInfo(name[0]);
+			if (!info.exportsInfo) return;
+			return info.exportsInfo.getNestedExportsInfo(name.slice(1));
+		}
+		return this;
+	}
+
+	/**
+	 * Sets unknown exports provided.
+	 * @param {boolean=} canMangle true, if exports can still be mangled (defaults to false)
+	 * @param {ExportsSpecExcludeExports=} excludeExports list of unaffected exports
+	 * @param {Dependency=} targetKey use this as key for the target
+	 * @param {ModuleGraphConnection=} targetModule set this module as target
+	 * @param {number=} priority priority
+	 * @returns {boolean} true, if this call changed something
+	 */
+	setUnknownExportsProvided(
+		canMangle,
+		excludeExports,
+		targetKey,
+		targetModule,
+		priority
+	) {
+		let changed = false;
+		if (excludeExports) {
+			for (const name of excludeExports) {
+				// Make sure these entries exist, so they can get different info
+				this.getExportInfo(name);
+			}
+		}
+		for (const exportInfo of this._exports.values()) {
+			if (!canMangle && exportInfo.canMangleProvide !== false) {
+				exportInfo.canMangleProvide = false;
+				changed = true;
+			}
+			if (excludeExports && excludeExports.has(exportInfo.name)) continue;
+			if (exportInfo.provided !== true && exportInfo.provided !== null) {
+				exportInfo.provided = null;
+				changed = true;
+			}
+			if (targetKey) {
+				exportInfo.setTarget(
+					targetKey,
+					/** @type {ModuleGraphConnection} */
+					(targetModule),
+					[exportInfo.name],
+					-1
+				);
+			}
+		}
+		if (this._redirectTo !== undefined) {
+			if (
+				this._redirectTo.setUnknownExportsProvided(
+					canMangle,
+					excludeExports,
+					targetKey,
+					targetModule,
+					priority
+				)
+			) {
+				changed = true;
+			}
+		} else {
+			if (
+				this._otherExportsInfo.provided !== true &&
+				this._otherExportsInfo.provided !== null
+			) {
+				this._otherExportsInfo.provided = null;
+				changed = true;
+			}
+			if (!canMangle && this._otherExportsInfo.canMangleProvide !== false) {
+				this._otherExportsInfo.canMangleProvide = false;
+				changed = true;
+			}
+			if (targetKey) {
+				this._otherExportsInfo.setTarget(
+					targetKey,
+					/** @type {ModuleGraphConnection} */ (targetModule),
+					undefined,
+					priority
+				);
+			}
+		}
+		return changed;
+	}
+
+	/**
+	 * Sets used in unknown way.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, when something changed
+	 */
+	setUsedInUnknownWay(runtime) {
+		let changed = false;
+		for (const exportInfo of this._exports.values()) {
+			if (exportInfo.setUsedInUnknownWay(runtime)) {
+				changed = true;
+			}
+		}
+		if (this._redirectTo !== undefined) {
+			if (this._redirectTo.setUsedInUnknownWay(runtime)) {
+				changed = true;
+			}
+		} else if (this._otherExportsInfo.setUsedInUnknownWay(runtime)) {
+			changed = true;
+		}
+		return changed;
+	}
+
+	/**
+	 * Sets used without info.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, when something changed
+	 */
+	setUsedWithoutInfo(runtime) {
+		let changed = false;
+		for (const exportInfo of this._exports.values()) {
+			if (exportInfo.setUsedWithoutInfo(runtime)) {
+				changed = true;
+			}
+		}
+		if (this._redirectTo !== undefined) {
+			if (this._redirectTo.setUsedWithoutInfo(runtime)) {
+				changed = true;
+			}
+		} else if (this._otherExportsInfo.setUsedWithoutInfo(runtime)) {
+			changed = true;
+		}
+		return changed;
+	}
+
+	/**
+	 * Sets all known exports used.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, when something changed
+	 */
+	setAllKnownExportsUsed(runtime) {
+		let changed = false;
+		for (const exportInfo of this._exports.values()) {
+			if (!exportInfo.provided) continue;
+			if (exportInfo.setUsed(UsageState.Used, runtime)) {
+				changed = true;
+			}
+		}
+		return changed;
+	}
+
+	/**
+	 * Sets used for side effects only.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, when something changed
+	 */
+	setUsedForSideEffectsOnly(runtime) {
+		return this._sideEffectsOnlyInfo.setUsedConditionally(
+			(used) => used === UsageState.Unused,
+			UsageState.Used,
+			runtime
+		);
+	}
+
+	/**
+	 * Checks whether this exports info is used.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, when the module exports are used in any way
+	 */
+	isUsed(runtime) {
+		if (this._redirectTo !== undefined) {
+			if (this._redirectTo.isUsed(runtime)) {
+				return true;
+			}
+		} else if (this._otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
+			return true;
+		}
+		for (const exportInfo of this._exports.values()) {
+			if (exportInfo.getUsed(runtime) !== UsageState.Unused) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether this exports info is module used.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, when the module is used in any way
+	 */
+	isModuleUsed(runtime) {
+		if (this.isUsed(runtime)) return true;
+		if (this._sideEffectsOnlyInfo.getUsed(runtime) !== UsageState.Unused) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns set of used exports, or true (when namespace object is used), or false (when unused), or null (when unknown).
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {SortableSet<ExportInfoName> | boolean | null} set of used exports, or true (when namespace object is used), or false (when unused), or null (when unknown)
+	 */
+	getUsedExports(runtime) {
+		switch (this._otherExportsInfo.getUsed(runtime)) {
+			case UsageState.NoInfo:
+				return null;
+			case UsageState.Unknown:
+			case UsageState.OnlyPropertiesUsed:
+			case UsageState.Used:
+				return true;
+		}
+
+		/** @type {ExportInfoName[]} */
+		const array = [];
+		if (!this._exportsAreOrdered) this._sortExports();
+		for (const exportInfo of this._exports.values()) {
+			switch (exportInfo.getUsed(runtime)) {
+				case UsageState.NoInfo:
+					return null;
+				case UsageState.Unknown:
+					return true;
+				case UsageState.OnlyPropertiesUsed:
+				case UsageState.Used:
+					array.push(exportInfo.name);
+			}
+		}
+		if (this._redirectTo !== undefined) {
+			const inner = this._redirectTo.getUsedExports(runtime);
+			if (inner === null) return null;
+			if (inner === true) return true;
+			if (inner !== false) {
+				for (const item of inner) {
+					array.push(item);
+				}
+			}
+		}
+		if (array.length === 0) {
+			switch (this._sideEffectsOnlyInfo.getUsed(runtime)) {
+				case UsageState.NoInfo:
+					return null;
+				case UsageState.Unused:
+					return false;
+			}
+		}
+		return /** @type {SortableSet<ExportInfoName>} */ (new SortableSet(array));
+	}
+
+	/**
+	 * Gets provided exports.
+	 * @returns {null | true | ExportInfoName[]} list of exports when known
+	 */
+	getProvidedExports() {
+		switch (this._otherExportsInfo.provided) {
+			case undefined:
+				return null;
+			case null:
+				return true;
+			case true:
+				return true;
+		}
+
+		/** @type {ExportInfoName[]} */
+		const array = [];
+		if (!this._exportsAreOrdered) this._sortExports();
+		for (const exportInfo of this._exports.values()) {
+			switch (exportInfo.provided) {
+				case undefined:
+					return null;
+				case null:
+					return true;
+				case true:
+					array.push(exportInfo.name);
+			}
+		}
+		if (this._redirectTo !== undefined) {
+			const inner = this._redirectTo.getProvidedExports();
+			if (inner === null) return null;
+			if (inner === true) return true;
+			for (const item of inner) {
+				if (!array.includes(item)) {
+					array.push(item);
+				}
+			}
+		}
+		return array;
+	}
+
+	/**
+	 * Gets relevant exports.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {ExportInfo[]} exports that are relevant (not unused and potential provided)
+	 */
+	getRelevantExports(runtime) {
+		/** @type {ExportInfo[]} */
+		const list = [];
+		for (const exportInfo of this._exports.values()) {
+			const used = exportInfo.getUsed(runtime);
+			if (used === UsageState.Unused) continue;
+			if (exportInfo.provided === false) continue;
+			list.push(exportInfo);
+		}
+		if (this._redirectTo !== undefined) {
+			for (const exportInfo of this._redirectTo.getRelevantExports(runtime)) {
+				if (!this._exports.has(exportInfo.name)) list.push(exportInfo);
+			}
+		}
+		if (
+			this._otherExportsInfo.provided !== false &&
+			this._otherExportsInfo.getUsed(runtime) !== UsageState.Unused
+		) {
+			list.push(this._otherExportsInfo);
+		}
+		return list;
+	}
+
+	/**
+	 * Checks whether this exports info is export provided.
+	 * @param {ExportInfoName | ExportInfoName[]} name the name of the export
+	 * @returns {boolean | undefined | null} if the export is provided
+	 */
+	isExportProvided(name) {
+		if (Array.isArray(name)) {
+			const info = this.getReadOnlyExportInfo(name[0]);
+			if (info.exportsInfo && name.length > 1) {
+				return info.exportsInfo.isExportProvided(name.slice(1));
+			}
+			return info.provided ? name.length === 1 || undefined : info.provided;
+		}
+		const info = this.getReadOnlyExportInfo(name);
+		return info.provided;
+	}
+
+	/**
+	 * Returns key representing the usage.
+	 * @param {RuntimeSpec} runtime runtime
+	 * @returns {string} key representing the usage
+	 */
+	getUsageKey(runtime) {
+		/** @type {(string | number)[]} */
+		const key = [];
+		if (this._redirectTo !== undefined) {
+			key.push(this._redirectTo.getUsageKey(runtime));
+		} else {
+			key.push(this._otherExportsInfo.getUsed(runtime));
+		}
+		key.push(this._sideEffectsOnlyInfo.getUsed(runtime));
+		for (const exportInfo of this.orderedOwnedExports) {
+			key.push(exportInfo.getUsed(runtime));
+		}
+		return key.join("|");
+	}
+
+	/**
+	 * Checks whether this exports info is equally used.
+	 * @param {RuntimeSpec} runtimeA first runtime
+	 * @param {RuntimeSpec} runtimeB second runtime
+	 * @returns {boolean} true, when equally used
+	 */
+	isEquallyUsed(runtimeA, runtimeB) {
+		if (this._redirectTo !== undefined) {
+			if (!this._redirectTo.isEquallyUsed(runtimeA, runtimeB)) return false;
+		} else if (
+			this._otherExportsInfo.getUsed(runtimeA) !==
+			this._otherExportsInfo.getUsed(runtimeB)
+		) {
+			return false;
+		}
+		if (
+			this._sideEffectsOnlyInfo.getUsed(runtimeA) !==
+			this._sideEffectsOnlyInfo.getUsed(runtimeB)
+		) {
+			return false;
+		}
+		for (const exportInfo of this.ownedExports) {
+			if (exportInfo.getUsed(runtimeA) !== exportInfo.getUsed(runtimeB)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Returns usage status.
+	 * @param {ExportInfoName | ExportInfoName[]} name export name
+	 * @param {RuntimeSpec} runtime check usage for this runtime only
+	 * @returns {UsageStateType} usage status
+	 */
+	getUsed(name, runtime) {
+		if (Array.isArray(name)) {
+			if (name.length === 0) return this.otherExportsInfo.getUsed(runtime);
+			const info = this.getReadOnlyExportInfo(name[0]);
+			if (info.exportsInfo && name.length > 1) {
+				return info.exportsInfo.getUsed(name.slice(1), runtime);
+			}
+			return info.getUsed(runtime);
+		}
+		const info = this.getReadOnlyExportInfo(name);
+		return info.getUsed(runtime);
+	}
+
+	/**
+	 * Returns the used name.
+	 * @param {ExportInfoName | ExportInfoName[]} name the export name
+	 * @param {RuntimeSpec} runtime check usage for this runtime only
+	 * @returns {UsedName} the used name
+	 */
+	getUsedName(name, runtime) {
+		if (Array.isArray(name)) {
+			// TODO improve this
+			if (name.length === 0) {
+				if (!this.isUsed(runtime)) return false;
+				return name;
+			}
+			const info = this.getReadOnlyExportInfo(name[0]);
+			const x = info.getUsedName(name[0], runtime);
+			if (x === false) return false;
+			const arr =
+				/** @type {ExportInfoName[]} */
+				(x === name[0] && name.length === 1 ? name : [x]);
+			if (name.length === 1) {
+				return arr;
+			}
+			if (
+				info.exportsInfo &&
+				info.getUsed(runtime) === UsageState.OnlyPropertiesUsed
+			) {
+				const nested = info.exportsInfo.getUsedName(name.slice(1), runtime);
+				if (!nested) return false;
+				return [...arr, ...(Array.isArray(nested) ? nested : [nested])];
+			}
+			return [...arr, ...name.slice(1)];
+		}
+		const info = this.getReadOnlyExportInfo(name);
+		const usedName = info.getUsedName(name, runtime);
+		return usedName;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {void}
+	 */
+	updateHash(hash, runtime) {
+		this._updateHash(hash, runtime, new Set());
+	}
+
+	/**
+	 * Updates hash using the provided hash.
+	 * @param {Hash} hash the hash
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {Set<ExportsInfo>} alreadyVisitedExportsInfo for circular references
+	 * @returns {void}
+	 */
+	_updateHash(hash, runtime, alreadyVisitedExportsInfo) {
+		const set = new Set(alreadyVisitedExportsInfo);
+		set.add(this);
+		for (const exportInfo of this.orderedExports) {
+			if (exportInfo.hasInfo(this._otherExportsInfo, runtime)) {
+				exportInfo._updateHash(hash, runtime, set);
+			}
+		}
+		this._sideEffectsOnlyInfo._updateHash(hash, runtime, set);
+		this._otherExportsInfo._updateHash(hash, runtime, set);
+		if (this._redirectTo !== undefined) {
+			this._redirectTo._updateHash(hash, runtime, set);
+		}
+	}
+
+	/**
+	 * Gets restore provided data.
+	 * @returns {RestoreProvidedData} restore provided data
+	 */
+	getRestoreProvidedData() {
+		const otherProvided = this._otherExportsInfo.provided;
+		const otherCanMangleProvide = this._otherExportsInfo.canMangleProvide;
+		const otherTerminalBinding = this._otherExportsInfo.terminalBinding;
+		/** @type {RestoreProvidedDataExports[]} */
+		const exports = [];
+		for (const exportInfo of this.orderedExports) {
+			if (
+				exportInfo.provided !== otherProvided ||
+				exportInfo.canMangleProvide !== otherCanMangleProvide ||
+				exportInfo.terminalBinding !== otherTerminalBinding ||
+				exportInfo.exportsInfoOwned
+			) {
+				exports.push({
+					name: exportInfo.name,
+					provided: exportInfo.provided,
+					canMangleProvide: exportInfo.canMangleProvide,
+					terminalBinding: exportInfo.terminalBinding,
+					exportsInfo: exportInfo.exportsInfoOwned
+						? /** @type {NonNullable<ExportInfo["exportsInfo"]>} */
+							(exportInfo.exportsInfo).getRestoreProvidedData()
+						: undefined
+				});
+			}
+		}
+		return new RestoreProvidedData(
+			exports,
+			otherProvided,
+			otherCanMangleProvide,
+			otherTerminalBinding
+		);
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {RestoreProvidedData} data data
+	 */
+	restoreProvided({
+		otherProvided,
+		otherCanMangleProvide,
+		otherTerminalBinding,
+		exports
+	}) {
+		let wasEmpty = true;
+		for (const exportInfo of this._exports.values()) {
+			wasEmpty = false;
+			exportInfo.provided = otherProvided;
+			exportInfo.canMangleProvide = otherCanMangleProvide;
+			exportInfo.terminalBinding = otherTerminalBinding;
+		}
+		this._otherExportsInfo.provided = otherProvided;
+		this._otherExportsInfo.canMangleProvide = otherCanMangleProvide;
+		this._otherExportsInfo.terminalBinding = otherTerminalBinding;
+		for (const exp of exports) {
+			const exportInfo = this.getExportInfo(exp.name);
+			exportInfo.provided = exp.provided;
+			exportInfo.canMangleProvide = exp.canMangleProvide;
+			exportInfo.terminalBinding = exp.terminalBinding;
+			if (exp.exportsInfo) {
+				const exportsInfo = exportInfo.createNestedExportsInfo();
+				exportsInfo.restoreProvided(exp.exportsInfo);
+			}
+		}
+		if (wasEmpty) this._exportsAreOrdered = true;
+	}
+}
+
+class ExportInfo {
+	/**
+	 * Creates an instance of ExportInfo.
+	 * @param {ExportInfoName | null} name the original name of the export
+	 * @param {ExportInfo=} initFrom init values from this ExportInfo
+	 */
+	constructor(name, initFrom) {
+		/** @type {ExportInfoName} */
+		this.name = /** @type {ExportInfoName} */ (name);
+		/**
+		 * @private
+		 * @type {ExportInfoUsedName}
+		 */
+		this._usedName = initFrom ? initFrom._usedName : null;
+		/**
+		 * @private
+		 * @type {UsageStateType | undefined}
+		 */
+		this._globalUsed = initFrom ? initFrom._globalUsed : undefined;
+		/**
+		 * @private
+		 * @type {UsedInRuntime | undefined}
+		 */
+		this._usedInRuntime =
+			initFrom && initFrom._usedInRuntime
+				? new Map(initFrom._usedInRuntime)
+				: undefined;
+		/**
+		 * @private
+		 * @type {boolean}
+		 */
+		this._hasUseInRuntimeInfo = initFrom
+			? initFrom._hasUseInRuntimeInfo
+			: false;
+		/**
+		 * true: it is provided
+		 * false: it is not provided
+		 * null: only the runtime knows if it is provided
+		 * undefined: it was not determined if it is provided
+		 * @type {ExportInfoProvided | undefined}
+		 */
+		this.provided = initFrom ? initFrom.provided : undefined;
+		/**
+		 * is the export a terminal binding that should be checked for export star conflicts
+		 * @type {boolean}
+		 */
+		this.terminalBinding = initFrom ? initFrom.terminalBinding : false;
+		/**
+		 * true: it can be mangled
+		 * false: is can not be mangled
+		 * undefined: it was not determined if it can be mangled
+		 * @type {boolean | undefined}
+		 */
+		this.canMangleProvide = initFrom ? initFrom.canMangleProvide : undefined;
+		/**
+		 * true: it can be mangled
+		 * false: is can not be mangled
+		 * undefined: it was not determined if it can be mangled
+		 * @type {boolean | undefined}
+		 */
+		this.canMangleUse = initFrom ? initFrom.canMangleUse : undefined;
+		/** @type {boolean} */
+		this.exportsInfoOwned = false;
+		/** @type {ExportsInfo | undefined} */
+		this.exportsInfo = undefined;
+		/** @type {Target | undefined} */
+		this._target = undefined;
+		if (initFrom && initFrom._target) {
+			this._target = /** @type {Target} */ (new Map());
+			for (const [key, value] of initFrom._target) {
+				this._target.set(key, {
+					connection: value.connection,
+					export: value.export || [name],
+					priority: value.priority
+				});
+			}
+		}
+		/** @type {Target | undefined} */
+		this._maxTarget = undefined;
+	}
+
+	get canMangle() {
+		switch (this.canMangleProvide) {
+			case undefined:
+				return this.canMangleUse === false ? false : undefined;
+			case false:
+				return false;
+			case true:
+				switch (this.canMangleUse) {
+					case undefined:
+						return undefined;
+					case false:
+						return false;
+					case true:
+						return true;
+				}
+		}
+		throw new Error(
+			`Unexpected flags for canMangle ${this.canMangleProvide} ${this.canMangleUse}`
+		);
+	}
+
+	/**
+	 * Sets used in unknown way.
+	 * @param {RuntimeSpec} runtime only apply to this runtime
+	 * @returns {boolean} true, when something changed
+	 */
+	setUsedInUnknownWay(runtime) {
+		let changed = false;
+		if (
+			this.setUsedConditionally(
+				(used) => used < UsageState.Unknown,
+				UsageState.Unknown,
+				runtime
+			)
+		) {
+			changed = true;
+		}
+		if (this.canMangleUse !== false) {
+			this.canMangleUse = false;
+			changed = true;
+		}
+		return changed;
+	}
+
+	/**
+	 * Sets used without info.
+	 * @param {RuntimeSpec} runtime only apply to this runtime
+	 * @returns {boolean} true, when something changed
+	 */
+	setUsedWithoutInfo(runtime) {
+		let changed = false;
+		if (this.setUsed(UsageState.NoInfo, runtime)) {
+			changed = true;
+		}
+		if (this.canMangleUse !== false) {
+			this.canMangleUse = false;
+			changed = true;
+		}
+		return changed;
+	}
+
+	setHasProvideInfo() {
+		if (this.provided === undefined) {
+			this.provided = false;
+		}
+		if (this.canMangleProvide === undefined) {
+			this.canMangleProvide = true;
+		}
+	}
+
+	setHasUseInfo() {
+		if (!this._hasUseInRuntimeInfo) {
+			this._hasUseInRuntimeInfo = true;
+		}
+		if (this.canMangleUse === undefined) {
+			this.canMangleUse = true;
+		}
+		if (this.exportsInfoOwned) {
+			/** @type {ExportsInfo} */
+			(this.exportsInfo).setHasUseInfo();
+		}
+	}
+
+	/**
+	 * Sets used conditionally.
+	 * @param {(condition: UsageStateType) => boolean} condition compare with old value
+	 * @param {UsageStateType} newValue set when condition is true
+	 * @param {RuntimeSpec} runtime only apply to this runtime
+	 * @returns {boolean} true when something has changed
+	 */
+	setUsedConditionally(condition, newValue, runtime) {
+		if (runtime === undefined) {
+			if (this._globalUsed === undefined) {
+				this._globalUsed = newValue;
+				return true;
+			}
+			if (this._globalUsed !== newValue && condition(this._globalUsed)) {
+				this._globalUsed = newValue;
+				return true;
+			}
+		} else if (this._usedInRuntime === undefined) {
+			if (newValue !== UsageState.Unused && condition(UsageState.Unused)) {
+				this._usedInRuntime = new Map();
+				forEachRuntime(runtime, (runtime) =>
+					/** @type {UsedInRuntime} */
+					(this._usedInRuntime).set(/** @type {string} */ (runtime), newValue)
+				);
+				return true;
+			}
+		} else {
+			let changed = false;
+			forEachRuntime(runtime, (runtime_) => {
+				const runtime = /** @type {string} */ (runtime_);
+				const usedInRuntime =
+					/** @type {UsedInRuntime} */
+					(this._usedInRuntime);
+				let oldValue =
+					/** @type {UsageStateType} */
+					(usedInRuntime.get(runtime));
+				if (oldValue === undefined) oldValue = UsageState.Unused;
+				if (newValue !== oldValue && condition(oldValue)) {
+					if (newValue === UsageState.Unused) {
+						usedInRuntime.delete(runtime);
+					} else {
+						usedInRuntime.set(runtime, newValue);
+					}
+					changed = true;
+				}
+			});
+			if (changed) {
+				if (this._usedInRuntime.size === 0) this._usedInRuntime = undefined;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Updates used using the provided new value.
+	 * @param {UsageStateType} newValue new value of the used state
+	 * @param {RuntimeSpec} runtime only apply to this runtime
+	 * @returns {boolean} true when something has changed
+	 */
+	setUsed(newValue, runtime) {
+		if (runtime === undefined) {
+			if (this._globalUsed !== newValue) {
+				this._globalUsed = newValue;
+				return true;
+			}
+		} else if (this._usedInRuntime === undefined) {
+			if (newValue !== UsageState.Unused) {
+				this._usedInRuntime = new Map();
+				forEachRuntime(runtime, (runtime) =>
+					/** @type {UsedInRuntime} */
+					(this._usedInRuntime).set(/** @type {string} */ (runtime), newValue)
+				);
+				return true;
+			}
+		} else {
+			let changed = false;
+			forEachRuntime(runtime, (_runtime) => {
+				const runtime = /** @type {string} */ (_runtime);
+				const usedInRuntime =
+					/** @type {UsedInRuntime} */
+					(this._usedInRuntime);
+				let oldValue =
+					/** @type {UsageStateType} */
+					(usedInRuntime.get(runtime));
+				if (oldValue === undefined) oldValue = UsageState.Unused;
+				if (newValue !== oldValue) {
+					if (newValue === UsageState.Unused) {
+						usedInRuntime.delete(runtime);
+					} else {
+						usedInRuntime.set(runtime, newValue);
+					}
+					changed = true;
+				}
+			});
+			if (changed) {
+				if (this._usedInRuntime.size === 0) this._usedInRuntime = undefined;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns true, if something has changed.
+	 * @param {Dependency} key the key
+	 * @returns {boolean} true, if something has changed
+	 */
+	unsetTarget(key) {
+		if (!this._target) return false;
+		if (this._target.delete(key)) {
+			this._maxTarget = undefined;
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Updates target using the provided key.
+	 * @param {Dependency} key the key
+	 * @param {ModuleGraphConnection} connection the target module if a single one
+	 * @param {ExportInfoName[] | null=} exportName the exported name
+	 * @param {number=} priority priority
+	 * @returns {boolean} true, if something has changed
+	 */
+	setTarget(key, connection, exportName, priority = 0) {
+		if (exportName) exportName = [...exportName];
+		if (!this._target) {
+			this._target = /** @type {Target} */ (new Map());
+			this._target.set(key, {
+				connection,
+				export: /** @type {ExportInfoName[]} */ (exportName),
+				priority
+			});
+			return true;
+		}
+		const oldTarget = this._target.get(key);
+		if (!oldTarget) {
+			if (oldTarget === null && !connection) return false;
+			this._target.set(key, {
+				connection,
+				export: /** @type {ExportInfoName[]} */ (exportName),
+				priority
+			});
+			this._maxTarget = undefined;
+			return true;
+		}
+		if (
+			oldTarget.connection !== connection ||
+			oldTarget.priority !== priority ||
+			(exportName
+				? !oldTarget.export || !equals(oldTarget.export, exportName)
+				: oldTarget.export)
+		) {
+			oldTarget.connection = connection;
+			oldTarget.export = /** @type {ExportInfoName[]} */ (exportName);
+			oldTarget.priority = priority;
+			this._maxTarget = undefined;
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns usage state.
+	 * @param {RuntimeSpec} runtime for this runtime
+	 * @returns {UsageStateType} usage state
+	 */
+	getUsed(runtime) {
+		if (!this._hasUseInRuntimeInfo) return UsageState.NoInfo;
+		if (this._globalUsed !== undefined) return this._globalUsed;
+		if (this._usedInRuntime === undefined) {
+			return UsageState.Unused;
+		} else if (typeof runtime === "string") {
+			const value = this._usedInRuntime.get(runtime);
+			return value === undefined ? UsageState.Unused : value;
+		} else if (runtime === undefined) {
+			/** @type {UsageStateType} */
+			let max = UsageState.Unused;
+			for (const value of this._usedInRuntime.values()) {
+				if (value === UsageState.Used) {
+					return UsageState.Used;
+				}
+				if (max < value) max = value;
+			}
+			return max;
+		}
+
+		/** @type {UsageStateType} */
+		let max = UsageState.Unused;
+		for (const item of runtime) {
+			const value = this._usedInRuntime.get(item);
+			if (value !== undefined) {
+				if (value === UsageState.Used) {
+					return UsageState.Used;
+				}
+				if (max < value) max = value;
+			}
+		}
+		return max;
+	}
+
+	/**
+	 * Returns used name.
+	 * @param {string | undefined} fallbackName fallback name for used exports with no name
+	 * @param {RuntimeSpec} runtime check usage for this runtime only
+	 * @returns {string | false} used name
+	 */
+	getUsedName(fallbackName, runtime) {
+		if (this._hasUseInRuntimeInfo) {
+			if (this._globalUsed !== undefined) {
+				if (this._globalUsed === UsageState.Unused) return false;
+			} else {
+				if (this._usedInRuntime === undefined) return false;
+				if (typeof runtime === "string") {
+					if (!this._usedInRuntime.has(runtime)) {
+						return false;
+					}
+				} else if (
+					runtime !== undefined &&
+					[...runtime].every(
+						(runtime) =>
+							!(/** @type {UsedInRuntime} */ (this._usedInRuntime).has(runtime))
+					)
+				) {
+					return false;
+				}
+			}
+		}
+		if (this._usedName !== null) return this._usedName;
+		return /** @type {string | false} */ (this.name || fallbackName);
+	}
+
+	/**
+	 * Checks whether this export info has used name.
+	 * @returns {boolean} true, when a mangled name of this export is set
+	 */
+	hasUsedName() {
+		return this._usedName !== null;
+	}
+
+	/**
+	 * Updates used name using the provided name.
+	 * @param {string} name the new name
+	 * @returns {void}
+	 */
+	setUsedName(name) {
+		this._usedName = name;
+	}
+
+	/**
+	 * Gets terminal binding.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ResolveTargetFilter} resolveTargetFilter filter function to further resolve target
+	 * @returns {ExportInfo | ExportsInfo | undefined} the terminal binding export(s) info if known
+	 */
+	getTerminalBinding(moduleGraph, resolveTargetFilter = RETURNS_TRUE) {
+		if (this.terminalBinding) return this;
+		const target = this.getTarget(moduleGraph, resolveTargetFilter);
+		if (!target) return;
+		const exportsInfo = moduleGraph.getExportsInfo(target.module);
+		if (!target.export) return exportsInfo;
+		return exportsInfo.getReadOnlyExportInfoRecursive(target.export);
+	}
+
+	isReexport() {
+		return !this.terminalBinding && this._target && this._target.size > 0;
+	}
+
+	_getMaxTarget() {
+		if (this._maxTarget !== undefined) return this._maxTarget;
+		if (/** @type {Target} */ (this._target).size <= 1) {
+			return (this._maxTarget = this._target);
+		}
+		let maxPriority = -Infinity;
+		let minPriority = Infinity;
+		for (const { priority } of /** @type {Target} */ (this._target).values()) {
+			if (maxPriority < priority) maxPriority = priority;
+			if (minPriority > priority) minPriority = priority;
+		}
+		// This should be very common
+		if (maxPriority === minPriority) return (this._maxTarget = this._target);
+
+		// This is an edge case
+		/** @type {Target} */
+		const map = new Map();
+		for (const [key, value] of /** @type {Target} */ (this._target)) {
+			if (maxPriority === value.priority) {
+				map.set(key, value);
+			}
+		}
+		this._maxTarget = map;
+		return map;
+	}
+
+	/**
+	 * Returns the target, undefined when there is no target, false when no target is valid.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ValidTargetModuleFilter} validTargetModuleFilter a valid target module
+	 * @returns {TargetItemWithoutConnection | null | undefined | false} the target, undefined when there is no target, false when no target is valid
+	 */
+	findTarget(moduleGraph, validTargetModuleFilter) {
+		return this._findTarget(moduleGraph, validTargetModuleFilter, new Set());
+	}
+
+	/**
+	 * Returns the target, undefined when there is no target, false when no target is valid.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ValidTargetModuleFilter} validTargetModuleFilter a valid target module
+	 * @param {AlreadyVisitedExportInfo} alreadyVisited set of already visited export info to avoid circular references
+	 * @returns {TargetItemWithoutConnection | null | undefined | false} the target, undefined when there is no target, false when no target is valid
+	 */
+	_findTarget(moduleGraph, validTargetModuleFilter, alreadyVisited) {
+		if (!this._target || this._target.size === 0) return;
+		const rawTarget =
+			/** @type {Target} */
+			(this._getMaxTarget()).values().next().value;
+		if (!rawTarget) return;
+		/** @type {TargetItemWithoutConnection} */
+		let target = {
+			module: rawTarget.connection.module,
+			export: rawTarget.export,
+			deferred: Boolean(
+				rawTarget.connection.dependency &&
+				ImportPhaseUtils.isDefer(
+					/** @type {HarmonyImportDependency} */ (
+						rawTarget.connection.dependency
+					).phase
+				)
+			)
+		};
+		for (;;) {
+			if (validTargetModuleFilter(target.module)) return target;
+			const exportsInfo = moduleGraph.getExportsInfo(target.module);
+			const exportInfo = exportsInfo.getExportInfo(target.export[0]);
+			if (alreadyVisited.has(exportInfo)) return null;
+			const newTarget = exportInfo._findTarget(
+				moduleGraph,
+				validTargetModuleFilter,
+				alreadyVisited
+			);
+			if (!newTarget) return false;
+			if (target.export.length === 1) {
+				target = newTarget;
+			} else {
+				target = {
+					module: newTarget.module,
+					export: newTarget.export
+						? [...newTarget.export, ...target.export.slice(1)]
+						: target.export.slice(1),
+					deferred: newTarget.deferred
+				};
+			}
+		}
+	}
+
+	/**
+	 * Returns the target.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ResolveTargetFilter} resolveTargetFilter filter function to further resolve target
+	 * @returns {TargetItemWithConnection | undefined} the target
+	 */
+	getTarget(moduleGraph, resolveTargetFilter = RETURNS_TRUE) {
+		const result = this._getTarget(moduleGraph, resolveTargetFilter, undefined);
+		if (result === CIRCULAR) return;
+		return result;
+	}
+
+	/**
+	 * Returns the target.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ResolveTargetFilter} resolveTargetFilter filter function to further resolve target
+	 * @param {AlreadyVisitedExportInfo | undefined} alreadyVisited set of already visited export info to avoid circular references
+	 * @returns {TargetItemWithConnection | CIRCULAR | undefined} the target
+	 */
+	_getTarget(moduleGraph, resolveTargetFilter, alreadyVisited) {
+		/**
+		 * Returns resolved target.
+		 * @param {TargetItem | undefined | null} inputTarget unresolved target
+		 * @param {AlreadyVisitedExportInfo} alreadyVisited set of already visited export info to avoid circular references
+		 * @returns {TargetItemWithConnection | CIRCULAR | null} resolved target
+		 */
+		const resolveTarget = (inputTarget, alreadyVisited) => {
+			if (!inputTarget) return null;
+			if (!inputTarget.export) {
+				return {
+					module: inputTarget.connection.module,
+					connection: inputTarget.connection,
+					export: undefined
+				};
+			}
+			/** @type {TargetItemWithConnection} */
+			let target = {
+				module: inputTarget.connection.module,
+				connection: inputTarget.connection,
+				export: inputTarget.export
+			};
+			if (!resolveTargetFilter(target)) return target;
+			let alreadyVisitedOwned = false;
+			for (;;) {
+				const exportsInfo = moduleGraph.getExportsInfo(target.module);
+				const exportInfo = exportsInfo.getExportInfo(
+					/** @type {NonNullable<TargetItemWithConnection["export"]>} */
+					(target.export)[0]
+				);
+				if (!exportInfo) return target;
+				if (alreadyVisited.has(exportInfo)) return CIRCULAR;
+				const newTarget = exportInfo._getTarget(
+					moduleGraph,
+					resolveTargetFilter,
+					alreadyVisited
+				);
+				if (newTarget === CIRCULAR) return CIRCULAR;
+				if (!newTarget) return target;
+				if (
+					/** @type {NonNullable<TargetItemWithConnection["export"]>} */
+					(target.export).length === 1
+				) {
+					target = newTarget;
+					if (!target.export) return target;
+				} else {
+					target = {
+						module: newTarget.module,
+						connection: newTarget.connection,
+						export: newTarget.export
+							? [
+									...newTarget.export,
+									.../** @type {NonNullable<TargetItemWithConnection["export"]>} */
+									(target.export).slice(1)
+								]
+							: /** @type {NonNullable<TargetItemWithConnection["export"]>} */
+								(target.export).slice(1)
+					};
+				}
+				if (!resolveTargetFilter(target)) return target;
+				if (!alreadyVisitedOwned) {
+					alreadyVisited = new Set(alreadyVisited);
+					alreadyVisitedOwned = true;
+				}
+				alreadyVisited.add(exportInfo);
+			}
+		};
+
+		if (!this._target || this._target.size === 0) return;
+		if (alreadyVisited && alreadyVisited.has(this)) return CIRCULAR;
+		const newAlreadyVisited = new Set(alreadyVisited);
+		newAlreadyVisited.add(this);
+		const values = /** @type {Target} */ (this._getMaxTarget()).values();
+		const target = resolveTarget(values.next().value, newAlreadyVisited);
+		if (target === CIRCULAR) return CIRCULAR;
+		if (target === null) return;
+		let result = values.next();
+		while (!result.done) {
+			const t = resolveTarget(result.value, newAlreadyVisited);
+			if (t === CIRCULAR) return CIRCULAR;
+			if (t === null) return;
+			if (t.module !== target.module) return;
+			if (!t.export !== !target.export) return;
+			if (
+				target.export &&
+				!equals(/** @type {ArrayLike<string>} */ (t.export), target.export)
+			) {
+				return;
+			}
+			result = values.next();
+		}
+		return target;
+	}
+
+	/**
+	 * Move the target forward as long resolveTargetFilter is fulfilled
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ResolveTargetFilter} resolveTargetFilter filter function to further resolve target
+	 * @param {(target: TargetItemWithConnection) => ModuleGraphConnection=} updateOriginalConnection updates the original connection instead of using the target connection
+	 * @returns {TargetItemWithConnection | undefined} the resolved target when moved
+	 */
+	moveTarget(moduleGraph, resolveTargetFilter, updateOriginalConnection) {
+		const target = this._getTarget(moduleGraph, resolveTargetFilter, undefined);
+		if (target === CIRCULAR) return;
+		if (!target) return;
+		const originalTarget =
+			/** @type {TargetItem} */
+			(
+				/** @type {Target} */
+				(this._getMaxTarget()).values().next().value
+			);
+		if (
+			originalTarget.connection === target.connection &&
+			originalTarget.export === target.export
+		) {
+			return;
+		}
+		/** @type {Target} */
+		(this._target).clear();
+		/** @type {Target} */
+		(this._target).set(undefined, {
+			connection: updateOriginalConnection
+				? updateOriginalConnection(target)
+				: target.connection,
+			export: /** @type {NonNullable<TargetItemWithConnection["export"]>} */ (
+				target.export
+			),
+			priority: 0
+		});
+		return target;
+	}
+
+	/**
+	 * Creates a nested exports info.
+	 * @returns {ExportsInfo} an exports info
+	 */
+	createNestedExportsInfo() {
+		if (this.exportsInfoOwned) {
+			return /** @type {ExportsInfo} */ (this.exportsInfo);
+		}
+		this.exportsInfoOwned = true;
+		const oldExportsInfo = this.exportsInfo;
+		this.exportsInfo = new ExportsInfo();
+		this.exportsInfo.setHasProvideInfo();
+		if (oldExportsInfo) {
+			this.exportsInfo.setRedirectNamedTo(oldExportsInfo);
+		}
+		return this.exportsInfo;
+	}
+
+	getNestedExportsInfo() {
+		return this.exportsInfo;
+	}
+
+	/**
+	 * Checks whether this export info contains the base info.
+	 * @param {ExportInfo} baseInfo base info
+	 * @param {RuntimeSpec} runtime runtime
+	 * @returns {boolean} true when has info, otherwise false
+	 */
+	hasInfo(baseInfo, runtime) {
+		return (
+			(this._usedName && this._usedName !== this.name) ||
+			this.provided ||
+			this.terminalBinding ||
+			this.getUsed(runtime) !== baseInfo.getUsed(runtime)
+		);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {void}
+	 */
+	updateHash(hash, runtime) {
+		this._updateHash(hash, runtime, new Set());
+	}
+
+	/**
+	 * Updates hash using the provided hash.
+	 * @param {Hash} hash the hash
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {Set<ExportsInfo>} alreadyVisitedExportsInfo for circular references
+	 */
+	_updateHash(hash, runtime, alreadyVisitedExportsInfo) {
+		hash.update(
+			`${this._usedName || this.name}${this.getUsed(runtime)}${this.provided}${
+				this.terminalBinding
+			}`
+		);
+		if (this.exportsInfo && !alreadyVisitedExportsInfo.has(this.exportsInfo)) {
+			this.exportsInfo._updateHash(hash, runtime, alreadyVisitedExportsInfo);
+		}
+	}
+
+	getUsedInfo() {
+		if (this._globalUsed !== undefined) {
+			switch (this._globalUsed) {
+				case UsageState.Unused:
+					return "unused";
+				case UsageState.NoInfo:
+					return "no usage info";
+				case UsageState.Unknown:
+					return "maybe used (runtime-defined)";
+				case UsageState.Used:
+					return "used";
+				case UsageState.OnlyPropertiesUsed:
+					return "only properties used";
+			}
+		} else if (this._usedInRuntime !== undefined) {
+			/** @type {Map<RuntimeUsageStateType, string[]>} */
+			const map = new Map();
+			for (const [runtime, used] of this._usedInRuntime) {
+				const list = map.get(used);
+				if (list !== undefined) list.push(runtime);
+				else map.set(used, [runtime]);
+			}
+			// eslint-disable-next-line array-callback-return
+			const specificInfo = Array.from(map, ([used, runtimes]) => {
+				switch (used) {
+					case UsageState.NoInfo:
+						return `no usage info in ${runtimes.join(", ")}`;
+					case UsageState.Unknown:
+						return `maybe used in ${runtimes.join(", ")} (runtime-defined)`;
+					case UsageState.Used:
+						return `used in ${runtimes.join(", ")}`;
+					case UsageState.OnlyPropertiesUsed:
+						return `only properties used in ${runtimes.join(", ")}`;
+				}
+			});
+			if (specificInfo.length > 0) {
+				return specificInfo.join("; ");
+			}
+		}
+		return this._hasUseInRuntimeInfo ? "unused" : "no usage info";
+	}
+
+	getProvidedInfo() {
+		switch (this.provided) {
+			case undefined:
+				return "no provided info";
+			case null:
+				return "maybe provided (runtime-defined)";
+			case true:
+				return "provided";
+			case false:
+				return "not provided";
+		}
+	}
+
+	getRenameInfo() {
+		if (this._usedName !== null && this._usedName !== this.name) {
+			return `renamed to ${JSON.stringify(this._usedName).slice(1, -1)}`;
+		}
+		switch (this.canMangleProvide) {
+			case undefined:
+				switch (this.canMangleUse) {
+					case undefined:
+						return "missing provision and use info prevents renaming";
+					case false:
+						return "usage prevents renaming (no provision info)";
+					case true:
+						return "missing provision info prevents renaming";
+				}
+				break;
+			case true:
+				switch (this.canMangleUse) {
+					case undefined:
+						return "missing usage info prevents renaming";
+					case false:
+						return "usage prevents renaming";
+					case true:
+						return "could be renamed";
+				}
+				break;
+			case false:
+				switch (this.canMangleUse) {
+					case undefined:
+						return "provision prevents renaming (no use info)";
+					case false:
+						return "usage and provision prevents renaming";
+					case true:
+						return "provision prevents renaming";
+				}
+				break;
+		}
+		throw new Error(
+			`Unexpected flags for getRenameInfo ${this.canMangleProvide} ${this.canMangleUse}`
+		);
+	}
+}
+
+module.exports = ExportsInfo;
+module.exports.ExportInfo = ExportInfo;
+module.exports.RestoreProvidedData = RestoreProvidedData;
+module.exports.UsageState = UsageState;
Index: frontend/node_modules/webpack/lib/ExportsInfoApiPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ExportsInfoApiPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ExportsInfoApiPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,88 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const ConstDependency = require("./dependencies/ConstDependency");
+const ExportsInfoDependency = require("./dependencies/ExportsInfoDependency");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "ExportsInfoApiPlugin";
+
+class ExportsInfoApiPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					ExportsInfoDependency,
+					new ExportsInfoDependency.Template()
+				);
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @returns {void}
+				 */
+				const handler = (parser) => {
+					parser.hooks.expressionMemberChain
+						.for("__webpack_exports_info__")
+						.tap(PLUGIN_NAME, (expr, members) => {
+							const dep =
+								members.length >= 2
+									? new ExportsInfoDependency(
+											/** @type {Range} */ (expr.range),
+											members.slice(0, -1),
+											members[members.length - 1]
+										)
+									: new ExportsInfoDependency(
+											/** @type {Range} */ (expr.range),
+											null,
+											members[0]
+										);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addDependency(dep);
+							return true;
+						});
+					parser.hooks.expression
+						.for("__webpack_exports_info__")
+						.tap(PLUGIN_NAME, (expr) => {
+							const dep = new ConstDependency(
+								"true",
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+				};
+				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);
+			}
+		);
+	}
+}
+
+module.exports = ExportsInfoApiPlugin;
Index: frontend/node_modules/webpack/lib/ExternalModule.js
===================================================================
--- frontend/node_modules/webpack/lib/ExternalModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ExternalModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1305 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncBailHook } = require("tapable");
+const { OriginalSource, RawSource } = require("webpack-sources");
+const ConcatenationScope = require("./ConcatenationScope");
+const { UsageState } = require("./ExportsInfo");
+const InitFragment = require("./InitFragment");
+const Module = require("./Module");
+const {
+	ASSET_URL_TYPE,
+	ASSET_URL_TYPES,
+	CSS_IMPORT_TYPES,
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("./ModuleSourceTypeConstants");
+const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const Template = require("./Template");
+const { DEFAULTS } = require("./config/defaults");
+const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
+const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
+const EnvironmentNotSupportAsyncWarning = require("./errors/EnvironmentNotSupportAsyncWarning");
+const createHash = require("./util/createHash");
+const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
+const makeSerializable = require("./util/makeSerializable");
+const { propertyAccess } = require("./util/property");
+const { register } = require("./util/serialization");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").ExternalsType} ExternalsType */
+/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Compilation").UnsafeCacheData} UnsafeCacheData */
+/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("./ExportsInfo")} ExportsInfo */
+/** @typedef {import("./Generator").GenerateContext} GenerateContext */
+/** @typedef {import("./Generator").SourceTypes} SourceTypes */
+/** @typedef {import("./Module").ModuleId} ModuleId */
+/** @typedef {import("./Module").BuildCallback} BuildCallback */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("./Module").LibIdent} LibIdent */
+/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("./Module").Sources} Sources */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
+/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("./dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {{ attributes?: ImportAttributes, phase?: ImportPhaseType, externalType: "import" | "module" | undefined }} ImportDependencyMeta */
+/** @typedef {{ layer?: string, supports?: string, media?: string }} CssImportDependencyMeta */
+/** @typedef {{ sourceType: "asset-url" | "css-url" }} AssetDependencyMeta */
+
+/** @typedef {ImportDependencyMeta | CssImportDependencyMeta | AssetDependencyMeta} DependencyMeta */
+
+/**
+ * Defines the source data type used by this module.
+ * @typedef {object} SourceData
+ * @property {boolean=} iife
+ * @property {string=} init
+ * @property {string} expression
+ * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
+ * @property {ReadOnlyRuntimeRequirements=} runtimeRequirements
+ * @property {[string, string][]=} specifiers
+ */
+
+/** @typedef {true | [string, string][]} Imported */
+
+/** @type {RuntimeRequirements} */
+const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
+/** @type {RuntimeRequirements} */
+const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
+/** @type {RuntimeRequirements} */
+const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
+	RuntimeGlobals.definePropertyGetters
+]);
+/** @type {RuntimeRequirements} */
+const EMPTY_RUNTIME_REQUIREMENTS = new Set();
+
+/**
+ * Gets source for global variable external.
+ * @param {string | string[]} variableName the variable name or path
+ * @param {string} type the module system
+ * @returns {SourceData} the generated source
+ */
+const getSourceForGlobalVariableExternal = (variableName, type) => {
+	if (!Array.isArray(variableName)) {
+		// make it an array as the look up works the same basically
+		variableName = [variableName];
+	}
+
+	// needed for e.g. window["some"]["thing"]
+	const objectLookup = variableName
+		.map((r) => `[${JSON.stringify(r)}]`)
+		.join("");
+	return {
+		iife: type === "this",
+		expression: `${type}${objectLookup}`
+	};
+};
+
+/** @typedef {string | string[]} ModuleAndSpecifiers */
+
+/**
+ * Gets source for common js external.
+ * @param {ModuleAndSpecifiers} moduleAndSpecifiers the module request
+ * @returns {SourceData} the generated source
+ */
+const getSourceForCommonJsExternal = (moduleAndSpecifiers) => {
+	if (!Array.isArray(moduleAndSpecifiers)) {
+		return {
+			expression: `require(${JSON.stringify(moduleAndSpecifiers)})`
+		};
+	}
+	const moduleName = moduleAndSpecifiers[0];
+	return {
+		expression: `require(${JSON.stringify(moduleName)})${propertyAccess(
+			moduleAndSpecifiers,
+			1
+		)}`
+	};
+};
+
+/**
+ * Gets external module node commonjs init fragment.
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @returns {InitFragment<ChunkRenderContext>} code
+ */
+const getExternalModuleNodeCommonjsInitFragment = (runtimeTemplate) => {
+	const importMetaName = runtimeTemplate.outputOptions.importMetaName;
+
+	return new InitFragment(
+		`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from ${runtimeTemplate.renderNodePrefixForCoreModule(
+			"module"
+		)};\n${runtimeTemplate.renderConst()} __WEBPACK_EXTERNAL_createRequire_require = __WEBPACK_EXTERNAL_createRequire(${importMetaName}.url);\n`,
+		InitFragment.STAGE_HARMONY_IMPORTS,
+		0,
+		"external module node-commonjs"
+	);
+};
+
+/**
+ * Gets source for common js external in node module.
+ * @param {ModuleAndSpecifiers} moduleAndSpecifiers the module request
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @returns {SourceData} the generated source
+ */
+const getSourceForCommonJsExternalInNodeModule = (
+	moduleAndSpecifiers,
+	runtimeTemplate
+) => {
+	const chunkInitFragments = [
+		getExternalModuleNodeCommonjsInitFragment(runtimeTemplate)
+	];
+	if (!Array.isArray(moduleAndSpecifiers)) {
+		return {
+			chunkInitFragments,
+			expression: `__WEBPACK_EXTERNAL_createRequire_require(${JSON.stringify(
+				moduleAndSpecifiers
+			)})`
+		};
+	}
+	const moduleName = moduleAndSpecifiers[0];
+	return {
+		chunkInitFragments,
+		expression: `__WEBPACK_EXTERNAL_createRequire_require(${JSON.stringify(
+			moduleName
+		)})${propertyAccess(moduleAndSpecifiers, 1)}`
+	};
+};
+
+/**
+ * Gets source for import external.
+ * @param {ModuleAndSpecifiers} moduleAndSpecifiers the module request
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {ImportDependencyMeta=} dependencyMeta the dependency meta
+ * @returns {SourceData} the generated source
+ */
+const getSourceForImportExternal = (
+	moduleAndSpecifiers,
+	runtimeTemplate,
+	dependencyMeta
+) => {
+	const baseImportName = runtimeTemplate.outputOptions.importFunctionName;
+	if (
+		!runtimeTemplate.supportsDynamicImport() &&
+		(baseImportName === "import" || baseImportName === "module-import")
+	) {
+		throw new Error(
+			"The target environment doesn't support 'import()' so it's not possible to use external type 'import'"
+		);
+	}
+	const phase = dependencyMeta && dependencyMeta.phase;
+	// `import.defer(…)` and `import.source(…)` are only valid forms of the
+	// native `import(…)` function, so we only emit the phase suffix when the
+	// importFunctionName is the default `"import"`.
+	const importName =
+		baseImportName === "import" && ImportPhaseUtils.isDefer(phase)
+			? "import.defer"
+			: baseImportName === "import" && ImportPhaseUtils.isSource(phase)
+				? "import.source"
+				: baseImportName;
+	const attributes =
+		dependencyMeta && dependencyMeta.attributes
+			? dependencyMeta.attributes._isLegacyAssert
+				? `, { assert: ${JSON.stringify(
+						dependencyMeta.attributes,
+						importAssertionReplacer
+					)} }`
+				: `, { with: ${JSON.stringify(dependencyMeta.attributes)} }`
+			: "";
+	if (!Array.isArray(moduleAndSpecifiers)) {
+		return {
+			expression: `${importName}(${JSON.stringify(
+				moduleAndSpecifiers
+			)}${attributes});`
+		};
+	}
+	if (moduleAndSpecifiers.length === 1) {
+		return {
+			expression: `${importName}(${JSON.stringify(
+				moduleAndSpecifiers[0]
+			)}${attributes});`
+		};
+	}
+	const moduleName = moduleAndSpecifiers[0];
+	return {
+		expression: `${importName}(${JSON.stringify(
+			moduleName
+		)}${attributes}).then(${runtimeTemplate.returningFunction(
+			`module${propertyAccess(moduleAndSpecifiers, 1)}`,
+			"module"
+		)});`
+	};
+};
+
+/**
+ * Import assertion replacer.
+ * @param {string} key key
+ * @param {ImportAttributes | string | boolean | undefined} value value
+ * @returns {ImportAttributes | string | boolean | undefined} replaced value
+ */
+const importAssertionReplacer = (key, value) => {
+	if (key === "_isLegacyAssert") {
+		return;
+	}
+
+	return value;
+};
+
+/**
+ * Represents ModuleExternalInitFragment.
+ * @extends {InitFragment<GenerateContext>}
+ */
+class ModuleExternalInitFragment extends InitFragment {
+	/**
+	 * Creates an instance of ModuleExternalInitFragment.
+	 * @param {string} request import source
+	 * @param {Imported} imported the imported specifiers
+	 * @param {string=} ident recomputed ident
+	 * @param {ImportDependencyMeta=} dependencyMeta the dependency meta
+	 * @param {HashFunction=} hashFunction the hash function to use
+	 */
+	constructor(
+		request,
+		imported,
+		ident,
+		dependencyMeta,
+		hashFunction = DEFAULTS.HASH_FUNCTION
+	) {
+		if (ident === undefined) {
+			ident = Template.toIdentifier(request);
+			if (ident !== request) {
+				ident += `_${createHash(hashFunction)
+					.update(request)
+					.digest("hex")
+					.slice(0, 8)}`;
+			}
+		}
+
+		super(
+			"",
+			InitFragment.STAGE_HARMONY_IMPORTS,
+			0,
+			`external module import ${ident} ${
+				imported === true ? imported : imported.join(" ")
+			}`
+		);
+		this._ident = ident;
+		this._request = request;
+		this._dependencyMeta = dependencyMeta;
+		this._identifier = this.buildIdentifier(ident);
+		this._imported = this.buildImported(imported);
+	}
+
+	/**
+	 * Returns imported.
+	 * @returns {Imported} imported
+	 */
+	getImported() {
+		return this._imported;
+	}
+
+	/**
+	 * Updates imported using the provided imported.
+	 * @param {Imported} imported imported
+	 */
+	setImported(imported) {
+		this._imported = imported;
+	}
+
+	/**
+	 * Returns the source code that will be included as initialization code.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included as initialization code
+	 */
+	getContent(context) {
+		const {
+			_dependencyMeta: dependencyMeta,
+			_imported: imported,
+			_request: request,
+			_identifier: identifier
+		} = this;
+		const attributes =
+			dependencyMeta && dependencyMeta.attributes
+				? dependencyMeta.attributes._isLegacyAssert
+					? ` assert ${JSON.stringify(
+							dependencyMeta.attributes,
+							importAssertionReplacer
+						)}`
+					: ` with ${JSON.stringify(dependencyMeta.attributes)}`
+				: "";
+		const phase = dependencyMeta && dependencyMeta.phase;
+		let content = "";
+		if (imported === true) {
+			// namespace
+			const phaseKeyword = ImportPhaseUtils.isDefer(phase) ? "defer " : "";
+			content = `import ${phaseKeyword}* as ${identifier} from ${JSON.stringify(
+				request
+			)}${attributes};\n`;
+		} else if (imported.length === 0) {
+			// just import, no use
+			content = `import ${JSON.stringify(request)}${attributes};\n`;
+		} else if (
+			ImportPhaseUtils.isSource(phase) &&
+			imported.length === 1 &&
+			imported[0][0] === "default"
+		) {
+			// `import source x from "…"` — the source-phase form binds the source
+			// object directly to a single identifier (no namespace, no destructuring).
+			content = `import source ${imported[0][1]} from ${JSON.stringify(
+				request
+			)}${attributes};\n`;
+		} else {
+			content = `import { ${imported
+				.map(([name, finalName]) => {
+					if (name !== finalName) {
+						return `${name} as ${finalName}`;
+					}
+					return name;
+				})
+				.join(", ")} } from ${JSON.stringify(request)}${attributes};\n`;
+		}
+		return content;
+	}
+
+	getNamespaceIdentifier() {
+		return this._identifier;
+	}
+
+	/**
+	 * Returns identifier.
+	 * @param {string} ident ident
+	 * @returns {string} identifier
+	 */
+	buildIdentifier(ident) {
+		return `__WEBPACK_EXTERNAL_MODULE_${ident}__`;
+	}
+
+	/**
+	 * Returns normalized imported.
+	 * @param {Imported} imported imported
+	 * @returns {Imported} normalized imported
+	 */
+	buildImported(imported) {
+		if (Array.isArray(imported)) {
+			return imported.map(([name]) => {
+				const ident = `${this._ident}_${name}`;
+				return [name, this.buildIdentifier(ident)];
+			});
+		}
+		return imported;
+	}
+}
+
+register(
+	ModuleExternalInitFragment,
+	"webpack/lib/ExternalModule",
+	"ModuleExternalInitFragment",
+	{
+		serialize(obj, { write }) {
+			write(obj._request);
+			write(obj._imported);
+			write(obj._ident);
+			write(obj._dependencyMeta);
+		},
+		deserialize({ read }) {
+			return new ModuleExternalInitFragment(read(), read(), read(), read());
+		}
+	}
+);
+
+/**
+ * Generates module remapping.
+ * @param {string} input input
+ * @param {ExportsInfo} exportsInfo the exports info
+ * @param {RuntimeSpec=} runtime the runtime
+ * @param {RuntimeTemplate=} runtimeTemplate the runtime template
+ * @returns {string | undefined} the module remapping
+ */
+const generateModuleRemapping = (
+	input,
+	exportsInfo,
+	runtime,
+	runtimeTemplate
+) => {
+	if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
+		/** @type {string[]} */
+		const properties = [];
+		for (const exportInfo of exportsInfo.orderedExports) {
+			const used = exportInfo.getUsedName(exportInfo.name, runtime);
+			if (!used) continue;
+			const nestedInfo = exportInfo.getNestedExportsInfo();
+			if (nestedInfo) {
+				const nestedExpr = generateModuleRemapping(
+					`${input}${propertyAccess([exportInfo.name])}`,
+					nestedInfo
+				);
+				if (nestedExpr) {
+					properties.push(`[${JSON.stringify(used)}]: y(${nestedExpr})`);
+					continue;
+				}
+			}
+			properties.push(
+				`[${JSON.stringify(used)}]: ${
+					/** @type {RuntimeTemplate} */ (runtimeTemplate).returningFunction(
+						`${input}${propertyAccess([exportInfo.name])}`
+					)
+				}`
+			);
+		}
+		return `x({ ${properties.join(", ")} })`;
+	}
+};
+
+/**
+ * Gets source for module external.
+ * @param {ModuleAndSpecifiers} moduleAndSpecifiers the module request
+ * @param {ExportsInfo} exportsInfo exports info of this module
+ * @param {RuntimeSpec} runtime the runtime
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {ImportDependencyMeta} dependencyMeta the dependency meta
+ * @param {ConcatenationScope=} concatenationScope concatenationScope
+ * @returns {SourceData} the generated source
+ */
+const getSourceForModuleExternal = (
+	moduleAndSpecifiers,
+	exportsInfo,
+	runtime,
+	runtimeTemplate,
+	dependencyMeta,
+	concatenationScope
+) => {
+	const phase = dependencyMeta && dependencyMeta.phase;
+	/** @type {Imported} */
+	let imported = true;
+	if (concatenationScope) {
+		const usedExports = exportsInfo.getUsedExports(runtime);
+		switch (usedExports) {
+			case true:
+			case null:
+				// unknown exports
+				imported = true;
+				break;
+			case false:
+				// no used exports
+				imported = [];
+				break;
+			default:
+				imported = [...usedExports.entries()];
+		}
+	}
+
+	if (!Array.isArray(moduleAndSpecifiers)) {
+		moduleAndSpecifiers = [moduleAndSpecifiers];
+	}
+
+	// Return to `namespace` when the external request includes a specific export
+	if (moduleAndSpecifiers.length > 1) {
+		imported = true;
+	}
+
+	// `import defer …` is only valid as `import defer * as ns from "…"`, so
+	// keep the namespace form even if usage analysis would otherwise narrow
+	// the import down to specific names. Defer + concatenation is semantically
+	// at odds (lazy vs. eager), so we preserve the user-written shape here.
+	if (ImportPhaseUtils.isDefer(phase)) {
+		imported = true;
+	}
+
+	const initFragment = new ModuleExternalInitFragment(
+		moduleAndSpecifiers[0],
+		imported,
+		undefined,
+		dependencyMeta,
+		runtimeTemplate.outputOptions.hashFunction
+	);
+	const normalizedImported = initFragment.getImported();
+
+	const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess(
+		moduleAndSpecifiers,
+		1
+	)}`;
+	let expression = baseAccess;
+
+	const useNamespace = imported === true;
+	/** @type {undefined | string} */
+	let moduleRemapping;
+	if (useNamespace) {
+		moduleRemapping = generateModuleRemapping(
+			baseAccess,
+			exportsInfo,
+			runtime,
+			runtimeTemplate
+		);
+		expression = moduleRemapping || baseAccess;
+	}
+	return {
+		expression,
+		init: moduleRemapping
+			? `var x = ${runtimeTemplate.basicFunction(
+					"y",
+					`var x = {}; ${RuntimeGlobals.definePropertyGetters}(x, y); return x`
+				)} \nvar y = ${runtimeTemplate.returningFunction(
+					runtimeTemplate.returningFunction("x"),
+					"x"
+				)}`
+			: undefined,
+		specifiers: normalizedImported === true ? undefined : normalizedImported,
+		runtimeRequirements: moduleRemapping
+			? RUNTIME_REQUIREMENTS_FOR_MODULE
+			: undefined,
+		chunkInitFragments: [
+			/** @type {InitFragment<EXPECTED_ANY>} */ (initFragment)
+		]
+	};
+};
+
+/**
+ * Gets source for script external.
+ * @param {string | string[]} urlAndGlobal the script request
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @returns {SourceData} the generated source
+ */
+const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => {
+	if (typeof urlAndGlobal === "string") {
+		urlAndGlobal = extractUrlAndGlobal(urlAndGlobal);
+	}
+	const url = urlAndGlobal[0];
+	const globalName = urlAndGlobal[1];
+	return {
+		init: "var __webpack_error__ = new Error();",
+		expression: `new Promise(${runtimeTemplate.basicFunction(
+			"resolve, reject",
+			[
+				`if(typeof ${globalName} !== "undefined") return resolve();`,
+				`${RuntimeGlobals.loadScript}(${JSON.stringify(
+					url
+				)}, ${runtimeTemplate.basicFunction("event", [
+					`if(typeof ${globalName} !== "undefined") return resolve();`,
+					"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
+					"var realSrc = event && event.target && event.target.src;",
+					"__webpack_error__.message = 'Loading script failed.\\n(' + errorType + ': ' + realSrc + ')';",
+					"__webpack_error__.name = 'ScriptExternalLoadError';",
+					"__webpack_error__.type = errorType;",
+					"__webpack_error__.request = realSrc;",
+					"reject(__webpack_error__);"
+				])}, ${JSON.stringify(globalName)});`
+			]
+		)}).then(${runtimeTemplate.returningFunction(
+			`${globalName}${propertyAccess(urlAndGlobal, 2)}`
+		)})`,
+		runtimeRequirements: RUNTIME_REQUIREMENTS_FOR_SCRIPT
+	};
+};
+
+/**
+ * Checks external variable.
+ * @param {string} variableName the variable name to check
+ * @param {string} request the request path
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @returns {string} the generated source
+ */
+const checkExternalVariable = (variableName, request, runtimeTemplate) =>
+	`if(typeof ${variableName} === 'undefined') { ${runtimeTemplate.throwMissingModuleErrorBlock(
+		{ request }
+	)} }\n`;
+
+/**
+ * Gets source for amd or umd external.
+ * @param {ModuleId | string} id the module id
+ * @param {boolean} optional true, if the module is optional
+ * @param {string | string[]} request the request path
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @returns {SourceData} the generated source
+ */
+const getSourceForAmdOrUmdExternal = (
+	id,
+	optional,
+	request,
+	runtimeTemplate
+) => {
+	const externalVariable = `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
+		`${id}`
+	)}__`;
+	return {
+		init: optional
+			? checkExternalVariable(
+					externalVariable,
+					Array.isArray(request) ? request.join(".") : request,
+					runtimeTemplate
+				)
+			: undefined,
+		expression: externalVariable
+	};
+};
+
+/**
+ * Gets source for default case.
+ * @param {boolean} optional true, if the module is optional
+ * @param {string | string[]} request the request path
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @returns {SourceData} the generated source
+ */
+const getSourceForDefaultCase = (optional, request, runtimeTemplate) => {
+	if (!Array.isArray(request)) {
+		// make it an array as the look up works the same basically
+		request = [request];
+	}
+
+	const variableName = request[0];
+	const objectLookup = propertyAccess(request, 1);
+	return {
+		init: optional
+			? checkExternalVariable(variableName, request.join("."), runtimeTemplate)
+			: undefined,
+		expression: `${variableName}${objectLookup}`
+	};
+};
+
+/** @typedef {Record<string, string | string[]>} RequestRecord */
+/** @typedef {string | string[] | RequestRecord} ExternalModuleRequest */
+
+/**
+ * Defines the external module hooks type used by this module.
+ * @typedef {object} ExternalModuleHooks
+ * @property {SyncBailHook<[Chunk, Compilation], boolean>} chunkCondition
+ */
+
+/** @type {WeakMap<Compilation, ExternalModuleHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class ExternalModule extends Module {
+	/**
+	 * Creates an instance of ExternalModule.
+	 * @param {ExternalModuleRequest} request request
+	 * @param {ExternalsType} type type
+	 * @param {string} userRequest user request
+	 * @param {DependencyMeta=} dependencyMeta dependency meta
+	 */
+	constructor(request, type, userRequest, dependencyMeta) {
+		super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);
+
+		// Info from Factory
+		/** @type {ExternalModuleRequest} */
+		this.request = request;
+		/** @type {ExternalsType} */
+		this.externalType = type;
+		/** @type {string} */
+		this.userRequest = userRequest;
+		/** @type {DependencyMeta=} */
+		this.dependencyMeta = dependencyMeta;
+	}
+
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {ExternalModuleHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				chunkCondition: new SyncBailHook(["chunk", "compilation"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		if (this.externalType === "asset" && this.dependencyMeta) {
+			const sourceType =
+				/** @type {AssetDependencyMeta} */
+				(this.dependencyMeta).sourceType;
+			// TODO webpack 6 drop "css-url" once the alias is removed
+			if (sourceType === ASSET_URL_TYPE || sourceType === "css-url") {
+				return ASSET_URL_TYPES;
+			}
+		} else if (this.externalType === "css-import") {
+			return CSS_IMPORT_TYPES;
+		}
+
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return this.userRequest;
+	}
+
+	/**
+	 * Returns true if the module can be placed in the chunk.
+	 * @param {Chunk} chunk the chunk which condition should be checked
+	 * @param {Compilation} compilation the compilation
+	 * @returns {boolean} true if the module can be placed in the chunk
+	 */
+	chunkCondition(chunk, compilation) {
+		const { chunkCondition } = ExternalModule.getCompilationHooks(compilation);
+		const condition = chunkCondition.call(chunk, compilation);
+		if (condition !== undefined) return condition;
+
+		const type = this._resolveExternalType(this.externalType);
+
+		// For `import()` externals, keep them in the initial chunk to avoid loading
+		// them asynchronously twice and to improve runtime performance.
+		if (["css-import", "module"].includes(type)) {
+			return true;
+		}
+		return compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		let id = `external ${this._resolveExternalType(
+			this.externalType
+		)} ${JSON.stringify(this.request)}`;
+		const meta = /** @type {ImportDependencyMeta | undefined} */ (
+			this.dependencyMeta
+		);
+		if (meta) {
+			if (meta.phase) {
+				id += `|phase=${ImportPhaseUtils.stringify(meta.phase)}`;
+			}
+			if (meta.attributes) {
+				id += `|attributes=${JSON.stringify(meta.attributes)}`;
+			}
+		}
+		return id;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `external ${JSON.stringify(this.request)}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, !this.buildMeta);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {
+			async: false,
+			exportsType: undefined
+		};
+		this.buildInfo = {
+			strict: true,
+			topLevelDeclarations: new Set(),
+			javascriptModule: compilation.outputOptions.module
+		};
+		const { request, externalType } = this._getRequestAndExternalType();
+		this.buildMeta.exportsType = "dynamic";
+		let canMangle = false;
+		this.clearDependenciesAndBlocks();
+		switch (externalType) {
+			case "this":
+				this.buildInfo.strict = false;
+				break;
+			case "system":
+				if (!Array.isArray(request) || request.length === 1) {
+					this.buildMeta.exportsType = "namespace";
+					canMangle = true;
+				}
+				break;
+			case "module":
+				if (this.buildInfo.javascriptModule) {
+					if (!Array.isArray(request) || request.length === 1) {
+						this.buildMeta.exportsType = "namespace";
+						canMangle = true;
+					}
+				} else {
+					this.buildMeta.async = true;
+					EnvironmentNotSupportAsyncWarning.check(
+						this,
+						compilation.runtimeTemplate,
+						"external module"
+					);
+					if (!Array.isArray(request) || request.length === 1) {
+						this.buildMeta.exportsType = "namespace";
+						canMangle = false;
+					}
+				}
+				break;
+			case "script":
+				this.buildMeta.async = true;
+				EnvironmentNotSupportAsyncWarning.check(
+					this,
+					compilation.runtimeTemplate,
+					"external script"
+				);
+				break;
+			case "promise":
+				this.buildMeta.async = true;
+				EnvironmentNotSupportAsyncWarning.check(
+					this,
+					compilation.runtimeTemplate,
+					"external promise"
+				);
+				break;
+			case "import":
+				this.buildMeta.async = true;
+				EnvironmentNotSupportAsyncWarning.check(
+					this,
+					compilation.runtimeTemplate,
+					"external import"
+				);
+				if (!Array.isArray(request) || request.length === 1) {
+					this.buildMeta.exportsType = "namespace";
+					canMangle = false;
+				}
+				break;
+		}
+		this.addDependency(new StaticExportsDependency(true, canMangle));
+		callback();
+	}
+
+	/**
+	 * restore unsafe cache data
+	 * @param {UnsafeCacheData} unsafeCacheData data from getUnsafeCacheData
+	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
+	 */
+	restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
+		this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory);
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(context) {
+		switch (this.externalType) {
+			case "amd":
+			case "amd-require":
+			case "umd":
+			case "umd2":
+			case "system":
+			case "jsonp":
+				return `${this.externalType} externals can't be concatenated`;
+		}
+		return undefined;
+	}
+
+	/**
+	 * Get request and external type.
+	 * @private
+	 * @returns {{ request: string | string[], externalType: ExternalsType }} the request and external type
+	 */
+	_getRequestAndExternalType() {
+		let { request, externalType } = this;
+		if (typeof request === "object" && !Array.isArray(request)) {
+			request = request[externalType];
+		}
+		externalType = this._resolveExternalType(externalType);
+		return { request, externalType };
+	}
+
+	/**
+	 * Resolve the detailed external type from the raw external type.
+	 * e.g. resolve "module" or "import" from "module-import" type
+	 * @param {ExternalsType} externalType raw external type
+	 * @returns {ExternalsType} resolved external type
+	 */
+	_resolveExternalType(externalType) {
+		if (externalType === "module-import") {
+			if (
+				this.dependencyMeta &&
+				/** @type {ImportDependencyMeta} */
+				(this.dependencyMeta).externalType
+			) {
+				return /** @type {ImportDependencyMeta} */ (this.dependencyMeta)
+					.externalType;
+			}
+			return "module";
+		} else if (externalType === "asset") {
+			if (
+				this.dependencyMeta &&
+				/** @type {AssetDependencyMeta} */
+				(this.dependencyMeta).sourceType
+			) {
+				return /** @type {AssetDependencyMeta} */ (this.dependencyMeta)
+					.sourceType;
+			}
+
+			return "asset";
+		}
+
+		return externalType;
+	}
+
+	/**
+	 * Returns the source data.
+	 * @private
+	 * @param {string | string[]} request request
+	 * @param {ExternalsType} externalType the external type
+	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {DependencyMeta | undefined} dependencyMeta the dependency meta
+	 * @param {ConcatenationScope=} concatenationScope concatenationScope
+	 * @returns {SourceData} the source data
+	 */
+	_getSourceData(
+		request,
+		externalType,
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime,
+		dependencyMeta,
+		concatenationScope
+	) {
+		switch (externalType) {
+			case "this":
+			case "window":
+			case "self":
+				return getSourceForGlobalVariableExternal(request, this.externalType);
+			case "global":
+				return getSourceForGlobalVariableExternal(
+					request,
+					runtimeTemplate.globalObject
+				);
+			case "commonjs":
+			case "commonjs2":
+			case "commonjs-module":
+			case "commonjs-static":
+				return getSourceForCommonJsExternal(request);
+			case "node-commonjs":
+				return /** @type {BuildInfo} */ (this.buildInfo).javascriptModule
+					? getSourceForCommonJsExternalInNodeModule(request, runtimeTemplate)
+					: getSourceForCommonJsExternal(request);
+			case "amd":
+			case "amd-require":
+			case "umd":
+			case "umd2":
+			case "system":
+			case "jsonp": {
+				const id = chunkGraph.getModuleId(this);
+				return getSourceForAmdOrUmdExternal(
+					id !== null ? id : this.identifier(),
+					this.isOptional(moduleGraph),
+					request,
+					runtimeTemplate
+				);
+			}
+			case "import":
+				return getSourceForImportExternal(
+					request,
+					runtimeTemplate,
+					/** @type {ImportDependencyMeta} */ (dependencyMeta)
+				);
+			case "script":
+				return getSourceForScriptExternal(request, runtimeTemplate);
+			case "module": {
+				if (!(/** @type {BuildInfo} */ (this.buildInfo).javascriptModule)) {
+					if (!runtimeTemplate.supportsDynamicImport()) {
+						throw new Error(
+							`The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script${
+								runtimeTemplate.supportsEcmaScriptModuleSyntax()
+									? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
+									: ""
+							}`
+						);
+					}
+					return getSourceForImportExternal(
+						request,
+						runtimeTemplate,
+						/** @type {ImportDependencyMeta} */ (dependencyMeta)
+					);
+				}
+				if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
+					throw new Error(
+						"The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"
+					);
+				}
+				return getSourceForModuleExternal(
+					request,
+					moduleGraph.getExportsInfo(this),
+					runtime,
+					runtimeTemplate,
+					/** @type {ImportDependencyMeta} */ (dependencyMeta),
+					concatenationScope
+				);
+			}
+			case "var":
+			case "promise":
+			case "assign":
+			default:
+				return getSourceForDefaultCase(
+					this.isOptional(moduleGraph),
+					request,
+					runtimeTemplate
+				);
+		}
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime,
+		concatenationScope
+	}) {
+		const { request, externalType } = this._getRequestAndExternalType();
+		switch (externalType) {
+			case "asset": {
+				/** @type {Sources} */
+				const sources = new Map();
+				sources.set(
+					JAVASCRIPT_TYPE,
+					new RawSource(`module.exports = ${JSON.stringify(request)};`)
+				);
+				/** @type {CodeGenerationResultData} */
+				const data = new Map();
+				data.set("url", { javascript: /** @type {string} */ (request) });
+				return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
+			}
+			// TODO webpack 6 remove "css-url" alias
+			case "css-url":
+			case "asset-url": {
+				/** @type {Sources} */
+				const sources = new Map();
+				/** @type {CodeGenerationResultData} */
+				const data = new Map();
+				data.set("url", { [ASSET_URL_TYPE]: /** @type {string} */ (request) });
+				return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
+			}
+			case "css-import": {
+				/** @type {Sources} */
+				const sources = new Map();
+				const dependencyMeta = /** @type {CssImportDependencyMeta} */ (
+					this.dependencyMeta
+				);
+				const layer =
+					dependencyMeta.layer !== undefined
+						? ` layer(${dependencyMeta.layer})`
+						: "";
+				const supports = dependencyMeta.supports
+					? ` supports(${dependencyMeta.supports})`
+					: "";
+				const media = dependencyMeta.media ? ` ${dependencyMeta.media}` : "";
+				sources.set(
+					"css-import",
+					new RawSource(
+						`@import url(${JSON.stringify(
+							request
+						)})${layer}${supports}${media};`
+					)
+				);
+				return {
+					sources,
+					runtimeRequirements: EMPTY_RUNTIME_REQUIREMENTS
+				};
+			}
+			default: {
+				const sourceData = this._getSourceData(
+					request,
+					externalType,
+					runtimeTemplate,
+					moduleGraph,
+					chunkGraph,
+					runtime,
+					this.dependencyMeta,
+					concatenationScope
+				);
+
+				// sourceString can be empty str only when there is concatenationScope
+				let sourceString = sourceData.expression;
+				if (sourceData.iife) {
+					sourceString = `(function() { return ${sourceString}; }())`;
+				}
+
+				const specifiers = sourceData.specifiers;
+				if (specifiers) {
+					sourceString = "";
+					const scope = /** @type {ConcatenationScope} */ (concatenationScope);
+					for (const [specifier, finalName] of specifiers) {
+						scope.registerRawExport(specifier, finalName);
+					}
+				} else if (concatenationScope) {
+					sourceString = `${runtimeTemplate.renderConst()} ${
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					} = ${sourceString};`;
+					concatenationScope.registerNamespaceExport(
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					);
+				} else {
+					sourceString = `module.exports = ${sourceString};`;
+				}
+				if (sourceData.init) {
+					sourceString = `${sourceData.init}\n${sourceString}`;
+				}
+
+				/** @type {undefined | CodeGenerationResultData} */
+				let data;
+				if (sourceData.chunkInitFragments) {
+					data = new Map();
+					data.set("chunkInitFragments", sourceData.chunkInitFragments);
+				}
+
+				/** @type {Sources} */
+				const sources = new Map();
+				if (this.useSourceMap || this.useSimpleSourceMap) {
+					sources.set(
+						JAVASCRIPT_TYPE,
+						new OriginalSource(sourceString, this.identifier())
+					);
+				} else {
+					sources.set(JAVASCRIPT_TYPE, new RawSource(sourceString));
+				}
+
+				let runtimeRequirements = sourceData.runtimeRequirements;
+				if (!concatenationScope) {
+					if (!runtimeRequirements) {
+						runtimeRequirements = RUNTIME_REQUIREMENTS;
+					} else {
+						const set = new Set(runtimeRequirements);
+						set.add(RuntimeGlobals.module);
+						runtimeRequirements = set;
+					}
+				}
+
+				return {
+					sources,
+					runtimeRequirements:
+						runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
+					data
+				};
+			}
+		}
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		const { chunkGraph } = context;
+		hash.update(
+			`${this._resolveExternalType(this.externalType)}${JSON.stringify(
+				this.request
+			)}${this.isOptional(chunkGraph.moduleGraph)}`
+		);
+		const meta = /** @type {ImportDependencyMeta | undefined} */ (
+			this.dependencyMeta
+		);
+		if (meta) {
+			if (meta.phase) {
+				hash.update(`|phase=${ImportPhaseUtils.stringify(meta.phase)}`);
+			}
+			if (meta.attributes) {
+				hash.update(`|attributes=${JSON.stringify(meta.attributes)}`);
+			}
+		}
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.request);
+		write(this.externalType);
+		write(this.userRequest);
+		write(this.dependencyMeta);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.request = read();
+		this.externalType = read();
+		this.userRequest = read();
+		this.dependencyMeta = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ExternalModule, "webpack/lib/ExternalModule");
+
+module.exports = ExternalModule;
+module.exports.ModuleExternalInitFragment = ModuleExternalInitFragment;
+module.exports.getExternalModuleNodeCommonjsInitFragment =
+	getExternalModuleNodeCommonjsInitFragment;
Index: frontend/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,386 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const ExternalModule = require("./ExternalModule");
+const { ASSET_URL_TYPE } = require("./ModuleSourceTypeConstants");
+const ContextElementDependency = require("./dependencies/ContextElementDependency");
+const CssImportDependency = require("./dependencies/CssImportDependency");
+const CssUrlDependency = require("./dependencies/CssUrlDependency");
+const HarmonyImportDependency = require("./dependencies/HarmonyImportDependency");
+const ImportDependency = require("./dependencies/ImportDependency");
+const { cachedSetProperty, resolveByProperty } = require("./util/cleverMerge");
+
+/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("../declarations/WebpackOptions").ExternalsType} ExternalsType */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItem} ExternalItem */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemValue} ExternalItemValue */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectKnown} ExternalItemObjectKnown */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectUnknown} ExternalItemObjectUnknown */
+/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./ExternalModule").DependencyMeta} DependencyMeta */
+/** @typedef {import("./ModuleFactory").IssuerLayer} IssuerLayer */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
+/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
+
+/** @typedef {((context: string, request: string, callback: (err?: Error | null, result?: string | false, resolveRequest?: import("enhanced-resolve").ResolveRequest) => void) => void)} ExternalItemFunctionDataGetResolveCallbackResult */
+/** @typedef {((context: string, request: string) => Promise<string>)} ExternalItemFunctionDataGetResolveResult */
+/** @typedef {(options?: ResolveOptions) => ExternalItemFunctionDataGetResolveCallbackResult | ExternalItemFunctionDataGetResolveResult} ExternalItemFunctionDataGetResolve */
+
+/**
+ * Defines the external item function data type used by this module.
+ * @typedef {object} ExternalItemFunctionData
+ * @property {string} context the directory in which the request is placed
+ * @property {ModuleFactoryCreateDataContextInfo} contextInfo contextual information
+ * @property {string} dependencyType the category of the referencing dependency
+ * @property {ExternalItemFunctionDataGetResolve} getResolve get a resolve function with the current resolver options
+ * @property {string} request the request as written by the user in the require/import expression/statement
+ */
+
+/** @typedef {((data: ExternalItemFunctionData, callback: (err?: (Error | null), result?: ExternalItemValue) => void) => void)} ExternalItemFunctionCallback */
+/** @typedef {((data: import("../lib/ExternalModuleFactoryPlugin").ExternalItemFunctionData) => Promise<ExternalItemValue>)} ExternalItemFunctionPromise */
+
+const UNSPECIFIED_EXTERNAL_TYPE_REGEXP = /^[a-z0-9-]+ /;
+const EMPTY_RESOLVE_OPTIONS = {};
+
+// TODO webpack 6 remove this
+const callDeprecatedExternals = util.deprecate(
+	/**
+	 * Handles the callback logic for this hook.
+	 * @param {EXPECTED_FUNCTION} externalsFunction externals function
+	 * @param {string} context context
+	 * @param {string} request request
+	 * @param {(err: Error | null | undefined, value: ExternalValue | undefined, ty: ExternalsType | undefined) => void} cb cb
+	 */
+	(externalsFunction, context, request, cb) => {
+		// eslint-disable-next-line no-useless-call
+		externalsFunction.call(null, context, request, cb);
+	},
+	"The externals-function should be defined like ({context, request}, cb) => { ... }",
+	"DEP_WEBPACK_EXTERNALS_FUNCTION_PARAMETERS"
+);
+
+/** @typedef {(layer: string | null) => ExternalItem} ExternalItemByLayerFn */
+/** @typedef {ExternalItemObjectKnown & ExternalItemObjectUnknown} ExternalItemObject */
+
+/**
+ * Defines the external weak cache type used by this module.
+ * @template {ExternalItemObject} T
+ * @typedef {WeakMap<T, Map<IssuerLayer, Omit<T, "byLayer">>>} ExternalWeakCache
+ */
+
+/** @type {ExternalWeakCache<ExternalItemObject>} */
+const cache = new WeakMap();
+
+/**
+ * Returns result.
+ * @param {ExternalItemObject} obj obj
+ * @param {IssuerLayer} layer layer
+ * @returns {Omit<ExternalItemObject, "byLayer">} result
+ */
+const resolveLayer = (obj, layer) => {
+	let map = cache.get(obj);
+	if (map === undefined) {
+		map = new Map();
+		cache.set(obj, map);
+	} else {
+		const cacheEntry = map.get(layer);
+		if (cacheEntry !== undefined) return cacheEntry;
+	}
+	const result = resolveByProperty(obj, "byLayer", layer);
+	map.set(layer, result);
+	return result;
+};
+
+/** @typedef {string | string[] | boolean | Record<string, string | string[]>} ExternalValue */
+
+const PLUGIN_NAME = "ExternalModuleFactoryPlugin";
+
+class ExternalModuleFactoryPlugin {
+	/**
+	 * Creates an instance of ExternalModuleFactoryPlugin.
+	 * @param {ExternalsType | ((dependency: Dependency) => ExternalsType)} type default external type
+	 * @param {Externals} externals externals config
+	 */
+	constructor(type, externals) {
+		this.type = type;
+		this.externals = externals;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory
+	 * @returns {void}
+	 */
+	apply(normalModuleFactory) {
+		const globalType = this.type;
+		normalModuleFactory.hooks.factorize.tapAsync(
+			PLUGIN_NAME,
+			(data, callback) => {
+				const context = data.context;
+				const contextInfo = data.contextInfo;
+				const dependency = data.dependencies[0];
+				const dependencyType = data.dependencyType;
+
+				/** @typedef {(err?: Error | null, externalModule?: ExternalModule) => void} HandleExternalCallback */
+
+				/**
+				 * Processes the provided value.
+				 * @param {ExternalValue} value the external config
+				 * @param {ExternalsType | undefined} type type of external
+				 * @param {HandleExternalCallback} callback callback
+				 * @returns {void}
+				 */
+				const handleExternal = (value, type, callback) => {
+					if (value === false) {
+						// Not externals, fallback to original factory
+						return callback();
+					}
+					/** @type {ExternalValue} */
+					let externalConfig = value === true ? dependency.request : value;
+					// When no explicit type is specified, extract it from the externalConfig
+					if (type === undefined) {
+						if (
+							typeof externalConfig === "string" &&
+							UNSPECIFIED_EXTERNAL_TYPE_REGEXP.test(externalConfig)
+						) {
+							const idx = externalConfig.indexOf(" ");
+							type =
+								/** @type {ExternalsType} */
+								(externalConfig.slice(0, idx));
+							externalConfig = externalConfig.slice(idx + 1);
+						} else if (
+							Array.isArray(externalConfig) &&
+							externalConfig.length > 0 &&
+							UNSPECIFIED_EXTERNAL_TYPE_REGEXP.test(externalConfig[0])
+						) {
+							const firstItem = externalConfig[0];
+							const idx = firstItem.indexOf(" ");
+							type = /** @type {ExternalsType} */ (firstItem.slice(0, idx));
+							externalConfig = [
+								firstItem.slice(idx + 1),
+								...externalConfig.slice(1)
+							];
+						}
+					}
+
+					const defaultType =
+						typeof globalType === "function"
+							? globalType(dependency)
+							: globalType;
+					const resolvedType = type || defaultType;
+
+					// TODO make it pluggable/add hooks to `ExternalModule` to allow output modules own externals?
+					/** @type {DependencyMeta | undefined} */
+					let dependencyMeta;
+
+					if (
+						dependency instanceof HarmonyImportDependency ||
+						dependency instanceof ImportDependency ||
+						dependency instanceof ContextElementDependency
+					) {
+						const externalType =
+							dependency instanceof HarmonyImportDependency
+								? "module"
+								: dependency instanceof ImportDependency
+									? "import"
+									: undefined;
+
+						dependencyMeta = {
+							attributes: dependency.attributes,
+							phase:
+								dependency instanceof HarmonyImportDependency ||
+								dependency instanceof ImportDependency
+									? dependency.phase
+									: undefined,
+							externalType
+						};
+					} else if (dependency instanceof CssImportDependency) {
+						dependencyMeta = {
+							layer: dependency.layer,
+							supports: dependency.supports,
+							media: dependency.media
+						};
+					}
+
+					if (
+						resolvedType === "asset" &&
+						dependency instanceof CssUrlDependency
+					) {
+						dependencyMeta = { sourceType: ASSET_URL_TYPE };
+					}
+
+					callback(
+						null,
+						new ExternalModule(
+							externalConfig,
+							resolvedType,
+							dependency.request,
+							dependencyMeta
+						)
+					);
+				};
+
+				/**
+				 * Processes the provided external.
+				 * @param {Externals} externals externals config
+				 * @param {HandleExternalCallback} callback callback
+				 * @returns {void}
+				 */
+				const handleExternals = (externals, callback) => {
+					if (typeof externals === "string") {
+						if (externals === dependency.request) {
+							return handleExternal(dependency.request, undefined, callback);
+						}
+					} else if (Array.isArray(externals)) {
+						let i = 0;
+						const next = () => {
+							/** @type {boolean | undefined} */
+							let asyncFlag;
+							/**
+							 * Handle externals and callback.
+							 * @param {(Error | null)=} err err
+							 * @param {ExternalModule=} module module
+							 * @returns {void}
+							 */
+							const handleExternalsAndCallback = (err, module) => {
+								if (err) return callback(err);
+								if (!module) {
+									if (asyncFlag) {
+										asyncFlag = false;
+										return;
+									}
+									return next();
+								}
+								callback(null, module);
+							};
+
+							do {
+								asyncFlag = true;
+								if (i >= externals.length) return callback();
+								handleExternals(externals[i++], handleExternalsAndCallback);
+							} while (!asyncFlag);
+							asyncFlag = false;
+						};
+
+						next();
+						return;
+					} else if (externals instanceof RegExp) {
+						if (externals.test(dependency.request)) {
+							return handleExternal(dependency.request, undefined, callback);
+						}
+					} else if (typeof externals === "function") {
+						/**
+						 * Processes the provided err.
+						 * @param {Error | null | undefined} err err
+						 * @param {ExternalValue=} value value
+						 * @param {ExternalsType=} type type
+						 * @returns {void}
+						 */
+						const cb = (err, value, type) => {
+							if (err) return callback(err);
+							if (value !== undefined) {
+								handleExternal(value, type, callback);
+							} else {
+								callback();
+							}
+						};
+						if (externals.length === 3) {
+							// TODO webpack 6 remove this
+							callDeprecatedExternals(
+								externals,
+								context,
+								dependency.request,
+								cb
+							);
+						} else {
+							const promise = externals(
+								{
+									context,
+									request: dependency.request,
+									dependencyType,
+									contextInfo,
+									getResolve: (options) => (context, request, callback) => {
+										/** @type {ResolveContext} */
+										const resolveContext = {
+											fileDependencies: data.fileDependencies,
+											missingDependencies: data.missingDependencies,
+											contextDependencies: data.contextDependencies
+										};
+										let resolver = normalModuleFactory.getResolver(
+											"normal",
+											dependencyType
+												? cachedSetProperty(
+														data.resolveOptions || EMPTY_RESOLVE_OPTIONS,
+														"dependencyType",
+														dependencyType
+													)
+												: data.resolveOptions
+										);
+										if (options) resolver = resolver.withOptions(options);
+										if (callback) {
+											resolver.resolve(
+												{},
+												context,
+												request,
+												resolveContext,
+												callback
+											);
+										} else {
+											return new Promise((resolve, reject) => {
+												resolver.resolve(
+													{},
+													context,
+													request,
+													resolveContext,
+													(err, result) => {
+														if (err) reject(err);
+														else resolve(result);
+													}
+												);
+											});
+										}
+									}
+								},
+								cb
+							);
+							if (promise && promise.then) {
+								promise.then((r) => cb(null, r), cb);
+							}
+						}
+						return;
+					} else if (typeof externals === "object") {
+						const resolvedExternals = resolveLayer(
+							externals,
+							/** @type {IssuerLayer} */
+							(contextInfo.issuerLayer)
+						);
+						if (
+							Object.prototype.hasOwnProperty.call(
+								resolvedExternals,
+								dependency.request
+							)
+						) {
+							return handleExternal(
+								resolvedExternals[dependency.request],
+								undefined,
+								callback
+							);
+						}
+					}
+					callback();
+				};
+
+				handleExternals(this.externals, callback);
+			}
+		);
+	}
+}
+
+module.exports = ExternalModuleFactoryPlugin;
Index: frontend/node_modules/webpack/lib/ExternalsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ExternalsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ExternalsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,94 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ModuleExternalInitFragment } = require("./ExternalModule");
+const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin");
+const ConcatenatedModule = require("./optimize/ConcatenatedModule");
+
+/** @typedef {import("../declarations/WebpackOptions").ExternalsType} ExternalsType */
+/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./ExternalModule").Imported} Imported */
+/** @typedef {import("./Dependency")} Dependency */
+
+const PLUGIN_NAME = "ExternalsPlugin";
+
+class ExternalsPlugin {
+	/**
+	 * Creates an instance of ExternalsPlugin.
+	 * @param {ExternalsType | ((dependency: Dependency) => ExternalsType)} type default external type
+	 * @param {Externals} externals externals config
+	 */
+	constructor(type, externals) {
+		this.type = type;
+		this.externals = externals;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compile.tap(PLUGIN_NAME, ({ normalModuleFactory }) => {
+			new ExternalModuleFactoryPlugin(this.type, this.externals).apply(
+				normalModuleFactory
+			);
+		});
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const { concatenatedModuleInfo } =
+				ConcatenatedModule.getCompilationHooks(compilation);
+			concatenatedModuleInfo.tap(PLUGIN_NAME, (updatedInfo, moduleInfo) => {
+				const rawExportMap = updatedInfo.rawExportMap;
+
+				if (!rawExportMap) {
+					return;
+				}
+
+				const chunkInitFragments = moduleInfo.chunkInitFragments;
+				const moduleExternalInitFragments =
+					/** @type {ModuleExternalInitFragment[]} */
+					(
+						chunkInitFragments
+							? /** @type {unknown[]} */
+								(chunkInitFragments).filter(
+									(fragment) => fragment instanceof ModuleExternalInitFragment
+								)
+							: []
+					);
+
+				let initFragmentChanged = false;
+
+				for (const fragment of moduleExternalInitFragments) {
+					const imported = fragment.getImported();
+
+					if (Array.isArray(imported)) {
+						const newImported =
+							/** @type {Imported} */
+							(
+								imported.map(([specifier, finalName]) => [
+									specifier,
+									rawExportMap.has(specifier)
+										? rawExportMap.get(specifier)
+										: finalName
+								])
+							);
+						fragment.setImported(newImported);
+						initFragmentChanged = true;
+					}
+				}
+
+				if (initFragmentChanged) {
+					return true;
+				}
+			});
+		});
+	}
+}
+
+module.exports = ExternalsPlugin;
Index: frontend/node_modules/webpack/lib/FileSystemInfo.js
===================================================================
--- frontend/node_modules/webpack/lib/FileSystemInfo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/FileSystemInfo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,4353 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const nodeModule = require("module");
+const { isAbsolute } = require("path");
+const { create: createResolver } = require("enhanced-resolve");
+const asyncLib = require("neo-async");
+const { DEFAULTS } = require("./config/defaults");
+const AsyncQueue = require("./util/AsyncQueue");
+const StackedCacheMap = require("./util/StackedCacheMap");
+const createHash = require("./util/createHash");
+const { dirname, join, lstatReadlinkAbsolute, relative } = require("./util/fs");
+const makeSerializable = require("./util/makeSerializable");
+const memoize = require("./util/memoize");
+const processAsyncTree = require("./util/processAsyncTree");
+
+/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
+/** @typedef {import("enhanced-resolve").ResolveFunctionAsync} ResolveFunctionAsync */
+/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./errors/WebpackError")} WebpackError */
+/** @typedef {import("./util/fs").JsonObject} JsonObject */
+/** @typedef {import("./util/fs").IStats} IStats */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/**
+ * Defines the processor callback type used by this module.
+ * @template T
+ * @typedef {import("./util/AsyncQueue").Callback<T>} ProcessorCallback
+ */
+/**
+ * Defines the processor type used by this module.
+ * @template T, R
+ * @typedef {import("./util/AsyncQueue").Processor<T, R>} Processor
+ */
+
+const supportsEsm = Number(process.versions.modules) >= 83;
+
+/** @type {Set<string>} */
+const builtinModules = new Set(nodeModule.builtinModules);
+
+let FS_ACCURACY = 2000;
+
+/** @type {Set<string>} */
+const EMPTY_SET = new Set();
+
+const RBDT_RESOLVE_INITIAL = 0;
+const RBDT_RESOLVE_FILE = 1;
+const RBDT_RESOLVE_DIRECTORY = 2;
+const RBDT_RESOLVE_CJS_FILE = 3;
+const RBDT_RESOLVE_CJS_FILE_AS_CHILD = 4;
+const RBDT_RESOLVE_ESM_FILE = 5;
+const RBDT_DIRECTORY = 6;
+const RBDT_FILE = 7;
+const RBDT_DIRECTORY_DEPENDENCIES = 8;
+const RBDT_FILE_DEPENDENCIES = 9;
+
+/** @typedef {RBDT_RESOLVE_INITIAL | RBDT_RESOLVE_FILE | RBDT_RESOLVE_DIRECTORY | RBDT_RESOLVE_CJS_FILE | RBDT_RESOLVE_CJS_FILE_AS_CHILD | RBDT_RESOLVE_ESM_FILE | RBDT_DIRECTORY | RBDT_FILE | RBDT_DIRECTORY_DEPENDENCIES | RBDT_FILE_DEPENDENCIES} JobType */
+
+const INVALID = Symbol("invalid");
+
+// eslint-disable-next-line jsdoc/ts-no-empty-object-type
+/** @typedef {{  }} ExistenceOnlyTimeEntry */
+
+/**
+ * Defines the file system info entry type used by this module.
+ * @typedef {object} FileSystemInfoEntry
+ * @property {number} safeTime
+ * @property {number=} timestamp
+ */
+
+/**
+ * Defines the resolved context file system info entry type used by this module.
+ * @typedef {object} ResolvedContextFileSystemInfoEntry
+ * @property {number} safeTime
+ * @property {string=} timestampHash
+ */
+
+/** @typedef {Set<string>} Symlinks */
+
+/**
+ * Defines the context file system info entry type used by this module.
+ * @typedef {object} ContextFileSystemInfoEntry
+ * @property {number} safeTime
+ * @property {string=} timestampHash
+ * @property {ResolvedContextFileSystemInfoEntry=} resolved
+ * @property {Symlinks=} symlinks
+ */
+
+/**
+ * Defines the timestamp and hash type used by this module.
+ * @typedef {object} TimestampAndHash
+ * @property {number} safeTime
+ * @property {number=} timestamp
+ * @property {string} hash
+ */
+
+/**
+ * Defines the resolved context timestamp and hash type used by this module.
+ * @typedef {object} ResolvedContextTimestampAndHash
+ * @property {number} safeTime
+ * @property {string=} timestampHash
+ * @property {string} hash
+ */
+
+/**
+ * Defines the context timestamp and hash type used by this module.
+ * @typedef {object} ContextTimestampAndHash
+ * @property {number} safeTime
+ * @property {string=} timestampHash
+ * @property {string} hash
+ * @property {ResolvedContextTimestampAndHash=} resolved
+ * @property {Symlinks=} symlinks
+ */
+
+/**
+ * Defines the context hash type used by this module.
+ * @typedef {object} ContextHash
+ * @property {string} hash
+ * @property {string=} resolved
+ * @property {Symlinks=} symlinks
+ */
+
+/** @typedef {Set<string>} SnapshotContent */
+
+/**
+ * Defines the snapshot optimization entry type used by this module.
+ * @typedef {object} SnapshotOptimizationEntry
+ * @property {Snapshot} snapshot
+ * @property {number} shared
+ * @property {SnapshotContent | undefined} snapshotContent
+ * @property {Set<SnapshotOptimizationEntry> | undefined} children
+ */
+
+/** @typedef {Map<string, string | false | undefined>} ResolveResults */
+
+/** @typedef {Set<string>} Files */
+/** @typedef {Set<string>} Directories */
+/** @typedef {Set<string>} Missing */
+
+/**
+ * Defines the resolve dependencies type used by this module.
+ * @typedef {object} ResolveDependencies
+ * @property {Files} files list of files
+ * @property {Directories} directories list of directories
+ * @property {Missing} missing list of missing entries
+ */
+
+/**
+ * Defines the resolve build dependencies result type used by this module.
+ * @typedef {object} ResolveBuildDependenciesResult
+ * @property {Files} files list of files
+ * @property {Directories} directories list of directories
+ * @property {Missing} missing list of missing entries
+ * @property {ResolveResults} resolveResults stored resolve results
+ * @property {ResolveDependencies} resolveDependencies dependencies of the resolving
+ */
+
+/**
+ * Defines the snapshot options type used by this module.
+ * @typedef {object} SnapshotOptions
+ * @property {boolean=} hash should use hash to snapshot
+ * @property {boolean=} timestamp should use timestamp to snapshot
+ */
+
+const DONE_ITERATOR_RESULT = new Set().keys().next();
+
+// cspell:word tshs
+// Tsh = Timestamp + Hash
+// Tshs = Timestamp + Hash combinations
+
+class SnapshotIterator {
+	/**
+	 * Creates an instance of SnapshotIterator.
+	 * @param {() => IteratorResult<string>} next next
+	 */
+	constructor(next) {
+		this.next = next;
+	}
+}
+
+/**
+ * Defines the get maps function type used by this module.
+ * @template T
+ * @typedef {(snapshot: Snapshot) => T[]} GetMapsFunction
+ */
+
+/**
+ * Represents SnapshotIterable.
+ * @template T
+ */
+class SnapshotIterable {
+	/**
+	 * Creates an instance of SnapshotIterable.
+	 * @param {Snapshot} snapshot snapshot
+	 * @param {GetMapsFunction<T>} getMaps get maps function
+	 */
+	constructor(snapshot, getMaps) {
+		this.snapshot = snapshot;
+		this.getMaps = getMaps;
+	}
+
+	[Symbol.iterator]() {
+		let state = 0;
+		/** @type {IterableIterator<string>} */
+		let it;
+		/** @type {GetMapsFunction<T>} */
+		let getMaps;
+		/** @type {T[]} */
+		let maps;
+		/** @type {Snapshot} */
+		let snapshot;
+		/** @type {Snapshot[] | undefined} */
+		let queue;
+		return new SnapshotIterator(() => {
+			for (;;) {
+				switch (state) {
+					case 0:
+						snapshot = this.snapshot;
+						getMaps = this.getMaps;
+						maps = getMaps(snapshot);
+						state = 1;
+					/* falls through */
+					case 1:
+						if (maps.length > 0) {
+							const map = maps.pop();
+							if (map !== undefined) {
+								it =
+									/** @type {Set<string> | Map<string, EXPECTED_ANY>} */
+									(map).keys();
+								state = 2;
+							} else {
+								break;
+							}
+						} else {
+							state = 3;
+							break;
+						}
+					/* falls through */
+					case 2: {
+						const result = it.next();
+						if (!result.done) return result;
+						state = 1;
+						break;
+					}
+					case 3: {
+						const children = snapshot.children;
+						if (children !== undefined) {
+							if (children.size === 1) {
+								// shortcut for a single child
+								// avoids allocation of queue
+								for (const child of children) snapshot = child;
+								maps = getMaps(snapshot);
+								state = 1;
+								break;
+							}
+							if (queue === undefined) queue = [];
+							for (const child of children) {
+								queue.push(child);
+							}
+						}
+						if (queue !== undefined && queue.length > 0) {
+							snapshot = /** @type {Snapshot} */ (queue.pop());
+							maps = getMaps(snapshot);
+							state = 1;
+							break;
+						} else {
+							state = 4;
+						}
+					}
+					/* falls through */
+					case 4:
+						return DONE_ITERATOR_RESULT;
+				}
+			}
+		});
+	}
+}
+
+/** @typedef {Map<string, FileSystemInfoEntry | null>} FileTimestamps */
+/** @typedef {Map<string, string | null>} FileHashes */
+/** @typedef {Map<string, TimestampAndHash | string | null>} FileTshs */
+/** @typedef {Map<string, ResolvedContextFileSystemInfoEntry | null>} ContextTimestamps */
+/** @typedef {Map<string, string | null>} ContextHashes */
+/** @typedef {Map<string, ResolvedContextTimestampAndHash | null>} ContextTshs */
+/** @typedef {Map<string, boolean>} MissingExistence */
+/** @typedef {Map<string, string>} ManagedItemInfo */
+/** @typedef {Set<string>} ManagedFiles */
+/** @typedef {Set<string>} ManagedContexts */
+/** @typedef {Set<string>} ManagedMissing */
+/** @typedef {Set<Snapshot>} Children */
+
+class Snapshot {
+	constructor() {
+		this._flags = 0;
+		/** @type {Iterable<string> | undefined} */
+		this._cachedFileIterable = undefined;
+		/** @type {Iterable<string> | undefined} */
+		this._cachedContextIterable = undefined;
+		/** @type {Iterable<string> | undefined} */
+		this._cachedMissingIterable = undefined;
+		/** @type {number | undefined} */
+		this.startTime = undefined;
+		/** @type {FileTimestamps | undefined} */
+		this.fileTimestamps = undefined;
+		/** @type {FileHashes | undefined} */
+		this.fileHashes = undefined;
+		/** @type {FileTshs | undefined} */
+		this.fileTshs = undefined;
+		/** @type {ContextTimestamps | undefined} */
+		this.contextTimestamps = undefined;
+		/** @type {ContextHashes | undefined} */
+		this.contextHashes = undefined;
+		/** @type {ContextTshs | undefined} */
+		this.contextTshs = undefined;
+		/** @type {MissingExistence | undefined} */
+		this.missingExistence = undefined;
+		/** @type {ManagedItemInfo | undefined} */
+		this.managedItemInfo = undefined;
+		/** @type {ManagedFiles | undefined} */
+		this.managedFiles = undefined;
+		/** @type {ManagedContexts | undefined} */
+		this.managedContexts = undefined;
+		/** @type {ManagedMissing | undefined} */
+		this.managedMissing = undefined;
+		/** @type {Children | undefined} */
+		this.children = undefined;
+	}
+
+	hasStartTime() {
+		return (this._flags & 1) !== 0;
+	}
+
+	/**
+	 * Updates start time using the provided value.
+	 * @param {number} value start value
+	 */
+	setStartTime(value) {
+		this._flags |= 1;
+		this.startTime = value;
+	}
+
+	/**
+	 * Sets merged start time.
+	 * @param {number | undefined} value value
+	 * @param {Snapshot} snapshot snapshot
+	 */
+	setMergedStartTime(value, snapshot) {
+		if (value) {
+			if (snapshot.hasStartTime()) {
+				this.setStartTime(
+					Math.min(
+						value,
+						/** @type {NonNullable<Snapshot["startTime"]>} */
+						(snapshot.startTime)
+					)
+				);
+			} else {
+				this.setStartTime(value);
+			}
+		} else if (snapshot.hasStartTime()) {
+			this.setStartTime(
+				/** @type {NonNullable<Snapshot["startTime"]>} */
+				(snapshot.startTime)
+			);
+		}
+	}
+
+	hasFileTimestamps() {
+		return (this._flags & 2) !== 0;
+	}
+
+	/**
+	 * Sets file timestamps.
+	 * @param {FileTimestamps} value file timestamps
+	 */
+	setFileTimestamps(value) {
+		this._flags |= 2;
+		this.fileTimestamps = value;
+	}
+
+	hasFileHashes() {
+		return (this._flags & 4) !== 0;
+	}
+
+	/**
+	 * Updates file hashes using the provided value.
+	 * @param {FileHashes} value file hashes
+	 */
+	setFileHashes(value) {
+		this._flags |= 4;
+		this.fileHashes = value;
+	}
+
+	hasFileTshs() {
+		return (this._flags & 8) !== 0;
+	}
+
+	/**
+	 * Updates file tshs using the provided value.
+	 * @param {FileTshs} value file tshs
+	 */
+	setFileTshs(value) {
+		this._flags |= 8;
+		this.fileTshs = value;
+	}
+
+	hasContextTimestamps() {
+		return (this._flags & 0x10) !== 0;
+	}
+
+	/**
+	 * Sets context timestamps.
+	 * @param {ContextTimestamps} value context timestamps
+	 */
+	setContextTimestamps(value) {
+		this._flags |= 0x10;
+		this.contextTimestamps = value;
+	}
+
+	hasContextHashes() {
+		return (this._flags & 0x20) !== 0;
+	}
+
+	/**
+	 * Sets context hashes.
+	 * @param {ContextHashes} value context hashes
+	 */
+	setContextHashes(value) {
+		this._flags |= 0x20;
+		this.contextHashes = value;
+	}
+
+	hasContextTshs() {
+		return (this._flags & 0x40) !== 0;
+	}
+
+	/**
+	 * Updates context tshs using the provided value.
+	 * @param {ContextTshs} value context tshs
+	 */
+	setContextTshs(value) {
+		this._flags |= 0x40;
+		this.contextTshs = value;
+	}
+
+	hasMissingExistence() {
+		return (this._flags & 0x80) !== 0;
+	}
+
+	/**
+	 * Sets missing existence.
+	 * @param {MissingExistence} value context tshs
+	 */
+	setMissingExistence(value) {
+		this._flags |= 0x80;
+		this.missingExistence = value;
+	}
+
+	hasManagedItemInfo() {
+		return (this._flags & 0x100) !== 0;
+	}
+
+	/**
+	 * Sets managed item info.
+	 * @param {ManagedItemInfo} value managed item info
+	 */
+	setManagedItemInfo(value) {
+		this._flags |= 0x100;
+		this.managedItemInfo = value;
+	}
+
+	hasManagedFiles() {
+		return (this._flags & 0x200) !== 0;
+	}
+
+	/**
+	 * Sets managed files.
+	 * @param {ManagedFiles} value managed files
+	 */
+	setManagedFiles(value) {
+		this._flags |= 0x200;
+		this.managedFiles = value;
+	}
+
+	hasManagedContexts() {
+		return (this._flags & 0x400) !== 0;
+	}
+
+	/**
+	 * Sets managed contexts.
+	 * @param {ManagedContexts} value managed contexts
+	 */
+	setManagedContexts(value) {
+		this._flags |= 0x400;
+		this.managedContexts = value;
+	}
+
+	hasManagedMissing() {
+		return (this._flags & 0x800) !== 0;
+	}
+
+	/**
+	 * Sets managed missing.
+	 * @param {ManagedMissing} value managed missing
+	 */
+	setManagedMissing(value) {
+		this._flags |= 0x800;
+		this.managedMissing = value;
+	}
+
+	hasChildren() {
+		return (this._flags & 0x1000) !== 0;
+	}
+
+	/**
+	 * Updates children using the provided value.
+	 * @param {Children} value children
+	 */
+	setChildren(value) {
+		this._flags |= 0x1000;
+		this.children = value;
+	}
+
+	/**
+	 * Adds the provided child to the snapshot.
+	 * @param {Snapshot} child children
+	 */
+	addChild(child) {
+		if (!this.hasChildren()) {
+			this.setChildren(new Set());
+		}
+		/** @type {Children} */
+		(this.children).add(child);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this._flags);
+		if (this.hasStartTime()) write(this.startTime);
+		if (this.hasFileTimestamps()) write(this.fileTimestamps);
+		if (this.hasFileHashes()) write(this.fileHashes);
+		if (this.hasFileTshs()) write(this.fileTshs);
+		if (this.hasContextTimestamps()) write(this.contextTimestamps);
+		if (this.hasContextHashes()) write(this.contextHashes);
+		if (this.hasContextTshs()) write(this.contextTshs);
+		if (this.hasMissingExistence()) write(this.missingExistence);
+		if (this.hasManagedItemInfo()) write(this.managedItemInfo);
+		if (this.hasManagedFiles()) write(this.managedFiles);
+		if (this.hasManagedContexts()) write(this.managedContexts);
+		if (this.hasManagedMissing()) write(this.managedMissing);
+		if (this.hasChildren()) write(this.children);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize({ read }) {
+		this._flags = read();
+		if (this.hasStartTime()) this.startTime = read();
+		if (this.hasFileTimestamps()) this.fileTimestamps = read();
+		if (this.hasFileHashes()) this.fileHashes = read();
+		if (this.hasFileTshs()) this.fileTshs = read();
+		if (this.hasContextTimestamps()) this.contextTimestamps = read();
+		if (this.hasContextHashes()) this.contextHashes = read();
+		if (this.hasContextTshs()) this.contextTshs = read();
+		if (this.hasMissingExistence()) this.missingExistence = read();
+		if (this.hasManagedItemInfo()) this.managedItemInfo = read();
+		if (this.hasManagedFiles()) this.managedFiles = read();
+		if (this.hasManagedContexts()) this.managedContexts = read();
+		if (this.hasManagedMissing()) this.managedMissing = read();
+		if (this.hasChildren()) this.children = read();
+	}
+
+	/**
+	 * Creates an iterable from the provided get map.
+	 * @template T
+	 * @param {GetMapsFunction<T>} getMaps first
+	 * @returns {SnapshotIterable<T>} iterable
+	 */
+	_createIterable(getMaps) {
+		return new SnapshotIterable(this, getMaps);
+	}
+
+	/**
+	 * Gets file iterable.
+	 * @returns {Iterable<string>} iterable
+	 */
+	getFileIterable() {
+		if (this._cachedFileIterable === undefined) {
+			this._cachedFileIterable = this._createIterable((s) => [
+				s.fileTimestamps,
+				s.fileHashes,
+				s.fileTshs,
+				s.managedFiles
+			]);
+		}
+		return this._cachedFileIterable;
+	}
+
+	/**
+	 * Gets context iterable.
+	 * @returns {Iterable<string>} iterable
+	 */
+	getContextIterable() {
+		if (this._cachedContextIterable === undefined) {
+			this._cachedContextIterable = this._createIterable((s) => [
+				s.contextTimestamps,
+				s.contextHashes,
+				s.contextTshs,
+				s.managedContexts
+			]);
+		}
+		return this._cachedContextIterable;
+	}
+
+	/**
+	 * Gets missing iterable.
+	 * @returns {Iterable<string>} iterable
+	 */
+	getMissingIterable() {
+		if (this._cachedMissingIterable === undefined) {
+			this._cachedMissingIterable = this._createIterable((s) => [
+				s.missingExistence,
+				s.managedMissing
+			]);
+		}
+		return this._cachedMissingIterable;
+	}
+}
+
+makeSerializable(Snapshot, "webpack/lib/FileSystemInfo", "Snapshot");
+
+const MIN_COMMON_SNAPSHOT_SIZE = 3;
+
+/**
+ * Defines the snapshot optimization value type used by this module.
+ * @template U, T
+ * @typedef {U extends true ? Set<string> : Map<string, T>} SnapshotOptimizationValue
+ */
+
+/**
+ * Represents SnapshotOptimization.
+ * @template T
+ * @template {boolean} [U=false]
+ */
+class SnapshotOptimization {
+	/**
+	 * Creates an instance of SnapshotOptimization.
+	 * @param {(snapshot: Snapshot) => boolean} has has value
+	 * @param {(snapshot: Snapshot) => SnapshotOptimizationValue<U, T> | undefined} get get value
+	 * @param {(snapshot: Snapshot, value: SnapshotOptimizationValue<U, T>) => void} set set value
+	 * @param {boolean=} useStartTime use the start time of snapshots
+	 * @param {U=} isSet value is an Set instead of a Map
+	 */
+	constructor(
+		has,
+		get,
+		set,
+		useStartTime = true,
+		isSet = /** @type {U} */ (false)
+	) {
+		this._has = has;
+		this._get = get;
+		this._set = set;
+		this._useStartTime = useStartTime;
+		/** @type {U} */
+		this._isSet = isSet;
+		/** @type {Map<string, SnapshotOptimizationEntry>} */
+		this._map = new Map();
+		this._statItemsShared = 0;
+		this._statItemsUnshared = 0;
+		this._statSharedSnapshots = 0;
+		this._statReusedSharedSnapshots = 0;
+	}
+
+	getStatisticMessage() {
+		const total = this._statItemsShared + this._statItemsUnshared;
+		if (total === 0) return;
+		return `${
+			this._statItemsShared && Math.round((this._statItemsShared * 100) / total)
+		}% (${this._statItemsShared}/${total}) entries shared via ${
+			this._statSharedSnapshots
+		} shared snapshots (${
+			this._statReusedSharedSnapshots + this._statSharedSnapshots
+		} times referenced)`;
+	}
+
+	clear() {
+		this._map.clear();
+		this._statItemsShared = 0;
+		this._statItemsUnshared = 0;
+		this._statSharedSnapshots = 0;
+		this._statReusedSharedSnapshots = 0;
+	}
+
+	/**
+	 * Processes the provided new snapshot.
+	 * @param {Snapshot} newSnapshot snapshot
+	 * @param {Set<string>} capturedFiles files to snapshot/share
+	 * @returns {void}
+	 */
+	optimize(newSnapshot, capturedFiles) {
+		if (capturedFiles.size === 0) {
+			return;
+		}
+		/**
+		 * Increase shared and store optimization entry.
+		 * @param {SnapshotOptimizationEntry} entry optimization entry
+		 * @returns {void}
+		 */
+		const increaseSharedAndStoreOptimizationEntry = (entry) => {
+			if (entry.children !== undefined) {
+				for (const child of entry.children) {
+					increaseSharedAndStoreOptimizationEntry(child);
+				}
+			}
+			entry.shared++;
+			storeOptimizationEntry(entry);
+		};
+		/**
+		 * Stores optimization entry.
+		 * @param {SnapshotOptimizationEntry} entry optimization entry
+		 * @returns {void}
+		 */
+		const storeOptimizationEntry = (entry) => {
+			for (const path of /** @type {SnapshotContent} */ (
+				entry.snapshotContent
+			)) {
+				const old =
+					/** @type {SnapshotOptimizationEntry} */
+					(this._map.get(path));
+				if (old.shared < entry.shared) {
+					this._map.set(path, entry);
+				}
+				capturedFiles.delete(path);
+			}
+		};
+
+		/** @type {SnapshotOptimizationEntry | undefined} */
+		let newOptimizationEntry;
+
+		const capturedFilesSize = capturedFiles.size;
+
+		/** @type {Set<SnapshotOptimizationEntry> | undefined} */
+		const optimizationEntries = new Set();
+
+		for (const path of capturedFiles) {
+			const optimizationEntry = this._map.get(path);
+			if (optimizationEntry === undefined) {
+				if (newOptimizationEntry === undefined) {
+					newOptimizationEntry = {
+						snapshot: newSnapshot,
+						shared: 0,
+						snapshotContent: undefined,
+						children: undefined
+					};
+				}
+				this._map.set(path, newOptimizationEntry);
+			} else {
+				optimizationEntries.add(optimizationEntry);
+			}
+		}
+
+		optimizationEntriesLabel: for (const optimizationEntry of optimizationEntries) {
+			const snapshot = optimizationEntry.snapshot;
+			if (optimizationEntry.shared > 0) {
+				// It's a shared snapshot
+				// We can't change it, so we can only use it when all files match
+				// and startTime is compatible
+				if (
+					this._useStartTime &&
+					newSnapshot.startTime &&
+					(!snapshot.startTime || snapshot.startTime > newSnapshot.startTime)
+				) {
+					continue;
+				}
+				/** @type {Set<string>} */
+				const nonSharedFiles = new Set();
+				const snapshotContent =
+					/** @type {NonNullable<SnapshotOptimizationEntry["snapshotContent"]>} */
+					(optimizationEntry.snapshotContent);
+				const snapshotEntries =
+					/** @type {SnapshotOptimizationValue<U, T>} */
+					(this._get(snapshot));
+				for (const path of snapshotContent) {
+					if (!capturedFiles.has(path)) {
+						if (!snapshotEntries.has(path)) {
+							// File is not shared and can't be removed from the snapshot
+							// because it's in a child of the snapshot
+							continue optimizationEntriesLabel;
+						}
+						nonSharedFiles.add(path);
+					}
+				}
+				if (nonSharedFiles.size === 0) {
+					// The complete snapshot is shared
+					// add it as child
+					newSnapshot.addChild(snapshot);
+					increaseSharedAndStoreOptimizationEntry(optimizationEntry);
+					this._statReusedSharedSnapshots++;
+				} else {
+					// Only a part of the snapshot is shared
+					const sharedCount = snapshotContent.size - nonSharedFiles.size;
+					if (sharedCount < MIN_COMMON_SNAPSHOT_SIZE) {
+						// Common part it too small
+						continue;
+					}
+					// Extract common timestamps from both snapshots
+					/** @type {Set<string> | Map<string, T>} */
+					let commonMap;
+					if (this._isSet) {
+						commonMap = new Set();
+						for (const path of /** @type {Set<string>} */ (snapshotEntries)) {
+							if (nonSharedFiles.has(path)) continue;
+							commonMap.add(path);
+							snapshotEntries.delete(path);
+						}
+					} else {
+						commonMap = new Map();
+						const map = /** @type {Map<string, T>} */ (snapshotEntries);
+						for (const [path, value] of map) {
+							if (nonSharedFiles.has(path)) continue;
+							commonMap.set(path, value);
+							snapshotEntries.delete(path);
+						}
+					}
+					// Create and attach snapshot
+					const commonSnapshot = new Snapshot();
+					if (this._useStartTime) {
+						commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
+					}
+					this._set(
+						commonSnapshot,
+						/** @type {SnapshotOptimizationValue<U, T>} */ (commonMap)
+					);
+					newSnapshot.addChild(commonSnapshot);
+					snapshot.addChild(commonSnapshot);
+					// Create optimization entry
+					const newEntry = {
+						snapshot: commonSnapshot,
+						shared: optimizationEntry.shared + 1,
+						snapshotContent: new Set(commonMap.keys()),
+						children: undefined
+					};
+					if (optimizationEntry.children === undefined) {
+						optimizationEntry.children = new Set();
+					}
+					optimizationEntry.children.add(newEntry);
+					storeOptimizationEntry(newEntry);
+					this._statSharedSnapshots++;
+				}
+			} else {
+				// It's a unshared snapshot
+				// We can extract a common shared snapshot
+				// with all common files
+				const snapshotEntries = this._get(snapshot);
+				if (snapshotEntries === undefined) {
+					// Incomplete snapshot, that can't be used
+					continue;
+				}
+				/** @type {Set<string> | Map<string, T>} */
+				let commonMap;
+				if (this._isSet) {
+					commonMap = new Set();
+					const set = /** @type {Set<string>} */ (snapshotEntries);
+					if (capturedFiles.size < set.size) {
+						for (const path of capturedFiles) {
+							if (set.has(path)) commonMap.add(path);
+						}
+					} else {
+						for (const path of set) {
+							if (capturedFiles.has(path)) commonMap.add(path);
+						}
+					}
+				} else {
+					commonMap = new Map();
+					const map = /** @type {Map<string, T>} */ (snapshotEntries);
+					for (const path of capturedFiles) {
+						const ts = map.get(path);
+						if (ts === undefined) continue;
+						commonMap.set(path, ts);
+					}
+				}
+
+				if (commonMap.size < MIN_COMMON_SNAPSHOT_SIZE) {
+					// Common part it too small
+					continue;
+				}
+				// Create and attach snapshot
+				const commonSnapshot = new Snapshot();
+				if (this._useStartTime) {
+					commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
+				}
+				this._set(
+					commonSnapshot,
+					/** @type {SnapshotOptimizationValue<U, T>} */
+					(commonMap)
+				);
+				newSnapshot.addChild(commonSnapshot);
+				snapshot.addChild(commonSnapshot);
+				// Remove files from snapshot
+				for (const path of commonMap.keys()) snapshotEntries.delete(path);
+				const sharedCount = commonMap.size;
+				this._statItemsUnshared -= sharedCount;
+				this._statItemsShared += sharedCount;
+				// Create optimization entry
+				storeOptimizationEntry({
+					snapshot: commonSnapshot,
+					shared: 2,
+					snapshotContent: new Set(commonMap.keys()),
+					children: undefined
+				});
+				this._statSharedSnapshots++;
+			}
+		}
+		const unshared = capturedFiles.size;
+		this._statItemsUnshared += unshared;
+		this._statItemsShared += capturedFilesSize - unshared;
+	}
+}
+
+/**
+ * Returns result.
+ * @param {string} str input
+ * @returns {string} result
+ */
+const parseString = (str) => {
+	if (str[0] === "'" || str[0] === "`") {
+		str = `"${str.slice(1, -1).replace(/"/g, '\\"')}"`;
+	}
+	return JSON.parse(str);
+};
+
+/* istanbul ignore next */
+/**
+ * Processes the provided mtime.
+ * @param {number} mtime mtime
+ */
+const applyMtime = (mtime) => {
+	if (FS_ACCURACY > 1 && mtime % 2 !== 0) FS_ACCURACY = 1;
+	else if (FS_ACCURACY > 10 && mtime % 20 !== 0) FS_ACCURACY = 10;
+	else if (FS_ACCURACY > 100 && mtime % 200 !== 0) FS_ACCURACY = 100;
+	else if (FS_ACCURACY > 1000 && mtime % 2000 !== 0) FS_ACCURACY = 1000;
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @template T
+ * @template K
+ * @param {Map<T, K> | undefined} a source map
+ * @param {Map<T, K> | undefined} b joining map
+ * @returns {Map<T, K>} joined map
+ */
+const mergeMaps = (a, b) => {
+	if (!b || b.size === 0) return /** @type {Map<T, K>} */ (a);
+	if (!a || a.size === 0) return /** @type {Map<T, K>} */ (b);
+	/** @type {Map<T, K>} */
+	const map = new Map(a);
+	for (const [key, value] of b) {
+		map.set(key, value);
+	}
+	return map;
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @template T
+ * @param {Set<T> | undefined} a source map
+ * @param {Set<T> | undefined} b joining map
+ * @returns {Set<T>} joined map
+ */
+const mergeSets = (a, b) => {
+	if (!b || b.size === 0) return /** @type {Set<T>} */ (a);
+	if (!a || a.size === 0) return /** @type {Set<T>} */ (b);
+	/** @type {Set<T>} */
+	const map = new Set(a);
+	for (const item of b) {
+		map.add(item);
+	}
+	return map;
+};
+
+/**
+ * Finding file or directory to manage
+ * @param {string} managedPath path that is managing by {@link FileSystemInfo}
+ * @param {string} path path to file or directory
+ * @returns {string | null} managed item
+ * @example
+ * getManagedItem(
+ *   '/Users/user/my-project/node_modules/',
+ *   '/Users/user/my-project/node_modules/package/index.js'
+ * ) === '/Users/user/my-project/node_modules/package'
+ * getManagedItem(
+ *   '/Users/user/my-project/node_modules/',
+ *   '/Users/user/my-project/node_modules/package1/node_modules/package2'
+ * ) === '/Users/user/my-project/node_modules/package1/node_modules/package2'
+ * getManagedItem(
+ *   '/Users/user/my-project/node_modules/',
+ *   '/Users/user/my-project/node_modules/.bin/script.js'
+ * ) === null // hidden files are disallowed as managed items
+ * getManagedItem(
+ *   '/Users/user/my-project/node_modules/',
+ *   '/Users/user/my-project/node_modules/package'
+ * ) === '/Users/user/my-project/node_modules/package'
+ */
+const getManagedItem = (managedPath, path) => {
+	let i = managedPath.length;
+	let slashes = 1;
+	let startingPosition = true;
+	loop: while (i < path.length) {
+		switch (path.charCodeAt(i)) {
+			case 47: // slash
+			case 92: // backslash
+				if (--slashes === 0) break loop;
+				startingPosition = true;
+				break;
+			case 46: // .
+				// hidden files are disallowed as managed items
+				// it's probably .yarn-integrity or .cache
+				if (startingPosition) return null;
+				break;
+			case 64: // @
+				if (!startingPosition) return null;
+				slashes++;
+				break;
+			default:
+				startingPosition = false;
+				break;
+		}
+		i++;
+	}
+	if (i === path.length) slashes--;
+	// return null when path is incomplete
+	if (slashes !== 0) return null;
+	// if (path.slice(i + 1, i + 13) === "node_modules")
+	if (
+		path.length >= i + 13 &&
+		path.charCodeAt(i + 1) === 110 &&
+		path.charCodeAt(i + 2) === 111 &&
+		path.charCodeAt(i + 3) === 100 &&
+		path.charCodeAt(i + 4) === 101 &&
+		path.charCodeAt(i + 5) === 95 &&
+		path.charCodeAt(i + 6) === 109 &&
+		path.charCodeAt(i + 7) === 111 &&
+		path.charCodeAt(i + 8) === 100 &&
+		path.charCodeAt(i + 9) === 117 &&
+		path.charCodeAt(i + 10) === 108 &&
+		path.charCodeAt(i + 11) === 101 &&
+		path.charCodeAt(i + 12) === 115
+	) {
+		// if this is the end of the path
+		if (path.length === i + 13) {
+			// return the node_modules directory
+			// it's special
+			return path;
+		}
+		const c = path.charCodeAt(i + 13);
+		// if next symbol is slash or backslash
+		if (c === 47 || c === 92) {
+			// Managed subpath
+			return getManagedItem(path.slice(0, i + 14), path);
+		}
+	}
+	return path.slice(0, i);
+};
+
+/**
+ * Gets resolved timestamp.
+ * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T
+ * @param {T | null} entry entry
+ * @returns {T["resolved"] | null | undefined} the resolved entry
+ */
+const getResolvedTimestamp = (entry) => {
+	if (entry === null) return null;
+	if (entry.resolved !== undefined) return entry.resolved;
+	return entry.symlinks === undefined ? entry : undefined;
+};
+
+/**
+ * Gets resolved hash.
+ * @param {ContextHash | null} entry entry
+ * @returns {string | null | undefined} the resolved entry
+ */
+const getResolvedHash = (entry) => {
+	if (entry === null) return null;
+	if (entry.resolved !== undefined) return entry.resolved;
+	return entry.symlinks === undefined ? entry.hash : undefined;
+};
+
+/**
+ * Adds the provided source to the snapshot optimization.
+ * @template T
+ * @param {Set<T>} source source
+ * @param {Set<T>} target target
+ */
+const addAll = (source, target) => {
+	for (const key of source) target.add(key);
+};
+
+const getEsModuleLexer = memoize(() => require("es-module-lexer"));
+
+/** @typedef {Set<string>} LoggedPaths */
+
+/** @typedef {FileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null} FileTimestamp */
+/** @typedef {ContextFileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null} ContextTimestamp */
+/** @typedef {ResolvedContextFileSystemInfoEntry | "ignore" | null} ResolvedContextTimestamp */
+
+/**
+ * `watchpack` may report `{}` (existence-only) for files and directories it
+ * is watching but has no time information for. Such entries cannot be used
+ * for snapshot comparison, so cache lookups treat them as "no cached value"
+ * and fall back to a fresh on-disk read.
+ * @param {FileTimestamp | ContextTimestamp | undefined} entry cache entry
+ * @returns {entry is ExistenceOnlyTimeEntry} true if the entry exists but carries no time info
+ */
+const isExistenceOnly = (entry) => {
+	if (entry === undefined || entry === null || entry === "ignore") return false;
+	return (
+		/** @type {Partial<FileSystemInfoEntry> & Partial<ContextFileSystemInfoEntry>} */
+		(entry).safeTime === undefined
+	);
+};
+
+/** @typedef {(err?: WebpackError | null, result?: boolean) => void} CheckSnapshotValidCallback */
+
+/**
+ * Used to access information about the filesystem in a cached way
+ */
+class FileSystemInfo {
+	/**
+	 * Creates an instance of FileSystemInfo.
+	 * @param {InputFileSystem} fs file system
+	 * @param {object} options options
+	 * @param {Iterable<string | RegExp>=} options.unmanagedPaths paths that are not managed by a package manager and the contents are subject to change
+	 * @param {Iterable<string | RegExp>=} options.managedPaths paths that are only managed by a package manager
+	 * @param {Iterable<string | RegExp>=} options.immutablePaths paths that are immutable
+	 * @param {Logger=} options.logger logger used to log invalid snapshots
+	 * @param {HashFunction=} options.hashFunction the hash function to use
+	 */
+	constructor(
+		fs,
+		{
+			unmanagedPaths = [],
+			managedPaths = [],
+			immutablePaths = [],
+			logger,
+			hashFunction = DEFAULTS.HASH_FUNCTION
+		} = {}
+	) {
+		this.fs = fs;
+		this.logger = logger;
+		this._remainingLogs = logger ? 40 : 0;
+		/** @type {LoggedPaths | undefined} */
+		this._loggedPaths = logger ? new Set() : undefined;
+		this._hashFunction = hashFunction;
+		/** @type {WeakMap<Snapshot, boolean | CheckSnapshotValidCallback[]>} */
+		this._snapshotCache = new WeakMap();
+		this._fileTimestampsOptimization = new SnapshotOptimization(
+			(s) => s.hasFileTimestamps(),
+			(s) => s.fileTimestamps,
+			(s, v) => s.setFileTimestamps(v)
+		);
+		this._fileHashesOptimization = new SnapshotOptimization(
+			(s) => s.hasFileHashes(),
+			(s) => s.fileHashes,
+			(s, v) => s.setFileHashes(v),
+			false
+		);
+		this._fileTshsOptimization = new SnapshotOptimization(
+			(s) => s.hasFileTshs(),
+			(s) => s.fileTshs,
+			(s, v) => s.setFileTshs(v)
+		);
+		this._contextTimestampsOptimization = new SnapshotOptimization(
+			(s) => s.hasContextTimestamps(),
+			(s) => s.contextTimestamps,
+			(s, v) => s.setContextTimestamps(v)
+		);
+		this._contextHashesOptimization = new SnapshotOptimization(
+			(s) => s.hasContextHashes(),
+			(s) => s.contextHashes,
+			(s, v) => s.setContextHashes(v),
+			false
+		);
+		this._contextTshsOptimization = new SnapshotOptimization(
+			(s) => s.hasContextTshs(),
+			(s) => s.contextTshs,
+			(s, v) => s.setContextTshs(v)
+		);
+		this._missingExistenceOptimization = new SnapshotOptimization(
+			(s) => s.hasMissingExistence(),
+			(s) => s.missingExistence,
+			(s, v) => s.setMissingExistence(v),
+			false
+		);
+		this._managedItemInfoOptimization = new SnapshotOptimization(
+			(s) => s.hasManagedItemInfo(),
+			(s) => s.managedItemInfo,
+			(s, v) => s.setManagedItemInfo(v),
+			false
+		);
+		this._managedFilesOptimization = new SnapshotOptimization(
+			(s) => s.hasManagedFiles(),
+			(s) => s.managedFiles,
+			(s, v) => s.setManagedFiles(v),
+			false,
+			true
+		);
+		this._managedContextsOptimization = new SnapshotOptimization(
+			(s) => s.hasManagedContexts(),
+			(s) => s.managedContexts,
+			(s, v) => s.setManagedContexts(v),
+			false,
+			true
+		);
+		this._managedMissingOptimization = new SnapshotOptimization(
+			(s) => s.hasManagedMissing(),
+			(s) => s.managedMissing,
+			(s, v) => s.setManagedMissing(v),
+			false,
+			true
+		);
+		/** @type {StackedCacheMap<string, FileTimestamp>} */
+		this._fileTimestamps = new StackedCacheMap();
+		/** @type {Map<string, string | null>} */
+		this._fileHashes = new Map();
+		/** @type {Map<string, TimestampAndHash | string>} */
+		this._fileTshs = new Map();
+		/** @type {StackedCacheMap<string, ContextTimestamp>} */
+		this._contextTimestamps = new StackedCacheMap();
+		/** @type {Map<string, ContextHash>} */
+		this._contextHashes = new Map();
+		/** @type {Map<string, ContextTimestampAndHash>} */
+		this._contextTshs = new Map();
+		/** @type {Map<string, string>} */
+		this._managedItems = new Map();
+		/** @type {AsyncQueue<string, string, FileSystemInfoEntry>} */
+		this.fileTimestampQueue = new AsyncQueue({
+			name: "file timestamp",
+			parallelism: 30,
+			processor: this._readFileTimestamp.bind(this)
+		});
+		/** @type {AsyncQueue<string, string, string>} */
+		this.fileHashQueue = new AsyncQueue({
+			name: "file hash",
+			parallelism: 10,
+			processor: this._readFileHash.bind(this)
+		});
+		/** @type {AsyncQueue<string, string, ContextFileSystemInfoEntry>} */
+		this.contextTimestampQueue = new AsyncQueue({
+			name: "context timestamp",
+			parallelism: 2,
+			processor: this._readContextTimestamp.bind(this)
+		});
+		/** @type {AsyncQueue<string, string, ContextHash>} */
+		this.contextHashQueue = new AsyncQueue({
+			name: "context hash",
+			parallelism: 2,
+			processor: this._readContextHash.bind(this)
+		});
+		/** @type {AsyncQueue<string, string, ContextTimestampAndHash>} */
+		this.contextTshQueue = new AsyncQueue({
+			name: "context hash and timestamp",
+			parallelism: 2,
+			processor: this._readContextTimestampAndHash.bind(this)
+		});
+		/** @type {AsyncQueue<string, string, string>} */
+		this.managedItemQueue = new AsyncQueue({
+			name: "managed item info",
+			parallelism: 10,
+			processor: this._getManagedItemInfo.bind(this)
+		});
+		/** @type {AsyncQueue<string, string, Set<string>>} */
+		this.managedItemDirectoryQueue = new AsyncQueue({
+			name: "managed item directory info",
+			parallelism: 10,
+			processor: this._getManagedItemDirectoryInfo.bind(this)
+		});
+		const _unmanagedPaths = [...unmanagedPaths];
+		/** @type {string[]} */
+		this.unmanagedPathsWithSlash = _unmanagedPaths
+			.filter((p) => typeof p === "string")
+			.map((p) => join(fs, p, "_").slice(0, -1));
+		/** @type {RegExp[]} */
+		this.unmanagedPathsRegExps = _unmanagedPaths.filter(
+			(p) => typeof p !== "string"
+		);
+
+		this.managedPaths = [...managedPaths];
+		/** @type {string[]} */
+		this.managedPathsWithSlash = this.managedPaths
+			.filter((p) => typeof p === "string")
+			.map((p) => join(fs, p, "_").slice(0, -1));
+		/** @type {RegExp[]} */
+		this.managedPathsRegExps = this.managedPaths.filter(
+			(p) => typeof p !== "string"
+		);
+
+		this.immutablePaths = [...immutablePaths];
+		/** @type {string[]} */
+		this.immutablePathsWithSlash = this.immutablePaths
+			.filter((p) => typeof p === "string")
+			.map((p) => join(fs, p, "_").slice(0, -1));
+		/** @type {RegExp[]} */
+		this.immutablePathsRegExps = this.immutablePaths.filter(
+			(p) => typeof p !== "string"
+		);
+
+		this._cachedDeprecatedFileTimestamps = undefined;
+		this._cachedDeprecatedContextTimestamps = undefined;
+
+		this._warnAboutExperimentalEsmTracking = false;
+
+		this._statCreatedSnapshots = 0;
+		this._statTestedSnapshotsCached = 0;
+		this._statTestedSnapshotsNotCached = 0;
+		this._statTestedChildrenCached = 0;
+		this._statTestedChildrenNotCached = 0;
+		this._statTestedEntries = 0;
+	}
+
+	logStatistics() {
+		const logger = /** @type {Logger} */ (this.logger);
+		/**
+		 * Processes the provided header.
+		 * @param {string} header header
+		 * @param {string | undefined} message message
+		 */
+		const logWhenMessage = (header, message) => {
+			if (message) {
+				logger.log(`${header}: ${message}`);
+			}
+		};
+		logger.log(`${this._statCreatedSnapshots} new snapshots created`);
+		logger.log(
+			`${
+				this._statTestedSnapshotsNotCached &&
+				Math.round(
+					(this._statTestedSnapshotsNotCached * 100) /
+						(this._statTestedSnapshotsCached +
+							this._statTestedSnapshotsNotCached)
+				)
+			}% root snapshot uncached (${this._statTestedSnapshotsNotCached} / ${
+				this._statTestedSnapshotsCached + this._statTestedSnapshotsNotCached
+			})`
+		);
+		logger.log(
+			`${
+				this._statTestedChildrenNotCached &&
+				Math.round(
+					(this._statTestedChildrenNotCached * 100) /
+						(this._statTestedChildrenCached + this._statTestedChildrenNotCached)
+				)
+			}% children snapshot uncached (${this._statTestedChildrenNotCached} / ${
+				this._statTestedChildrenCached + this._statTestedChildrenNotCached
+			})`
+		);
+		logger.log(`${this._statTestedEntries} entries tested`);
+		logger.log(
+			`File info in cache: ${this._fileTimestamps.size} timestamps ${this._fileHashes.size} hashes ${this._fileTshs.size} timestamp hash combinations`
+		);
+		logWhenMessage(
+			"File timestamp snapshot optimization",
+			this._fileTimestampsOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"File hash snapshot optimization",
+			this._fileHashesOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"File timestamp hash combination snapshot optimization",
+			this._fileTshsOptimization.getStatisticMessage()
+		);
+		logger.log(
+			`Directory info in cache: ${this._contextTimestamps.size} timestamps ${this._contextHashes.size} hashes ${this._contextTshs.size} timestamp hash combinations`
+		);
+		logWhenMessage(
+			"Directory timestamp snapshot optimization",
+			this._contextTimestampsOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"Directory hash snapshot optimization",
+			this._contextHashesOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"Directory timestamp hash combination snapshot optimization",
+			this._contextTshsOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"Missing items snapshot optimization",
+			this._missingExistenceOptimization.getStatisticMessage()
+		);
+		logger.log(`Managed items info in cache: ${this._managedItems.size} items`);
+		logWhenMessage(
+			"Managed items snapshot optimization",
+			this._managedItemInfoOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"Managed files snapshot optimization",
+			this._managedFilesOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"Managed contexts snapshot optimization",
+			this._managedContextsOptimization.getStatisticMessage()
+		);
+		logWhenMessage(
+			"Managed missing snapshot optimization",
+			this._managedMissingOptimization.getStatisticMessage()
+		);
+	}
+
+	/**
+	 * Processes the provided path.
+	 * @private
+	 * @param {string} path path
+	 * @param {string} reason reason
+	 * @param {EXPECTED_ANY[]} args arguments
+	 */
+	_log(path, reason, ...args) {
+		const key = path + reason;
+		const loggedPaths = /** @type {LoggedPaths} */ (this._loggedPaths);
+		if (loggedPaths.has(key)) return;
+		loggedPaths.add(key);
+		/** @type {Logger} */
+		(this.logger).debug(`${path} invalidated because ${reason}`, ...args);
+		if (--this._remainingLogs === 0) {
+			/** @type {Logger} */
+			(this.logger).debug(
+				"Logging limit has been reached and no further logging will be emitted by FileSystemInfo"
+			);
+		}
+	}
+
+	clear() {
+		this._remainingLogs = this.logger ? 40 : 0;
+		if (this._loggedPaths !== undefined) this._loggedPaths.clear();
+
+		this._snapshotCache = new WeakMap();
+		this._fileTimestampsOptimization.clear();
+		this._fileHashesOptimization.clear();
+		this._fileTshsOptimization.clear();
+		this._contextTimestampsOptimization.clear();
+		this._contextHashesOptimization.clear();
+		this._contextTshsOptimization.clear();
+		this._missingExistenceOptimization.clear();
+		this._managedItemInfoOptimization.clear();
+		this._managedFilesOptimization.clear();
+		this._managedContextsOptimization.clear();
+		this._managedMissingOptimization.clear();
+		this._fileTimestamps.clear();
+		this._fileHashes.clear();
+		this._fileTshs.clear();
+		this._contextTimestamps.clear();
+		this._contextHashes.clear();
+		this._contextTshs.clear();
+		this._managedItems.clear();
+		this._managedItems.clear();
+
+		this._cachedDeprecatedFileTimestamps = undefined;
+		this._cachedDeprecatedContextTimestamps = undefined;
+
+		this._statCreatedSnapshots = 0;
+		this._statTestedSnapshotsCached = 0;
+		this._statTestedSnapshotsNotCached = 0;
+		this._statTestedChildrenCached = 0;
+		this._statTestedChildrenNotCached = 0;
+		this._statTestedEntries = 0;
+	}
+
+	/**
+	 * Adds file timestamps.
+	 * @param {ReadonlyMap<string, FileTimestamp>} map timestamps
+	 * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
+	 * @returns {void}
+	 */
+	addFileTimestamps(map, immutable) {
+		this._fileTimestamps.addAll(map, immutable);
+		this._cachedDeprecatedFileTimestamps = undefined;
+	}
+
+	/**
+	 * Adds context timestamps.
+	 * @param {ReadonlyMap<string, ContextTimestamp>} map timestamps
+	 * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
+	 * @returns {void}
+	 */
+	addContextTimestamps(map, immutable) {
+		this._contextTimestamps.addAll(map, immutable);
+		this._cachedDeprecatedContextTimestamps = undefined;
+	}
+
+	/**
+	 * Gets file timestamp.
+	 * @param {string} path file path
+	 * @param {(err?: WebpackError | null, fileTimestamp?: FileSystemInfoEntry | "ignore" | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	getFileTimestamp(path, callback) {
+		const cache = this._fileTimestamps.get(path);
+		if (cache !== undefined && !isExistenceOnly(cache)) {
+			return callback(
+				null,
+				/** @type {FileSystemInfoEntry | "ignore" | null} */ (cache)
+			);
+		}
+		this.fileTimestampQueue.add(path, callback);
+	}
+
+	/**
+	 * Gets context timestamp.
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, resolvedContextTimestamp?: ResolvedContextTimestamp) => void} callback callback function
+	 * @returns {void}
+	 */
+	getContextTimestamp(path, callback) {
+		const cache = this._contextTimestamps.get(path);
+		if (cache !== undefined && !isExistenceOnly(cache)) {
+			if (cache === "ignore") return callback(null, "ignore");
+			const fullEntry =
+				/** @type {ContextFileSystemInfoEntry | null} */
+				(cache);
+			const resolved = getResolvedTimestamp(fullEntry);
+			if (resolved !== undefined) return callback(null, resolved);
+			return this._resolveContextTimestamp(
+				/** @type {ContextFileSystemInfoEntry} */
+				(fullEntry),
+				callback
+			);
+		}
+		this._readFreshContextTimestamp(path, callback);
+	}
+
+	/**
+	 * Reads a context timestamp directly from disk, bypassing any cached
+	 * entry. Used by `getContextTimestamp` and the snapshot validity
+	 * checks when the cached entry is missing or is an `ExistenceOnlyTimeEntry`
+	 * (`{}`) supplied by watchpack — both cases require a fresh read to
+	 * obtain the `timestampHash`.
+	 * @private
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, resolvedContextTimestamp?: ResolvedContextTimestamp) => void} callback callback function
+	 * @returns {void}
+	 */
+	_readFreshContextTimestamp(path, callback) {
+		this.contextTimestampQueue.add(path, (err, _entry) => {
+			if (err) return callback(err);
+			const entry = /** @type {ContextFileSystemInfoEntry | null} */ (_entry);
+			if (entry === null) return callback(null, null);
+			const resolved = getResolvedTimestamp(entry);
+			if (resolved !== undefined) return callback(null, resolved);
+			this._resolveContextTimestamp(entry, callback);
+		});
+	}
+
+	/**
+	 * Get unresolved context timestamp. Existence-only cache entries (`{}`)
+	 * are bypassed so the callback always receives a complete entry, "ignore"
+	 * or null.
+	 * @private
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, contextTimestamp?: ContextFileSystemInfoEntry | "ignore" | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	_getUnresolvedContextTimestamp(path, callback) {
+		const cache = this._contextTimestamps.get(path);
+		if (cache !== undefined && !isExistenceOnly(cache)) {
+			return callback(
+				null,
+				/** @type {ContextFileSystemInfoEntry | "ignore" | null} */ (cache)
+			);
+		}
+		this.contextTimestampQueue.add(path, callback);
+	}
+
+	/**
+	 * Returns file hash.
+	 * @param {string} path file path
+	 * @param {(err?: WebpackError | null, hash?: string | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	getFileHash(path, callback) {
+		const cache = this._fileHashes.get(path);
+		if (cache !== undefined) return callback(null, cache);
+		this.fileHashQueue.add(path, callback);
+	}
+
+	/**
+	 * Returns context hash.
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, contextHash?: string) => void} callback callback function
+	 * @returns {void}
+	 */
+	getContextHash(path, callback) {
+		const cache = this._contextHashes.get(path);
+		if (cache !== undefined) {
+			const resolved = getResolvedHash(cache);
+			if (resolved !== undefined) {
+				return callback(null, /** @type {string} */ (resolved));
+			}
+			return this._resolveContextHash(cache, callback);
+		}
+		this.contextHashQueue.add(path, (err, _entry) => {
+			if (err) return callback(err);
+			const entry = /** @type {ContextHash} */ (_entry);
+			const resolved = getResolvedHash(entry);
+			if (resolved !== undefined) {
+				return callback(null, /** @type {string} */ (resolved));
+			}
+			this._resolveContextHash(entry, callback);
+		});
+	}
+
+	/**
+	 * Get unresolved context hash.
+	 * @private
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, contextHash?: ContextHash | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	_getUnresolvedContextHash(path, callback) {
+		const cache = this._contextHashes.get(path);
+		if (cache !== undefined) return callback(null, cache);
+		this.contextHashQueue.add(path, callback);
+	}
+
+	/**
+	 * Returns context tsh.
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, resolvedContextTimestampAndHash?: ResolvedContextTimestampAndHash | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	getContextTsh(path, callback) {
+		const cache = this._contextTshs.get(path);
+		if (cache !== undefined) {
+			const resolved = getResolvedTimestamp(cache);
+			if (resolved !== undefined) return callback(null, resolved);
+			return this._resolveContextTsh(cache, callback);
+		}
+		this.contextTshQueue.add(path, (err, _entry) => {
+			if (err) return callback(err);
+			const entry = /** @type {ContextTimestampAndHash} */ (_entry);
+			const resolved = getResolvedTimestamp(entry);
+			if (resolved !== undefined) return callback(null, resolved);
+			this._resolveContextTsh(entry, callback);
+		});
+	}
+
+	/**
+	 * Get unresolved context tsh.
+	 * @private
+	 * @param {string} path context path
+	 * @param {(err?: WebpackError | null, contextTimestampAndHash?: ContextTimestampAndHash | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	_getUnresolvedContextTsh(path, callback) {
+		const cache = this._contextTshs.get(path);
+		if (cache !== undefined) return callback(null, cache);
+		this.contextTshQueue.add(path, callback);
+	}
+
+	_createBuildDependenciesResolvers() {
+		const resolveContext = createResolver({
+			resolveToContext: true,
+			exportsFields: [],
+			fileSystem: this.fs
+		});
+		const resolveCjs = createResolver({
+			extensions: [".js", ".json", ".node"],
+			conditionNames: ["require", "module-sync", "node"],
+			exportsFields: ["exports"],
+			fileSystem: this.fs
+		});
+		const resolveCjsAsChild = createResolver({
+			extensions: [".js", ".json", ".node"],
+			conditionNames: ["require", "module-sync", "node"],
+			exportsFields: [],
+			fileSystem: this.fs
+		});
+		const resolveEsm = createResolver({
+			extensions: [".js", ".json", ".node"],
+			fullySpecified: true,
+			conditionNames: ["import", "module-sync", "node"],
+			exportsFields: ["exports"],
+			fileSystem: this.fs
+		});
+		return { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild };
+	}
+
+	/**
+	 * Resolves build dependencies.
+	 * @param {string} context context directory
+	 * @param {Iterable<string>} deps dependencies
+	 * @param {(err?: Error | null, resolveBuildDependenciesResult?: ResolveBuildDependenciesResult) => void} callback callback function
+	 * @returns {void}
+	 */
+	resolveBuildDependencies(context, deps, callback) {
+		const { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild } =
+			this._createBuildDependenciesResolvers();
+
+		/** @type {Files} */
+		const files = new Set();
+		/** @type {Symlinks} */
+		const fileSymlinks = new Set();
+		/** @type {Directories} */
+		const directories = new Set();
+		/** @type {Symlinks} */
+		const directorySymlinks = new Set();
+		/** @type {Missing} */
+		const missing = new Set();
+		/** @type {ResolveDependencies["files"]} */
+		const resolveFiles = new Set();
+		/** @type {ResolveDependencies["directories"]} */
+		const resolveDirectories = new Set();
+		/** @type {ResolveDependencies["missing"]} */
+		const resolveMissing = new Set();
+		/** @type {ResolveResults} */
+		const resolveResults = new Map();
+		/** @type {Set<string>} */
+		const invalidResolveResults = new Set();
+		const resolverContext = {
+			fileDependencies: resolveFiles,
+			contextDependencies: resolveDirectories,
+			missingDependencies: resolveMissing
+		};
+		/**
+		 * Expected to string.
+		 * @param {undefined | boolean | string} expected expected result
+		 * @returns {string} expected result
+		 */
+		const expectedToString = (expected) =>
+			expected ? ` (expected ${expected})` : "";
+		/** @typedef {{ type: JobType, context: string | undefined, path: string, issuer: Job | undefined, expected: undefined | boolean | string }} Job */
+
+		/**
+		 * Returns result.
+		 * @param {Job} job job
+		 * @returns {string} result
+		 */
+		const jobToString = (job) => {
+			switch (job.type) {
+				case RBDT_RESOLVE_FILE:
+					return `resolve file ${job.path}${expectedToString(job.expected)}`;
+				case RBDT_RESOLVE_DIRECTORY:
+					return `resolve directory ${job.path}`;
+				case RBDT_RESOLVE_CJS_FILE:
+					return `resolve commonjs file ${job.path}${expectedToString(
+						job.expected
+					)}`;
+				case RBDT_RESOLVE_ESM_FILE:
+					return `resolve esm file ${job.path}${expectedToString(
+						job.expected
+					)}`;
+				case RBDT_DIRECTORY:
+					return `directory ${job.path}`;
+				case RBDT_FILE:
+					return `file ${job.path}`;
+				case RBDT_DIRECTORY_DEPENDENCIES:
+					return `directory dependencies ${job.path}`;
+				case RBDT_FILE_DEPENDENCIES:
+					return `file dependencies ${job.path}`;
+			}
+			return `unknown ${job.type} ${job.path}`;
+		};
+		/**
+		 * Returns string value.
+		 * @param {Job} job job
+		 * @returns {string} string value
+		 */
+		const pathToString = (job) => {
+			let result = ` at ${jobToString(job)}`;
+			/** @type {Job | undefined} */
+			(job) = job.issuer;
+			while (job !== undefined) {
+				result += `\n at ${jobToString(job)}`;
+				job = /** @type {Job} */ (job.issuer);
+			}
+			return result;
+		};
+		const logger = /** @type {Logger} */ (this.logger);
+		processAsyncTree(
+			Array.from(
+				deps,
+				(dep) =>
+					/** @type {Job} */ ({
+						type: RBDT_RESOLVE_INITIAL,
+						context,
+						path: dep,
+						expected: undefined,
+						issuer: undefined
+					})
+			),
+			20,
+			(job, push, callback) => {
+				const { type, context, path, expected } = job;
+				/**
+				 * Resolves directory.
+				 * @param {string} path path
+				 * @returns {void}
+				 */
+				const resolveDirectory = (path) => {
+					const key = `d\n${context}\n${path}`;
+					if (resolveResults.has(key)) {
+						return callback();
+					}
+					resolveResults.set(key, undefined);
+					resolveContext(
+						/** @type {string} */ (context),
+						path,
+						resolverContext,
+						(err, _, result) => {
+							if (err) {
+								if (expected === false) {
+									resolveResults.set(key, false);
+									return callback();
+								}
+								invalidResolveResults.add(key);
+								err.message += `\nwhile resolving '${path}' in ${context} to a directory`;
+								return callback(err);
+							}
+							const resultPath = /** @type {ResolveRequest} */ (result).path;
+							resolveResults.set(key, resultPath);
+							push({
+								type: RBDT_DIRECTORY,
+								context: undefined,
+								path: /** @type {string} */ (resultPath),
+								expected: undefined,
+								issuer: job
+							});
+							callback();
+						}
+					);
+				};
+				/**
+				 * Processes the provided path.
+				 * @param {string} path path
+				 * @param {("f" | "c" | "e")=} symbol symbol
+				 * @param {(ResolveFunctionAsync)=} resolve resolve fn
+				 * @returns {void}
+				 */
+				const resolveFile = (path, symbol, resolve) => {
+					const key = `${symbol}\n${context}\n${path}`;
+					if (resolveResults.has(key)) {
+						return callback();
+					}
+					resolveResults.set(key, undefined);
+					/** @type {ResolveFunctionAsync} */
+					(resolve)(
+						/** @type {string} */ (context),
+						path,
+						resolverContext,
+						(err, _, result) => {
+							if (typeof expected === "string") {
+								if (!err && result && result.path === expected) {
+									resolveResults.set(key, result.path);
+								} else {
+									invalidResolveResults.add(key);
+									logger.warn(
+										`Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${
+											err || (result && result.path)
+										}' instead. Resolving dependencies are ignored for this path.\n${pathToString(
+											job
+										)}`
+									);
+								}
+							} else {
+								if (err) {
+									if (expected === false) {
+										resolveResults.set(key, false);
+										return callback();
+									}
+									invalidResolveResults.add(key);
+									err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString(
+										job
+									)}`;
+									return callback(err);
+								}
+								const resultPath = /** @type {ResolveRequest} */ (result).path;
+								resolveResults.set(key, resultPath);
+								push({
+									type: RBDT_FILE,
+									context: undefined,
+									path: /** @type {string} */ (resultPath),
+									expected: undefined,
+									issuer: job
+								});
+							}
+							callback();
+						}
+					);
+				};
+				const resolvedType =
+					type === RBDT_RESOLVE_INITIAL
+						? /[\\/]$/.test(path)
+							? RBDT_RESOLVE_DIRECTORY
+							: RBDT_RESOLVE_FILE
+						: type;
+				switch (resolvedType) {
+					case RBDT_RESOLVE_FILE: {
+						resolveFile(
+							path,
+							"f",
+							/\.mjs$/.test(path) ? resolveEsm : resolveCjs
+						);
+						break;
+					}
+					case RBDT_RESOLVE_DIRECTORY: {
+						resolveDirectory(
+							type === RBDT_RESOLVE_INITIAL ? path.slice(0, -1) : path
+						);
+						break;
+					}
+					case RBDT_RESOLVE_CJS_FILE: {
+						resolveFile(path, "f", resolveCjs);
+						break;
+					}
+					case RBDT_RESOLVE_CJS_FILE_AS_CHILD: {
+						resolveFile(path, "c", resolveCjsAsChild);
+						break;
+					}
+					case RBDT_RESOLVE_ESM_FILE: {
+						resolveFile(path, "e", resolveEsm);
+						break;
+					}
+					case RBDT_FILE: {
+						if (files.has(path)) {
+							callback();
+							break;
+						}
+						files.add(path);
+						/** @type {NonNullable<InputFileSystem["realpath"]>} */
+						(this.fs.realpath)(path, (err, _realPath) => {
+							if (err) return callback(err);
+							const realPath = /** @type {string} */ (_realPath);
+							if (realPath !== path) {
+								fileSymlinks.add(path);
+								resolveFiles.add(path);
+								if (files.has(realPath)) return callback();
+								files.add(realPath);
+							}
+							push({
+								type: RBDT_FILE_DEPENDENCIES,
+								context: undefined,
+								path: realPath,
+								expected: undefined,
+								issuer: job
+							});
+							callback();
+						});
+						break;
+					}
+					case RBDT_DIRECTORY: {
+						if (directories.has(path)) {
+							callback();
+							break;
+						}
+						directories.add(path);
+						/** @type {NonNullable<InputFileSystem["realpath"]>} */
+						(this.fs.realpath)(path, (err, _realPath) => {
+							if (err) return callback(err);
+							const realPath = /** @type {string} */ (_realPath);
+							if (realPath !== path) {
+								directorySymlinks.add(path);
+								resolveFiles.add(path);
+								if (directories.has(realPath)) return callback();
+								directories.add(realPath);
+							}
+							push({
+								type: RBDT_DIRECTORY_DEPENDENCIES,
+								context: undefined,
+								path: realPath,
+								expected: undefined,
+								issuer: job
+							});
+							callback();
+						});
+						break;
+					}
+					case RBDT_FILE_DEPENDENCIES: {
+						// Check for known files without dependencies
+						if (/\.json5?$|\.yarn-integrity$|yarn\.lock$|\.ya?ml/.test(path)) {
+							process.nextTick(callback);
+							break;
+						}
+						// Check commonjs cache for the module
+						/** @type {NodeModule | undefined} */
+						const module = require.cache[path];
+						if (
+							module &&
+							Array.isArray(module.children) &&
+							// https://github.com/nodejs/node/issues/59868
+							// Force use `es-module-lexer` for mjs
+							!/\.mjs$/.test(path)
+						) {
+							children: for (const child of module.children) {
+								const childPath = child.filename;
+								if (childPath) {
+									push({
+										type: RBDT_FILE,
+										context: undefined,
+										path: childPath,
+										expected: undefined,
+										issuer: job
+									});
+									const context = dirname(this.fs, path);
+									for (const modulePath of module.paths) {
+										if (childPath.startsWith(modulePath)) {
+											const subPath = childPath.slice(modulePath.length + 1);
+											const packageMatch = /^@[^\\/]+[\\/][^\\/]+/.exec(
+												subPath
+											);
+											if (packageMatch) {
+												push({
+													type: RBDT_FILE,
+													context: undefined,
+													path: `${
+														modulePath +
+														childPath[modulePath.length] +
+														packageMatch[0] +
+														childPath[modulePath.length]
+													}package.json`,
+													expected: false,
+													issuer: job
+												});
+											}
+											let request = subPath.replace(/\\/g, "/");
+											if (request.endsWith(".js")) {
+												request = request.slice(0, -3);
+											}
+											push({
+												type: RBDT_RESOLVE_CJS_FILE_AS_CHILD,
+												context,
+												path: request,
+												expected: child.filename,
+												issuer: job
+											});
+											continue children;
+										}
+									}
+									let request = relative(this.fs, context, childPath);
+									if (request.endsWith(".js")) request = request.slice(0, -3);
+									request = request.replace(/\\/g, "/");
+									if (!request.startsWith("../") && !isAbsolute(request)) {
+										request = `./${request}`;
+									}
+									push({
+										type: RBDT_RESOLVE_CJS_FILE,
+										context,
+										path: request,
+										expected: child.filename,
+										issuer: job
+									});
+								}
+							}
+						} else if (supportsEsm && /\.m?js$/.test(path)) {
+							if (!this._warnAboutExperimentalEsmTracking) {
+								logger.log(
+									"Node.js doesn't offer a (nice) way to introspect the ESM dependency graph yet.\n" +
+										"Until a full solution is available webpack uses an experimental ESM tracking based on parsing.\n" +
+										"As best effort webpack parses the ESM files to guess dependencies. But this can lead to expensive and incorrect tracking."
+								);
+								this._warnAboutExperimentalEsmTracking = true;
+							}
+
+							const lexer = getEsModuleLexer();
+
+							lexer.init.then(() => {
+								this.fs.readFile(path, (err, content) => {
+									if (err) return callback(err);
+									try {
+										const context = dirname(this.fs, path);
+										const source = /** @type {Buffer} */ (content).toString();
+										const [imports] = lexer.parse(source);
+										/** @type {Set<string>} */
+										const added = new Set();
+										for (const imp of imports) {
+											try {
+												/** @type {string} */
+												let dependency;
+												if (imp.d === -1) {
+													// import ... from "..."
+													dependency = parseString(
+														source.slice(imp.s - 1, imp.e + 1)
+													);
+												} else if (imp.d > -1) {
+													// import()
+													const expr = source.slice(imp.s, imp.e).trim();
+													dependency = parseString(expr);
+												} else {
+													// e.g. import.meta
+													continue;
+												}
+
+												// We should not track Node.js build dependencies
+												if (dependency.startsWith("node:")) continue;
+												if (builtinModules.has(dependency)) continue;
+												// Avoid extra jobs for identical imports
+												if (added.has(dependency)) continue;
+
+												push({
+													type: RBDT_RESOLVE_ESM_FILE,
+													context,
+													path: dependency,
+													expected: imp.d > -1 ? false : undefined,
+													issuer: job
+												});
+												added.add(dependency);
+											} catch (err1) {
+												logger.warn(
+													`Parsing of ${path} for build dependencies failed at 'import(${source.slice(
+														imp.s,
+														imp.e
+													)})'.\n` +
+														"Build dependencies behind this expression are ignored and might cause incorrect cache invalidation."
+												);
+												logger.debug(pathToString(job));
+												logger.debug(/** @type {Error} */ (err1).stack);
+											}
+										}
+									} catch (err2) {
+										logger.warn(
+											`Parsing of ${path} for build dependencies failed and all dependencies of this file are ignored, which might cause incorrect cache invalidation..`
+										);
+										logger.debug(pathToString(job));
+										logger.debug(/** @type {Error} */ (err2).stack);
+									}
+									process.nextTick(callback);
+								});
+							}, callback);
+							break;
+						} else {
+							logger.log(
+								`Assuming ${path} has no dependencies as we were unable to assign it to any module system.`
+							);
+							logger.debug(pathToString(job));
+						}
+						process.nextTick(callback);
+						break;
+					}
+					case RBDT_DIRECTORY_DEPENDENCIES: {
+						const match =
+							/(^.+[\\/]node_modules[\\/](?:@[^\\/]+[\\/])?[^\\/]+)/.exec(path);
+						const packagePath = match ? match[1] : path;
+						const packageJson = join(this.fs, packagePath, "package.json");
+						this.fs.readFile(packageJson, (err, content) => {
+							if (err) {
+								if (err.code === "ENOENT") {
+									resolveMissing.add(packageJson);
+									const parent = dirname(this.fs, packagePath);
+									if (parent !== packagePath) {
+										push({
+											type: RBDT_DIRECTORY_DEPENDENCIES,
+											context: undefined,
+											path: parent,
+											expected: undefined,
+											issuer: job
+										});
+									}
+									callback();
+									return;
+								}
+								return callback(err);
+							}
+							resolveFiles.add(packageJson);
+							/** @type {JsonObject} */
+							let packageData;
+							try {
+								packageData = JSON.parse(
+									/** @type {Buffer} */
+									(content).toString("utf8")
+								);
+							} catch (parseErr) {
+								return callback(/** @type {Error} */ (parseErr));
+							}
+							const depsObject = packageData.dependencies;
+							const optionalDepsObject = packageData.optionalDependencies;
+							/** @type {Set<string>} */
+							const allDeps = new Set();
+							/** @type {Set<string>} */
+							const optionalDeps = new Set();
+							if (typeof depsObject === "object" && depsObject) {
+								for (const dep of Object.keys(depsObject)) {
+									allDeps.add(dep);
+								}
+							}
+							if (
+								typeof optionalDepsObject === "object" &&
+								optionalDepsObject
+							) {
+								for (const dep of Object.keys(optionalDepsObject)) {
+									allDeps.add(dep);
+									optionalDeps.add(dep);
+								}
+							}
+							for (const dep of allDeps) {
+								push({
+									type: RBDT_RESOLVE_DIRECTORY,
+									context: packagePath,
+									path: dep,
+									expected: !optionalDeps.has(dep),
+									issuer: job
+								});
+							}
+							callback();
+						});
+						break;
+					}
+				}
+			},
+			(err) => {
+				if (err) return callback(err);
+				for (const l of fileSymlinks) files.delete(l);
+				for (const l of directorySymlinks) directories.delete(l);
+				for (const k of invalidResolveResults) resolveResults.delete(k);
+				callback(null, {
+					files,
+					directories,
+					missing,
+					resolveResults,
+					resolveDependencies: {
+						files: resolveFiles,
+						directories: resolveDirectories,
+						missing: resolveMissing
+					}
+				});
+			}
+		);
+	}
+
+	/**
+	 * Checks resolve results valid.
+	 * @param {ResolveResults} resolveResults results from resolving
+	 * @param {(err?: Error | null, result?: boolean) => void} callback callback with true when resolveResults resolve the same way
+	 * @returns {void}
+	 */
+	checkResolveResultsValid(resolveResults, callback) {
+		const { resolveCjs, resolveCjsAsChild, resolveEsm, resolveContext } =
+			this._createBuildDependenciesResolvers();
+		asyncLib.eachLimit(
+			resolveResults,
+			20,
+			([key, expectedResult], callback) => {
+				const [type, context, path] = key.split("\n");
+				switch (type) {
+					case "d":
+						resolveContext(context, path, {}, (err, _, result) => {
+							if (expectedResult === false) {
+								return callback(err ? undefined : INVALID);
+							}
+							if (err) return callback(err);
+							const resultPath = /** @type {ResolveRequest} */ (result).path;
+							if (resultPath !== expectedResult) return callback(INVALID);
+							callback();
+						});
+						break;
+					case "f":
+						resolveCjs(context, path, {}, (err, _, result) => {
+							if (expectedResult === false) {
+								return callback(err ? undefined : INVALID);
+							}
+							if (err) return callback(err);
+							const resultPath = /** @type {ResolveRequest} */ (result).path;
+							if (resultPath !== expectedResult) return callback(INVALID);
+							callback();
+						});
+						break;
+					case "c":
+						resolveCjsAsChild(context, path, {}, (err, _, result) => {
+							if (expectedResult === false) {
+								return callback(err ? undefined : INVALID);
+							}
+							if (err) return callback(err);
+							const resultPath = /** @type {ResolveRequest} */ (result).path;
+							if (resultPath !== expectedResult) return callback(INVALID);
+							callback();
+						});
+						break;
+					case "e":
+						resolveEsm(context, path, {}, (err, _, result) => {
+							if (expectedResult === false) {
+								return callback(err ? undefined : INVALID);
+							}
+							if (err) return callback(err);
+							const resultPath = /** @type {ResolveRequest} */ (result).path;
+							if (resultPath !== expectedResult) return callback(INVALID);
+							callback();
+						});
+						break;
+					default:
+						callback(new Error("Unexpected type in resolve result key"));
+						break;
+				}
+			},
+			/**
+			 * Processes the provided err.
+			 * @param {Error | typeof INVALID=} err error or invalid flag
+			 * @returns {void}
+			 */
+			/** @type {import("neo-async").ErrorCallback<Error | typeof INVALID>} */ (
+				(err) => {
+					if (err === INVALID) {
+						return callback(null, false);
+					}
+					if (err) {
+						return callback(err);
+					}
+					return callback(null, true);
+				}
+			)
+		);
+	}
+
+	/**
+	 * Creates a snapshot.
+	 * @param {number | null | undefined} startTime when processing the files has started
+	 * @param {Iterable<string> | null | undefined} files all files
+	 * @param {Iterable<string> | null | undefined} directories all directories
+	 * @param {Iterable<string> | null | undefined} missing all missing files or directories
+	 * @param {SnapshotOptions | null | undefined} options options object (for future extensions)
+	 * @param {(err: WebpackError | null, snapshot: Snapshot | null) => void} callback callback function
+	 * @returns {void}
+	 */
+	createSnapshot(startTime, files, directories, missing, options, callback) {
+		/** @type {FileTimestamps} */
+		const fileTimestamps = new Map();
+		/** @type {FileHashes} */
+		const fileHashes = new Map();
+		/** @type {FileTshs} */
+		const fileTshs = new Map();
+		/** @type {ContextTimestamps} */
+		const contextTimestamps = new Map();
+		/** @type {ContextHashes} */
+		const contextHashes = new Map();
+		/** @type {ContextTshs} */
+		const contextTshs = new Map();
+		/** @type {MissingExistence} */
+		const missingExistence = new Map();
+		/** @type {ManagedItemInfo} */
+		const managedItemInfo = new Map();
+		/** @type {ManagedFiles} */
+		const managedFiles = new Set();
+		/** @type {ManagedContexts} */
+		const managedContexts = new Set();
+		/** @type {ManagedMissing} */
+		const managedMissing = new Set();
+		/** @type {Children} */
+		const children = new Set();
+
+		const snapshot = new Snapshot();
+		if (startTime) snapshot.setStartTime(startTime);
+
+		/** @type {Set<string>} */
+		const managedItems = new Set();
+
+		/** 1 = timestamp, 2 = hash, 3 = timestamp + hash */
+		const mode = options && options.hash ? (options.timestamp ? 3 : 2) : 1;
+
+		let jobs = 1;
+		const jobDone = () => {
+			if (--jobs === 0) {
+				if (fileTimestamps.size !== 0) {
+					snapshot.setFileTimestamps(fileTimestamps);
+				}
+				if (fileHashes.size !== 0) {
+					snapshot.setFileHashes(fileHashes);
+				}
+				if (fileTshs.size !== 0) {
+					snapshot.setFileTshs(fileTshs);
+				}
+				if (contextTimestamps.size !== 0) {
+					snapshot.setContextTimestamps(contextTimestamps);
+				}
+				if (contextHashes.size !== 0) {
+					snapshot.setContextHashes(contextHashes);
+				}
+				if (contextTshs.size !== 0) {
+					snapshot.setContextTshs(contextTshs);
+				}
+				if (missingExistence.size !== 0) {
+					snapshot.setMissingExistence(missingExistence);
+				}
+				if (managedItemInfo.size !== 0) {
+					snapshot.setManagedItemInfo(managedItemInfo);
+				}
+				this._managedFilesOptimization.optimize(snapshot, managedFiles);
+				if (managedFiles.size !== 0) {
+					snapshot.setManagedFiles(managedFiles);
+				}
+				this._managedContextsOptimization.optimize(snapshot, managedContexts);
+				if (managedContexts.size !== 0) {
+					snapshot.setManagedContexts(managedContexts);
+				}
+				this._managedMissingOptimization.optimize(snapshot, managedMissing);
+				if (managedMissing.size !== 0) {
+					snapshot.setManagedMissing(managedMissing);
+				}
+				if (children.size !== 0) {
+					snapshot.setChildren(children);
+				}
+				this._snapshotCache.set(snapshot, true);
+				this._statCreatedSnapshots++;
+
+				callback(null, snapshot);
+			}
+		};
+		const jobError = () => {
+			if (jobs > 0) {
+				// large negative number instead of NaN or something else to keep jobs to stay a SMI (v8)
+				jobs = -100000000;
+				callback(null, null);
+			}
+		};
+		/**
+		 * Checks true when managed.
+		 * @param {string} path path
+		 * @param {ManagedFiles} managedSet managed set
+		 * @returns {boolean} true when managed
+		 */
+		const checkManaged = (path, managedSet) => {
+			for (const unmanagedPath of this.unmanagedPathsRegExps) {
+				if (unmanagedPath.test(path)) return false;
+			}
+			for (const unmanagedPath of this.unmanagedPathsWithSlash) {
+				if (path.startsWith(unmanagedPath)) return false;
+			}
+			for (const immutablePath of this.immutablePathsRegExps) {
+				if (immutablePath.test(path)) {
+					managedSet.add(path);
+					return true;
+				}
+			}
+			for (const immutablePath of this.immutablePathsWithSlash) {
+				if (path.startsWith(immutablePath)) {
+					managedSet.add(path);
+					return true;
+				}
+			}
+			for (const managedPath of this.managedPathsRegExps) {
+				const match = managedPath.exec(path);
+				if (match) {
+					const managedItem = getManagedItem(match[1], path);
+					if (managedItem) {
+						managedItems.add(managedItem);
+						managedSet.add(path);
+						return true;
+					}
+				}
+			}
+			for (const managedPath of this.managedPathsWithSlash) {
+				if (path.startsWith(managedPath)) {
+					const managedItem = getManagedItem(managedPath, path);
+					if (managedItem) {
+						managedItems.add(managedItem);
+						managedSet.add(path);
+						return true;
+					}
+				}
+			}
+			return false;
+		};
+		/**
+		 * Capture non managed.
+		 * @param {Iterable<string>} items items
+		 * @param {Set<string>} managedSet managed set
+		 * @returns {Set<string>} result
+		 */
+		const captureNonManaged = (items, managedSet) => {
+			/** @type {Set<string>} */
+			const capturedItems = new Set();
+			for (const path of items) {
+				if (!checkManaged(path, managedSet)) capturedItems.add(path);
+			}
+			return capturedItems;
+		};
+		/**
+		 * Process captured files.
+		 * @param {ManagedFiles} capturedFiles captured files
+		 */
+		const processCapturedFiles = (capturedFiles) => {
+			if (capturedFiles.size === 0) {
+				return;
+			}
+			switch (mode) {
+				case 3:
+					this._fileTshsOptimization.optimize(snapshot, capturedFiles);
+					for (const path of capturedFiles) {
+						const cache = this._fileTshs.get(path);
+						if (cache !== undefined) {
+							fileTshs.set(path, cache);
+						} else {
+							jobs++;
+							this._getFileTimestampAndHash(path, (err, entry) => {
+								if (err) {
+									if (this.logger) {
+										this.logger.debug(
+											`Error snapshotting file timestamp hash combination of ${path}: ${err.stack}`
+										);
+									}
+									jobError();
+								} else {
+									fileTshs.set(path, /** @type {TimestampAndHash} */ (entry));
+									jobDone();
+								}
+							});
+						}
+					}
+					break;
+				case 2:
+					this._fileHashesOptimization.optimize(snapshot, capturedFiles);
+					for (const path of capturedFiles) {
+						const cache = this._fileHashes.get(path);
+						if (cache !== undefined) {
+							fileHashes.set(path, cache);
+						} else {
+							jobs++;
+							this.fileHashQueue.add(path, (err, entry) => {
+								if (err) {
+									if (this.logger) {
+										this.logger.debug(
+											`Error snapshotting file hash of ${path}: ${err.stack}`
+										);
+									}
+									jobError();
+								} else {
+									fileHashes.set(path, /** @type {string} */ (entry));
+									jobDone();
+								}
+							});
+						}
+					}
+					break;
+				case 1:
+					this._fileTimestampsOptimization.optimize(snapshot, capturedFiles);
+					for (const path of capturedFiles) {
+						const cache = this._fileTimestamps.get(path);
+						if (cache !== undefined && !isExistenceOnly(cache)) {
+							if (cache !== "ignore") {
+								fileTimestamps.set(
+									path,
+									/** @type {FileSystemInfoEntry | null} */ (cache)
+								);
+							}
+						} else {
+							jobs++;
+							this.fileTimestampQueue.add(path, (err, entry) => {
+								if (err) {
+									if (this.logger) {
+										this.logger.debug(
+											`Error snapshotting file timestamp of ${path}: ${err.stack}`
+										);
+									}
+									jobError();
+								} else {
+									fileTimestamps.set(
+										path,
+										/** @type {FileSystemInfoEntry} */
+										(entry)
+									);
+									jobDone();
+								}
+							});
+						}
+					}
+					break;
+			}
+		};
+		if (files) {
+			processCapturedFiles(captureNonManaged(files, managedFiles));
+		}
+		/**
+		 * Process captured directories.
+		 * @param {ManagedContexts} capturedDirectories captured directories
+		 */
+		const processCapturedDirectories = (capturedDirectories) => {
+			if (capturedDirectories.size === 0) {
+				return;
+			}
+			switch (mode) {
+				case 3:
+					this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
+					for (const path of capturedDirectories) {
+						const cache = this._contextTshs.get(path);
+						/** @type {ResolvedContextTimestampAndHash | null | undefined} */
+						let resolved;
+						if (
+							cache !== undefined &&
+							(resolved = getResolvedTimestamp(cache)) !== undefined
+						) {
+							contextTshs.set(path, resolved);
+						} else {
+							jobs++;
+							/**
+							 * Processes the provided err.
+							 * @param {(WebpackError | null)=} err error
+							 * @param {(ResolvedContextTimestampAndHash | null)=} entry entry
+							 * @returns {void}
+							 */
+							const callback = (err, entry) => {
+								if (err) {
+									if (this.logger) {
+										this.logger.debug(
+											`Error snapshotting context timestamp hash combination of ${path}: ${err.stack}`
+										);
+									}
+									jobError();
+								} else {
+									contextTshs.set(
+										path,
+										/** @type {ResolvedContextTimestampAndHash | null} */
+										(entry)
+									);
+									jobDone();
+								}
+							};
+							if (cache !== undefined) {
+								this._resolveContextTsh(cache, callback);
+							} else {
+								this.getContextTsh(path, callback);
+							}
+						}
+					}
+					break;
+				case 2:
+					this._contextHashesOptimization.optimize(
+						snapshot,
+						capturedDirectories
+					);
+					for (const path of capturedDirectories) {
+						const cache = this._contextHashes.get(path);
+						/** @type {undefined | null | string} */
+						let resolved;
+						if (
+							cache !== undefined &&
+							(resolved = getResolvedHash(cache)) !== undefined
+						) {
+							contextHashes.set(path, resolved);
+						} else {
+							jobs++;
+							/**
+							 * Processes the provided err.
+							 * @param {(WebpackError | null)=} err err
+							 * @param {string=} entry entry
+							 */
+							const callback = (err, entry) => {
+								if (err) {
+									if (this.logger) {
+										this.logger.debug(
+											`Error snapshotting context hash of ${path}: ${err.stack}`
+										);
+									}
+									jobError();
+								} else {
+									contextHashes.set(path, /** @type {string} */ (entry));
+									jobDone();
+								}
+							};
+							if (cache !== undefined) {
+								this._resolveContextHash(cache, callback);
+							} else {
+								this.getContextHash(path, callback);
+							}
+						}
+					}
+					break;
+				case 1:
+					this._contextTimestampsOptimization.optimize(
+						snapshot,
+						capturedDirectories
+					);
+					for (const path of capturedDirectories) {
+						const cache = this._contextTimestamps.get(path);
+						if (cache === "ignore") continue;
+						/** @type {ContextFileSystemInfoEntry | null | undefined} */
+						const usableCache =
+							cache === undefined || isExistenceOnly(cache)
+								? undefined
+								: /** @type {ContextFileSystemInfoEntry | null} */ (cache);
+						// A non-null cache entry without `timestampHash` cannot be
+						// used to populate the snapshot — the snapshot would then
+						// miss directory-change detection, since validity relies on
+						// `timestampHash`. Re-read the directory in that case.
+						const cacheLacksHash =
+							usableCache !== undefined &&
+							usableCache !== null &&
+							usableCache.timestampHash === undefined;
+						/** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
+						let resolved;
+						if (
+							usableCache !== undefined &&
+							!cacheLacksHash &&
+							(resolved = getResolvedTimestamp(usableCache)) !== undefined
+						) {
+							contextTimestamps.set(path, resolved);
+						} else {
+							jobs++;
+							/**
+							 * Processes the provided err.
+							 * @param {(WebpackError | null)=} err error
+							 * @param {ResolvedContextTimestamp=} entry entry
+							 * @returns {void}
+							 */
+							const callback = (err, entry) => {
+								if (err) {
+									if (this.logger) {
+										this.logger.debug(
+											`Error snapshotting context timestamp of ${path}: ${err.stack}`
+										);
+									}
+									jobError();
+								} else {
+									contextTimestamps.set(
+										path,
+										/** @type {ResolvedContextFileSystemInfoEntry | null} */
+										(entry)
+									);
+									jobDone();
+								}
+							};
+							if (cacheLacksHash) {
+								this._readFreshContextTimestamp(path, callback);
+							} else if (usableCache !== undefined && usableCache !== null) {
+								this._resolveContextTimestamp(usableCache, callback);
+							} else {
+								// Force a fresh on-disk read so the snapshot stores a
+								// complete entry (with `timestampHash`).
+								this._readFreshContextTimestamp(path, callback);
+							}
+						}
+					}
+					break;
+			}
+		};
+		if (directories) {
+			processCapturedDirectories(
+				captureNonManaged(directories, managedContexts)
+			);
+		}
+		/**
+		 * Process captured missing.
+		 * @param {ManagedMissing} capturedMissing captured missing
+		 */
+		const processCapturedMissing = (capturedMissing) => {
+			if (capturedMissing.size === 0) {
+				return;
+			}
+			this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
+			for (const path of capturedMissing) {
+				const cache = this._fileTimestamps.get(path);
+				if (cache !== undefined && !isExistenceOnly(cache)) {
+					if (cache !== "ignore") {
+						missingExistence.set(path, Boolean(cache));
+					}
+				} else {
+					jobs++;
+					this.fileTimestampQueue.add(path, (err, entry) => {
+						if (err) {
+							if (this.logger) {
+								this.logger.debug(
+									`Error snapshotting missing timestamp of ${path}: ${err.stack}`
+								);
+							}
+							jobError();
+						} else {
+							missingExistence.set(path, Boolean(entry));
+							jobDone();
+						}
+					});
+				}
+			}
+		};
+		if (missing) {
+			processCapturedMissing(captureNonManaged(missing, managedMissing));
+		}
+		this._managedItemInfoOptimization.optimize(snapshot, managedItems);
+		for (const path of managedItems) {
+			const cache = this._managedItems.get(path);
+			if (cache !== undefined) {
+				if (!cache.startsWith("*")) {
+					managedFiles.add(join(this.fs, path, "package.json"));
+				} else if (cache === "*nested") {
+					managedMissing.add(join(this.fs, path, "package.json"));
+				}
+				managedItemInfo.set(path, cache);
+			} else {
+				jobs++;
+				this.managedItemQueue.add(path, (err, entry) => {
+					if (err) {
+						if (this.logger) {
+							this.logger.debug(
+								`Error snapshotting managed item ${path}: ${err.stack}`
+							);
+						}
+						jobError();
+					} else if (entry) {
+						if (!entry.startsWith("*")) {
+							managedFiles.add(join(this.fs, path, "package.json"));
+						} else if (cache === "*nested") {
+							managedMissing.add(join(this.fs, path, "package.json"));
+						}
+						managedItemInfo.set(path, entry);
+						jobDone();
+					} else {
+						// Fallback to normal snapshotting
+						/**
+						 * Processes the provided set.
+						 * @param {Set<string>} set set
+						 * @param {(set: Set<string>) => void} fn fn
+						 */
+						const process = (set, fn) => {
+							if (set.size === 0) return;
+							/** @type {Set<string>} */
+							const captured = new Set();
+							for (const file of set) {
+								if (file.startsWith(path)) captured.add(file);
+							}
+							if (captured.size > 0) fn(captured);
+						};
+						process(managedFiles, processCapturedFiles);
+						process(managedContexts, processCapturedDirectories);
+						process(managedMissing, processCapturedMissing);
+						jobDone();
+					}
+				});
+			}
+		}
+		jobDone();
+	}
+
+	/**
+	 * Merges the provided values into a single result.
+	 * @param {Snapshot} snapshot1 a snapshot
+	 * @param {Snapshot} snapshot2 a snapshot
+	 * @returns {Snapshot} merged snapshot
+	 */
+	mergeSnapshots(snapshot1, snapshot2) {
+		const snapshot = new Snapshot();
+		if (snapshot1.hasStartTime() && snapshot2.hasStartTime()) {
+			snapshot.setStartTime(
+				Math.min(
+					/** @type {NonNullable<Snapshot["startTime"]>} */
+					(snapshot1.startTime),
+					/** @type {NonNullable<Snapshot["startTime"]>} */
+					(snapshot2.startTime)
+				)
+			);
+		} else if (snapshot2.hasStartTime()) {
+			snapshot.startTime = snapshot2.startTime;
+		} else if (snapshot1.hasStartTime()) {
+			snapshot.startTime = snapshot1.startTime;
+		}
+		if (snapshot1.hasFileTimestamps() || snapshot2.hasFileTimestamps()) {
+			snapshot.setFileTimestamps(
+				mergeMaps(snapshot1.fileTimestamps, snapshot2.fileTimestamps)
+			);
+		}
+		if (snapshot1.hasFileHashes() || snapshot2.hasFileHashes()) {
+			snapshot.setFileHashes(
+				mergeMaps(snapshot1.fileHashes, snapshot2.fileHashes)
+			);
+		}
+		if (snapshot1.hasFileTshs() || snapshot2.hasFileTshs()) {
+			snapshot.setFileTshs(mergeMaps(snapshot1.fileTshs, snapshot2.fileTshs));
+		}
+		if (snapshot1.hasContextTimestamps() || snapshot2.hasContextTimestamps()) {
+			snapshot.setContextTimestamps(
+				mergeMaps(snapshot1.contextTimestamps, snapshot2.contextTimestamps)
+			);
+		}
+		if (snapshot1.hasContextHashes() || snapshot2.hasContextHashes()) {
+			snapshot.setContextHashes(
+				mergeMaps(snapshot1.contextHashes, snapshot2.contextHashes)
+			);
+		}
+		if (snapshot1.hasContextTshs() || snapshot2.hasContextTshs()) {
+			snapshot.setContextTshs(
+				mergeMaps(snapshot1.contextTshs, snapshot2.contextTshs)
+			);
+		}
+		if (snapshot1.hasMissingExistence() || snapshot2.hasMissingExistence()) {
+			snapshot.setMissingExistence(
+				mergeMaps(snapshot1.missingExistence, snapshot2.missingExistence)
+			);
+		}
+		if (snapshot1.hasManagedItemInfo() || snapshot2.hasManagedItemInfo()) {
+			snapshot.setManagedItemInfo(
+				mergeMaps(snapshot1.managedItemInfo, snapshot2.managedItemInfo)
+			);
+		}
+		if (snapshot1.hasManagedFiles() || snapshot2.hasManagedFiles()) {
+			snapshot.setManagedFiles(
+				mergeSets(snapshot1.managedFiles, snapshot2.managedFiles)
+			);
+		}
+		if (snapshot1.hasManagedContexts() || snapshot2.hasManagedContexts()) {
+			snapshot.setManagedContexts(
+				mergeSets(snapshot1.managedContexts, snapshot2.managedContexts)
+			);
+		}
+		if (snapshot1.hasManagedMissing() || snapshot2.hasManagedMissing()) {
+			snapshot.setManagedMissing(
+				mergeSets(snapshot1.managedMissing, snapshot2.managedMissing)
+			);
+		}
+		if (snapshot1.hasChildren() || snapshot2.hasChildren()) {
+			snapshot.setChildren(mergeSets(snapshot1.children, snapshot2.children));
+		}
+		if (
+			this._snapshotCache.get(snapshot1) === true &&
+			this._snapshotCache.get(snapshot2) === true
+		) {
+			this._snapshotCache.set(snapshot, true);
+		}
+		return snapshot;
+	}
+
+	/**
+	 * Checks snapshot valid.
+	 * @param {Snapshot} snapshot the snapshot made
+	 * @param {CheckSnapshotValidCallback} callback callback function
+	 * @returns {void}
+	 */
+	checkSnapshotValid(snapshot, callback) {
+		const cachedResult = this._snapshotCache.get(snapshot);
+		if (cachedResult !== undefined) {
+			this._statTestedSnapshotsCached++;
+			if (typeof cachedResult === "boolean") {
+				callback(null, cachedResult);
+			} else {
+				cachedResult.push(callback);
+			}
+			return;
+		}
+		this._statTestedSnapshotsNotCached++;
+		this._checkSnapshotValidNoCache(snapshot, callback);
+	}
+
+	/**
+	 * Check snapshot valid no cache.
+	 * @private
+	 * @param {Snapshot} snapshot the snapshot made
+	 * @param {CheckSnapshotValidCallback} callback callback function
+	 * @returns {void}
+	 */
+	_checkSnapshotValidNoCache(snapshot, callback) {
+		/** @type {number | undefined} */
+		let startTime;
+		if (snapshot.hasStartTime()) {
+			startTime = snapshot.startTime;
+		}
+		let jobs = 1;
+		const jobDone = () => {
+			if (--jobs === 0) {
+				this._snapshotCache.set(snapshot, true);
+				callback(null, true);
+			}
+		};
+		const invalid = () => {
+			if (jobs > 0) {
+				// large negative number instead of NaN or something else to keep jobs to stay a SMI (v8)
+				jobs = -100000000;
+				this._snapshotCache.set(snapshot, false);
+				callback(null, false);
+			}
+		};
+		/**
+		 * Invalid with error.
+		 * @param {string} path path
+		 * @param {WebpackError} err err
+		 */
+		const invalidWithError = (path, err) => {
+			if (this._remainingLogs > 0) {
+				this._log(path, "error occurred: %s", err);
+			}
+			invalid();
+		};
+		/**
+		 * Checks true, if ok.
+		 * @param {string} path file path
+		 * @param {string | null} current current hash
+		 * @param {string | null} snap snapshot hash
+		 * @returns {boolean} true, if ok
+		 */
+		const checkHash = (path, current, snap) => {
+			if (current !== snap) {
+				// If hash differ it's invalid
+				if (this._remainingLogs > 0) {
+					this._log(path, "hashes differ (%s != %s)", current, snap);
+				}
+				return false;
+			}
+			return true;
+		};
+		/**
+		 * Checks true, if ok.
+		 * @param {string} path file path
+		 * @param {boolean} current current entry
+		 * @param {boolean} snap entry from snapshot
+		 * @returns {boolean} true, if ok
+		 */
+		const checkExistence = (path, current, snap) => {
+			if (!current !== !snap) {
+				// If existence of item differs
+				// it's invalid
+				if (this._remainingLogs > 0) {
+					this._log(
+						path,
+						current ? "it didn't exist before" : "it does no longer exist"
+					);
+				}
+				return false;
+			}
+			return true;
+		};
+		/**
+		 * Checks true, if ok.
+		 * @param {string} path file path
+		 * @param {FileSystemInfoEntry | null} c current entry
+		 * @param {FileSystemInfoEntry | null} s entry from snapshot
+		 * @param {boolean} log log reason
+		 * @returns {boolean} true, if ok
+		 */
+		const checkFile = (path, c, s, log = true) => {
+			if (c === s) return true;
+			if (!checkExistence(path, Boolean(c), Boolean(s))) return false;
+			if (c) {
+				// For existing items only
+				if (typeof startTime === "number" && c.safeTime > startTime) {
+					// If a change happened after starting reading the item
+					// this may no longer be valid
+					if (log && this._remainingLogs > 0) {
+						this._log(
+							path,
+							"it may have changed (%d) after the start time of the snapshot (%d)",
+							c.safeTime,
+							startTime
+						);
+					}
+					return false;
+				}
+				const snap = /** @type {FileSystemInfoEntry} */ (s);
+				if (snap.timestamp !== undefined && c.timestamp !== snap.timestamp) {
+					// If we have a timestamp (it was a file or symlink) and it differs from current timestamp
+					// it's invalid
+					if (log && this._remainingLogs > 0) {
+						this._log(
+							path,
+							"timestamps differ (%d != %d)",
+							c.timestamp,
+							snap.timestamp
+						);
+					}
+					return false;
+				}
+			}
+			return true;
+		};
+		/**
+		 * Checks true, if ok.
+		 * @param {string} path file path
+		 * @param {ResolvedContextFileSystemInfoEntry | null} c current entry
+		 * @param {ResolvedContextFileSystemInfoEntry | null} s entry from snapshot
+		 * @param {boolean} log log reason
+		 * @returns {boolean} true, if ok
+		 */
+		const checkContext = (path, c, s, log = true) => {
+			if (c === s) return true;
+			if (!checkExistence(path, Boolean(c), Boolean(s))) return false;
+			if (c) {
+				// For existing items only
+				if (typeof startTime === "number" && c.safeTime > startTime) {
+					// If a change happened after starting reading the item
+					// this may no longer be valid
+					if (log && this._remainingLogs > 0) {
+						this._log(
+							path,
+							"it may have changed (%d) after the start time of the snapshot (%d)",
+							c.safeTime,
+							startTime
+						);
+					}
+					return false;
+				}
+				const snap = /** @type {ResolvedContextFileSystemInfoEntry} */ (s);
+				if (
+					snap.timestampHash !== undefined &&
+					c.timestampHash !== snap.timestampHash
+				) {
+					// If we have a timestampHash (it was a directory) and it differs from current timestampHash
+					// it's invalid
+					if (log && this._remainingLogs > 0) {
+						this._log(
+							path,
+							"timestamps hashes differ (%s != %s)",
+							c.timestampHash,
+							snap.timestampHash
+						);
+					}
+					return false;
+				}
+			}
+			return true;
+		};
+		if (snapshot.hasChildren()) {
+			/**
+			 * Processes the provided err.
+			 * @param {(WebpackError | null)=} err err
+			 * @param {boolean=} result result
+			 * @returns {void}
+			 */
+			const childCallback = (err, result) => {
+				if (err || !result) return invalid();
+				jobDone();
+			};
+			for (const child of /** @type {Children} */ (snapshot.children)) {
+				const cache = this._snapshotCache.get(child);
+				if (cache !== undefined) {
+					this._statTestedChildrenCached++;
+					/* istanbul ignore else */
+					if (typeof cache === "boolean") {
+						if (cache === false) {
+							invalid();
+							return;
+						}
+					} else {
+						jobs++;
+						cache.push(childCallback);
+					}
+				} else {
+					this._statTestedChildrenNotCached++;
+					jobs++;
+					this._checkSnapshotValidNoCache(child, childCallback);
+				}
+			}
+		}
+		if (snapshot.hasFileTimestamps()) {
+			const fileTimestamps =
+				/** @type {FileTimestamps} */
+				(snapshot.fileTimestamps);
+			this._statTestedEntries += fileTimestamps.size;
+			for (const [path, ts] of fileTimestamps) {
+				const cache = this._fileTimestamps.get(path);
+				if (cache !== undefined && !isExistenceOnly(cache)) {
+					if (
+						cache !== "ignore" &&
+						!checkFile(
+							path,
+							/** @type {FileSystemInfoEntry | null} */ (cache),
+							ts
+						)
+					) {
+						invalid();
+						return;
+					}
+				} else {
+					jobs++;
+					this.fileTimestampQueue.add(path, (err, entry) => {
+						if (err) return invalidWithError(path, err);
+						if (
+							!checkFile(
+								path,
+								/** @type {FileSystemInfoEntry | null} */ (entry),
+								ts
+							)
+						) {
+							invalid();
+						} else {
+							jobDone();
+						}
+					});
+				}
+			}
+		}
+		/**
+		 * Process file hash snapshot.
+		 * @param {string} path file path
+		 * @param {string | null} hash hash
+		 */
+		const processFileHashSnapshot = (path, hash) => {
+			const cache = this._fileHashes.get(path);
+			if (cache !== undefined) {
+				if (cache !== "ignore" && !checkHash(path, cache, hash)) {
+					invalid();
+				}
+			} else {
+				jobs++;
+				this.fileHashQueue.add(path, (err, entry) => {
+					if (err) return invalidWithError(path, err);
+					if (!checkHash(path, /** @type {string} */ (entry), hash)) {
+						invalid();
+					} else {
+						jobDone();
+					}
+				});
+			}
+		};
+		if (snapshot.hasFileHashes()) {
+			const fileHashes = /** @type {FileHashes} */ (snapshot.fileHashes);
+			this._statTestedEntries += fileHashes.size;
+			for (const [path, hash] of fileHashes) {
+				processFileHashSnapshot(path, hash);
+			}
+		}
+		if (snapshot.hasFileTshs()) {
+			const fileTshs = /** @type {FileTshs} */ (snapshot.fileTshs);
+			this._statTestedEntries += fileTshs.size;
+			for (const [path, tsh] of fileTshs) {
+				if (typeof tsh === "string") {
+					processFileHashSnapshot(path, tsh);
+				} else {
+					const cache = this._fileTimestamps.get(path);
+					if (cache !== undefined && !isExistenceOnly(cache)) {
+						if (
+							cache === "ignore" ||
+							!checkFile(
+								path,
+								/** @type {FileSystemInfoEntry | null} */ (cache),
+								tsh,
+								false
+							)
+						) {
+							processFileHashSnapshot(path, tsh && tsh.hash);
+						}
+					} else {
+						jobs++;
+						this.fileTimestampQueue.add(path, (err, entry) => {
+							if (err) return invalidWithError(path, err);
+							if (
+								!checkFile(
+									path,
+									/** @type {FileSystemInfoEntry | null} */
+									(entry),
+									tsh,
+									false
+								)
+							) {
+								processFileHashSnapshot(path, tsh && tsh.hash);
+							}
+							jobDone();
+						});
+					}
+				}
+			}
+		}
+		if (snapshot.hasContextTimestamps()) {
+			const contextTimestamps =
+				/** @type {ContextTimestamps} */
+				(snapshot.contextTimestamps);
+			this._statTestedEntries += contextTimestamps.size;
+			for (const [path, ts] of contextTimestamps) {
+				const cache = this._contextTimestamps.get(path);
+				if (cache === "ignore") continue;
+				// Treat existence-only entries (`{}` from watchpack) as a cache
+				// miss — they carry no time info, so we cannot compare them to
+				// the snapshot.
+				/** @type {ContextFileSystemInfoEntry | null | undefined} */
+				const usableCache =
+					cache === undefined || isExistenceOnly(cache)
+						? undefined
+						: /** @type {ContextFileSystemInfoEntry | null} */ (cache);
+				// A non-null cache entry that lacks `timestampHash` while the
+				// snapshot has one cannot be used either; we re-read the
+				// directory through the disk-backed queue instead.
+				const cacheLacksHash =
+					usableCache !== undefined &&
+					usableCache !== null &&
+					usableCache.timestampHash === undefined &&
+					ts !== null &&
+					ts.timestampHash !== undefined;
+				/** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
+				let resolved;
+				if (
+					usableCache !== undefined &&
+					!cacheLacksHash &&
+					(resolved = getResolvedTimestamp(usableCache)) !== undefined
+				) {
+					if (!checkContext(path, resolved, ts)) {
+						invalid();
+						return;
+					}
+				} else {
+					jobs++;
+					/**
+					 * Processes the provided err.
+					 * @param {(WebpackError | null)=} err error
+					 * @param {ResolvedContextTimestamp=} entry entry
+					 * @returns {void}
+					 */
+					const callback = (err, entry) => {
+						if (err) return invalidWithError(path, err);
+						if (
+							!checkContext(
+								path,
+								/** @type {ResolvedContextFileSystemInfoEntry | null} */
+								(entry),
+								ts
+							)
+						) {
+							invalid();
+						} else {
+							jobDone();
+						}
+					};
+					if (cacheLacksHash) {
+						this._readFreshContextTimestamp(path, callback);
+					} else if (usableCache !== undefined && usableCache !== null) {
+						this._resolveContextTimestamp(usableCache, callback);
+					} else {
+						this.getContextTimestamp(path, callback);
+					}
+				}
+			}
+		}
+		/**
+		 * Process context hash snapshot.
+		 * @param {string} path path
+		 * @param {string | null} hash hash
+		 */
+		const processContextHashSnapshot = (path, hash) => {
+			const cache = this._contextHashes.get(path);
+			/** @type {undefined | null | string} */
+			let resolved;
+			if (
+				cache !== undefined &&
+				(resolved = getResolvedHash(cache)) !== undefined
+			) {
+				if (!checkHash(path, resolved, hash)) {
+					invalid();
+				}
+			} else {
+				jobs++;
+				/**
+				 * Processes the provided err.
+				 * @param {(WebpackError | null)=} err err
+				 * @param {string=} entry entry
+				 * @returns {void}
+				 */
+				const callback = (err, entry) => {
+					if (err) return invalidWithError(path, err);
+					if (!checkHash(path, /** @type {string} */ (entry), hash)) {
+						invalid();
+					} else {
+						jobDone();
+					}
+				};
+				if (cache !== undefined) {
+					this._resolveContextHash(cache, callback);
+				} else {
+					this.getContextHash(path, callback);
+				}
+			}
+		};
+		if (snapshot.hasContextHashes()) {
+			const contextHashes =
+				/** @type {ContextHashes} */
+				(snapshot.contextHashes);
+			this._statTestedEntries += contextHashes.size;
+			for (const [path, hash] of contextHashes) {
+				processContextHashSnapshot(path, hash);
+			}
+		}
+		if (snapshot.hasContextTshs()) {
+			const contextTshs = /** @type {ContextTshs} */ (snapshot.contextTshs);
+			this._statTestedEntries += contextTshs.size;
+			for (const [path, tsh] of contextTshs) {
+				if (typeof tsh === "string") {
+					processContextHashSnapshot(path, tsh);
+				} else {
+					const cache = this._contextTimestamps.get(path);
+					if (cache === "ignore") continue;
+					// See the matching block in `hasContextTimestamps` above.
+					/** @type {ContextFileSystemInfoEntry | null | undefined} */
+					const usableCache =
+						cache === undefined || isExistenceOnly(cache)
+							? undefined
+							: /** @type {ContextFileSystemInfoEntry | null} */ (cache);
+					const cacheLacksHash =
+						usableCache !== undefined &&
+						usableCache !== null &&
+						usableCache.timestampHash === undefined &&
+						tsh !== null &&
+						tsh.timestampHash !== undefined;
+					/** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
+					let resolved;
+					if (
+						usableCache !== undefined &&
+						!cacheLacksHash &&
+						(resolved = getResolvedTimestamp(usableCache)) !== undefined
+					) {
+						if (!checkContext(path, resolved, tsh, false)) {
+							processContextHashSnapshot(path, tsh && tsh.hash);
+						}
+					} else {
+						jobs++;
+						/**
+						 * Processes the provided err.
+						 * @param {(WebpackError | null)=} err error
+						 * @param {ResolvedContextTimestamp=} entry entry
+						 * @returns {void}
+						 */
+						const callback = (err, entry) => {
+							if (err) return invalidWithError(path, err);
+							if (
+								!checkContext(
+									path,
+									// TODO: test with `"ignore"`
+									/** @type {ResolvedContextFileSystemInfoEntry | null} */
+									(entry),
+									tsh,
+									false
+								)
+							) {
+								processContextHashSnapshot(path, tsh && tsh.hash);
+							}
+							jobDone();
+						};
+						if (cacheLacksHash) {
+							this._readFreshContextTimestamp(path, callback);
+						} else if (usableCache !== undefined && usableCache !== null) {
+							this._resolveContextTimestamp(usableCache, callback);
+						} else {
+							this.getContextTimestamp(path, callback);
+						}
+					}
+				}
+			}
+		}
+		if (snapshot.hasMissingExistence()) {
+			const missingExistence =
+				/** @type {MissingExistence} */
+				(snapshot.missingExistence);
+			this._statTestedEntries += missingExistence.size;
+			for (const [path, existence] of missingExistence) {
+				const cache = this._fileTimestamps.get(path);
+				if (cache !== undefined && !isExistenceOnly(cache)) {
+					if (
+						cache !== "ignore" &&
+						!checkExistence(path, Boolean(cache), Boolean(existence))
+					) {
+						invalid();
+						return;
+					}
+				} else {
+					jobs++;
+					this.fileTimestampQueue.add(path, (err, entry) => {
+						if (err) return invalidWithError(path, err);
+						if (!checkExistence(path, Boolean(entry), Boolean(existence))) {
+							invalid();
+						} else {
+							jobDone();
+						}
+					});
+				}
+			}
+		}
+		if (snapshot.hasManagedItemInfo()) {
+			const managedItemInfo =
+				/** @type {ManagedItemInfo} */
+				(snapshot.managedItemInfo);
+			this._statTestedEntries += managedItemInfo.size;
+			for (const [path, info] of managedItemInfo) {
+				const cache = this._managedItems.get(path);
+				if (cache !== undefined) {
+					if (!checkHash(path, cache, info)) {
+						invalid();
+						return;
+					}
+				} else {
+					jobs++;
+					this.managedItemQueue.add(path, (err, entry) => {
+						if (err) return invalidWithError(path, err);
+						if (!checkHash(path, /** @type {string} */ (entry), info)) {
+							invalid();
+						} else {
+							jobDone();
+						}
+					});
+				}
+			}
+		}
+		jobDone();
+
+		// if there was an async action
+		// try to join multiple concurrent request for this snapshot
+		if (jobs > 0) {
+			const callbacks = [callback];
+			callback = (err, result) => {
+				for (const callback of callbacks) callback(err, result);
+			};
+			this._snapshotCache.set(snapshot, callbacks);
+		}
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, FileSystemInfoEntry>}
+	 */
+	_readFileTimestamp(path, callback) {
+		this.fs.stat(path, (err, _stat) => {
+			if (err) {
+				if (err.code === "ENOENT") {
+					this._fileTimestamps.set(path, null);
+					this._cachedDeprecatedFileTimestamps = undefined;
+					return callback(null, null);
+				}
+				return callback(/** @type {WebpackError} */ (err));
+			}
+			const stat = /** @type {IStats} */ (_stat);
+			/** @type {FileSystemInfoEntry} */
+			let ts;
+			if (stat.isDirectory()) {
+				ts = {
+					safeTime: 0,
+					timestamp: undefined
+				};
+			} else {
+				const mtime = Number(stat.mtime);
+
+				if (mtime) applyMtime(mtime);
+
+				ts = {
+					safeTime: mtime ? mtime + FS_ACCURACY : Infinity,
+					timestamp: mtime
+				};
+			}
+
+			this._fileTimestamps.set(path, ts);
+			this._cachedDeprecatedFileTimestamps = undefined;
+
+			callback(null, ts);
+		});
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, string>}
+	 */
+	_readFileHash(path, callback) {
+		this.fs.readFile(path, (err, content) => {
+			if (err) {
+				if (err.code === "EISDIR") {
+					this._fileHashes.set(path, "directory");
+					return callback(null, "directory");
+				}
+				if (err.code === "ENOENT") {
+					this._fileHashes.set(path, null);
+					return callback(null, null);
+				}
+				if (err.code === "ERR_FS_FILE_TOO_LARGE") {
+					/** @type {Logger} */
+					(this.logger).warn(`Ignoring ${path} for hashing as it's very large`);
+					this._fileHashes.set(path, "too large");
+					return callback(null, "too large");
+				}
+				return callback(/** @type {WebpackError} */ (err));
+			}
+
+			const hash = createHash(this._hashFunction);
+
+			hash.update(/** @type {string | Buffer} */ (content));
+
+			const digest = hash.digest("hex");
+
+			this._fileHashes.set(path, digest);
+
+			callback(null, digest);
+		});
+	}
+
+	/**
+	 * Get file timestamp and hash.
+	 * @private
+	 * @param {string} path path
+	 * @param {(err: WebpackError | null, timestampAndHash?: TimestampAndHash | string) => void} callback callback
+	 */
+	_getFileTimestampAndHash(path, callback) {
+		/**
+		 * Continue with hash.
+		 * @param {string} hash hash
+		 * @returns {void}
+		 */
+		const continueWithHash = (hash) => {
+			const cache = this._fileTimestamps.get(path);
+			if (cache !== undefined) {
+				if (cache !== "ignore") {
+					/** @type {TimestampAndHash} */
+					const result = {
+						.../** @type {FileSystemInfoEntry} */ (cache),
+						hash
+					};
+					this._fileTshs.set(path, result);
+					return callback(null, result);
+				}
+				this._fileTshs.set(path, hash);
+				return callback(null, hash);
+			}
+			this.fileTimestampQueue.add(path, (err, entry) => {
+				if (err) {
+					return callback(err);
+				}
+				/** @type {TimestampAndHash} */
+				const result = {
+					.../** @type {FileSystemInfoEntry} */ (entry),
+					hash
+				};
+				this._fileTshs.set(path, result);
+				return callback(null, result);
+			});
+		};
+
+		const cache = this._fileHashes.get(path);
+		if (cache !== undefined) {
+			continueWithHash(/** @type {string} */ (cache));
+		} else {
+			this.fileHashQueue.add(path, (err, entry) => {
+				if (err) {
+					return callback(err);
+				}
+				continueWithHash(/** @type {string} */ (entry));
+			});
+		}
+	}
+
+	/**
+	 * Processes the provided object.
+	 * @private
+	 * @template T
+	 * @template ItemType
+	 * @param {object} options options
+	 * @param {string} options.path path
+	 * @param {(value: string) => ItemType} options.fromImmutablePath called when context item is an immutable path
+	 * @param {(value: string) => ItemType} options.fromManagedItem called when context item is a managed path
+	 * @param {(value: string, result: string, callback: (err?: WebpackError | null, itemType?: ItemType) => void) => void} options.fromSymlink called when context item is a symlink
+	 * @param {(value: string, stats: IStats, callback: (err?: WebpackError | null, itemType?: ItemType | null) => void) => void} options.fromFile called when context item is a file
+	 * @param {(value: string, stats: IStats, callback: (err?: WebpackError | null, itemType?: ItemType) => void) => void} options.fromDirectory called when context item is a directory
+	 * @param {(arr: string[], arr1: ItemType[]) => T} options.reduce called from all context items
+	 * @param {(err?: Error | null, result?: T | null) => void} callback callback
+	 */
+	_readContext(
+		{
+			path,
+			fromImmutablePath,
+			fromManagedItem,
+			fromSymlink,
+			fromFile,
+			fromDirectory,
+			reduce
+		},
+		callback
+	) {
+		this.fs.readdir(path, (err, _files) => {
+			if (err) {
+				if (err.code === "ENOENT") {
+					return callback(null, null);
+				}
+				return callback(err);
+			}
+			const files = /** @type {string[]} */ (_files)
+				.map((file) => file.normalize("NFC"))
+				.filter((file) => !/^\./.test(file))
+				.sort();
+			asyncLib.map(
+				files,
+				(file, callback) => {
+					const child = join(this.fs, path, file);
+					for (const immutablePath of this.immutablePathsRegExps) {
+						if (immutablePath.test(path)) {
+							// ignore any immutable path for timestamping
+							return callback(null, fromImmutablePath(path));
+						}
+					}
+					for (const immutablePath of this.immutablePathsWithSlash) {
+						if (path.startsWith(immutablePath)) {
+							// ignore any immutable path for timestamping
+							return callback(null, fromImmutablePath(path));
+						}
+					}
+					for (const managedPath of this.managedPathsRegExps) {
+						const match = managedPath.exec(path);
+						if (match) {
+							const managedItem = getManagedItem(match[1], path);
+							if (managedItem) {
+								// construct timestampHash from managed info
+								return this.managedItemQueue.add(managedItem, (err, info) => {
+									if (err) return callback(err);
+									return callback(
+										null,
+										fromManagedItem(/** @type {string} */ (info))
+									);
+								});
+							}
+						}
+					}
+					for (const managedPath of this.managedPathsWithSlash) {
+						if (path.startsWith(managedPath)) {
+							const managedItem = getManagedItem(managedPath, child);
+							if (managedItem) {
+								// construct timestampHash from managed info
+								return this.managedItemQueue.add(managedItem, (err, info) => {
+									if (err) return callback(err);
+									return callback(
+										null,
+										fromManagedItem(/** @type {string} */ (info))
+									);
+								});
+							}
+						}
+					}
+
+					lstatReadlinkAbsolute(this.fs, child, (err, _stat) => {
+						if (err) return callback(err);
+
+						const stat = /** @type {IStats | string} */ (_stat);
+
+						if (typeof stat === "string") {
+							return fromSymlink(child, stat, callback);
+						}
+
+						if (stat.isFile()) {
+							return fromFile(child, stat, callback);
+						}
+						if (stat.isDirectory()) {
+							return fromDirectory(child, stat, callback);
+						}
+						callback(null, null);
+					});
+				},
+				(err, results) => {
+					if (err) return callback(err);
+					const result = reduce(files, /** @type {ItemType[]} */ (results));
+					callback(null, result);
+				}
+			);
+		});
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, ContextFileSystemInfoEntry>}
+	 */
+	_readContextTimestamp(path, callback) {
+		this._readContext(
+			{
+				path,
+				fromImmutablePath: () =>
+					/** @type {ContextFileSystemInfoEntry | FileSystemInfoEntry | "ignore" | null} */
+					(null),
+				fromManagedItem: (info) => ({
+					safeTime: 0,
+					timestampHash: info
+				}),
+				fromSymlink: (file, target, callback) => {
+					callback(
+						null,
+						/** @type {ContextFileSystemInfoEntry} */
+						({
+							timestampHash: target,
+							symlinks: new Set([target])
+						})
+					);
+				},
+				fromFile: (file, stat, callback) => {
+					// Prefer the cached value over our new stat to report consistent results
+					const cache = this._fileTimestamps.get(file);
+					if (cache !== undefined && !isExistenceOnly(cache)) {
+						return callback(
+							null,
+							cache === "ignore"
+								? null
+								: /** @type {FileSystemInfoEntry | null} */ (cache)
+						);
+					}
+
+					const mtime = Number(stat.mtime);
+
+					if (mtime) applyMtime(mtime);
+
+					/** @type {FileSystemInfoEntry} */
+					const ts = {
+						safeTime: mtime ? mtime + FS_ACCURACY : Infinity,
+						timestamp: mtime
+					};
+
+					this._fileTimestamps.set(file, ts);
+					this._cachedDeprecatedFileTimestamps = undefined;
+					callback(null, ts);
+				},
+				fromDirectory: (directory, stat, callback) => {
+					this.contextTimestampQueue.increaseParallelism();
+					this._getUnresolvedContextTimestamp(directory, (err, tsEntry) => {
+						this.contextTimestampQueue.decreaseParallelism();
+						callback(err, tsEntry);
+					});
+				},
+				reduce: (files, tsEntries) => {
+					/** @type {undefined | Symlinks} */
+					let symlinks;
+
+					const hash = createHash(this._hashFunction);
+
+					for (const file of files) hash.update(file);
+					let safeTime = 0;
+					for (const _e of tsEntries) {
+						if (!_e) {
+							hash.update("n");
+							continue;
+						}
+						const entry =
+							/** @type {FileSystemInfoEntry | ContextFileSystemInfoEntry} */
+							(_e);
+						if (/** @type {FileSystemInfoEntry} */ (entry).timestamp) {
+							hash.update("f");
+							hash.update(
+								`${/** @type {FileSystemInfoEntry} */ (entry).timestamp}`
+							);
+						} else if (
+							/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash
+						) {
+							hash.update("d");
+							hash.update(
+								`${/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash}`
+							);
+						}
+						if (
+							/** @type {ContextFileSystemInfoEntry} */
+							(entry).symlinks !== undefined
+						) {
+							if (symlinks === undefined) symlinks = new Set();
+							addAll(
+								/** @type {ContextFileSystemInfoEntry} */ (entry).symlinks,
+								symlinks
+							);
+						}
+						if (entry.safeTime) {
+							safeTime = Math.max(safeTime, entry.safeTime);
+						}
+					}
+
+					const digest = hash.digest("hex");
+					/** @type {ContextFileSystemInfoEntry} */
+					const result = {
+						safeTime,
+						timestampHash: digest
+					};
+					if (symlinks) result.symlinks = symlinks;
+					return result;
+				}
+			},
+			(err, result) => {
+				if (err) return callback(/** @type {WebpackError} */ (err));
+				this._contextTimestamps.set(path, result);
+				this._cachedDeprecatedContextTimestamps = undefined;
+
+				callback(null, result);
+			}
+		);
+	}
+
+	/**
+	 * Resolve context timestamp.
+	 * @private
+	 * @param {ContextFileSystemInfoEntry} entry entry
+	 * @param {(err?: WebpackError | null, resolvedContextTimestamp?: ResolvedContextTimestamp) => void} callback callback
+	 * @returns {void}
+	 */
+	_resolveContextTimestamp(entry, callback) {
+		/** @type {string[]} */
+		const hashes = [];
+		let safeTime = 0;
+		processAsyncTree(
+			/** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
+			10,
+			(target, push, callback) => {
+				this._getUnresolvedContextTimestamp(target, (err, entry) => {
+					if (err) return callback(err);
+					if (entry && entry !== "ignore") {
+						hashes.push(/** @type {string} */ (entry.timestampHash));
+						if (entry.safeTime) {
+							safeTime = Math.max(safeTime, entry.safeTime);
+						}
+						if (entry.symlinks !== undefined) {
+							for (const target of entry.symlinks) push(target);
+						}
+					}
+					callback();
+				});
+			},
+			(err) => {
+				if (err) return callback(/** @type {WebpackError} */ (err));
+				const hash = createHash(this._hashFunction);
+				hash.update(/** @type {string} */ (entry.timestampHash));
+				if (entry.safeTime) {
+					safeTime = Math.max(safeTime, entry.safeTime);
+				}
+				hashes.sort();
+				for (const h of hashes) {
+					hash.update(h);
+				}
+				callback(
+					null,
+					(entry.resolved = {
+						safeTime,
+						timestampHash: hash.digest("hex")
+					})
+				);
+			}
+		);
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, ContextHash>}
+	 */
+	_readContextHash(path, callback) {
+		this._readContext(
+			{
+				path,
+				fromImmutablePath: () => /** @type {ContextHash | ""} */ (""),
+				fromManagedItem: (info) => info || "",
+				fromSymlink: (file, target, callback) => {
+					callback(
+						null,
+						/** @type {ContextHash} */
+						({
+							hash: target,
+							symlinks: new Set([target])
+						})
+					);
+				},
+				fromFile: (file, stat, callback) =>
+					this.getFileHash(file, (err, hash) => {
+						callback(err, hash || "");
+					}),
+				fromDirectory: (directory, stat, callback) => {
+					this.contextHashQueue.increaseParallelism();
+					this._getUnresolvedContextHash(directory, (err, hash) => {
+						this.contextHashQueue.decreaseParallelism();
+						callback(err, hash || "");
+					});
+				},
+				/**
+				 * Returns reduced hash.
+				 * @param {string[]} files files
+				 * @param {(string | ContextHash)[]} fileHashes hashes
+				 * @returns {ContextHash} reduced hash
+				 */
+				reduce: (files, fileHashes) => {
+					/** @type {undefined | Symlinks} */
+					let symlinks;
+					const hash = createHash(this._hashFunction);
+
+					for (const file of files) hash.update(file);
+					for (const entry of fileHashes) {
+						if (typeof entry === "string") {
+							hash.update(entry);
+						} else {
+							hash.update(entry.hash);
+							if (entry.symlinks) {
+								if (symlinks === undefined) symlinks = new Set();
+								addAll(entry.symlinks, symlinks);
+							}
+						}
+					}
+
+					/** @type {ContextHash} */
+					const result = {
+						hash: hash.digest("hex")
+					};
+					if (symlinks) result.symlinks = symlinks;
+					return result;
+				}
+			},
+			(err, _result) => {
+				if (err) return callback(/** @type {WebpackError} */ (err));
+				const result = /** @type {ContextHash} */ (_result);
+				this._contextHashes.set(path, result);
+				return callback(null, result);
+			}
+		);
+	}
+
+	/**
+	 * Resolve context hash.
+	 * @private
+	 * @param {ContextHash} entry context hash
+	 * @param {(err: WebpackError | null, contextHash?: string) => void} callback callback
+	 * @returns {void}
+	 */
+	_resolveContextHash(entry, callback) {
+		/** @type {string[]} */
+		const hashes = [];
+		processAsyncTree(
+			/** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
+			10,
+			(target, push, callback) => {
+				this._getUnresolvedContextHash(target, (err, hash) => {
+					if (err) return callback(err);
+					if (hash) {
+						hashes.push(hash.hash);
+						if (hash.symlinks !== undefined) {
+							for (const target of hash.symlinks) push(target);
+						}
+					}
+					callback();
+				});
+			},
+			(err) => {
+				if (err) return callback(/** @type {WebpackError} */ (err));
+				const hash = createHash(this._hashFunction);
+				hash.update(entry.hash);
+				hashes.sort();
+				for (const h of hashes) {
+					hash.update(h);
+				}
+				callback(null, (entry.resolved = hash.digest("hex")));
+			}
+		);
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, ContextTimestampAndHash>}
+	 */
+	_readContextTimestampAndHash(path, callback) {
+		/**
+		 * Processes the provided timestamp.
+		 * @param {ContextTimestamp} timestamp timestamp
+		 * @param {ContextHash} hash hash
+		 */
+		const finalize = (timestamp, hash) => {
+			const result =
+				/** @type {ContextTimestampAndHash} */
+				(timestamp === "ignore" ? hash : { ...timestamp, ...hash });
+			this._contextTshs.set(path, result);
+			callback(null, result);
+		};
+		const cachedHash = this._contextHashes.get(path);
+		const cachedTimestamp = this._contextTimestamps.get(path);
+		if (cachedHash !== undefined) {
+			if (cachedTimestamp !== undefined) {
+				finalize(cachedTimestamp, cachedHash);
+			} else {
+				this.contextTimestampQueue.add(path, (err, entry) => {
+					if (err) return callback(err);
+					finalize(
+						/** @type {ContextFileSystemInfoEntry} */
+						(entry),
+						cachedHash
+					);
+				});
+			}
+		} else if (cachedTimestamp !== undefined) {
+			this.contextHashQueue.add(path, (err, entry) => {
+				if (err) return callback(err);
+				finalize(cachedTimestamp, /** @type {ContextHash} */ (entry));
+			});
+		} else {
+			this._readContext(
+				{
+					path,
+					fromImmutablePath: () =>
+						/** @type {ContextTimestampAndHash | Omit<ContextTimestampAndHash, "safeTime"> | string | null} */ (
+							null
+						),
+					fromManagedItem: (info) => ({
+						safeTime: 0,
+						timestampHash: info,
+						hash: info || ""
+					}),
+					fromSymlink: (file, target, callback) => {
+						callback(null, {
+							timestampHash: target,
+							hash: target,
+							symlinks: new Set([target])
+						});
+					},
+					fromFile: (file, stat, callback) => {
+						this._getFileTimestampAndHash(file, callback);
+					},
+					fromDirectory: (directory, stat, callback) => {
+						this.contextTshQueue.increaseParallelism();
+						this.contextTshQueue.add(directory, (err, result) => {
+							this.contextTshQueue.decreaseParallelism();
+							callback(err, result);
+						});
+					},
+					/**
+					 * Returns tsh.
+					 * @param {string[]} files files
+					 * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results
+					 * @returns {ContextTimestampAndHash} tsh
+					 */
+					reduce: (files, results) => {
+						/** @type {undefined | Symlinks} */
+						let symlinks;
+
+						const tsHash = createHash(this._hashFunction);
+						const hash = createHash(this._hashFunction);
+
+						for (const file of files) {
+							tsHash.update(file);
+							hash.update(file);
+						}
+						let safeTime = 0;
+						for (const entry of results) {
+							if (!entry) {
+								tsHash.update("n");
+								continue;
+							}
+							if (typeof entry === "string") {
+								tsHash.update("n");
+								hash.update(entry);
+								continue;
+							}
+							if (entry.timestamp) {
+								tsHash.update("f");
+								tsHash.update(`${entry.timestamp}`);
+							} else if (entry.timestampHash) {
+								tsHash.update("d");
+								tsHash.update(`${entry.timestampHash}`);
+							}
+							if (entry.symlinks !== undefined) {
+								if (symlinks === undefined) symlinks = new Set();
+								addAll(entry.symlinks, symlinks);
+							}
+							if (entry.safeTime) {
+								safeTime = Math.max(safeTime, entry.safeTime);
+							}
+							hash.update(/** @type {string} */ (entry.hash));
+						}
+
+						/** @type {ContextTimestampAndHash} */
+						const result = {
+							safeTime,
+							timestampHash: tsHash.digest("hex"),
+							hash: hash.digest("hex")
+						};
+						if (symlinks) result.symlinks = symlinks;
+						return result;
+					}
+				},
+				(err, _result) => {
+					if (err) return callback(/** @type {WebpackError} */ (err));
+					const result = /** @type {ContextTimestampAndHash} */ (_result);
+					this._contextTshs.set(path, result);
+					return callback(null, result);
+				}
+			);
+		}
+	}
+
+	/**
+	 * Resolve context tsh.
+	 * @private
+	 * @param {ContextTimestampAndHash} entry entry
+	 * @param {ProcessorCallback<ResolvedContextTimestampAndHash>} callback callback
+	 * @returns {void}
+	 */
+	_resolveContextTsh(entry, callback) {
+		/** @type {string[]} */
+		const hashes = [];
+		/** @type {string[]} */
+		const tsHashes = [];
+		let safeTime = 0;
+		processAsyncTree(
+			/** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
+			10,
+			(target, push, callback) => {
+				this._getUnresolvedContextTsh(target, (err, entry) => {
+					if (err) return callback(err);
+					if (entry) {
+						hashes.push(entry.hash);
+						if (entry.timestampHash) tsHashes.push(entry.timestampHash);
+						if (entry.safeTime) {
+							safeTime = Math.max(safeTime, entry.safeTime);
+						}
+						if (entry.symlinks !== undefined) {
+							for (const target of entry.symlinks) push(target);
+						}
+					}
+					callback();
+				});
+			},
+			(err) => {
+				if (err) return callback(/** @type {WebpackError} */ (err));
+				const hash = createHash(this._hashFunction);
+				const tsHash = createHash(this._hashFunction);
+				hash.update(entry.hash);
+				if (entry.timestampHash) tsHash.update(entry.timestampHash);
+				if (entry.safeTime) {
+					safeTime = Math.max(safeTime, entry.safeTime);
+				}
+				hashes.sort();
+				for (const h of hashes) {
+					hash.update(h);
+				}
+				tsHashes.sort();
+				for (const h of tsHashes) {
+					tsHash.update(h);
+				}
+				callback(
+					null,
+					(entry.resolved = {
+						safeTime,
+						timestampHash: tsHash.digest("hex"),
+						hash: hash.digest("hex")
+					})
+				);
+			}
+		);
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, Set<string>>}
+	 */
+	_getManagedItemDirectoryInfo(path, callback) {
+		this.fs.readdir(path, (err, elements) => {
+			if (err) {
+				if (err.code === "ENOENT" || err.code === "ENOTDIR") {
+					return callback(null, EMPTY_SET);
+				}
+				return callback(/** @type {WebpackError} */ (err));
+			}
+			const set = new Set(
+				/** @type {string[]} */
+				(elements).map((element) => join(this.fs, path, element))
+			);
+			callback(null, set);
+		});
+	}
+
+	/**
+	 * @private
+	 * @type {Processor<string, string>}
+	 */
+	_getManagedItemInfo(path, callback) {
+		const dir = dirname(this.fs, path);
+		this.managedItemDirectoryQueue.add(dir, (err, elements) => {
+			if (err) {
+				return callback(err);
+			}
+			if (!(/** @type {Set<string>} */ (elements).has(path))) {
+				// file or directory doesn't exist
+				this._managedItems.set(path, "*missing");
+				return callback(null, "*missing");
+			}
+			// something exists
+			// it may be a file or directory
+			if (
+				path.endsWith("node_modules") &&
+				(path.endsWith("/node_modules") || path.endsWith("\\node_modules"))
+			) {
+				// we are only interested in existence of this special directory
+				this._managedItems.set(path, "*node_modules");
+				return callback(null, "*node_modules");
+			}
+
+			// we assume it's a directory, as files shouldn't occur in managed paths
+			const packageJsonPath = join(this.fs, path, "package.json");
+			this.fs.readFile(packageJsonPath, (err, content) => {
+				if (err) {
+					if (err.code === "ENOENT" || err.code === "ENOTDIR") {
+						// no package.json or path is not a directory
+						this.fs.readdir(path, (err, elements) => {
+							if (
+								!err &&
+								/** @type {string[]} */ (elements).length === 1 &&
+								/** @type {string[]} */ (elements)[0] === "node_modules"
+							) {
+								// This is only a grouping folder e.g. used by yarn
+								// we are only interested in existence of this special directory
+								this._managedItems.set(path, "*nested");
+								return callback(null, "*nested");
+							}
+							/** @type {Logger} */
+							(this.logger).warn(
+								`Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)`
+							);
+							return callback();
+						});
+						return;
+					}
+					return callback(/** @type {WebpackError} */ (err));
+				}
+				/** @type {JsonObject} */
+				let data;
+				try {
+					data = JSON.parse(/** @type {Buffer} */ (content).toString("utf8"));
+				} catch (parseErr) {
+					return callback(/** @type {WebpackError} */ (parseErr));
+				}
+				if (!data.name) {
+					/** @type {Logger} */
+					(this.logger).warn(
+						`${packageJsonPath} doesn't contain a "name" property (see snapshot.managedPaths option)`
+					);
+					return callback();
+				}
+				const info = `${data.name || ""}@${data.version || ""}`;
+				this._managedItems.set(path, info);
+				callback(null, info);
+			});
+		});
+	}
+
+	getDeprecatedFileTimestamps() {
+		if (this._cachedDeprecatedFileTimestamps !== undefined) {
+			return this._cachedDeprecatedFileTimestamps;
+		}
+		/** @type {Map<string, number | null>} */
+		const map = new Map();
+		for (const [path, info] of this._fileTimestamps) {
+			if (info) {
+				const safeTime =
+					typeof info === "object"
+						? /** @type {Partial<FileSystemInfoEntry>} */ (info).safeTime
+						: undefined;
+				map.set(path, safeTime === undefined ? null : safeTime);
+			}
+		}
+		return (this._cachedDeprecatedFileTimestamps = map);
+	}
+
+	getDeprecatedContextTimestamps() {
+		if (this._cachedDeprecatedContextTimestamps !== undefined) {
+			return this._cachedDeprecatedContextTimestamps;
+		}
+		/** @type {Map<string, number | null>} */
+		const map = new Map();
+		for (const [path, info] of this._contextTimestamps) {
+			if (info) {
+				const safeTime =
+					typeof info === "object"
+						? /** @type {Partial<ContextFileSystemInfoEntry>} */ (info).safeTime
+						: undefined;
+				map.set(path, safeTime === undefined ? null : safeTime);
+			}
+		}
+		return (this._cachedDeprecatedContextTimestamps = map);
+	}
+}
+
+module.exports = FileSystemInfo;
+module.exports.Snapshot = Snapshot;
Index: frontend/node_modules/webpack/lib/FlagAllModulesAsUsedPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/FlagAllModulesAsUsedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/FlagAllModulesAsUsedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,56 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { getEntryRuntime, mergeRuntimeOwned } = require("./util/runtime");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Module").FactoryMeta} FactoryMeta */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+const PLUGIN_NAME = "FlagAllModulesAsUsedPlugin";
+class FlagAllModulesAsUsedPlugin {
+	/**
+	 * Creates an instance of FlagAllModulesAsUsedPlugin.
+	 * @param {string} explanation explanation
+	 */
+	constructor(explanation) {
+		this.explanation = explanation;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			compilation.hooks.optimizeDependencies.tap(PLUGIN_NAME, (modules) => {
+				/** @type {RuntimeSpec} */
+				let runtime;
+				for (const [name, { options }] of compilation.entries) {
+					runtime = mergeRuntimeOwned(
+						runtime,
+						getEntryRuntime(compilation, name, options)
+					);
+				}
+				for (const module of modules) {
+					const exportsInfo = moduleGraph.getExportsInfo(module);
+					exportsInfo.setUsedInUnknownWay(runtime);
+					moduleGraph.addExtraReason(module, this.explanation);
+					if (module.factoryMeta === undefined) {
+						module.factoryMeta = {};
+					}
+					/** @type {FactoryMeta} */
+					(module.factoryMeta).sideEffectFree = false;
+				}
+			});
+		});
+	}
+}
+
+module.exports = FlagAllModulesAsUsedPlugin;
Index: frontend/node_modules/webpack/lib/FlagDependencyExportsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/FlagDependencyExportsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/FlagDependencyExportsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,440 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const Queue = require("./util/Queue");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").ExportSpec} ExportSpec */
+/** @typedef {import("./Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("./ExportsInfo")} ExportsInfo */
+/** @typedef {import("./ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("./ExportsInfo").RestoreProvidedData} RestoreProvidedData */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+
+const PLUGIN_NAME = "FlagDependencyExportsPlugin";
+const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`;
+
+class FlagDependencyExportsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			const cache = compilation.getCache(PLUGIN_NAME);
+			compilation.hooks.finishModules.tapAsync(
+				PLUGIN_NAME,
+				(modules, callback) => {
+					const logger = compilation.getLogger(PLUGIN_LOGGER_NAME);
+					let statRestoredFromMemCache = 0;
+					let statRestoredFromCache = 0;
+					let statNoExports = 0;
+					let statFlaggedUncached = 0;
+					let statNotCached = 0;
+					let statQueueItemsProcessed = 0;
+
+					const { moduleMemCaches } = compilation;
+
+					/** @type {Queue<Module>} */
+					const queue = new Queue();
+
+					// Step 1: Try to restore cached provided export info from cache
+					logger.time("restore cached provided exports");
+					asyncLib.each(
+						/** @type {import("neo-async").IterableCollection<Module>} */ (
+							/** @type {unknown} */ (modules)
+						),
+						(module, callback) => {
+							const exportsInfo = moduleGraph.getExportsInfo(module);
+							// If the module doesn't have an exportsType, it's a module
+							// without declared exports.
+							if (
+								(!module.buildMeta || !module.buildMeta.exportsType) &&
+								exportsInfo.otherExportsInfo.provided !== null
+							) {
+								// It's a module without declared exports
+								statNoExports++;
+								exportsInfo.setHasProvideInfo();
+								exportsInfo.setUnknownExportsProvided();
+								return callback();
+							}
+							// If the module has no hash, it's uncacheable
+							if (
+								typeof (/** @type {BuildInfo} */ (module.buildInfo).hash) !==
+								"string"
+							) {
+								statFlaggedUncached++;
+								// Enqueue uncacheable module for determining the exports
+								queue.enqueue(module);
+								exportsInfo.setHasProvideInfo();
+								return callback();
+							}
+							const memCache = moduleMemCaches && moduleMemCaches.get(module);
+							const memCacheValue = memCache && memCache.get(this);
+							if (memCacheValue !== undefined) {
+								statRestoredFromMemCache++;
+								exportsInfo.restoreProvided(memCacheValue);
+								return callback();
+							}
+							cache.get(
+								module.identifier(),
+								/** @type {BuildInfo} */
+								(module.buildInfo).hash,
+								(err, result) => {
+									if (err) return callback(err);
+
+									if (result !== undefined) {
+										statRestoredFromCache++;
+										exportsInfo.restoreProvided(result);
+									} else {
+										statNotCached++;
+										// Without cached info enqueue module for determining the exports
+										queue.enqueue(module);
+										exportsInfo.setHasProvideInfo();
+									}
+									callback();
+								}
+							);
+						},
+						(err) => {
+							logger.timeEnd("restore cached provided exports");
+							if (err) return callback(err);
+
+							/** @type {Set<Module>} */
+							const modulesToStore = new Set();
+
+							/** @type {Map<Module, Set<Module>>} */
+							const dependencies = new Map();
+
+							/** @type {Module} */
+							let module;
+
+							/** @type {ExportsInfo} */
+							let exportsInfo;
+
+							/** @type {Map<Dependency, ExportsSpec>} */
+							const exportsSpecsFromDependencies = new Map();
+
+							let cacheable = true;
+							let changed = false;
+
+							/**
+							 * Process dependencies block.
+							 * @param {DependenciesBlock} depBlock the dependencies block
+							 * @returns {void}
+							 */
+							const processDependenciesBlock = (depBlock) => {
+								for (const dep of depBlock.dependencies) {
+									processDependency(dep);
+								}
+								for (const block of depBlock.blocks) {
+									processDependenciesBlock(block);
+								}
+							};
+
+							/**
+							 * Process dependency.
+							 * @param {Dependency} dep the dependency
+							 * @returns {void}
+							 */
+							const processDependency = (dep) => {
+								const exportDesc = dep.getExports(moduleGraph);
+								if (!exportDesc) return;
+								exportsSpecsFromDependencies.set(dep, exportDesc);
+							};
+
+							/**
+							 * Process exports spec.
+							 * @param {Dependency} dep dependency
+							 * @param {ExportsSpec} exportDesc info
+							 * @returns {void}
+							 */
+							const processExportsSpec = (dep, exportDesc) => {
+								const exports = exportDesc.exports;
+								const globalCanMangle = exportDesc.canMangle;
+								const globalFrom = exportDesc.from;
+								const globalPriority = exportDesc.priority;
+								const globalTerminalBinding =
+									exportDesc.terminalBinding || false;
+								const exportDeps = exportDesc.dependencies;
+								if (exportDesc.hideExports) {
+									for (const name of exportDesc.hideExports) {
+										const exportInfo = exportsInfo.getExportInfo(name);
+										exportInfo.unsetTarget(dep);
+									}
+								}
+								if (exports === true) {
+									// unknown exports
+									if (
+										exportsInfo.setUnknownExportsProvided(
+											globalCanMangle,
+											exportDesc.excludeExports,
+											globalFrom && dep,
+											globalFrom,
+											globalPriority
+										)
+									) {
+										changed = true;
+									}
+								} else if (Array.isArray(exports)) {
+									/**
+									 * merge in new exports
+									 * @param {ExportsInfo} exportsInfo own exports info
+									 * @param {(ExportSpec | string)[]} exports list of exports
+									 */
+									const mergeExports = (exportsInfo, exports) => {
+										for (const exportNameOrSpec of exports) {
+											/** @type {ExportInfoName} */
+											let name;
+											let canMangle = globalCanMangle;
+											let terminalBinding = globalTerminalBinding;
+											/** @type {ExportSpec["exports"]} */
+											let exports;
+											let from = globalFrom;
+											/** @type {ExportSpec["export"]} */
+											let fromExport;
+											let priority = globalPriority;
+											let hidden = false;
+											if (typeof exportNameOrSpec === "string") {
+												name = exportNameOrSpec;
+											} else {
+												name = exportNameOrSpec.name;
+												if (exportNameOrSpec.canMangle !== undefined) {
+													canMangle = exportNameOrSpec.canMangle;
+												}
+												if (exportNameOrSpec.export !== undefined) {
+													fromExport = exportNameOrSpec.export;
+												}
+												if (exportNameOrSpec.exports !== undefined) {
+													exports = exportNameOrSpec.exports;
+												}
+												if (exportNameOrSpec.from !== undefined) {
+													from = exportNameOrSpec.from;
+												}
+												if (exportNameOrSpec.priority !== undefined) {
+													priority = exportNameOrSpec.priority;
+												}
+												if (exportNameOrSpec.terminalBinding !== undefined) {
+													terminalBinding = exportNameOrSpec.terminalBinding;
+												}
+												if (exportNameOrSpec.hidden !== undefined) {
+													hidden = exportNameOrSpec.hidden;
+												}
+											}
+											const exportInfo = exportsInfo.getExportInfo(name);
+
+											if (
+												exportInfo.provided === false ||
+												exportInfo.provided === null
+											) {
+												exportInfo.provided = true;
+												changed = true;
+											}
+
+											if (
+												exportInfo.canMangleProvide !== false &&
+												canMangle === false
+											) {
+												exportInfo.canMangleProvide = false;
+												changed = true;
+											}
+
+											if (terminalBinding && !exportInfo.terminalBinding) {
+												exportInfo.terminalBinding = true;
+												changed = true;
+											}
+
+											if (exports) {
+												const nestedExportsInfo =
+													exportInfo.createNestedExportsInfo();
+												mergeExports(
+													/** @type {ExportsInfo} */ (nestedExportsInfo),
+													exports
+												);
+											}
+
+											if (
+												from &&
+												(hidden
+													? exportInfo.unsetTarget(dep)
+													: exportInfo.setTarget(
+															dep,
+															from,
+															fromExport === undefined ? [name] : fromExport,
+															priority
+														))
+											) {
+												changed = true;
+											}
+
+											// Recalculate target exportsInfo
+											const target = exportInfo.getTarget(moduleGraph);
+											/** @type {undefined | ExportsInfo} */
+											let targetExportsInfo;
+											if (target) {
+												const targetModuleExportsInfo =
+													moduleGraph.getExportsInfo(target.module);
+												targetExportsInfo =
+													targetModuleExportsInfo.getNestedExportsInfo(
+														target.export
+													);
+												// add dependency for this module
+												const set = dependencies.get(target.module);
+												if (set === undefined) {
+													dependencies.set(target.module, new Set([module]));
+												} else {
+													set.add(module);
+												}
+											}
+
+											if (exportInfo.exportsInfoOwned) {
+												if (
+													/** @type {ExportsInfo} */
+													(exportInfo.exportsInfo).setRedirectNamedTo(
+														targetExportsInfo
+													)
+												) {
+													changed = true;
+												}
+											} else if (exportInfo.exportsInfo !== targetExportsInfo) {
+												exportInfo.exportsInfo = targetExportsInfo;
+												changed = true;
+											}
+										}
+									};
+									mergeExports(exportsInfo, exports);
+								}
+								// store dependencies
+								if (exportDeps) {
+									cacheable = false;
+									for (const exportDependency of exportDeps) {
+										// add dependency for this module
+										const set = dependencies.get(exportDependency);
+										if (set === undefined) {
+											dependencies.set(exportDependency, new Set([module]));
+										} else {
+											set.add(module);
+										}
+									}
+								}
+							};
+
+							const notifyDependencies = () => {
+								const deps = dependencies.get(module);
+								if (deps !== undefined) {
+									for (const dep of deps) {
+										queue.enqueue(dep);
+									}
+								}
+							};
+
+							logger.time("figure out provided exports");
+							while (queue.length > 0) {
+								module = /** @type {Module} */ (queue.dequeue());
+
+								statQueueItemsProcessed++;
+
+								exportsInfo = moduleGraph.getExportsInfo(module);
+
+								cacheable = true;
+								changed = false;
+
+								exportsSpecsFromDependencies.clear();
+								moduleGraph.freeze();
+								processDependenciesBlock(module);
+								moduleGraph.unfreeze();
+								for (const [dep, exportsSpec] of exportsSpecsFromDependencies) {
+									processExportsSpec(dep, exportsSpec);
+								}
+
+								if (cacheable) {
+									modulesToStore.add(module);
+								}
+
+								if (changed) {
+									notifyDependencies();
+								}
+							}
+							logger.timeEnd("figure out provided exports");
+
+							logger.log(
+								`${Math.round(
+									(100 * (statFlaggedUncached + statNotCached)) /
+										(statRestoredFromMemCache +
+											statRestoredFromCache +
+											statNotCached +
+											statFlaggedUncached +
+											statNoExports)
+								)}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${statRestoredFromMemCache} from mem cache, ${
+									statQueueItemsProcessed - statNotCached - statFlaggedUncached
+								} additional calculations due to dependencies)`
+							);
+
+							logger.time("store provided exports into cache");
+							asyncLib.each(
+								modulesToStore,
+								(module, callback) => {
+									if (
+										typeof (
+											/** @type {BuildInfo} */
+											(module.buildInfo).hash
+										) !== "string"
+									) {
+										// not cacheable
+										return callback();
+									}
+									const cachedData = moduleGraph
+										.getExportsInfo(module)
+										.getRestoreProvidedData();
+									const memCache =
+										moduleMemCaches && moduleMemCaches.get(module);
+									if (memCache) {
+										memCache.set(this, cachedData);
+									}
+									cache.store(
+										module.identifier(),
+										/** @type {BuildInfo} */
+										(module.buildInfo).hash,
+										cachedData,
+										callback
+									);
+								},
+								(err) => {
+									logger.timeEnd("store provided exports into cache");
+									callback(err);
+								}
+							);
+						}
+					);
+				}
+			);
+
+			/** @type {WeakMap<Module, RestoreProvidedData>} */
+			const providedExportsCache = new WeakMap();
+			compilation.hooks.rebuildModule.tap(PLUGIN_NAME, (module) => {
+				providedExportsCache.set(
+					module,
+					moduleGraph.getExportsInfo(module).getRestoreProvidedData()
+				);
+			});
+			compilation.hooks.finishRebuildingModule.tap(PLUGIN_NAME, (module) => {
+				moduleGraph.getExportsInfo(module).restoreProvided(
+					/** @type {RestoreProvidedData} */
+					(providedExportsCache.get(module))
+				);
+			});
+		});
+	}
+}
+
+module.exports = FlagDependencyExportsPlugin;
Index: frontend/node_modules/webpack/lib/FlagDependencyUsagePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/FlagDependencyUsagePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/FlagDependencyUsagePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,352 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("./Dependency");
+const { UsageState } = require("./ExportsInfo");
+const ModuleGraphConnection = require("./ModuleGraphConnection");
+const { STAGE_DEFAULT } = require("./OptimizationStages");
+const ArrayQueue = require("./util/ArrayQueue");
+const TupleQueue = require("./util/TupleQueue");
+const { getEntryRuntime, mergeRuntimeOwned } = require("./util/runtime");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("./Dependency").ReferencedExport} ReferencedExport */
+/** @typedef {import("./Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("./ExportsInfo")} ExportsInfo */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+const { NO_EXPORTS_REFERENCED, EXPORTS_OBJECT_REFERENCED } = Dependency;
+
+const PLUGIN_NAME = "FlagDependencyUsagePlugin";
+const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`;
+
+class FlagDependencyUsagePlugin {
+	/**
+	 * Creates an instance of FlagDependencyUsagePlugin.
+	 * @param {boolean} global do a global analysis instead of per runtime
+	 */
+	constructor(global) {
+		/** @type {boolean} */
+		this.global = global;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			compilation.hooks.optimizeDependencies.tap(
+				{ name: PLUGIN_NAME, stage: STAGE_DEFAULT },
+				(modules) => {
+					if (compilation.moduleMemCaches) {
+						throw new Error(
+							"optimization.usedExports can't be used with cacheUnaffected as export usage is a global effect"
+						);
+					}
+
+					const logger = compilation.getLogger(PLUGIN_LOGGER_NAME);
+					/** @type {Map<ExportsInfo, Module>} */
+					const exportInfoToModuleMap = new Map();
+
+					/** @type {TupleQueue<Module, RuntimeSpec>} */
+					const queue = new TupleQueue();
+
+					/**
+					 * Process referenced module.
+					 * @param {Module} module module to process
+					 * @param {ReferencedExports} usedExports list of used exports
+					 * @param {RuntimeSpec} runtime part of which runtime
+					 * @param {boolean} forceSideEffects always apply side effects
+					 * @returns {void}
+					 */
+					const processReferencedModule = (
+						module,
+						usedExports,
+						runtime,
+						forceSideEffects
+					) => {
+						const exportsInfo = moduleGraph.getExportsInfo(module);
+						if (usedExports.length > 0) {
+							if (!module.buildMeta || !module.buildMeta.exportsType) {
+								if (exportsInfo.setUsedWithoutInfo(runtime)) {
+									queue.enqueue(module, runtime);
+								}
+								return;
+							}
+							for (const usedExportInfo of usedExports) {
+								/** @type {string[]} */
+								let usedExport;
+								let canMangle = true;
+								if (Array.isArray(usedExportInfo)) {
+									usedExport = usedExportInfo;
+								} else {
+									usedExport = usedExportInfo.name;
+									canMangle = usedExportInfo.canMangle !== false;
+								}
+								if (usedExport.length === 0) {
+									if (exportsInfo.setUsedInUnknownWay(runtime)) {
+										queue.enqueue(module, runtime);
+									}
+								} else {
+									let currentExportsInfo = exportsInfo;
+									for (let i = 0; i < usedExport.length; i++) {
+										const exportInfo = currentExportsInfo.getExportInfo(
+											usedExport[i]
+										);
+										if (canMangle === false) {
+											exportInfo.canMangleUse = false;
+										}
+										const lastOne = i === usedExport.length - 1;
+										if (!lastOne) {
+											const nestedInfo = exportInfo.getNestedExportsInfo();
+											if (nestedInfo) {
+												if (
+													exportInfo.setUsedConditionally(
+														(used) => used === UsageState.Unused,
+														UsageState.OnlyPropertiesUsed,
+														runtime
+													)
+												) {
+													const currentModule =
+														currentExportsInfo === exportsInfo
+															? module
+															: exportInfoToModuleMap.get(currentExportsInfo);
+													if (currentModule) {
+														queue.enqueue(currentModule, runtime);
+													}
+												}
+												currentExportsInfo = nestedInfo;
+												continue;
+											}
+										}
+										if (
+											exportInfo.setUsedConditionally(
+												(v) => v !== UsageState.Used,
+												UsageState.Used,
+												runtime
+											)
+										) {
+											const currentModule =
+												currentExportsInfo === exportsInfo
+													? module
+													: exportInfoToModuleMap.get(currentExportsInfo);
+											if (currentModule) {
+												queue.enqueue(currentModule, runtime);
+											}
+										}
+										break;
+									}
+								}
+							}
+						} else {
+							// for a module without side effects we stop tracking usage here when no export is used
+							// This module won't be evaluated in this case
+							// TODO webpack 6 remove this check
+							if (
+								!forceSideEffects &&
+								module.factoryMeta !== undefined &&
+								module.factoryMeta.sideEffectFree
+							) {
+								return;
+							}
+							if (exportsInfo.setUsedForSideEffectsOnly(runtime)) {
+								queue.enqueue(module, runtime);
+							}
+						}
+					};
+
+					/**
+					 * Processes the provided module.
+					 * @param {DependenciesBlock} module the module
+					 * @param {RuntimeSpec} runtime part of which runtime
+					 * @param {boolean} forceSideEffects always apply side effects
+					 * @returns {void}
+					 */
+					const processModule = (module, runtime, forceSideEffects) => {
+						/** @typedef {Map<string, string[] | ReferencedExport>} ExportMaps */
+						/** @type {Map<Module, ReferencedExports | ExportMaps>} */
+						const map = new Map();
+
+						/** @type {ArrayQueue<DependenciesBlock>} */
+						const queue = new ArrayQueue();
+						queue.enqueue(module);
+						for (;;) {
+							const block = queue.dequeue();
+							if (block === undefined) break;
+							for (const b of block.blocks) {
+								if (b.groupOptions && b.groupOptions.entryOptions) {
+									processModule(
+										b,
+										this.global
+											? undefined
+											: b.groupOptions.entryOptions.runtime || undefined,
+										true
+									);
+								} else {
+									queue.enqueue(b);
+								}
+							}
+							for (const dep of block.dependencies) {
+								const connection = moduleGraph.getConnection(dep);
+								if (!connection || !connection.module) {
+									continue;
+								}
+								const activeState = connection.getActiveState(runtime);
+								if (activeState === false) continue;
+								const { module } = connection;
+								if (activeState === ModuleGraphConnection.TRANSITIVE_ONLY) {
+									processModule(module, runtime, false);
+									continue;
+								}
+								const oldReferencedExports = map.get(module);
+								if (oldReferencedExports === EXPORTS_OBJECT_REFERENCED) {
+									continue;
+								}
+								const referencedExports =
+									compilation.getDependencyReferencedExports(dep, runtime);
+								if (
+									oldReferencedExports === undefined ||
+									oldReferencedExports === NO_EXPORTS_REFERENCED ||
+									referencedExports === EXPORTS_OBJECT_REFERENCED
+								) {
+									map.set(module, referencedExports);
+								} else if (
+									oldReferencedExports !== undefined &&
+									referencedExports === NO_EXPORTS_REFERENCED
+								) {
+									continue;
+								} else {
+									/** @type {undefined | ExportMaps} */
+									let exportsMap;
+									if (Array.isArray(oldReferencedExports)) {
+										exportsMap = new Map();
+										for (const item of oldReferencedExports) {
+											if (Array.isArray(item)) {
+												exportsMap.set(item.join("\n"), item);
+											} else {
+												exportsMap.set(item.name.join("\n"), item);
+											}
+										}
+										map.set(module, exportsMap);
+									} else {
+										exportsMap = oldReferencedExports;
+									}
+									for (const item of referencedExports) {
+										if (Array.isArray(item)) {
+											const key = item.join("\n");
+											const oldItem = exportsMap.get(key);
+											if (oldItem === undefined) {
+												exportsMap.set(key, item);
+											}
+											// if oldItem is already an array we have to do nothing
+											// if oldItem is an ReferencedExport object, we don't have to do anything
+											// as canMangle defaults to true for arrays
+										} else {
+											const key = item.name.join("\n");
+											const oldItem = exportsMap.get(key);
+											if (oldItem === undefined || Array.isArray(oldItem)) {
+												exportsMap.set(key, item);
+											} else {
+												exportsMap.set(key, {
+													name: item.name,
+													canMangle: item.canMangle && oldItem.canMangle
+												});
+											}
+										}
+									}
+								}
+							}
+						}
+
+						for (const [module, referencedExports] of map) {
+							if (Array.isArray(referencedExports)) {
+								processReferencedModule(
+									module,
+									referencedExports,
+									runtime,
+									forceSideEffects
+								);
+							} else {
+								processReferencedModule(
+									module,
+									[...referencedExports.values()],
+									runtime,
+									forceSideEffects
+								);
+							}
+						}
+					};
+
+					logger.time("initialize exports usage");
+					for (const module of modules) {
+						const exportsInfo = moduleGraph.getExportsInfo(module);
+						exportInfoToModuleMap.set(exportsInfo, module);
+						exportsInfo.setHasUseInfo();
+					}
+					logger.timeEnd("initialize exports usage");
+
+					logger.time("trace exports usage in graph");
+
+					/**
+					 * Process entry dependency.
+					 * @param {Dependency} dep dependency
+					 * @param {RuntimeSpec} runtime runtime
+					 */
+					const processEntryDependency = (dep, runtime) => {
+						const module = moduleGraph.getModule(dep);
+						if (module) {
+							processReferencedModule(
+								module,
+								NO_EXPORTS_REFERENCED,
+								runtime,
+								true
+							);
+						}
+					};
+					/** @type {RuntimeSpec} */
+					let globalRuntime;
+					for (const [
+						entryName,
+						{ dependencies: deps, includeDependencies: includeDeps, options }
+					] of compilation.entries) {
+						const runtime = this.global
+							? undefined
+							: getEntryRuntime(compilation, entryName, options);
+						for (const dep of deps) {
+							processEntryDependency(dep, runtime);
+						}
+						for (const dep of includeDeps) {
+							processEntryDependency(dep, runtime);
+						}
+						globalRuntime = mergeRuntimeOwned(globalRuntime, runtime);
+					}
+					for (const dep of compilation.globalEntry.dependencies) {
+						processEntryDependency(dep, globalRuntime);
+					}
+					for (const dep of compilation.globalEntry.includeDependencies) {
+						processEntryDependency(dep, globalRuntime);
+					}
+
+					while (queue.length) {
+						const [module, runtime] = /** @type {[Module, RuntimeSpec]} */ (
+							queue.dequeue()
+						);
+						processModule(module, runtime, false);
+					}
+					logger.timeEnd("trace exports usage in graph");
+				}
+			);
+		});
+	}
+}
+
+module.exports = FlagDependencyUsagePlugin;
Index: frontend/node_modules/webpack/lib/FlagEntryExportAsUsedPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/FlagEntryExportAsUsedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/FlagEntryExportAsUsedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,57 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { getEntryRuntime } = require("./util/runtime");
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "FlagEntryExportAsUsedPlugin";
+
+class FlagEntryExportAsUsedPlugin {
+	/**
+	 * Creates an instance of FlagEntryExportAsUsedPlugin.
+	 * @param {boolean} nsObjectUsed true, if the ns object is used
+	 * @param {string} explanation explanation for the reason
+	 */
+	constructor(nsObjectUsed, explanation) {
+		this.nsObjectUsed = nsObjectUsed;
+		this.explanation = explanation;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			compilation.hooks.seal.tap(PLUGIN_NAME, () => {
+				for (const [
+					entryName,
+					{ dependencies: deps, options }
+				] of compilation.entries) {
+					const runtime = getEntryRuntime(compilation, entryName, options);
+					for (const dep of deps) {
+						const module = moduleGraph.getModule(dep);
+						if (module) {
+							const exportsInfo = moduleGraph.getExportsInfo(module);
+							if (this.nsObjectUsed) {
+								exportsInfo.setUsedInUnknownWay(runtime);
+							} else {
+								exportsInfo.setAllKnownExportsUsed(runtime);
+							}
+							moduleGraph.addExtraReason(module, this.explanation);
+						}
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = FlagEntryExportAsUsedPlugin;
Index: frontend/node_modules/webpack/lib/Generator.js
===================================================================
--- frontend/node_modules/webpack/lib/Generator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Generator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,201 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { JAVASCRIPT_TYPE } = require("./ModuleSourceTypeConstants");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
+/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./Module").SourceType} SourceType */
+/** @typedef {import("./Module").SourceTypes} SourceTypes */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./NormalModule")} NormalModule */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Defines the generate context type used by this module.
+ * @typedef {object} GenerateContext
+ * @property {DependencyTemplates} dependencyTemplates mapping from dependencies to templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {RuntimeRequirements} runtimeRequirements the requirements for runtime
+ * @property {RuntimeSpec} runtime the runtime
+ * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules
+ * @property {CodeGenerationResults=} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that)
+ * @property {SourceType} type which kind of code should be generated
+ * @property {() => CodeGenerationResultData=} getData get access to the code generation data
+ */
+
+/**
+ * Defines the generate error fn callback.
+ * @callback GenerateErrorFn
+ * @param {Error} error the error
+ * @param {NormalModule} module module for which the code should be generated
+ * @param {GenerateContext} generateContext context for generate
+ * @returns {Source | null} generated code
+ */
+
+/**
+ * Represents the generator runtime component.
+ * @typedef {object} UpdateHashContext
+ * @property {NormalModule} module the module
+ * @property {ChunkGraph} chunkGraph
+ * @property {RuntimeSpec} runtime
+ * @property {RuntimeTemplate=} runtimeTemplate
+ */
+
+class Generator {
+	/**
+	 * Returns generator by type.
+	 * @param {{ [key in SourceType]?: Generator }} map map of types
+	 * @returns {ByTypeGenerator} generator by type
+	 */
+	static byType(map) {
+		return new ByTypeGenerator(map);
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns the source types available for this module.
+	 * @abstract
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @abstract
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Generates generated code for this runtime module.
+	 * @abstract
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(
+		module,
+		{ dependencyTemplates, runtimeTemplate, moduleGraph, type }
+	) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		return `Module Concatenation is not implemented for ${this.constructor.name}`;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash that will be modified
+	 * @param {UpdateHashContext} updateHashContext context for updating hash
+	 */
+	updateHash(hash, { module, runtime }) {
+		// no nothing
+	}
+}
+
+/**
+ * @this {ByTypeGenerator}
+ * @type {GenerateErrorFn}
+ */
+function generateError(error, module, generateContext) {
+	const type = generateContext.type;
+	const generator =
+		/** @type {Generator & { generateError?: GenerateErrorFn }} */
+		(this.map[type]);
+	if (!generator) {
+		throw new Error(`Generator.byType: no generator specified for ${type}`);
+	}
+	if (typeof generator.generateError === "undefined") {
+		return null;
+	}
+	return generator.generateError(error, module, generateContext);
+}
+
+class ByTypeGenerator extends Generator {
+	/**
+	 * Creates an instance of ByTypeGenerator.
+	 * @param {{ [key in SourceType]?: Generator }} map map of types
+	 */
+	constructor(map) {
+		super();
+		this.map = map;
+		this._types = /** @type {SourceTypes} */ (new Set(Object.keys(map)));
+		/** @type {GenerateErrorFn | undefined} */
+		this.generateError = generateError.bind(this);
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return this._types;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type = JAVASCRIPT_TYPE) {
+		const t = type;
+		const generator = this.map[t];
+		return generator ? generator.getSize(module, t) : 0;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const type = generateContext.type;
+		const generator = this.map[type];
+		if (!generator) {
+			throw new Error(`Generator.byType: no generator specified for ${type}`);
+		}
+		return generator.generate(module, generateContext);
+	}
+}
+
+module.exports = Generator;
Index: frontend/node_modules/webpack/lib/HotModuleReplacementPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/HotModuleReplacementPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/HotModuleReplacementPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,956 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncBailHook } = require("tapable");
+const { RawSource } = require("webpack-sources");
+const ChunkGraph = require("./ChunkGraph");
+const Compilation = require("./Compilation");
+const HotUpdateChunk = require("./HotUpdateChunk");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM,
+	WEBPACK_MODULE_TYPE_RUNTIME
+} = require("./ModuleTypeConstants");
+const NormalModule = require("./NormalModule");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const { chunkHasCss } = require("./css/CssModulesPlugin");
+const ConstDependency = require("./dependencies/ConstDependency");
+const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency");
+const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency");
+const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency");
+const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency");
+const WebpackError = require("./errors/WebpackError");
+const HotModuleReplacementRuntimeModule = require("./hmr/HotModuleReplacementRuntimeModule");
+const JavascriptParser = require("./javascript/JavascriptParser");
+const {
+	evaluateToIdentifier
+} = require("./javascript/JavascriptParserHelpers");
+const ConcatenatedModule = require("./optimize/ConcatenatedModule");
+const { find, isSubset } = require("./util/SetHelpers");
+const TupleSet = require("./util/TupleSet");
+const { compareModulesById } = require("./util/comparators");
+const {
+	forEachRuntime,
+	getRuntimeKey,
+	intersectRuntime,
+	keyToRuntime,
+	mergeRuntimeOwned,
+	subtractRuntime
+} = require("./util/runtime");
+
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Chunk").ChunkId} ChunkId */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compilation").Records} Records */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./RuntimeModule")} RuntimeModule */
+/** @typedef {import("./javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("./javascript/JavascriptParserHelpers").Range} Range */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {string[]} Requests */
+
+/**
+ * Defines the hmr javascript parser hooks type used by this module.
+ * @typedef {object} HMRJavascriptParserHooks
+ * @property {SyncBailHook<[Expression | SpreadElement, Requests], void>} hotAcceptCallback
+ * @property {SyncBailHook<[CallExpression, Requests], void>} hotAcceptWithoutCallback
+ */
+
+/** @typedef {number} HotIndex */
+/** @typedef {Record<string, string>} FullHashChunkModuleHashes */
+/** @typedef {Record<string, string>} ChunkModuleHashes */
+/** @typedef {Record<ChunkId, string>} ChunkHashes */
+/** @typedef {Record<ChunkId, string>} ChunkRuntime */
+/** @typedef {Record<ChunkId, ModuleId[]>} ChunkModuleIds */
+
+/** @typedef {Set<ChunkId>} ChunkIds */
+/** @typedef {Set<Module>} ModuleSet */
+
+/** @typedef {{ updatedChunkIds: ChunkIds, removedChunkIds: ChunkIds, removedModules: ModuleSet, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */
+/** @typedef {Map<string, HotUpdateMainContentByRuntimeItem>} HotUpdateMainContentByRuntime */
+
+/** @type {WeakMap<JavascriptParser, HMRJavascriptParserHooks>} */
+const parserHooksMap = new WeakMap();
+
+const PLUGIN_NAME = "HotModuleReplacementPlugin";
+
+class HotModuleReplacementPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {HMRJavascriptParserHooks} the attached hooks
+	 */
+	static getParserHooks(parser) {
+		if (!(parser instanceof JavascriptParser)) {
+			throw new TypeError(
+				"The 'parser' argument must be an instance of JavascriptParser"
+			);
+		}
+		let hooks = parserHooksMap.get(parser);
+		if (hooks === undefined) {
+			hooks = {
+				hotAcceptCallback: new SyncBailHook(["expression", "requests"]),
+				hotAcceptWithoutCallback: new SyncBailHook(["expression", "requests"])
+			};
+			parserHooksMap.set(parser, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _backCompat: backCompat } = compiler;
+		if (compiler.options.output.strictModuleErrorHandling === undefined) {
+			compiler.options.output.strictModuleErrorHandling = true;
+		}
+		const runtimeRequirements = [RuntimeGlobals.module];
+
+		/**
+		 * Creates an accept handler.
+		 * @param {JavascriptParser} parser the parser
+		 * @param {typeof ModuleHotAcceptDependency} ParamDependency dependency
+		 * @returns {(expr: CallExpression) => boolean | undefined} callback
+		 */
+		const createAcceptHandler = (parser, ParamDependency) => {
+			const { hotAcceptCallback, hotAcceptWithoutCallback } =
+				HotModuleReplacementPlugin.getParserHooks(parser);
+
+			return (expr) => {
+				const module = parser.state.module;
+				const dep = new ConstDependency(
+					`${module.moduleArgument}.hot.accept`,
+					/** @type {Range} */ (expr.callee.range),
+					runtimeRequirements
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				module.addPresentationalDependency(dep);
+				/** @type {BuildInfo} */
+				(module.buildInfo).moduleConcatenationBailout =
+					"Hot Module Replacement";
+
+				if (expr.arguments.length >= 1) {
+					const arg = parser.evaluateExpression(expr.arguments[0]);
+					/** @type {BasicEvaluatedExpression[]} */
+					let params = [];
+					if (arg.isString()) {
+						params = [arg];
+					} else if (arg.isArray()) {
+						params =
+							/** @type {BasicEvaluatedExpression[]} */
+							(arg.items).filter((param) => param.isString());
+					}
+					/** @type {Requests} */
+					const requests = [];
+					if (params.length > 0) {
+						for (const [idx, param] of params.entries()) {
+							const request = /** @type {string} */ (param.string);
+							const dep = new ParamDependency(
+								request,
+								/** @type {Range} */ (param.range)
+							);
+							dep.optional = true;
+							dep.loc = Object.create(
+								/** @type {DependencyLocation} */ (expr.loc)
+							);
+							dep.loc.index = idx;
+							module.addDependency(dep);
+							requests.push(request);
+						}
+						if (expr.arguments.length > 1) {
+							hotAcceptCallback.call(expr.arguments[1], requests);
+							for (let i = 1; i < expr.arguments.length; i++) {
+								parser.walkExpression(expr.arguments[i]);
+							}
+							return true;
+						}
+						hotAcceptWithoutCallback.call(expr, requests);
+						return true;
+					}
+				}
+				parser.walkExpressions(expr.arguments);
+				return true;
+			};
+		};
+
+		/**
+		 * Creates a decline handler.
+		 * @param {JavascriptParser} parser the parser
+		 * @param {typeof ModuleHotDeclineDependency} ParamDependency dependency
+		 * @returns {(expr: CallExpression) => boolean | undefined} callback
+		 */
+		const createDeclineHandler = (parser, ParamDependency) => (expr) => {
+			const module = parser.state.module;
+			const dep = new ConstDependency(
+				`${module.moduleArgument}.hot.decline`,
+				/** @type {Range} */ (expr.callee.range),
+				runtimeRequirements
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			module.addPresentationalDependency(dep);
+			/** @type {BuildInfo} */
+			(module.buildInfo).moduleConcatenationBailout = "Hot Module Replacement";
+			if (expr.arguments.length === 1) {
+				const arg = parser.evaluateExpression(expr.arguments[0]);
+				/** @type {BasicEvaluatedExpression[]} */
+				let params = [];
+				if (arg.isString()) {
+					params = [arg];
+				} else if (arg.isArray()) {
+					params =
+						/** @type {BasicEvaluatedExpression[]} */
+						(arg.items).filter((param) => param.isString());
+				}
+				for (const [idx, param] of params.entries()) {
+					const dep = new ParamDependency(
+						/** @type {string} */ (param.string),
+						/** @type {Range} */ (param.range)
+					);
+					dep.optional = true;
+					dep.loc = Object.create(/** @type {DependencyLocation} */ (expr.loc));
+					dep.loc.index = idx;
+					module.addDependency(dep);
+				}
+			}
+			return true;
+		};
+
+		/**
+		 * Creates a hmr expression handler.
+		 * @param {JavascriptParser} parser the parser
+		 * @returns {(expr: Expression) => boolean | undefined} callback
+		 */
+		const createHMRExpressionHandler = (parser) => (expr) => {
+			const module = parser.state.module;
+			const dep = new ConstDependency(
+				`${module.moduleArgument}.hot`,
+				/** @type {Range} */ (expr.range),
+				runtimeRequirements
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			module.addPresentationalDependency(dep);
+			/** @type {BuildInfo} */
+			(module.buildInfo).moduleConcatenationBailout = "Hot Module Replacement";
+			return true;
+		};
+
+		/**
+		 * Processes the provided parser.
+		 * @param {JavascriptParser} parser the parser
+		 * @returns {void}
+		 */
+		const applyModuleHot = (parser) => {
+			parser.hooks.evaluateIdentifier.for("module.hot").tap(
+				{
+					name: PLUGIN_NAME,
+					before: "NodeStuffPlugin"
+				},
+				(expr) =>
+					evaluateToIdentifier(
+						"module.hot",
+						"module",
+						() => ["hot"],
+						true
+					)(expr)
+			);
+			parser.hooks.call
+				.for("module.hot.accept")
+				.tap(
+					PLUGIN_NAME,
+					createAcceptHandler(parser, ModuleHotAcceptDependency)
+				);
+			parser.hooks.call
+				.for("module.hot.decline")
+				.tap(
+					PLUGIN_NAME,
+					createDeclineHandler(parser, ModuleHotDeclineDependency)
+				);
+			parser.hooks.expression
+				.for("module.hot")
+				.tap(PLUGIN_NAME, createHMRExpressionHandler(parser));
+		};
+
+		/**
+		 * Apply import meta hot.
+		 * @param {JavascriptParser} parser the parser
+		 * @returns {void}
+		 */
+		const applyImportMetaHot = (parser) => {
+			parser.hooks.evaluateIdentifier
+				.for("import.meta.webpackHot")
+				.tap(PLUGIN_NAME, (expr) =>
+					evaluateToIdentifier(
+						"import.meta.webpackHot",
+						"import.meta",
+						() => ["webpackHot"],
+						true
+					)(expr)
+				);
+			parser.hooks.call
+				.for("import.meta.webpackHot.accept")
+				.tap(
+					PLUGIN_NAME,
+					createAcceptHandler(parser, ImportMetaHotAcceptDependency)
+				);
+			parser.hooks.call
+				.for("import.meta.webpackHot.decline")
+				.tap(
+					PLUGIN_NAME,
+					createDeclineHandler(parser, ImportMetaHotDeclineDependency)
+				);
+			parser.hooks.expression
+				.for("import.meta.webpackHot")
+				.tap(PLUGIN_NAME, createHMRExpressionHandler(parser));
+		};
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				// This applies the HMR plugin only to the targeted compiler
+				// It should not affect child compilations
+				if (compilation.compiler !== compiler) return;
+
+				// #region module.hot.* API
+				compilation.dependencyFactories.set(
+					ModuleHotAcceptDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ModuleHotAcceptDependency,
+					new ModuleHotAcceptDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					ModuleHotDeclineDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ModuleHotDeclineDependency,
+					new ModuleHotDeclineDependency.Template()
+				);
+				// #endregion
+
+				// #region import.meta.webpackHot.* API
+				compilation.dependencyFactories.set(
+					ImportMetaHotAcceptDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportMetaHotAcceptDependency,
+					new ImportMetaHotAcceptDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					ImportMetaHotDeclineDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportMetaHotDeclineDependency,
+					new ImportMetaHotDeclineDependency.Template()
+				);
+				// #endregion
+
+				/** @type {HotIndex} */
+				let hotIndex = 0;
+				/** @type {FullHashChunkModuleHashes} */
+				const fullHashChunkModuleHashes = {};
+				/** @type {ChunkModuleHashes} */
+				const chunkModuleHashes = {};
+
+				compilation.hooks.record.tap(PLUGIN_NAME, (compilation, records) => {
+					if (records.hash === compilation.hash) return;
+					const chunkGraph = compilation.chunkGraph;
+					records.hash = compilation.hash;
+					records.hotIndex = hotIndex;
+					records.fullHashChunkModuleHashes = fullHashChunkModuleHashes;
+					records.chunkModuleHashes = chunkModuleHashes;
+					records.chunkHashes = {};
+					records.chunkRuntime = {};
+					for (const chunk of compilation.chunks) {
+						const chunkId = /** @type {ChunkId} */ (chunk.id);
+						records.chunkHashes[chunkId] = /** @type {string} */ (chunk.hash);
+						records.chunkRuntime[chunkId] = getRuntimeKey(chunk.runtime);
+					}
+					records.chunkModuleIds = {};
+					for (const chunk of compilation.chunks) {
+						const chunkId = /** @type {ChunkId} */ (chunk.id);
+
+						/** @type {ModuleId[]} */
+						const moduleIds = [];
+						for (const m of chunkGraph.getOrderedChunkModulesIterable(
+							chunk,
+							compareModulesById(chunkGraph)
+						)) {
+							moduleIds.push(
+								/** @type {ModuleId} */ (chunkGraph.getModuleId(m))
+							);
+							if (m instanceof ConcatenatedModule && m.modules) {
+								for (const innerModule of m.modules) {
+									if (
+										innerModule.buildMeta &&
+										innerModule.buildMeta.needIdInConcatenation
+									) {
+										const innerId = chunkGraph.getModuleId(innerModule);
+										if (innerId !== null) {
+											moduleIds.push(innerId);
+										}
+									}
+								}
+							}
+						}
+						records.chunkModuleIds[chunkId] = moduleIds;
+					}
+				});
+				/** @type {TupleSet<Module, Chunk>} */
+				const updatedModules = new TupleSet();
+				/** @type {TupleSet<Module, Chunk>} */
+				const fullHashModules = new TupleSet();
+				/** @type {TupleSet<Module, RuntimeSpec>} */
+				const nonCodeGeneratedModules = new TupleSet();
+				compilation.hooks.fullHash.tap(PLUGIN_NAME, (hash) => {
+					const chunkGraph = compilation.chunkGraph;
+					const records = /** @type {Records} */ (compilation.records);
+					for (const chunk of compilation.chunks) {
+						/**
+						 * Returns module hash.
+						 * @param {Module} module module
+						 * @returns {string} module hash
+						 */
+						const getModuleHash = (module) => {
+							const codeGenerationResults =
+								/** @type {CodeGenerationResults} */
+								(compilation.codeGenerationResults);
+							if (codeGenerationResults.has(module, chunk.runtime)) {
+								return codeGenerationResults.getHash(module, chunk.runtime);
+							}
+							nonCodeGeneratedModules.add(module, chunk.runtime);
+							return chunkGraph.getModuleHash(module, chunk.runtime);
+						};
+						const fullHashModulesInThisChunk =
+							chunkGraph.getChunkFullHashModulesSet(chunk);
+						if (fullHashModulesInThisChunk !== undefined) {
+							for (const module of fullHashModulesInThisChunk) {
+								fullHashModules.add(module, chunk);
+							}
+						}
+						const modules = chunkGraph.getChunkModulesIterable(chunk);
+						if (modules !== undefined) {
+							if (records.chunkModuleHashes) {
+								if (fullHashModulesInThisChunk !== undefined) {
+									for (const module of modules) {
+										const key = `${chunk.id}|${module.identifier()}`;
+										const hash = getModuleHash(module);
+										if (
+											fullHashModulesInThisChunk.has(
+												/** @type {RuntimeModule} */
+												(module)
+											)
+										) {
+											if (
+												/** @type {FullHashChunkModuleHashes} */
+												(records.fullHashChunkModuleHashes)[key] !== hash
+											) {
+												updatedModules.add(module, chunk);
+											}
+											fullHashChunkModuleHashes[key] = hash;
+										} else {
+											if (records.chunkModuleHashes[key] !== hash) {
+												updatedModules.add(module, chunk);
+											}
+											chunkModuleHashes[key] = hash;
+										}
+									}
+								} else {
+									for (const module of modules) {
+										const key = `${chunk.id}|${module.identifier()}`;
+										const hash = getModuleHash(module);
+										if (records.chunkModuleHashes[key] !== hash) {
+											updatedModules.add(module, chunk);
+										}
+										chunkModuleHashes[key] = hash;
+									}
+								}
+							} else if (fullHashModulesInThisChunk !== undefined) {
+								for (const module of modules) {
+									const key = `${chunk.id}|${module.identifier()}`;
+									const hash = getModuleHash(module);
+									if (
+										fullHashModulesInThisChunk.has(
+											/** @type {RuntimeModule} */ (module)
+										)
+									) {
+										fullHashChunkModuleHashes[key] = hash;
+									} else {
+										chunkModuleHashes[key] = hash;
+									}
+								}
+							} else {
+								for (const module of modules) {
+									const key = `${chunk.id}|${module.identifier()}`;
+									const hash = getModuleHash(module);
+									chunkModuleHashes[key] = hash;
+								}
+							}
+						}
+					}
+
+					hotIndex = records.hotIndex || 0;
+					if (updatedModules.size > 0) hotIndex++;
+
+					hash.update(`${hotIndex}`);
+				});
+				compilation.hooks.processAssets.tap(
+					{
+						name: PLUGIN_NAME,
+						stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
+					},
+					() => {
+						const chunkGraph = compilation.chunkGraph;
+						const records = /** @type {Records} */ (compilation.records);
+						if (records.hash === compilation.hash) return;
+						if (
+							!records.chunkModuleHashes ||
+							!records.chunkHashes ||
+							!records.chunkModuleIds
+						) {
+							return;
+						}
+						const codeGenerationResults =
+							/** @type {CodeGenerationResults} */
+							(compilation.codeGenerationResults);
+						for (const [module, chunk] of fullHashModules) {
+							const key = `${chunk.id}|${module.identifier()}`;
+							const hash = nonCodeGeneratedModules.has(module, chunk.runtime)
+								? chunkGraph.getModuleHash(module, chunk.runtime)
+								: codeGenerationResults.getHash(module, chunk.runtime);
+							if (records.chunkModuleHashes[key] !== hash) {
+								updatedModules.add(module, chunk);
+							}
+							chunkModuleHashes[key] = hash;
+						}
+
+						/** @type {HotUpdateMainContentByRuntime} */
+						const hotUpdateMainContentByRuntime = new Map();
+						/** @type {RuntimeSpec} */
+						let allOldRuntime;
+						const chunkRuntime =
+							/** @type {ChunkRuntime} */
+							(records.chunkRuntime);
+						for (const key of Object.keys(chunkRuntime)) {
+							const runtime = keyToRuntime(chunkRuntime[key]);
+							allOldRuntime = mergeRuntimeOwned(allOldRuntime, runtime);
+						}
+						forEachRuntime(allOldRuntime, (runtime) => {
+							const { path: filename, info: assetInfo } =
+								compilation.getPathWithInfo(
+									compilation.outputOptions.hotUpdateMainFilename,
+									{
+										hash: records.hash,
+										runtime
+									}
+								);
+							hotUpdateMainContentByRuntime.set(
+								/** @type {string} */ (runtime),
+								{
+									/** @type {ChunkIds} */
+									updatedChunkIds: new Set(),
+									/** @type {ChunkIds} */
+									removedChunkIds: new Set(),
+									/** @type {ModuleSet} */
+									removedModules: new Set(),
+									filename,
+									assetInfo
+								}
+							);
+						});
+						if (hotUpdateMainContentByRuntime.size === 0) return;
+
+						// Create a list of all active modules to verify which modules are removed completely
+						/** @type {Map<ModuleId, Module>} */
+						const allModules = new Map();
+						for (const module of compilation.modules) {
+							const id =
+								/** @type {ModuleId} */
+								(chunkGraph.getModuleId(module));
+							allModules.set(id, module);
+						}
+
+						// List of completely removed modules
+						/** @type {Set<ModuleId>} */
+						const completelyRemovedModules = new Set();
+
+						for (const key of Object.keys(records.chunkHashes)) {
+							const oldRuntime = keyToRuntime(
+								/** @type {ChunkRuntime} */
+								(records.chunkRuntime)[key]
+							);
+							/** @type {Module[]} */
+							const remainingModules = [];
+							// Check which modules are removed
+							for (const id of records.chunkModuleIds[key]) {
+								const module = allModules.get(id);
+								if (module === undefined) {
+									completelyRemovedModules.add(id);
+								} else {
+									remainingModules.push(module);
+								}
+							}
+
+							/** @type {ChunkId | null} */
+							let chunkId;
+							/** @type {undefined | Module[]} */
+							let newModules;
+							/** @type {undefined | RuntimeModule[]} */
+							let newRuntimeModules;
+							/** @type {undefined | RuntimeModule[]} */
+							let newFullHashModules;
+							/** @type {undefined | RuntimeModule[]} */
+							let newDependentHashModules;
+							/** @type {RuntimeSpec} */
+							let newRuntime;
+							/** @type {RuntimeSpec} */
+							let removedFromRuntime;
+							const currentChunk = find(
+								compilation.chunks,
+								(chunk) => `${chunk.id}` === key
+							);
+							if (currentChunk) {
+								chunkId = currentChunk.id;
+								newRuntime = intersectRuntime(
+									currentChunk.runtime,
+									allOldRuntime
+								);
+								if (newRuntime === undefined) continue;
+								newModules = chunkGraph
+									.getChunkModules(currentChunk)
+									.filter((module) => updatedModules.has(module, currentChunk));
+								newRuntimeModules = [
+									...chunkGraph.getChunkRuntimeModulesIterable(currentChunk)
+								].filter((module) => updatedModules.has(module, currentChunk));
+								const fullHashModules =
+									chunkGraph.getChunkFullHashModulesIterable(currentChunk);
+								newFullHashModules =
+									fullHashModules &&
+									[...fullHashModules].filter((module) =>
+										updatedModules.has(module, currentChunk)
+									);
+								const dependentHashModules =
+									chunkGraph.getChunkDependentHashModulesIterable(currentChunk);
+								newDependentHashModules =
+									dependentHashModules &&
+									[...dependentHashModules].filter((module) =>
+										updatedModules.has(module, currentChunk)
+									);
+								removedFromRuntime = subtractRuntime(oldRuntime, newRuntime);
+							} else {
+								// chunk has completely removed
+								chunkId = `${Number(key)}` === key ? Number(key) : key;
+								removedFromRuntime = oldRuntime;
+								newRuntime = oldRuntime;
+							}
+							if (removedFromRuntime) {
+								// chunk was removed from some runtimes
+								forEachRuntime(removedFromRuntime, (runtime) => {
+									const item =
+										/** @type {HotUpdateMainContentByRuntimeItem} */
+										(
+											hotUpdateMainContentByRuntime.get(
+												/** @type {string} */ (runtime)
+											)
+										);
+									item.removedChunkIds.add(/** @type {ChunkId} */ (chunkId));
+								});
+								// dispose modules from the chunk in these runtimes
+								// where they are no longer in this runtime
+								for (const module of remainingModules) {
+									const moduleKey = `${key}|${module.identifier()}`;
+									const oldHash = records.chunkModuleHashes[moduleKey];
+									const runtimes = chunkGraph.getModuleRuntimes(module);
+									if (oldRuntime === newRuntime && runtimes.has(newRuntime)) {
+										// Module is still in the same runtime combination
+										const hash = nonCodeGeneratedModules.has(module, newRuntime)
+											? chunkGraph.getModuleHash(module, newRuntime)
+											: codeGenerationResults.getHash(module, newRuntime);
+										if (hash !== oldHash) {
+											if (module.type === WEBPACK_MODULE_TYPE_RUNTIME) {
+												newRuntimeModules = newRuntimeModules || [];
+												newRuntimeModules.push(
+													/** @type {RuntimeModule} */ (module)
+												);
+											} else {
+												newModules = newModules || [];
+												newModules.push(module);
+											}
+										}
+									} else {
+										// module is no longer in this runtime combination
+										// We (incorrectly) assume that it's not in an overlapping runtime combination
+										// and dispose it from the main runtimes the chunk was removed from
+										forEachRuntime(removedFromRuntime, (runtime) => {
+											// If the module is still used in this runtime, do not dispose it
+											// This could create a bad runtime state where the module is still loaded,
+											// but no chunk which contains it. This means we don't receive further HMR updates
+											// to this module and that's bad.
+											// TODO force load one of the chunks which contains the module
+											for (const moduleRuntime of runtimes) {
+												if (typeof moduleRuntime === "string") {
+													if (moduleRuntime === runtime) return;
+												} else if (
+													moduleRuntime !== undefined &&
+													moduleRuntime.has(/** @type {string} */ (runtime))
+												) {
+													return;
+												}
+											}
+											const item =
+												/** @type {HotUpdateMainContentByRuntimeItem} */ (
+													hotUpdateMainContentByRuntime.get(
+														/** @type {string} */ (runtime)
+													)
+												);
+											item.removedModules.add(module);
+										});
+									}
+								}
+							}
+							if (
+								(newModules && newModules.length > 0) ||
+								(newRuntimeModules && newRuntimeModules.length > 0)
+							) {
+								const hotUpdateChunk = new HotUpdateChunk();
+								if (backCompat) {
+									ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph);
+								}
+								hotUpdateChunk.id = chunkId;
+								hotUpdateChunk.runtime = currentChunk
+									? currentChunk.runtime
+									: newRuntime;
+								if (currentChunk) {
+									for (const group of currentChunk.groupsIterable) {
+										hotUpdateChunk.addGroup(group);
+									}
+								}
+								chunkGraph.attachModules(hotUpdateChunk, newModules || []);
+								chunkGraph.attachRuntimeModules(
+									hotUpdateChunk,
+									newRuntimeModules || []
+								);
+								if (newFullHashModules) {
+									chunkGraph.attachFullHashModules(
+										hotUpdateChunk,
+										newFullHashModules
+									);
+								}
+								if (newDependentHashModules) {
+									chunkGraph.attachDependentHashModules(
+										hotUpdateChunk,
+										newDependentHashModules
+									);
+								}
+								const renderManifest = compilation.getRenderManifest({
+									chunk: hotUpdateChunk,
+									hash: /** @type {string} */ (records.hash),
+									fullHash: /** @type {string} */ (records.hash),
+									outputOptions: compilation.outputOptions,
+									moduleTemplates: compilation.moduleTemplates,
+									dependencyTemplates: compilation.dependencyTemplates,
+									codeGenerationResults: /** @type {CodeGenerationResults} */ (
+										compilation.codeGenerationResults
+									),
+									runtimeTemplate: compilation.runtimeTemplate,
+									moduleGraph: compilation.moduleGraph,
+									chunkGraph
+								});
+								for (const entry of renderManifest) {
+									/** @type {string} */
+									let filename;
+									/** @type {AssetInfo} */
+									let assetInfo;
+									if ("filename" in entry) {
+										filename = entry.filename;
+										assetInfo = entry.info;
+									} else {
+										({ path: filename, info: assetInfo } =
+											compilation.getPathWithInfo(
+												entry.filenameTemplate,
+												entry.pathOptions
+											));
+									}
+									const source = entry.render();
+									compilation.additionalChunkAssets.push(filename);
+									compilation.emitAsset(filename, source, {
+										hotModuleReplacement: true,
+										...assetInfo
+									});
+									if (currentChunk) {
+										currentChunk.files.add(filename);
+										compilation.hooks.chunkAsset.call(currentChunk, filename);
+									}
+								}
+								forEachRuntime(newRuntime, (runtime) => {
+									const item =
+										/** @type {HotUpdateMainContentByRuntimeItem} */ (
+											hotUpdateMainContentByRuntime.get(
+												/** @type {string} */ (runtime)
+											)
+										);
+									item.updatedChunkIds.add(/** @type {ChunkId} */ (chunkId));
+								});
+							}
+						}
+						const completelyRemovedModulesArray = [...completelyRemovedModules];
+						/** @type {Map<string, Omit<HotUpdateMainContentByRuntimeItem, "filename">>} */
+						const hotUpdateMainContentByFilename = new Map();
+						for (const {
+							removedChunkIds,
+							removedModules,
+							updatedChunkIds,
+							filename,
+							assetInfo
+						} of hotUpdateMainContentByRuntime.values()) {
+							const old = hotUpdateMainContentByFilename.get(filename);
+							if (
+								old &&
+								(!isSubset(old.removedChunkIds, removedChunkIds) ||
+									!isSubset(old.removedModules, removedModules) ||
+									!isSubset(old.updatedChunkIds, updatedChunkIds))
+							) {
+								compilation.warnings.push(
+									new WebpackError(`HotModuleReplacementPlugin
+The configured output.hotUpdateMainFilename doesn't lead to unique filenames per runtime and HMR update differs between runtimes.
+This might lead to incorrect runtime behavior of the applied update.
+To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename option, or use the default config.`)
+								);
+								for (const chunkId of removedChunkIds) {
+									old.removedChunkIds.add(chunkId);
+								}
+								for (const chunkId of removedModules) {
+									old.removedModules.add(chunkId);
+								}
+								for (const chunkId of updatedChunkIds) {
+									old.updatedChunkIds.add(chunkId);
+								}
+								continue;
+							}
+							hotUpdateMainContentByFilename.set(filename, {
+								removedChunkIds,
+								removedModules,
+								updatedChunkIds,
+								assetInfo
+							});
+						}
+						for (const [
+							filename,
+							{ removedChunkIds, removedModules, updatedChunkIds, assetInfo }
+						] of hotUpdateMainContentByFilename) {
+							/** @type {{ c: ChunkId[], r: ChunkId[], m: ModuleId[], css?: { r: ChunkId[] } }} */
+							const hotUpdateMainJson = {
+								c: [...updatedChunkIds],
+								r: [...removedChunkIds],
+								m:
+									removedModules.size === 0
+										? completelyRemovedModulesArray
+										: [
+												...completelyRemovedModulesArray,
+												...Array.from(
+													removedModules,
+													(m) =>
+														/** @type {ModuleId} */ (chunkGraph.getModuleId(m))
+												)
+											]
+							};
+
+							// Build CSS removed chunks list (chunks in updatedChunkIds that no longer have CSS)
+							/** @type {ChunkId[]} */
+							const cssRemovedChunkIds = [];
+							if (compilation.options.experiments.css) {
+								for (const chunkId of updatedChunkIds) {
+									for (const /** @type {Chunk} */ chunk of compilation.chunks) {
+										if (chunk.id === chunkId) {
+											if (!chunkHasCss(chunk, chunkGraph)) {
+												cssRemovedChunkIds.push(chunkId);
+											}
+											break;
+										}
+									}
+								}
+							}
+
+							if (cssRemovedChunkIds.length > 0) {
+								hotUpdateMainJson.css = { r: cssRemovedChunkIds };
+							}
+
+							const source = new RawSource(
+								(filename.endsWith(".json") ? "" : "export default ") +
+									JSON.stringify(hotUpdateMainJson)
+							);
+							compilation.emitAsset(filename, source, {
+								hotModuleReplacement: true,
+								...assetInfo
+							});
+						}
+					}
+				);
+
+				compilation.hooks.additionalTreeRuntimeRequirements.tap(
+					PLUGIN_NAME,
+					(chunk, runtimeRequirements) => {
+						runtimeRequirements.add(RuntimeGlobals.hmrDownloadManifest);
+						runtimeRequirements.add(RuntimeGlobals.hmrDownloadUpdateHandlers);
+						runtimeRequirements.add(RuntimeGlobals.interceptModuleExecution);
+						runtimeRequirements.add(RuntimeGlobals.moduleCache);
+						compilation.addRuntimeModule(
+							chunk,
+							new HotModuleReplacementRuntimeModule()
+						);
+					}
+				);
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, (parser) => {
+						applyModuleHot(parser);
+						applyImportMetaHot(parser);
+					});
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, (parser) => {
+						applyModuleHot(parser);
+					});
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, (parser) => {
+						applyImportMetaHot(parser);
+					});
+				normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module) => {
+					module.hot = true;
+					return module;
+				});
+
+				NormalModule.getCompilationHooks(compilation).loader.tap(
+					PLUGIN_NAME,
+					(context) => {
+						context.hot = true;
+					}
+				);
+			}
+		);
+	}
+}
+
+module.exports = HotModuleReplacementPlugin;
Index: frontend/node_modules/webpack/lib/HotUpdateChunk.js
===================================================================
--- frontend/node_modules/webpack/lib/HotUpdateChunk.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/HotUpdateChunk.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Chunk = require("./Chunk");
+
+class HotUpdateChunk extends Chunk {
+	constructor() {
+		super();
+	}
+}
+
+module.exports = HotUpdateChunk;
Index: frontend/node_modules/webpack/lib/IgnorePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/IgnorePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/IgnorePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,108 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RawModule = require("./RawModule");
+const EntryDependency = require("./dependencies/EntryDependency");
+
+/** @typedef {import("../declarations/plugins/IgnorePlugin").IgnorePluginOptions} IgnorePluginOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */
+/** @typedef {import("./ContextModuleFactory").BeforeContextResolveData} BeforeContextResolveData */
+
+/** @typedef {(resource: string, context: string) => boolean} CheckResourceFn */
+
+const PLUGIN_NAME = "IgnorePlugin";
+
+class IgnorePlugin {
+	/**
+	 * Creates an instance of IgnorePlugin.
+	 * @param {IgnorePluginOptions} options IgnorePlugin options
+	 */
+	constructor(options) {
+		this.options = options;
+		this.checkIgnore = this.checkIgnore.bind(this);
+	}
+
+	/**
+	 * Note that if "contextRegExp" is given, both the "resourceRegExp" and "contextRegExp" have to match.
+	 * @param {ResolveData | BeforeContextResolveData} resolveData resolve data
+	 * @returns {false | undefined} returns false when the request should be ignored, otherwise undefined
+	 */
+	checkIgnore(resolveData) {
+		if (
+			"checkResource" in this.options &&
+			this.options.checkResource &&
+			this.options.checkResource(resolveData.request, resolveData.context)
+		) {
+			return false;
+		}
+
+		if (
+			"resourceRegExp" in this.options &&
+			this.options.resourceRegExp &&
+			this.options.resourceRegExp.test(resolveData.request)
+		) {
+			if ("contextRegExp" in this.options && this.options.contextRegExp) {
+				// if "contextRegExp" is given,
+				// both the "resourceRegExp" and "contextRegExp" have to match.
+				if (this.options.contextRegExp.test(resolveData.context)) {
+					return false;
+				}
+			} else {
+				return false;
+			}
+		}
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				/** @type {EXPECTED_ANY} */
+				(require("../schemas/plugins/IgnorePlugin.json")),
+				this.options,
+				{
+					name: "Ignore Plugin",
+					baseDataPath: "options"
+				},
+				(options) => require("../schemas/plugins/IgnorePlugin.check")(options)
+			);
+		});
+
+		compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, (nmf) => {
+			nmf.hooks.beforeResolve.tap(PLUGIN_NAME, (resolveData) => {
+				const result = this.checkIgnore(resolveData);
+
+				if (
+					result === false &&
+					resolveData.dependencies.length > 0 &&
+					resolveData.dependencies[0] instanceof EntryDependency
+				) {
+					const module = new RawModule(
+						"",
+						"ignored-entry-module",
+						"(ignored-entry-module)"
+					);
+					module.factoryMeta = { sideEffectFree: true };
+
+					resolveData.ignoredModule = module;
+				}
+
+				return result;
+			});
+		});
+		compiler.hooks.contextModuleFactory.tap(PLUGIN_NAME, (cmf) => {
+			cmf.hooks.beforeResolve.tap(PLUGIN_NAME, this.checkIgnore);
+		});
+	}
+}
+
+module.exports = IgnorePlugin;
Index: frontend/node_modules/webpack/lib/IgnoreWarningsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/IgnoreWarningsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/IgnoreWarningsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Compilation")} Compilation */
+
+/** @typedef {(warning: Error, compilation: Compilation) => boolean} IgnoreFn */
+
+const PLUGIN_NAME = "IgnoreWarningsPlugin";
+
+class IgnoreWarningsPlugin {
+	/**
+	 * Creates an instance of IgnoreWarningsPlugin.
+	 * @param {IgnoreFn[]} ignoreWarnings conditions to ignore warnings
+	 */
+	constructor(ignoreWarnings) {
+		/** @type {IgnoreFn[]} */
+		this._ignoreWarnings = ignoreWarnings;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.processWarnings.tap(PLUGIN_NAME, (warnings) =>
+				warnings.filter(
+					(warning) =>
+						!this._ignoreWarnings.some((ignore) => ignore(warning, compilation))
+				)
+			);
+		});
+	}
+}
+
+module.exports = IgnoreWarningsPlugin;
Index: frontend/node_modules/webpack/lib/InitFragment.js
===================================================================
--- frontend/node_modules/webpack/lib/InitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/InitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,214 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const makeSerializable = require("./util/makeSerializable");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./Generator").GenerateContext} GenerateContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {string} InitFragmentKey */
+
+/**
+ * Defines the maybe mergeable init fragment type used by this module.
+ * @template GenerateContext
+ * @typedef {object} MaybeMergeableInitFragment
+ * @property {InitFragmentKey=} key
+ * @property {number} stage
+ * @property {number} position
+ * @property {(context: GenerateContext) => string | Source | undefined} getContent
+ * @property {(context: GenerateContext) => string | Source | undefined} getEndContent
+ * @property {(fragments: MaybeMergeableInitFragment<GenerateContext>) => MaybeMergeableInitFragment<GenerateContext>=} merge
+ * @property {(fragments: MaybeMergeableInitFragment<GenerateContext>[]) => MaybeMergeableInitFragment<GenerateContext>[]=} mergeAll
+ */
+
+/**
+ * Extract fragment index.
+ * @template T
+ * @param {T} fragment the init fragment
+ * @param {number} index index
+ * @returns {[T, number]} tuple with both
+ */
+const extractFragmentIndex = (fragment, index) => [fragment, index];
+
+/**
+ * Sorts fragment with index.
+ * @template T
+ * @param {[MaybeMergeableInitFragment<T>, number]} a first pair
+ * @param {[MaybeMergeableInitFragment<T>, number]} b second pair
+ * @returns {number} sort value
+ */
+const sortFragmentWithIndex = ([a, i], [b, j]) => {
+	const stageCmp = a.stage - b.stage;
+	if (stageCmp !== 0) return stageCmp;
+	const positionCmp = a.position - b.position;
+	if (positionCmp !== 0) return positionCmp;
+	return i - j;
+};
+
+/**
+ * Represents InitFragment.
+ * @template GenerateContext
+ * @implements {MaybeMergeableInitFragment<GenerateContext>}
+ */
+class InitFragment {
+	/**
+	 * Creates an instance of InitFragment.
+	 * @param {string | Source | undefined} content the source code that will be included as initialization code
+	 * @param {number} stage category of initialization code (contribute to order)
+	 * @param {number} position position in the category (contribute to order)
+	 * @param {InitFragmentKey=} key unique key to avoid emitting the same initialization code twice
+	 * @param {string | Source=} endContent the source code that will be included at the end of the module
+	 */
+	constructor(content, stage, position, key, endContent) {
+		this.content = content;
+		this.stage = stage;
+		this.position = position;
+		this.key = key;
+		this.endContent = endContent;
+	}
+
+	/**
+	 * Returns the source code that will be included as initialization code.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included as initialization code
+	 */
+	getContent(context) {
+		return this.content;
+	}
+
+	/**
+	 * Returns the source code that will be included at the end of the module.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included at the end of the module
+	 */
+	getEndContent(context) {
+		return this.endContent;
+	}
+
+	/**
+	 * Adds the provided source to the init fragment.
+	 * @template Context
+	 * @param {Source} source sources
+	 * @param {MaybeMergeableInitFragment<Context>[]} initFragments init fragments
+	 * @param {Context} context context
+	 * @returns {Source} source
+	 */
+	static addToSource(source, initFragments, context) {
+		if (initFragments.length > 0) {
+			// Sort fragments by position. If 2 fragments have the same position,
+			// use their index.
+			const sortedFragments = initFragments
+				.map(extractFragmentIndex)
+				.sort(sortFragmentWithIndex);
+
+			// Deduplicate fragments. If a fragment has no key, it is always included.
+			/** @type {Map<InitFragmentKey | symbol, MaybeMergeableInitFragment<Context> | MaybeMergeableInitFragment<Context>[]>} */
+			const keyedFragments = new Map();
+			for (const [fragment] of sortedFragments) {
+				if (typeof fragment.mergeAll === "function") {
+					if (!fragment.key) {
+						throw new Error(
+							`InitFragment with mergeAll function must have a valid key: ${fragment.constructor.name}`
+						);
+					}
+					const oldValue = keyedFragments.get(fragment.key);
+					if (oldValue === undefined) {
+						keyedFragments.set(fragment.key, fragment);
+					} else if (Array.isArray(oldValue)) {
+						oldValue.push(fragment);
+					} else {
+						keyedFragments.set(fragment.key, [oldValue, fragment]);
+					}
+					continue;
+				} else if (typeof fragment.merge === "function") {
+					const key = /** @type {InitFragmentKey} */ (fragment.key);
+					const oldValue =
+						/** @type {MaybeMergeableInitFragment<Context>} */
+						(keyedFragments.get(key));
+					if (oldValue !== undefined) {
+						keyedFragments.set(key, fragment.merge(oldValue));
+						continue;
+					}
+				}
+				keyedFragments.set(fragment.key || Symbol("fragment key"), fragment);
+			}
+
+			const concatSource = new ConcatSource();
+			/** @type {(string | Source)[]} */
+			const endContents = [];
+			for (let fragment of keyedFragments.values()) {
+				if (Array.isArray(fragment)) {
+					fragment =
+						/** @type {[MaybeMergeableInitFragment<Context> & { mergeAll: (fragments: MaybeMergeableInitFragment<Context>[]) => MaybeMergeableInitFragment<Context>[] }, ...MaybeMergeableInitFragment<Context>[]]} */
+						(fragment)[0].mergeAll(fragment);
+				}
+				const content =
+					/** @type {MaybeMergeableInitFragment<Context>} */
+					(fragment).getContent(context);
+				if (content) {
+					concatSource.add(content);
+				}
+				const endContent =
+					/** @type {MaybeMergeableInitFragment<Context>} */
+					(fragment).getEndContent(context);
+				if (endContent) {
+					endContents.push(endContent);
+				}
+			}
+
+			concatSource.add(source);
+			for (const content of endContents.reverse()) {
+				concatSource.add(content);
+			}
+			return concatSource;
+		}
+		return source;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.content);
+		write(this.stage);
+		write(this.position);
+		write(this.key);
+		write(this.endContent);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.content = read();
+		this.stage = read();
+		this.position = read();
+		this.key = read();
+		this.endContent = read();
+	}
+}
+
+makeSerializable(InitFragment, "webpack/lib/InitFragment");
+
+InitFragment.STAGE_CONSTANTS = 10;
+InitFragment.STAGE_ASYNC_BOUNDARY = 20;
+InitFragment.STAGE_HARMONY_EXPORTS = 30;
+InitFragment.STAGE_HARMONY_IMPORTS = 40;
+InitFragment.STAGE_PROVIDES = 50;
+InitFragment.STAGE_ASYNC_DEPENDENCIES = 60;
+InitFragment.STAGE_ASYNC_HARMONY_IMPORTS = 70;
+
+module.exports = InitFragment;
Index: frontend/node_modules/webpack/lib/JavascriptMetaInfoPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/JavascriptMetaInfoPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/JavascriptMetaInfoPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,79 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const InnerGraph = require("./optimize/InnerGraph");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+
+const PLUGIN_NAME = "JavascriptMetaInfoPlugin";
+
+class JavascriptMetaInfoPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @returns {void}
+				 */
+				const handler = (parser) => {
+					parser.hooks.call.for("eval").tap(PLUGIN_NAME, () => {
+						const buildInfo =
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo);
+						buildInfo.moduleConcatenationBailout = "eval()";
+						const currentSymbol = InnerGraph.getTopLevelSymbol(parser.state);
+						if (currentSymbol) {
+							InnerGraph.addUsage(parser.state, null, currentSymbol);
+						} else {
+							InnerGraph.bailout(parser.state);
+						}
+					});
+					parser.hooks.finish.tap(PLUGIN_NAME, () => {
+						const buildInfo =
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo);
+						let topLevelDeclarations = buildInfo.topLevelDeclarations;
+						if (topLevelDeclarations === undefined) {
+							topLevelDeclarations = buildInfo.topLevelDeclarations = new Set();
+						}
+						for (const name of parser.scope.definitions.asSet()) {
+							if (parser.isVariableDefined(name)) {
+								topLevelDeclarations.add(name);
+							}
+						}
+					});
+				};
+
+				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);
+			}
+		);
+	}
+}
+
+module.exports = JavascriptMetaInfoPlugin;
Index: frontend/node_modules/webpack/lib/LibraryTemplatePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/LibraryTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/LibraryTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,49 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const EnableLibraryPlugin = require("./library/EnableLibraryPlugin");
+
+/** @typedef {import("../declarations/WebpackOptions").AuxiliaryComment} AuxiliaryComment */
+/** @typedef {import("../declarations/WebpackOptions").LibraryExport} LibraryExport */
+/** @typedef {import("../declarations/WebpackOptions").LibraryName} LibraryName */
+/** @typedef {import("../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../declarations/WebpackOptions").UmdNamedDefine} UmdNamedDefine */
+/** @typedef {import("./Compiler")} Compiler */
+
+// TODO webpack 6 remove
+class LibraryTemplatePlugin {
+	/**
+	 * Creates an instance of LibraryTemplatePlugin.
+	 * @param {LibraryName} name name of library
+	 * @param {LibraryType} target type of library
+	 * @param {UmdNamedDefine} umdNamedDefine setting this to true will name the UMD module
+	 * @param {AuxiliaryComment} auxiliaryComment comment in the UMD wrapper
+	 * @param {LibraryExport} exportProperty which export should be exposed as library
+	 */
+	constructor(name, target, umdNamedDefine, auxiliaryComment, exportProperty) {
+		this.library = {
+			type: target || "var",
+			name,
+			umdNamedDefine,
+			auxiliaryComment,
+			export: exportProperty
+		};
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { output } = compiler.options;
+		output.library = this.library;
+		new EnableLibraryPlugin(this.library.type).apply(compiler);
+	}
+}
+
+module.exports = LibraryTemplatePlugin;
Index: frontend/node_modules/webpack/lib/LoaderOptionsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/LoaderOptionsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/LoaderOptionsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
+const NormalModule = require("./NormalModule");
+
+/** @typedef {import("../declarations/plugins/LoaderOptionsPlugin").LoaderOptionsPluginOptions} LoaderOptionsPluginOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./ModuleFilenameHelpers").MatchObject} MatchObject  */
+
+/**
+ * Defines the loader context type used by this module.
+ * @template T
+ * @typedef {import("../declarations/LoaderContext").LoaderContext<T>} LoaderContext
+ */
+
+const PLUGIN_NAME = "LoaderOptionsPlugin";
+
+class LoaderOptionsPlugin {
+	/**
+	 * Creates an instance of LoaderOptionsPlugin.
+	 * @param {LoaderOptionsPluginOptions & MatchObject} options options object
+	 */
+	constructor(options = {}) {
+		// If no options are set then generate empty options object
+		if (typeof options !== "object") options = {};
+		if (!options.test) {
+			options.test = () => true;
+		}
+		/** @type {LoaderOptionsPluginOptions & MatchObject} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../schemas/plugins/LoaderOptionsPlugin.json"),
+				this.options,
+				{
+					name: "Loader Options Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../schemas/plugins/LoaderOptionsPlugin.check")(options)
+			);
+		});
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			NormalModule.getCompilationHooks(compilation).loader.tap(
+				PLUGIN_NAME,
+				(context, module) => {
+					const resource = module.resource;
+					if (!resource) return;
+					const i = resource.indexOf("?");
+					if (
+						ModuleFilenameHelpers.matchObject(
+							this.options,
+							i < 0 ? resource : resource.slice(0, i)
+						)
+					) {
+						for (const key of Object.keys(this.options)) {
+							if (key === "include" || key === "exclude" || key === "test") {
+								continue;
+							}
+
+							/** @type {LoaderContext<EXPECTED_ANY> & Record<string, EXPECTED_ANY>} */
+							(context)[key] = this.options[key];
+						}
+					}
+				}
+			);
+		});
+	}
+}
+
+module.exports = LoaderOptionsPlugin;
Index: frontend/node_modules/webpack/lib/LoaderTargetPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/LoaderTargetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/LoaderTargetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const NormalModule = require("./NormalModule");
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "LoaderTargetPlugin";
+
+class LoaderTargetPlugin {
+	/**
+	 * Creates an instance of LoaderTargetPlugin.
+	 * @param {string} target the target
+	 */
+	constructor(target) {
+		this.target = target;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			NormalModule.getCompilationHooks(compilation).loader.tap(
+				PLUGIN_NAME,
+				(loaderContext) => {
+					loaderContext.target = this.target;
+				}
+			);
+		});
+	}
+}
+
+module.exports = LoaderTargetPlugin;
Index: frontend/node_modules/webpack/lib/MainTemplate.js
===================================================================
--- frontend/node_modules/webpack/lib/MainTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/MainTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,386 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const { SyncWaterfallHook } = require("tapable");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("tapable").Tap} Tap */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").Output} OutputOptions */
+/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compilation").InterpolatedPathAndAssetInfo} InterpolatedPathAndAssetInfo */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderBootstrapContext} RenderBootstrapContext */
+/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions */
+/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */
+/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
+/** @typedef {import("./TemplatedPathPlugin").PathData} PathData */
+/**
+ * Defines the if set type used by this module.
+ * @template T
+ * @typedef {import("tapable").IfSet<T>} IfSet
+ */
+
+const getJavascriptModulesPlugin = memoize(() =>
+	require("./javascript/JavascriptModulesPlugin")
+);
+const getJsonpTemplatePlugin = memoize(() =>
+	require("./web/JsonpTemplatePlugin")
+);
+const getLoadScriptRuntimeModule = memoize(() =>
+	require("./runtime/LoadScriptRuntimeModule")
+);
+
+// TODO webpack 6 remove this class
+class MainTemplate {
+	/**
+	 * Creates an instance of MainTemplate.
+	 * @param {OutputOptions} outputOptions output options for the MainTemplate
+	 * @param {Compilation} compilation the compilation
+	 */
+	constructor(outputOptions, compilation) {
+		/** @type {OutputOptions} */
+		this._outputOptions = outputOptions || {};
+		this.hooks = Object.freeze({
+			renderManifest: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(renderManifestEntries: RenderManifestEntry[], renderManifestOptions: RenderManifestOptions) => RenderManifestEntry[]} fn fn
+					 */
+					(options, fn) => {
+						compilation.hooks.renderManifest.tap(
+							options,
+							(entries, options) => {
+								if (!options.chunk.hasRuntime()) return entries;
+								return fn(entries, options);
+							}
+						);
+					},
+					"MainTemplate.hooks.renderManifest is deprecated (use Compilation.hooks.renderManifest instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_RENDER_MANIFEST"
+				)
+			},
+			modules: {
+				tap: () => {
+					throw new Error(
+						"MainTemplate.hooks.modules has been removed (there is no replacement, please create an issue to request that)"
+					);
+				}
+			},
+			moduleObj: {
+				tap: () => {
+					throw new Error(
+						"MainTemplate.hooks.moduleObj has been removed (there is no replacement, please create an issue to request that)"
+					);
+				}
+			},
+			require: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(value: string, renderBootstrapContext: RenderBootstrapContext) => string} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderRequire.tap(options, fn);
+					},
+					"MainTemplate.hooks.require is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderRequire instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_REQUIRE"
+				)
+			},
+			beforeStartup: {
+				tap: () => {
+					throw new Error(
+						"MainTemplate.hooks.beforeStartup has been removed (use RuntimeGlobals.startupOnlyBefore instead)"
+					);
+				}
+			},
+			startup: {
+				tap: () => {
+					throw new Error(
+						"MainTemplate.hooks.startup has been removed (use RuntimeGlobals.startup instead)"
+					);
+				}
+			},
+			afterStartup: {
+				tap: () => {
+					throw new Error(
+						"MainTemplate.hooks.afterStartup has been removed (use RuntimeGlobals.startupOnlyAfter instead)"
+					);
+				}
+			},
+			render: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, chunk: Chunk, hash: string | undefined, moduleTemplate: ModuleTemplate, dependencyTemplates: DependencyTemplates) => Source} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.render.tap(options, (source, renderContext) => {
+								if (
+									renderContext.chunkGraph.getNumberOfEntryModules(
+										renderContext.chunk
+									) === 0 ||
+									!renderContext.chunk.hasRuntime()
+								) {
+									return source;
+								}
+								return fn(
+									source,
+									renderContext.chunk,
+									compilation.hash,
+									compilation.moduleTemplates.javascript,
+									compilation.dependencyTemplates
+								);
+							});
+					},
+					"MainTemplate.hooks.render is deprecated (use JavascriptModulesPlugin.getCompilationHooks().render instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_RENDER"
+				)
+			},
+			renderWithEntry: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, chunk: Chunk, hash: string | undefined) => Source} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.render.tap(options, (source, renderContext) => {
+								if (
+									renderContext.chunkGraph.getNumberOfEntryModules(
+										renderContext.chunk
+									) === 0 ||
+									!renderContext.chunk.hasRuntime()
+								) {
+									return source;
+								}
+								return fn(source, renderContext.chunk, compilation.hash);
+							});
+					},
+					"MainTemplate.hooks.renderWithEntry is deprecated (use JavascriptModulesPlugin.getCompilationHooks().render instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_RENDER_WITH_ENTRY"
+				)
+			},
+			assetPath: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(value: string, path: PathData, assetInfo: AssetInfo | undefined) => string} fn fn
+					 */
+					(options, fn) => {
+						compilation.hooks.assetPath.tap(options, fn);
+					},
+					"MainTemplate.hooks.assetPath is deprecated (use Compilation.hooks.assetPath instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_ASSET_PATH"
+				),
+				call: util.deprecate(
+					/**
+					 * Handles the call callback for this hook.
+					 * @param {TemplatePath} filename used to get asset path with hash
+					 * @param {PathData} options context data
+					 * @returns {string} interpolated path
+					 */
+					(filename, options) => compilation.getAssetPath(filename, options),
+					"MainTemplate.hooks.assetPath is deprecated (use Compilation.hooks.assetPath instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_ASSET_PATH"
+				)
+			},
+			hash: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(hash: Hash) => void} fn fn
+					 */
+					(options, fn) => {
+						compilation.hooks.fullHash.tap(options, fn);
+					},
+					"MainTemplate.hooks.hash is deprecated (use Compilation.hooks.fullHash instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_HASH"
+				)
+			},
+			hashForChunk: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(hash: Hash, chunk: Chunk) => void} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.chunkHash.tap(options, (chunk, hash) => {
+								if (!chunk.hasRuntime()) return;
+								return fn(hash, chunk);
+							});
+					},
+					"MainTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK"
+				)
+			},
+			globalHashPaths: {
+				tap: util.deprecate(
+					() => {},
+					"MainTemplate.hooks.globalHashPaths has been removed (it's no longer needed)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK"
+				)
+			},
+			globalHash: {
+				tap: util.deprecate(
+					() => {},
+					"MainTemplate.hooks.globalHash has been removed (it's no longer needed)",
+					"DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK"
+				)
+			},
+			hotBootstrap: {
+				tap: () => {
+					throw new Error(
+						"MainTemplate.hooks.hotBootstrap has been removed (use your own RuntimeModule instead)"
+					);
+				}
+			},
+
+			// for compatibility:
+			/** @type {SyncWaterfallHook<[string, Chunk, string, ModuleTemplate, DependencyTemplates]>} */
+			bootstrap: new SyncWaterfallHook([
+				"source",
+				"chunk",
+				"hash",
+				"moduleTemplate",
+				"dependencyTemplates"
+			]),
+			/** @type {SyncWaterfallHook<[string, Chunk, string]>} */
+			localVars: new SyncWaterfallHook(["source", "chunk", "hash"]),
+			/** @type {SyncWaterfallHook<[string, Chunk, string]>} */
+			requireExtensions: new SyncWaterfallHook(["source", "chunk", "hash"]),
+			/** @type {SyncWaterfallHook<[string, Chunk, string, string]>} */
+			requireEnsure: new SyncWaterfallHook([
+				"source",
+				"chunk",
+				"hash",
+				"chunkIdExpression"
+			]),
+			get jsonpScript() {
+				const hooks =
+					getLoadScriptRuntimeModule().getCompilationHooks(compilation);
+				return hooks.createScript;
+			},
+			get linkPrefetch() {
+				const hooks = getJsonpTemplatePlugin().getCompilationHooks(compilation);
+				return hooks.linkPrefetch;
+			},
+			get linkPreload() {
+				const hooks = getJsonpTemplatePlugin().getCompilationHooks(compilation);
+				return hooks.linkPreload;
+			}
+		});
+
+		this.renderCurrentHashCode = util.deprecate(
+			/**
+			 * Handles the require ensure callback for this hook.
+			 * @deprecated
+			 * @param {string} hash the hash
+			 * @param {number=} length length of the hash
+			 * @returns {string} generated code
+			 */
+			(hash, length) => {
+				if (length) {
+					return `${RuntimeGlobals.getFullHash} ? ${
+						RuntimeGlobals.getFullHash
+					}().slice(0, ${length}) : ${hash.slice(0, length)}`;
+				}
+				return `${RuntimeGlobals.getFullHash} ? ${RuntimeGlobals.getFullHash}() : ${hash}`;
+			},
+			"MainTemplate.renderCurrentHashCode is deprecated (use RuntimeGlobals.getFullHash runtime function instead)",
+			"DEP_WEBPACK_MAIN_TEMPLATE_RENDER_CURRENT_HASH_CODE"
+		);
+
+		this.getPublicPath = util.deprecate(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {PathData} options context data
+			 * @returns {string} interpolated path
+			 */ (options) =>
+				compilation.getAssetPath(compilation.outputOptions.publicPath, options),
+			"MainTemplate.getPublicPath is deprecated (use Compilation.getAssetPath(compilation.outputOptions.publicPath, options) instead)",
+			"DEP_WEBPACK_MAIN_TEMPLATE_GET_PUBLIC_PATH"
+		);
+
+		this.getAssetPath = util.deprecate(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {TemplatePath} path used to get asset path with hash
+			 * @param {PathData} options context data
+			 * @returns {string} interpolated path
+			 */
+			(path, options) => compilation.getAssetPath(path, options),
+			"MainTemplate.getAssetPath is deprecated (use Compilation.getAssetPath instead)",
+			"DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH"
+		);
+
+		this.getAssetPathWithInfo = util.deprecate(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {TemplatePath} path used to get asset path with hash
+			 * @param {PathData} options context data
+			 * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info
+			 */
+			(path, options) => compilation.getAssetPathWithInfo(path, options),
+			"MainTemplate.getAssetPathWithInfo is deprecated (use Compilation.getAssetPath instead)",
+			"DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH_WITH_INFO"
+		);
+	}
+}
+
+Object.defineProperty(MainTemplate.prototype, "requireFn", {
+	get: util.deprecate(
+		() => RuntimeGlobals.require,
+		`MainTemplate.requireFn is deprecated (use "${RuntimeGlobals.require}")`,
+		"DEP_WEBPACK_MAIN_TEMPLATE_REQUIRE_FN"
+	)
+});
+
+Object.defineProperty(MainTemplate.prototype, "outputOptions", {
+	get: util.deprecate(
+		/**
+		 * Returns output options.
+		 * @this {MainTemplate}
+		 * @returns {OutputOptions} output options
+		 */
+		function outputOptions() {
+			return this._outputOptions;
+		},
+		"MainTemplate.outputOptions is deprecated (use Compilation.outputOptions instead)",
+		"DEP_WEBPACK_MAIN_TEMPLATE_OUTPUT_OPTIONS"
+	)
+});
+
+module.exports = MainTemplate;
Index: frontend/node_modules/webpack/lib/ManifestPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ManifestPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ManifestPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,251 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Haijie Xie @hai-x
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Compilation = require("./Compilation");
+const HotUpdateChunk = require("./HotUpdateChunk");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Chunk").ChunkName} ChunkName */
+/** @typedef {import("./Chunk").ChunkId} ChunkId */
+/** @typedef {import("./Compilation").Asset} Asset */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+
+/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestPluginOptions} ManifestPluginOptions */
+/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestObject} ManifestObject */
+/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestEntrypoint} ManifestEntrypoint */
+/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestItem} ManifestItem */
+
+/** @typedef {(item: ManifestItem) => boolean} Filter */
+/** @typedef {(manifest: ManifestObject) => ManifestObject} Generate */
+/** @typedef {(manifest: ManifestObject) => string} Serialize */
+
+const PLUGIN_NAME = "ManifestPlugin";
+
+/**
+ * Returns extname.
+ * @param {string} filename filename
+ * @returns {string} extname
+ */
+const extname = (filename) => {
+	const replaced = filename.replace(/\?.*/, "");
+	const split = replaced.split(".");
+	const last = split.pop();
+	if (!last) return "";
+	return last && /^(?:gz|br|map)$/i.test(last)
+		? `${split.pop()}.${last}`
+		: last;
+};
+
+const DEFAULT_PREFIX = "[publicpath]";
+const DEFAULT_FILENAME = "manifest.json";
+
+class ManifestPlugin {
+	/**
+	 * Creates an instance of ManifestPlugin.
+	 * @param {ManifestPluginOptions} options options
+	 */
+	constructor(options = {}) {
+		/** @type {ManifestPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../schemas/plugins/ManifestPlugin.json"),
+				this.options,
+				{
+					name: "ManifestPlugin",
+					baseDataPath: "options"
+				},
+				(options) => require("../schemas/plugins/ManifestPlugin.check")(options)
+			);
+		});
+
+		const entrypoints =
+			this.options.entrypoints !== undefined ? this.options.entrypoints : true;
+		const serialize =
+			this.options.serialize ||
+			((manifest) => JSON.stringify(manifest, null, 2));
+
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.processAssets.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
+				},
+				() => {
+					const hashDigestLength = compilation.outputOptions.hashDigestLength;
+					const publicPath = compilation.getPath(
+						compilation.outputOptions.publicPath
+					);
+
+					/**
+					 * Creates a hash reg exp.
+					 * @param {string | string[]} value value
+					 * @returns {RegExp} regexp to remove hash
+					 */
+					const createHashRegExp = (value) =>
+						new RegExp(
+							`(?:\\.${Array.isArray(value) ? `(${value.join("|")})` : value})(?=\\.)`,
+							"gi"
+						);
+
+					/**
+					 * Removes the provided name from the manifest plugin.
+					 * @param {string} name name
+					 * @param {AssetInfo | null} info asset info
+					 * @returns {string} hash removed name
+					 */
+					const removeHash = (name, info) => {
+						// Handles hashes that match configured `hashDigestLength`
+						// i.e. index.XXXX.html -> index.html (html-webpack-plugin)
+						if (hashDigestLength <= 0) return name;
+						const reg = createHashRegExp(`[a-f0-9]{${hashDigestLength},32}`);
+						return name.replace(reg, "");
+					};
+
+					/**
+					 * Returns chunk name or chunk id.
+					 * @param {Chunk} chunk chunk
+					 * @returns {ChunkName | ChunkId} chunk name or chunk id
+					 */
+					const getName = (chunk) => {
+						if (chunk.name) return chunk.name;
+
+						return chunk.id;
+					};
+
+					/** @type {ManifestObject} */
+					let manifest = {};
+
+					if (entrypoints) {
+						/** @type {ManifestObject["entrypoints"]} */
+						const entrypoints = {};
+
+						for (const [name, entrypoint] of compilation.entrypoints) {
+							/** @type {string[]} */
+							const imports = [];
+
+							for (const chunk of entrypoint.chunks) {
+								for (const file of chunk.files) {
+									const name = getName(chunk);
+
+									imports.push(name ? `${name}.${extname(file)}` : file);
+								}
+							}
+
+							/** @type {ManifestEntrypoint} */
+							const item = { imports };
+							const parents = entrypoint
+								.getParents()
+								.map((item) => /** @type {string} */ (item.name));
+
+							if (parents.length > 0) {
+								item.parents = parents;
+							}
+
+							entrypoints[name] = item;
+						}
+
+						manifest.entrypoints = entrypoints;
+					}
+
+					/** @type {ManifestObject["assets"]} */
+					const assets = {};
+
+					/** @type {Set<string>} */
+					const added = new Set();
+
+					/**
+					 * Processes the provided file.
+					 * @param {string} file file
+					 * @param {string=} usedName usedName
+					 * @returns {void}
+					 */
+					const handleFile = (file, usedName) => {
+						if (added.has(file)) return;
+						added.add(file);
+
+						const asset = compilation.getAsset(file);
+						if (!asset) return;
+						const sourceFilename = asset.info.sourceFilename;
+						const name =
+							usedName ||
+							sourceFilename ||
+							// Fallback for unofficial plugins, just remove hash from filename
+							removeHash(file, asset.info);
+
+						const prefix = (this.options.prefix || DEFAULT_PREFIX).replace(
+							/\[publicpath\]/gi,
+							() => (publicPath === "auto" ? "/" : publicPath)
+						);
+						/** @type {ManifestItem} */
+						const item = { file: prefix + file };
+
+						if (sourceFilename) {
+							item.src = sourceFilename;
+						}
+
+						if (this.options.filter) {
+							const needKeep = this.options.filter(item);
+
+							if (!needKeep) {
+								return;
+							}
+						}
+
+						assets[name] = item;
+					};
+
+					for (const chunk of compilation.chunks) {
+						if (chunk instanceof HotUpdateChunk) continue;
+
+						for (const auxiliaryFile of chunk.auxiliaryFiles) {
+							handleFile(auxiliaryFile);
+						}
+
+						const name = getName(chunk);
+
+						for (const file of chunk.files) {
+							handleFile(file, name ? `${name}.${extname(file)}` : file);
+						}
+					}
+
+					for (const asset of compilation.getAssets()) {
+						if (asset.info.hotModuleReplacement) {
+							continue;
+						}
+
+						handleFile(asset.name);
+					}
+
+					manifest.assets = assets;
+
+					if (this.options.generate) {
+						manifest = this.options.generate(manifest);
+					}
+
+					compilation.emitAsset(
+						this.options.filename || DEFAULT_FILENAME,
+						new RawSource(serialize(manifest)),
+						{ manifest: true }
+					);
+				}
+			);
+		});
+	}
+}
+
+module.exports = ManifestPlugin;
Index: frontend/node_modules/webpack/lib/Module.js
===================================================================
--- frontend/node_modules/webpack/lib/Module.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Module.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1463 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const ChunkGraph = require("./ChunkGraph");
+const DependenciesBlock = require("./DependenciesBlock");
+const ModuleGraph = require("./ModuleGraph");
+const {
+	JAVASCRIPT_TYPE,
+	UNKNOWN_TYPE
+} = require("./ModuleSourceTypeConstants");
+const { JAVASCRIPT_TYPES } = require("./ModuleSourceTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const { first } = require("./util/SetHelpers");
+const { compareChunksById } = require("./util/comparators");
+const makeSerializable = require("./util/makeSerializable");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./ChunkGroup")} ChunkGroup */
+/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compilation").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("./Compilation").UnsafeCacheData} UnsafeCacheData */
+/** @typedef {import("./ConcatenationScope")} ConcatenationScope */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("./DependencyTemplate").CssData} CssData */
+/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("./ModuleSourceTypeConstants").AllTypes} AllTypes */
+/** @typedef {import("./FileSystemInfo")} FileSystemInfo */
+/** @typedef {import("./FileSystemInfo").Snapshot} Snapshot */
+/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("./ModuleTypeConstants").ModuleTypes} ModuleTypes */
+/** @typedef {import("./ModuleGraph").OptimizationBailouts} OptimizationBailouts */
+/** @typedef {import("./ModuleProfile")} ModuleProfile */
+/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/**
+ * Defines the init fragment type used by this module.
+ * @template T
+ * @typedef {import("./InitFragment")<T>} InitFragment
+ */
+/** @typedef {import("./errors/WebpackError")} WebpackError */
+/** @typedef {import("./json/JsonData")} JsonData */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+/**
+ * @template T
+ * @typedef {import("./util/SortableSet")<T>} SortableSet
+ */
+/** @typedef {"namespace" | "default-only" | "default-with-named" | "dynamic"} ExportsType */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./util/LazySet")<T>} LazySet<T>
+ */
+
+/**
+ * Defines the source context type used by this module.
+ * @typedef {object} SourceContext
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {RuntimeSpec} runtime the runtimes code should be generated for
+ * @property {string=} type the type of source that should be generated
+ */
+
+/** @typedef {AllTypes} KnownSourceType */
+/** @typedef {KnownSourceType | string} SourceType */
+/** @typedef {ReadonlySet<SourceType>} SourceTypes */
+
+/** @typedef {ReadonlySet<typeof JAVASCRIPT_TYPE | string>} BasicSourceTypes */
+
+// TODO webpack 6: compilation will be required in CodeGenerationContext
+/**
+ * Defines the code generation context type used by this module.
+ * @typedef {object} CodeGenerationContext
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {RuntimeSpec} runtime the runtimes code should be generated for
+ * @property {RuntimeSpec[]} runtimes all runtimes code should be generated for
+ * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules
+ * @property {CodeGenerationResults | undefined} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that)
+ * @property {Compilation=} compilation the compilation
+ * @property {SourceTypes=} sourceTypes source types
+ */
+
+/**
+ * Defines the concatenation bailout reason context type used by this module.
+ * @typedef {object} ConcatenationBailoutReasonContext
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ */
+
+/** @typedef {Set<string>} RuntimeRequirements */
+/** @typedef {ReadonlySet<string>} ReadOnlyRuntimeRequirements */
+
+/**
+ * Defines the all code generation schemas type used by this module.
+ * @typedef {object} AllCodeGenerationSchemas
+ * @property {Set<string>} topLevelDeclarations top level declarations for javascript modules
+ * @property {InitFragment<EXPECTED_ANY>[]} chunkInitFragments chunk init fragments for javascript modules
+ * @property {{ javascript?: string, ["asset-url"]?: string }} url url for asset modules
+ * @property {string} filename a filename for asset modules
+ * @property {AssetInfo} assetInfo an asset info for asset modules
+ * @property {string} fullContentHash a full content hash for asset modules
+ * @property {[{ shareScope: string, initStage: number, init: string }]} share-init share-init for modules federation
+ */
+
+/**
+ * Defines the code gen value type used by this module.
+ * @template {string} K
+ * @typedef {K extends (keyof AllCodeGenerationSchemas) ? AllCodeGenerationSchemas[K] : EXPECTED_ANY} CodeGenValue
+ */
+
+/**
+ * Defines the code gen map overloads type used by this module.
+ * @typedef {object} CodeGenMapOverloads
+ * @property {<K extends string>(key: K) => CodeGenValue<K> | undefined} get
+ * @property {<K extends string>(key: K, value: CodeGenValue<K>) => CodeGenerationResultData} set
+ * @property {<K extends string>(key: K) => boolean} has
+ * @property {<K extends string>(key: K) => boolean} delete
+ */
+
+/**
+ * Defines the code generation result data type used by this module.
+ * @typedef {Omit<Map<string, EXPECTED_ANY>, "get" | "set" | "has" | "delete"> & CodeGenMapOverloads} CodeGenerationResultData
+ */
+
+/** @typedef {Map<SourceType, Source>} Sources */
+
+/**
+ * Defines the code generation result type used by this module.
+ * @typedef {object} CodeGenerationResult
+ * @property {Sources} sources the resulting sources for all source types
+ * @property {CodeGenerationResultData=} data the resulting data for all source types
+ * @property {ReadOnlyRuntimeRequirements | null} runtimeRequirements the runtime requirements
+ * @property {string=} hash a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided)
+ */
+
+/**
+ * Defines the lib ident options type used by this module.
+ * @typedef {object} LibIdentOptions
+ * @property {string} context absolute context path to which lib ident is relative to
+ * @property {AssociatedObjectForCache=} associatedObjectForCache object for caching
+ */
+
+/**
+ * Defines the known build meta type used by this module.
+ * @typedef {object} KnownBuildMeta
+ * @property {("default" | "namespace" | "flagged" | "dynamic")=} exportsType
+ * @property {(false | "redirect" | "redirect-warn")=} defaultObject
+ * @property {boolean=} strictHarmonyModule
+ * @property {boolean=} treatAsCommonJs
+ * @property {boolean=} async
+ * @property {boolean=} sideEffectFree
+ * @property {boolean=} isCssModule
+ * @property {boolean=} needIdInConcatenation
+ * @property {Record<string, string>=} jsIncompatibleExports
+ * @property {Map<string, Record<string, string>>=} exportsFinalNameByRuntime
+ * @property {Map<string, string>=} exportsSourceByRuntime
+ */
+
+/**
+ * Defines the known build info type used by this module.
+ * @typedef {object} KnownBuildInfo
+ * @property {boolean=} cacheable
+ * @property {boolean=} parsed
+ * @property {boolean=} strict
+ * @property {string=} moduleArgument using in AMD
+ * @property {string=} exportsArgument using in AMD
+ * @property {string=} moduleConcatenationBailout using in CommonJs
+ * @property {boolean=} needCreateRequire using in APIPlugin
+ * @property {string=} resourceIntegrity using in HttpUriPlugin
+ * @property {FileSystemDependencies=} fileDependencies using in NormalModule
+ * @property {FileSystemDependencies=} contextDependencies using in NormalModule
+ * @property {FileSystemDependencies=} missingDependencies using in NormalModule
+ * @property {FileSystemDependencies=} buildDependencies using in NormalModule
+ * @property {ValueCacheVersions=} valueDependencies using in NormalModule
+ * @property {Record<string, Source>=} assets using in NormalModule
+ * @property {Map<string, AssetInfo | undefined>=} assetsInfo using in NormalModule
+ * @property {string=} hash using in NormalModule
+ * @property {(Snapshot | null)=} snapshot using in ContextModule
+ * @property {string=} fullContentHash for assets modules
+ * @property {string=} filename for assets modules
+ * @property {boolean=} dataUrl for assets modules
+ * @property {AssetInfo=} assetInfo for assets modules
+ * @property {boolean=} javascriptModule for external modules
+ * @property {boolean=} active for lazy compilation modules
+ * @property {CssData=} cssData for css modules
+ * @property {string=} charset for css modules (charset at-rule)
+ * @property {JsonData=} jsonData for json modules
+ * @property {Set<string>=} topLevelDeclarations top level declaration names
+ */
+
+/** @typedef {string | Set<string>} ValueCacheVersion */
+/** @typedef {Map<string, ValueCacheVersion>} ValueCacheVersions */
+
+/**
+ * Defines the need build context type used by this module.
+ * @typedef {object} NeedBuildContext
+ * @property {Compilation} compilation
+ * @property {FileSystemInfo} fileSystemInfo
+ * @property {ValueCacheVersions} valueCacheVersions
+ */
+
+/** @typedef {(err?: WebpackError | null, needBuild?: boolean) => void} NeedBuildCallback */
+
+/** @typedef {(err?: WebpackError) => void} BuildCallback */
+
+/** @typedef {KnownBuildMeta & Record<string, EXPECTED_ANY>} BuildMeta */
+/** @typedef {KnownBuildInfo & Record<string, EXPECTED_ANY>} BuildInfo */
+
+/**
+ * Defines the factory meta type used by this module.
+ * @typedef {object} FactoryMeta
+ * @property {boolean=} sideEffectFree
+ */
+
+const EMPTY_RESOLVE_OPTIONS = {};
+
+let debugId = 1000;
+
+/** @type {SourceTypes} */
+const DEFAULT_TYPES_UNKNOWN = new Set([UNKNOWN_TYPE]);
+
+const deprecatedNeedRebuild = util.deprecate(
+	/**
+	 * Handles the callback logic for this hook.
+	 * @param {Module} module the module
+	 * @param {NeedBuildContext} context context info
+	 * @returns {boolean} true, when rebuild is needed
+	 */
+	(module, context) =>
+		module.needRebuild(
+			context.fileSystemInfo.getDeprecatedFileTimestamps(),
+			context.fileSystemInfo.getDeprecatedContextTimestamps()
+		),
+	"Module.needRebuild is deprecated in favor of Module.needBuild",
+	"DEP_WEBPACK_MODULE_NEED_REBUILD"
+);
+
+/** @typedef {string} LibIdent */
+/** @typedef {string} NameForCondition */
+
+/** @typedef {(requestShortener: RequestShortener) => string} OptimizationBailoutFunction */
+
+class Module extends DependenciesBlock {
+	/**
+	 * Creates an instance of Module.
+	 * @param {ModuleTypes | ""} type the module type, when deserializing the type is not known and is an empty string
+	 * @param {(string | null)=} context an optional context
+	 * @param {(string | null)=} layer an optional layer in which the module is
+	 */
+	constructor(type, context = null, layer = null) {
+		super();
+
+		/** @type {ModuleTypes} */
+		this.type = type;
+		/** @type {string | null} */
+		this.context = context;
+		/** @type {string | null} */
+		this.layer = layer;
+		/** @type {boolean} */
+		this.needId = true;
+
+		// Unique Id
+		/** @type {number} */
+		this.debugId = debugId++;
+
+		// Info from Factory
+		/** @type {ResolveOptions | undefined} */
+		this.resolveOptions = EMPTY_RESOLVE_OPTIONS;
+		/** @type {FactoryMeta | undefined} */
+		this.factoryMeta = undefined;
+		// TODO refactor this -> options object filled from Factory
+		// TODO webpack 6: use an enum
+		/** @type {boolean} */
+		this.useSourceMap = false;
+		/** @type {boolean} */
+		this.useSimpleSourceMap = false;
+
+		// Is in hot context, i.e. HotModuleReplacementPlugin.js enabled
+		// TODO do we need hot here?
+		/** @type {boolean} */
+		this.hot = false;
+		// Info from Build
+		/** @type {Error[] | undefined} */
+		this._warnings = undefined;
+		/** @type {Error[] | undefined} */
+		this._errors = undefined;
+		/** @type {BuildMeta | undefined} */
+		this.buildMeta = undefined;
+		/** @type {BuildInfo | undefined} */
+		this.buildInfo = undefined;
+		/** @type {Dependency[] | undefined} */
+		this.presentationalDependencies = undefined;
+		/** @type {Dependency[] | undefined} */
+		this.codeGenerationDependencies = undefined;
+	}
+
+	// TODO remove in webpack 6
+	// BACKWARD-COMPAT START
+	/**
+	 * Returns the module id assigned by the chunk graph.
+	 * @deprecated
+	 * @returns {ModuleId | null} module id
+	 */
+	get id() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.id",
+			"DEP_WEBPACK_MODULE_ID"
+		).getModuleId(this);
+	}
+
+	/**
+	 * Updates the module id using the provided value.
+	 * @deprecated
+	 * @param {ModuleId} value value
+	 */
+	set id(value) {
+		if (value === "") {
+			this.needId = false;
+			return;
+		}
+		ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.id",
+			"DEP_WEBPACK_MODULE_ID"
+		).setModuleId(this, value);
+	}
+
+	/**
+	 * Returns the hash of the module.
+	 * @deprecated
+	 * @returns {string} the hash of the module
+	 */
+	get hash() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.hash",
+			"DEP_WEBPACK_MODULE_HASH"
+		).getModuleHash(this, undefined);
+	}
+
+	/**
+	 * Returns the rendered hash of the module.
+	 * @deprecated
+	 * @returns {string} the shortened hash of the module
+	 */
+	get renderedHash() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.renderedHash",
+			"DEP_WEBPACK_MODULE_RENDERED_HASH"
+		).getRenderedModuleHash(this, undefined);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {ModuleProfile | undefined} module profile
+	 */
+	get profile() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.profile",
+			"DEP_WEBPACK_MODULE_PROFILE"
+		).getProfile(this);
+	}
+
+	/**
+	 * @deprecated
+	 * @param {ModuleProfile | undefined} value module profile
+	 */
+	set profile(value) {
+		ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.profile",
+			"DEP_WEBPACK_MODULE_PROFILE"
+		).setProfile(this, value);
+	}
+
+	/**
+	 * Returns the pre-order index.
+	 * @deprecated
+	 * @returns {number | null} the pre order index
+	 */
+	get index() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.index",
+			"DEP_WEBPACK_MODULE_INDEX"
+		).getPreOrderIndex(this);
+	}
+
+	/**
+	 * Updates the pre-order index using the provided value.
+	 * @deprecated
+	 * @param {number} value the pre order index
+	 */
+	set index(value) {
+		ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.index",
+			"DEP_WEBPACK_MODULE_INDEX"
+		).setPreOrderIndex(this, value);
+	}
+
+	/**
+	 * Returns the post-order index.
+	 * @deprecated
+	 * @returns {number | null} the post order index
+	 */
+	get index2() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.index2",
+			"DEP_WEBPACK_MODULE_INDEX2"
+		).getPostOrderIndex(this);
+	}
+
+	/**
+	 * Updates the post-order index using the provided value.
+	 * @deprecated
+	 * @param {number} value the post order index
+	 */
+	set index2(value) {
+		ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.index2",
+			"DEP_WEBPACK_MODULE_INDEX2"
+		).setPostOrderIndex(this, value);
+	}
+
+	/**
+	 * Returns the depth.
+	 * @deprecated
+	 * @returns {number | null} the depth
+	 */
+	get depth() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.depth",
+			"DEP_WEBPACK_MODULE_DEPTH"
+		).getDepth(this);
+	}
+
+	/**
+	 * Updates the depth using the provided value.
+	 * @deprecated
+	 * @param {number} value the depth
+	 */
+	set depth(value) {
+		ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.depth",
+			"DEP_WEBPACK_MODULE_DEPTH"
+		).setDepth(this, value);
+	}
+
+	/**
+	 * Returns the issuer.
+	 * @deprecated
+	 * @returns {Module | null | undefined} issuer
+	 */
+	get issuer() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.issuer",
+			"DEP_WEBPACK_MODULE_ISSUER"
+		).getIssuer(this);
+	}
+
+	/**
+	 * Updates the issuer using the provided value.
+	 * @deprecated
+	 * @param {Module | null} value issuer
+	 */
+	set issuer(value) {
+		ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.issuer",
+			"DEP_WEBPACK_MODULE_ISSUER"
+		).setIssuer(this, value);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {boolean | SortableSet<string> | null} used exports
+	 */
+	get usedExports() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.usedExports",
+			"DEP_WEBPACK_MODULE_USED_EXPORTS"
+		).getUsedExports(this, undefined);
+	}
+
+	/**
+	 * Gets optimization bailout.
+	 * @deprecated
+	 * @returns {OptimizationBailouts} list
+	 */
+	get optimizationBailout() {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.optimizationBailout",
+			"DEP_WEBPACK_MODULE_OPTIMIZATION_BAILOUT"
+		).getOptimizationBailout(this);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {boolean} true when optional, otherwise false
+	 */
+	get optional() {
+		return this.isOptional(
+			ModuleGraph.getModuleGraphForModule(
+				this,
+				"Module.optional",
+				"DEP_WEBPACK_MODULE_OPTIONAL"
+			)
+		);
+	}
+
+	/**
+	 * Adds the provided chunk to the module.
+	 * @deprecated
+	 * @param {Chunk} chunk the chunk
+	 * @returns {boolean} true, when the module was added
+	 */
+	addChunk(chunk) {
+		const chunkGraph = ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.addChunk",
+			"DEP_WEBPACK_MODULE_ADD_CHUNK"
+		);
+		if (chunkGraph.isModuleInChunk(this, chunk)) return false;
+		chunkGraph.connectChunkAndModule(chunk, this);
+		return true;
+	}
+
+	/**
+	 * Removes the provided chunk from the module.
+	 * @deprecated
+	 * @param {Chunk} chunk the chunk
+	 * @returns {void}
+	 */
+	removeChunk(chunk) {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.removeChunk",
+			"DEP_WEBPACK_MODULE_REMOVE_CHUNK"
+		).disconnectChunkAndModule(chunk, this);
+	}
+
+	/**
+	 * Checks whether this module is in the provided chunk.
+	 * @deprecated
+	 * @param {Chunk} chunk the chunk
+	 * @returns {boolean} true, when the module is in the chunk
+	 */
+	isInChunk(chunk) {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.isInChunk",
+			"DEP_WEBPACK_MODULE_IS_IN_CHUNK"
+		).isModuleInChunk(this, chunk);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {boolean} true when is entry module, otherwise false
+	 */
+	isEntryModule() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.isEntryModule",
+			"DEP_WEBPACK_MODULE_IS_ENTRY_MODULE"
+		).isEntryModule(this);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {Chunk[]} chunks
+	 */
+	getChunks() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.getChunks",
+			"DEP_WEBPACK_MODULE_GET_CHUNKS"
+		).getModuleChunks(this);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {number} number of chunks
+	 */
+	getNumberOfChunks() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.getNumberOfChunks",
+			"DEP_WEBPACK_MODULE_GET_NUMBER_OF_CHUNKS"
+		).getNumberOfModuleChunks(this);
+	}
+
+	/**
+	 * @deprecated
+	 * @returns {Iterable<Chunk>} chunks
+	 */
+	get chunksIterable() {
+		return ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.chunksIterable",
+			"DEP_WEBPACK_MODULE_CHUNKS_ITERABLE"
+		).getOrderedModuleChunksIterable(this, compareChunksById);
+	}
+
+	/**
+	 * Checks whether this module provides the specified export.
+	 * @deprecated
+	 * @param {string} exportName a name of an export
+	 * @returns {boolean | null} true, if the export is provided why the module.
+	 * null, if it's unknown.
+	 * false, if it's not provided.
+	 */
+	isProvided(exportName) {
+		return ModuleGraph.getModuleGraphForModule(
+			this,
+			"Module.usedExports",
+			"DEP_WEBPACK_MODULE_USED_EXPORTS"
+		).isExportProvided(this, exportName);
+	}
+	// BACKWARD-COMPAT END
+
+	/**
+	 * Gets exports argument.
+	 * @returns {string} name of the exports argument
+	 */
+	get exportsArgument() {
+		return (this.buildInfo && this.buildInfo.exportsArgument) || "exports";
+	}
+
+	/**
+	 * Gets module argument.
+	 * @returns {string} name of the module argument
+	 */
+	get moduleArgument() {
+		return (this.buildInfo && this.buildInfo.moduleArgument) || "module";
+	}
+
+	/**
+	 * Returns export type.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {boolean | undefined} strict the importing module is strict
+	 * @returns {ExportsType} export type
+	 * "namespace": Exports is already a namespace object. namespace = exports.
+	 * "dynamic": Check at runtime if __esModule is set. When set: namespace = { ...exports, default: exports }. When not set: namespace = { default: exports }.
+	 * "default-only": Provide a namespace object with only default export. namespace = { default: exports }
+	 * "default-with-named": Provide a namespace object with named and default export. namespace = { ...exports, default: exports }
+	 */
+	getExportsType(moduleGraph, strict) {
+		switch (this.buildMeta && this.buildMeta.exportsType) {
+			case "flagged":
+				return strict ? "default-with-named" : "namespace";
+			case "namespace":
+				return "namespace";
+			case "default":
+				switch (/** @type {BuildMeta} */ (this.buildMeta).defaultObject) {
+					case "redirect":
+						return "default-with-named";
+					case "redirect-warn":
+						return strict ? "default-only" : "default-with-named";
+					default:
+						return "default-only";
+				}
+			case "dynamic": {
+				if (strict) return "default-with-named";
+				// Try to figure out value of __esModule by following reexports
+				const handleDefault = () => {
+					switch (/** @type {BuildMeta} */ (this.buildMeta).defaultObject) {
+						case "redirect":
+						case "redirect-warn":
+							return "default-with-named";
+						default:
+							return "default-only";
+					}
+				};
+				const exportInfo = moduleGraph.getReadOnlyExportInfo(
+					this,
+					"__esModule"
+				);
+				if (exportInfo.provided === false) {
+					return handleDefault();
+				}
+				const target = exportInfo.getTarget(moduleGraph);
+				if (
+					!target ||
+					!target.export ||
+					target.export.length !== 1 ||
+					target.export[0] !== "__esModule"
+				) {
+					return "dynamic";
+				}
+				switch (
+					target.module.buildMeta &&
+					target.module.buildMeta.exportsType
+				) {
+					case "flagged":
+					case "namespace":
+						return "namespace";
+					case "default":
+						return handleDefault();
+					default:
+						return "dynamic";
+				}
+			}
+			default:
+				return strict ? "default-with-named" : "dynamic";
+		}
+	}
+
+	/**
+	 * Adds presentational dependency.
+	 * @param {Dependency} presentationalDependency dependency being tied to module.
+	 * This is a Dependency without edge in the module graph. It's only for presentation.
+	 * @returns {void}
+	 */
+	addPresentationalDependency(presentationalDependency) {
+		if (this.presentationalDependencies === undefined) {
+			this.presentationalDependencies = [];
+		}
+		this.presentationalDependencies.push(presentationalDependency);
+	}
+
+	/**
+	 * Adds code generation dependency.
+	 * @param {Dependency} codeGenerationDependency dependency being tied to module.
+	 * This is a Dependency where the code generation result of the referenced module is needed during code generation.
+	 * The Dependency should also be added to normal dependencies via addDependency.
+	 * @returns {void}
+	 */
+	addCodeGenerationDependency(codeGenerationDependency) {
+		if (this.codeGenerationDependencies === undefined) {
+			this.codeGenerationDependencies = [];
+		}
+		this.codeGenerationDependencies.push(codeGenerationDependency);
+	}
+
+	/**
+	 * Clear dependencies and blocks.
+	 * @returns {void}
+	 */
+	clearDependenciesAndBlocks() {
+		if (this.presentationalDependencies !== undefined) {
+			this.presentationalDependencies.length = 0;
+		}
+		if (this.codeGenerationDependencies !== undefined) {
+			this.codeGenerationDependencies.length = 0;
+		}
+		super.clearDependenciesAndBlocks();
+	}
+
+	/**
+	 * Adds the provided warning to the module.
+	 * @param {Error} warning the warning
+	 * @returns {void}
+	 */
+	addWarning(warning) {
+		if (this._warnings === undefined) {
+			this._warnings = [];
+		}
+		this._warnings.push(warning);
+	}
+
+	/**
+	 * Returns list of warnings if any.
+	 * @returns {Error[] | undefined} list of warnings if any
+	 */
+	getWarnings() {
+		return this._warnings;
+	}
+
+	/**
+	 * Gets number of warnings.
+	 * @returns {number} number of warnings
+	 */
+	getNumberOfWarnings() {
+		return this._warnings !== undefined ? this._warnings.length : 0;
+	}
+
+	/**
+	 * Adds the provided error to the module.
+	 * @param {Error} error the error
+	 * @returns {void}
+	 */
+	addError(error) {
+		if (this._errors === undefined) {
+			this._errors = [];
+		}
+		this._errors.push(error);
+	}
+
+	/**
+	 * Returns list of errors if any.
+	 * @returns {Error[] | undefined} list of errors if any
+	 */
+	getErrors() {
+		return this._errors;
+	}
+
+	/**
+	 * Gets number of errors.
+	 * @returns {number} number of errors
+	 */
+	getNumberOfErrors() {
+		return this._errors !== undefined ? this._errors.length : 0;
+	}
+
+	/**
+	 * removes all warnings and errors
+	 * @returns {void}
+	 */
+	clearWarningsAndErrors() {
+		if (this._warnings !== undefined) {
+			this._warnings.length = 0;
+		}
+		if (this._errors !== undefined) {
+			this._errors.length = 0;
+		}
+	}
+
+	/**
+	 * Checks whether this module is optional.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {boolean} true, if the module is optional
+	 */
+	isOptional(moduleGraph) {
+		let hasConnections = false;
+		for (const r of moduleGraph.getIncomingConnections(this)) {
+			if (
+				!r.dependency ||
+				!r.dependency.optional ||
+				!r.isTargetActive(undefined)
+			) {
+				return false;
+			}
+			hasConnections = true;
+		}
+		return hasConnections;
+	}
+
+	/**
+	 * Checks whether this module is accessible in chunk.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {Chunk} chunk a chunk
+	 * @param {Chunk=} ignoreChunk chunk to be ignored
+	 * @returns {boolean} true, if the module is accessible from "chunk" when ignoring "ignoreChunk"
+	 */
+	isAccessibleInChunk(chunkGraph, chunk, ignoreChunk) {
+		// Check if module is accessible in ALL chunk groups
+		for (const chunkGroup of chunk.groupsIterable) {
+			if (!this.isAccessibleInChunkGroup(chunkGraph, chunkGroup)) return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Checks whether this module is accessible in chunk group.
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {ChunkGroup} chunkGroup a chunk group
+	 * @param {Chunk=} ignoreChunk chunk to be ignored
+	 * @returns {boolean} true, if the module is accessible from "chunkGroup" when ignoring "ignoreChunk"
+	 */
+	isAccessibleInChunkGroup(chunkGraph, chunkGroup, ignoreChunk) {
+		const queue = new Set([chunkGroup]);
+
+		// Check if module is accessible from all items of the queue
+		queueFor: for (const cg of queue) {
+			// 1. If module is in one of the chunks of the group we can continue checking the next items
+			//    because it's accessible.
+			for (const chunk of cg.chunks) {
+				if (chunk !== ignoreChunk && chunkGraph.isModuleInChunk(this, chunk)) {
+					continue queueFor;
+				}
+			}
+			// 2. If the chunk group is initial, we can break here because it's not accessible.
+			if (chunkGroup.isInitial()) return false;
+			// 3. Enqueue all parents because it must be accessible from ALL parents
+			for (const parent of chunkGroup.parentsIterable) queue.add(parent);
+		}
+		// When we processed through the whole list and we didn't bailout, the module is accessible
+		return true;
+	}
+
+	/**
+	 * Checks whether this module contains the chunk.
+	 * @param {Chunk} chunk a chunk
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {boolean} true, if the module has any reason why "chunk" should be included
+	 */
+	hasReasonForChunk(chunk, moduleGraph, chunkGraph) {
+		// check for each reason if we need the chunk
+		for (const [
+			fromModule,
+			connections
+		] of moduleGraph.getIncomingConnectionsByOriginModule(this)) {
+			if (!connections.some((c) => c.isTargetActive(chunk.runtime))) continue;
+			for (const originChunk of chunkGraph.getModuleChunksIterable(
+				/** @type {Module} */ (fromModule)
+			)) {
+				// return true if module this is not reachable from originChunk when ignoring chunk
+				if (!this.isAccessibleInChunk(chunkGraph, originChunk, chunk)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether this module contains the module graph.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true if at least one other module depends on this module
+	 */
+	hasReasons(moduleGraph, runtime) {
+		for (const c of moduleGraph.getIncomingConnections(this)) {
+			if (c.isTargetActive(runtime)) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns a string representation.
+	 * @returns {string} for debugging
+	 */
+	toString() {
+		return `Module[${this.debugId}: ${this.identifier()}]`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		callback(
+			null,
+			!this.buildMeta ||
+				this.needRebuild === Module.prototype.needRebuild ||
+				deprecatedNeedRebuild(this, context)
+		);
+	}
+
+	/**
+	 * Checks whether it needs rebuild.
+	 * @deprecated Use needBuild instead
+	 * @param {Map<string, number | null>} fileTimestamps timestamps of files
+	 * @param {Map<string, number | null>} contextTimestamps timestamps of directories
+	 * @returns {boolean} true, if the module needs a rebuild
+	 */
+	needRebuild(fileTimestamps, contextTimestamps) {
+		return true;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(
+		hash,
+		context = {
+			chunkGraph: ChunkGraph.getChunkGraphForModule(
+				this,
+				"Module.updateHash",
+				"DEP_WEBPACK_MODULE_UPDATE_HASH"
+			),
+			runtime: undefined
+		}
+	) {
+		const { chunkGraph, runtime } = context;
+		hash.update(chunkGraph.getModuleGraphHash(this, runtime));
+		if (this.presentationalDependencies !== undefined) {
+			for (const dep of this.presentationalDependencies) {
+				dep.updateHash(hash, context);
+			}
+		}
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Invalidates the cached state associated with this value.
+	 * @returns {void}
+	 */
+	invalidateBuild() {
+		// should be overridden to support this feature
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @abstract
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @abstract
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @abstract
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @abstract
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		// Better override this method to return the correct types
+		if (this.source === Module.prototype.source) {
+			return DEFAULT_TYPES_UNKNOWN;
+		}
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Basic source types are high-level categories like javascript, css, webassembly, etc.
+	 * We only have built-in knowledge about the javascript basic type here; other basic types may be
+	 * added or changed over time by generators and do not need to be handled or detected here.
+	 *
+	 * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
+	 * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
+	 * @returns {BasicSourceTypes} types available (do not mutate)
+	 */
+	getSourceBasicTypes() {
+		return this.getSourceTypes();
+	}
+
+	/**
+	 * Returns generated source.
+	 * @abstract
+	 * @deprecated Use codeGeneration() instead
+	 * @param {DependencyTemplates} dependencyTemplates the dependency templates
+	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
+	 * @param {SourceType=} type the type of source that should be generated
+	 * @returns {Source} generated source
+	 */
+	source(dependencyTemplates, runtimeTemplate, type = JAVASCRIPT_TYPE) {
+		if (this.codeGeneration === Module.prototype.codeGeneration) {
+			const AbstractMethodError = require("./errors/AbstractMethodError");
+
+			throw new AbstractMethodError();
+		}
+		const chunkGraph = ChunkGraph.getChunkGraphForModule(
+			this,
+			"Module.source() is deprecated. Use Compilation.codeGenerationResults.getSource(module, runtime, type) instead",
+			"DEP_WEBPACK_MODULE_SOURCE"
+		);
+		/** @type {CodeGenerationContext} */
+		const codeGenContext = {
+			dependencyTemplates,
+			runtimeTemplate,
+			moduleGraph: chunkGraph.moduleGraph,
+			chunkGraph,
+			runtime: undefined,
+			runtimes: [],
+			codeGenerationResults: undefined
+		};
+		const sources = this.codeGeneration(codeGenContext).sources;
+
+		return /** @type {Source} */ (
+			type
+				? sources.get(type)
+				: sources.get(/** @type {SourceType} */ (first(this.getSourceTypes())))
+		);
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @abstract
+	 * @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) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return null;
+	}
+
+	/**
+	 * Returns the path used when matching this module against rule conditions.
+	 * @returns {NameForCondition | null} absolute path which should be used for condition matching (usually the resource path)
+	 */
+	nameForCondition() {
+		return null;
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(context) {
+		return `Module Concatenation is not implemented for ${this.constructor.name}`;
+	}
+
+	/**
+	 * Gets side effects connection state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only
+	 */
+	getSideEffectsConnectionState(moduleGraph) {
+		return true;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration(context) {
+		// Best override this method
+		/** @type {Sources} */
+		const sources = new Map();
+		for (const type of this.getSourceTypes()) {
+			if (type !== UNKNOWN_TYPE) {
+				sources.set(
+					type,
+					this.source(
+						context.dependencyTemplates,
+						context.runtimeTemplate,
+						type
+					)
+				);
+			}
+		}
+		return {
+			sources,
+			runtimeRequirements: new Set([
+				RuntimeGlobals.module,
+				RuntimeGlobals.exports,
+				RuntimeGlobals.require
+			])
+		};
+	}
+
+	/**
+	 * Returns true if the module can be placed in the chunk.
+	 * @param {Chunk} chunk the chunk which condition should be checked
+	 * @param {Compilation} compilation the compilation
+	 * @returns {boolean} true if the module can be placed in the chunk
+	 */
+	chunkCondition(chunk, compilation) {
+		return true;
+	}
+
+	hasChunkCondition() {
+		return this.chunkCondition !== Module.prototype.chunkCondition;
+	}
+
+	/**
+	 * 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) {
+		this.type = module.type;
+		this.layer = module.layer;
+		this.context = module.context;
+		this.factoryMeta = module.factoryMeta;
+		this.resolveOptions = module.resolveOptions;
+	}
+
+	/**
+	 * Module should be unsafe cached. Get data that's needed for that.
+	 * This data will be passed to restoreFromUnsafeCache later.
+	 * @returns {UnsafeCacheData} cached data
+	 */
+	getUnsafeCacheData() {
+		return {
+			factoryMeta: this.factoryMeta,
+			resolveOptions: this.resolveOptions
+		};
+	}
+
+	/**
+	 * restore unsafe cache data
+	 * @param {UnsafeCacheData} unsafeCacheData data from getUnsafeCacheData
+	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
+	 */
+	_restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
+		this.factoryMeta = unsafeCacheData.factoryMeta;
+		this.resolveOptions = unsafeCacheData.resolveOptions;
+	}
+
+	/**
+	 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
+	 */
+	cleanupForCache() {
+		this.factoryMeta = undefined;
+		this.resolveOptions = undefined;
+	}
+
+	/**
+	 * Gets the original source.
+	 * @returns {Source | null} the original source for the module before webpack transformation
+	 */
+	originalSource() {
+		return null;
+	}
+
+	/**
+	 * Adds the provided file dependencies to the module.
+	 * @param {FileSystemDependencies} fileDependencies set where file dependencies are added to
+	 * @param {FileSystemDependencies} contextDependencies set where context dependencies are added to
+	 * @param {FileSystemDependencies} missingDependencies set where missing dependencies are added to
+	 * @param {FileSystemDependencies} buildDependencies set where build dependencies are added to
+	 */
+	addCacheDependencies(
+		fileDependencies,
+		contextDependencies,
+		missingDependencies,
+		buildDependencies
+	) {}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.type);
+		write(this.layer);
+		write(this.context);
+		write(this.resolveOptions);
+		write(this.factoryMeta);
+		write(this.useSourceMap);
+		write(this.useSimpleSourceMap);
+		write(this.hot);
+		write(
+			this._warnings !== undefined && this._warnings.length === 0
+				? undefined
+				: this._warnings
+		);
+		write(
+			this._errors !== undefined && this._errors.length === 0
+				? undefined
+				: this._errors
+		);
+		write(this.buildMeta);
+		write(this.buildInfo);
+		write(this.presentationalDependencies);
+		write(this.codeGenerationDependencies);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.type = read();
+		this.layer = read();
+		this.context = read();
+		this.resolveOptions = read();
+		this.factoryMeta = read();
+		this.useSourceMap = read();
+		this.useSimpleSourceMap = read();
+		this.hot = read();
+		this._warnings = read();
+		this._errors = read();
+		this.buildMeta = read();
+		this.buildInfo = read();
+		this.presentationalDependencies = read();
+		this.codeGenerationDependencies = read();
+		super.deserialize(context);
+	}
+
+	// TODO remove in webpack 6
+	/**
+	 * Gets source basic types.
+	 * @deprecated In webpack 6, call getSourceBasicTypes() directly on the module instance instead of using this static method.
+	 * @param {Module} module the module
+	 * @returns {ReturnType<Module["getSourceBasicTypes"]>} the source types of the module
+	 */
+	static getSourceBasicTypes(module) {
+		if (!(module instanceof Module)) {
+			// https://github.com/webpack/webpack/issues/20597
+			// fallback to javascript
+			return JAVASCRIPT_TYPES;
+		}
+		return module.getSourceBasicTypes();
+	}
+}
+
+makeSerializable(Module, "webpack/lib/Module");
+
+// TODO remove in webpack 6
+Object.defineProperty(Module.prototype, "hasEqualsChunks", {
+	/**
+	 * Gets has equals chunks.
+	 * @deprecated
+	 * @returns {EXPECTED_ANY} throw an error
+	 */
+	get() {
+		throw new Error(
+			"Module.hasEqualsChunks was renamed (use hasEqualChunks instead)"
+		);
+	}
+});
+
+// TODO remove in webpack 6
+Object.defineProperty(Module.prototype, "isUsed", {
+	/**
+	 * Returns throw an error.
+	 * @deprecated
+	 * @returns {EXPECTED_ANY} throw an error
+	 */
+	get() {
+		throw new Error(
+			"Module.isUsed was renamed (use getUsedName, isExportUsed or isModuleUsed instead)"
+		);
+	}
+});
+
+// TODO remove in webpack 6
+Object.defineProperty(Module.prototype, "errors", {
+	/**
+	 * Returns errors.
+	 * @deprecated
+	 * @returns {Error[]} errors
+	 */
+	get: util.deprecate(
+		/**
+		 * Returns errors.
+		 * @this {Module}
+		 * @returns {Error[]} errors
+		 */
+		function errors() {
+			if (this._errors === undefined) {
+				this._errors = [];
+			}
+			return this._errors;
+		},
+		"Module.errors was removed (use getErrors instead)",
+		"DEP_WEBPACK_MODULE_ERRORS"
+	)
+});
+
+// TODO remove in webpack 6
+Object.defineProperty(Module.prototype, "warnings", {
+	/**
+	 * Returns warnings.
+	 * @deprecated
+	 * @returns {Error[]} warnings
+	 */
+	get: util.deprecate(
+		/**
+		 * Returns warnings.
+		 * @this {Module}
+		 * @returns {Error[]} warnings
+		 */
+		function warnings() {
+			if (this._warnings === undefined) {
+				this._warnings = [];
+			}
+			return this._warnings;
+		},
+		"Module.warnings was removed (use getWarnings instead)",
+		"DEP_WEBPACK_MODULE_WARNINGS"
+	)
+});
+
+// TODO remove in webpack 6
+Object.defineProperty(Module.prototype, "used", {
+	/**
+	 * Returns throw an error.
+	 * @deprecated
+	 * @returns {EXPECTED_ANY} throw an error
+	 */
+	get() {
+		throw new Error(
+			"Module.used was refactored (use ModuleGraph.getUsedExports instead)"
+		);
+	},
+	/**
+	 * Updates used using the provided value.
+	 * @param {EXPECTED_ANY} value value
+	 */
+	set(value) {
+		throw new Error(
+			"Module.used was refactored (use ModuleGraph.setUsedExports instead)"
+		);
+	}
+});
+
+module.exports = Module;
Index: frontend/node_modules/webpack/lib/ModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,62 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Module")} Module */
+
+/**
+ * Defines the module factory result type used by this module.
+ * @typedef {object} ModuleFactoryResult
+ * @property {Module=} module the created module or unset if no module was created
+ * @property {Set<string>=} fileDependencies
+ * @property {Set<string>=} contextDependencies
+ * @property {Set<string>=} missingDependencies
+ * @property {boolean=} cacheable allow to use the unsafe cache
+ */
+
+/** @typedef {string | null} IssuerLayer */
+
+/**
+ * Defines the module factory create data context info type used by this module.
+ * @typedef {object} ModuleFactoryCreateDataContextInfo
+ * @property {string} issuer
+ * @property {IssuerLayer} issuerLayer
+ * @property {string=} compiler
+ */
+
+/**
+ * Defines the module factory create data type used by this module.
+ * @typedef {object} ModuleFactoryCreateData
+ * @property {ModuleFactoryCreateDataContextInfo} contextInfo
+ * @property {ResolveOptions=} resolveOptions
+ * @property {string} context
+ * @property {Dependency[]} dependencies
+ */
+
+/**
+ * Represents the module factory runtime component.
+ * @typedef {(err?: Error | null, result?: ModuleFactoryResult) => void} ModuleFactoryCallback
+ */
+
+class ModuleFactory {
+	/* istanbul ignore next */
+	/**
+	 * Processes the provided data.
+	 * @abstract
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+}
+
+module.exports = ModuleFactory;
Index: frontend/node_modules/webpack/lib/ModuleFilenameHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleFilenameHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleFilenameHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,391 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const NormalModule = require("./NormalModule");
+const { DEFAULTS } = require("./config/defaults");
+const createHash = require("./util/createHash");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+
+/** @typedef {(str: string) => boolean} MatcherFn */
+/** @typedef {string | RegExp | MatcherFn | (string | RegExp | MatcherFn)[]} Matcher */
+/** @typedef {{ test?: Matcher, include?: Matcher, exclude?: Matcher }} MatchObject */
+
+const ModuleFilenameHelpers = module.exports;
+
+// TODO webpack 6: consider removing these
+ModuleFilenameHelpers.ALL_LOADERS_RESOURCE = "[all-loaders][resource]";
+ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE =
+	/\[all-?loaders\]\[resource\]/gi;
+ModuleFilenameHelpers.LOADERS_RESOURCE = "[loaders][resource]";
+ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE = /\[loaders\]\[resource\]/gi;
+ModuleFilenameHelpers.RESOURCE = "[resource]";
+ModuleFilenameHelpers.REGEXP_RESOURCE = /\[resource\]/gi;
+ModuleFilenameHelpers.ABSOLUTE_RESOURCE_PATH = "[absolute-resource-path]";
+// cSpell:words olute
+ModuleFilenameHelpers.REGEXP_ABSOLUTE_RESOURCE_PATH =
+	/\[abs(olute)?-?resource-?path\]/gi;
+ModuleFilenameHelpers.RESOURCE_PATH = "[resource-path]";
+ModuleFilenameHelpers.REGEXP_RESOURCE_PATH = /\[resource-?path\]/gi;
+ModuleFilenameHelpers.ALL_LOADERS = "[all-loaders]";
+ModuleFilenameHelpers.REGEXP_ALL_LOADERS = /\[all-?loaders\]/gi;
+ModuleFilenameHelpers.LOADERS = "[loaders]";
+ModuleFilenameHelpers.REGEXP_LOADERS = /\[loaders\]/gi;
+ModuleFilenameHelpers.QUERY = "[query]";
+ModuleFilenameHelpers.REGEXP_QUERY = /\[query\]/gi;
+ModuleFilenameHelpers.ID = "[id]";
+ModuleFilenameHelpers.REGEXP_ID = /\[id\]/gi;
+ModuleFilenameHelpers.HASH = "[hash]";
+ModuleFilenameHelpers.REGEXP_HASH = /\[hash\]/gi;
+ModuleFilenameHelpers.NAMESPACE = "[namespace]";
+ModuleFilenameHelpers.REGEXP_NAMESPACE = /\[namespace\]/gi;
+
+/** @typedef {() => string} ReturnStringCallback */
+
+/**
+ * Returns a function that returns the part of the string after the token
+ * @param {ReturnStringCallback} strFn the function to get the string
+ * @param {string} token the token to search for
+ * @returns {ReturnStringCallback} a function that returns the part of the string after the token
+ */
+const getAfter = (strFn, token) => () => {
+	const str = strFn();
+	const idx = str.indexOf(token);
+	return idx < 0 ? "" : str.slice(idx);
+};
+
+/**
+ * Returns a function that returns the part of the string before the token
+ * @param {ReturnStringCallback} strFn the function to get the string
+ * @param {string} token the token to search for
+ * @returns {ReturnStringCallback} a function that returns the part of the string before the token
+ */
+const getBefore = (strFn, token) => () => {
+	const str = strFn();
+	const idx = str.lastIndexOf(token);
+	return idx < 0 ? "" : str.slice(0, idx);
+};
+
+/**
+ * Returns a function that returns a hash of the string
+ * @param {ReturnStringCallback} strFn the function to get the string
+ * @param {HashFunction=} hashFunction the hash function to use
+ * @returns {ReturnStringCallback} a function that returns the hash of the string
+ */
+const getHash =
+	(strFn, hashFunction = DEFAULTS.HASH_FUNCTION) =>
+	() => {
+		const hash = createHash(hashFunction);
+		hash.update(strFn());
+		const digest = hash.digest("hex");
+		return digest.slice(0, 4);
+	};
+
+/**
+ * Returns the lazy access object.
+ * @template T
+ * Returns a lazy object. The object is lazy in the sense that the properties are
+ * only evaluated when they are accessed. This is only obtained by setting a function as the value for each key.
+ * @param {Record<string, () => T>} obj the object to convert to a lazy access object
+ * @returns {Record<string, T>} the lazy access object
+ */
+const lazyObject = (obj) => {
+	const newObj = /** @type {Record<string, T>} */ ({});
+	for (const key of Object.keys(obj)) {
+		const fn = obj[key];
+		Object.defineProperty(newObj, key, {
+			get: () => fn(),
+			set: (v) => {
+				Object.defineProperty(newObj, key, {
+					value: v,
+					enumerable: true,
+					writable: true
+				});
+			},
+			enumerable: true,
+			configurable: true
+		});
+	}
+	return newObj;
+};
+
+const SQUARE_BRACKET_TAG_REGEXP = /\[\\*([\w-]+)\\*\]/g;
+/**
+ * Defines the module filename template context type used by this module.
+ * @typedef {object} ModuleFilenameTemplateContext
+ * @property {string} identifier the identifier of the module
+ * @property {string} shortIdentifier the shortened identifier of the module
+ * @property {string} resource the resource of the module request
+ * @property {string} resourcePath the resource path of the module request
+ * @property {string} absoluteResourcePath the absolute resource path of the module request
+ * @property {string} loaders the loaders of the module request
+ * @property {string} allLoaders the all loaders of the module request
+ * @property {string} query the query of the module identifier
+ * @property {string} moduleId the module id of the module
+ * @property {string} hash the hash of the module identifier
+ * @property {string} namespace the module namespace
+ */
+/** @typedef {((context: ModuleFilenameTemplateContext) => string)} ModuleFilenameTemplateFunction */
+/** @typedef {string | ModuleFilenameTemplateFunction} ModuleFilenameTemplate */
+
+/**
+ * Returns the filename.
+ * @param {Module | string} module the module
+ * @param {{ namespace?: string, moduleFilenameTemplate?: ModuleFilenameTemplate }} options options
+ * @param {{ requestShortener: RequestShortener, chunkGraph: ChunkGraph, hashFunction?: HashFunction }} contextInfo context info
+ * @returns {string} the filename
+ */
+ModuleFilenameHelpers.createFilename = (
+	// eslint-disable-next-line default-param-last
+	module = "",
+	options,
+	{ requestShortener, chunkGraph, hashFunction = DEFAULTS.HASH_FUNCTION }
+) => {
+	const opts = {
+		namespace: "",
+		moduleFilenameTemplate: "",
+		...(typeof options === "object"
+			? options
+			: {
+					moduleFilenameTemplate: options
+				})
+	};
+
+	/** @type {ReturnStringCallback} */
+	let absoluteResourcePath;
+	/** @type {ReturnStringCallback} */
+	let hash;
+	/** @type {ReturnStringCallback} */
+	let identifier;
+	/** @type {ReturnStringCallback} */
+	let moduleId;
+	/** @type {ReturnStringCallback} */
+	let shortIdentifier;
+	if (typeof module === "string") {
+		shortIdentifier =
+			/** @type {ReturnStringCallback} */
+			(memoize(() => requestShortener.shorten(module)));
+		identifier = shortIdentifier;
+		moduleId = () => "";
+		absoluteResourcePath = () =>
+			/** @type {string} */ (module.split("!").pop());
+		hash = getHash(identifier, hashFunction);
+	} else {
+		shortIdentifier = memoize(() =>
+			module.readableIdentifier(requestShortener)
+		);
+		identifier =
+			/** @type {ReturnStringCallback} */
+			(memoize(() => requestShortener.shorten(module.identifier())));
+		moduleId =
+			/** @type {ReturnStringCallback} */
+			(() => chunkGraph.getModuleId(module));
+		absoluteResourcePath = () =>
+			module instanceof NormalModule
+				? module.resource
+				: /** @type {string} */ (module.identifier().split("!").pop());
+		hash = getHash(identifier, hashFunction);
+	}
+	const resource =
+		/** @type {ReturnStringCallback} */
+		(memoize(() => shortIdentifier().split("!").pop()));
+
+	const loaders = getBefore(shortIdentifier, "!");
+	const allLoaders = getBefore(identifier, "!");
+	const query = getAfter(resource, "?");
+	const resourcePath = () => {
+		const q = query().length;
+		return q === 0 ? resource() : resource().slice(0, -q);
+	};
+	if (typeof opts.moduleFilenameTemplate === "function") {
+		return opts.moduleFilenameTemplate(
+			/** @type {ModuleFilenameTemplateContext} */
+			(
+				lazyObject({
+					identifier,
+					shortIdentifier,
+					resource,
+					resourcePath: memoize(resourcePath),
+					absoluteResourcePath: memoize(absoluteResourcePath),
+					loaders: memoize(loaders),
+					allLoaders: memoize(allLoaders),
+					query: memoize(query),
+					moduleId: memoize(moduleId),
+					hash: memoize(hash),
+					namespace: () => opts.namespace
+				})
+			)
+		);
+	}
+
+	// TODO webpack 6: consider removing alternatives without dashes
+	/** @type {Map<string, () => string>} */
+	const replacements = new Map([
+		["identifier", identifier],
+		["short-identifier", shortIdentifier],
+		["resource", resource],
+		["resource-path", resourcePath],
+		// cSpell:words resourcepath
+		["resourcepath", resourcePath],
+		["absolute-resource-path", absoluteResourcePath],
+		["abs-resource-path", absoluteResourcePath],
+		// cSpell:words absoluteresource
+		["absoluteresource-path", absoluteResourcePath],
+		// cSpell:words absresource
+		["absresource-path", absoluteResourcePath],
+		// cSpell:words resourcepath
+		["absolute-resourcepath", absoluteResourcePath],
+		// cSpell:words resourcepath
+		["abs-resourcepath", absoluteResourcePath],
+		// cSpell:words absoluteresourcepath
+		["absoluteresourcepath", absoluteResourcePath],
+		// cSpell:words absresourcepath
+		["absresourcepath", absoluteResourcePath],
+		["all-loaders", allLoaders],
+		// cSpell:words allloaders
+		["allloaders", allLoaders],
+		["loaders", loaders],
+		["query", query],
+		["id", moduleId],
+		["hash", hash],
+		["namespace", () => opts.namespace]
+	]);
+
+	// TODO webpack 6: consider removing weird double placeholders
+	return /** @type {string} */ (opts.moduleFilenameTemplate)
+		.replace(ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE, "[identifier]")
+		.replace(
+			ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE,
+			"[short-identifier]"
+		)
+		.replace(SQUARE_BRACKET_TAG_REGEXP, (match, content) => {
+			if (content.length + 2 === match.length) {
+				const replacement = replacements.get(content.toLowerCase());
+				if (replacement !== undefined) {
+					return replacement();
+				}
+			} else if (match.startsWith("[\\") && match.endsWith("\\]")) {
+				return `[${match.slice(2, -2)}]`;
+			}
+			return match;
+		});
+};
+
+/**
+ * Replaces duplicate items in an array with new values generated by a callback function.
+ * The callback function is called with the duplicate item, the index of the duplicate item, and the number of times the item has been replaced.
+ * The callback function should return the new value for the duplicate item.
+ * @template T
+ * @param {T[]} array the array with duplicates to be replaced
+ * @param {(duplicateItem: T, duplicateItemIndex: number, numberOfTimesReplaced: number) => T} fn callback function to generate new values for the duplicate items
+ * @param {(firstElement: T, nextElement: T) => -1 | 0 | 1=} comparator optional comparator function to sort the duplicate items
+ * @returns {T[]} the array with duplicates replaced
+ * @example
+ * ```js
+ * const array = ["a", "b", "c", "a", "b", "a"];
+ * const result = ModuleFilenameHelpers.replaceDuplicates(array, (item, index, count) => `${item}-${count}`);
+ * // result: ["a-1", "b-1", "c", "a-2", "b-2", "a-3"]
+ * ```
+ */
+ModuleFilenameHelpers.replaceDuplicates = (array, fn, comparator) => {
+	const countMap = Object.create(null);
+	const posMap = Object.create(null);
+
+	for (const [idx, item] of array.entries()) {
+		countMap[item] = countMap[item] || [];
+		countMap[item].push(idx);
+		posMap[item] = 0;
+	}
+	if (comparator) {
+		for (const item of Object.keys(countMap)) {
+			countMap[item].sort(comparator);
+		}
+	}
+	return array.map((item, i) => {
+		if (countMap[item].length > 1) {
+			if (comparator && countMap[item][0] === i) return item;
+			return fn(item, i, posMap[item]++);
+		}
+		return item;
+	});
+};
+
+/**
+ * Tests if a string matches a RegExp or an array of RegExp.
+ * @param {string} str string to test
+ * @param {Matcher} test value which will be used to match against the string
+ * @returns {boolean} true, when the RegExp matches
+ * @example
+ * ```js
+ * ModuleFilenameHelpers.matchPart("foo.js", "foo"); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", "foo.js"); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", "foo."); // false
+ * ModuleFilenameHelpers.matchPart("foo.js", "foo*"); // false
+ * ModuleFilenameHelpers.matchPart("foo.js", "foo.*"); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", /^foo/); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, "bar"]); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, "bar"]); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, /^bar/]); // true
+ * ModuleFilenameHelpers.matchPart("foo.js", [/^baz/, /^bar/]); // false
+ * ```
+ */
+const matchPart = (str, test) => {
+	if (!test) return true;
+	if (test instanceof RegExp) {
+		return test.test(str);
+	} else if (typeof test === "string") {
+		return str.startsWith(test);
+	} else if (typeof test === "function") {
+		return test(str);
+	}
+
+	return test.some((test) => matchPart(str, test));
+};
+
+ModuleFilenameHelpers.matchPart = matchPart;
+
+/**
+ * Tests if a string matches a match object. The match object can have the following properties:
+ * - `test`: a RegExp or an array of RegExp
+ * - `include`: a RegExp or an array of RegExp
+ * - `exclude`: a RegExp or an array of RegExp
+ *
+ * The `test` property is tested first, then `include` and then `exclude`.
+ * @param {MatchObject} obj a match object to test against the string
+ * @param {string} str string to test against the matching object
+ * @returns {boolean} true, when the object matches
+ * @example
+ * ```js
+ * ModuleFilenameHelpers.matchObject({ test: "foo.js" }, "foo.js"); // true
+ * ModuleFilenameHelpers.matchObject({ test: /^foo/ }, "foo.js"); // true
+ * ModuleFilenameHelpers.matchObject({ test: [/^foo/, "bar"] }, "foo.js"); // true
+ * ModuleFilenameHelpers.matchObject({ test: [/^foo/, "bar"] }, "baz.js"); // false
+ * ModuleFilenameHelpers.matchObject({ include: "foo.js" }, "foo.js"); // true
+ * ModuleFilenameHelpers.matchObject({ include: "foo.js" }, "bar.js"); // false
+ * ModuleFilenameHelpers.matchObject({ include: /^foo/ }, "foo.js"); // true
+ * ModuleFilenameHelpers.matchObject({ include: [/^foo/, "bar"] }, "foo.js"); // true
+ * ModuleFilenameHelpers.matchObject({ include: [/^foo/, "bar"] }, "baz.js"); // false
+ * ModuleFilenameHelpers.matchObject({ exclude: "foo.js" }, "foo.js"); // false
+ * ModuleFilenameHelpers.matchObject({ exclude: [/^foo/, "bar"] }, "foo.js"); // false
+ * ```
+ */
+ModuleFilenameHelpers.matchObject = (obj, str) => {
+	if (obj.test && !ModuleFilenameHelpers.matchPart(str, obj.test)) {
+		return false;
+	}
+	if (obj.include && !ModuleFilenameHelpers.matchPart(str, obj.include)) {
+		return false;
+	}
+	if (obj.exclude && ModuleFilenameHelpers.matchPart(str, obj.exclude)) {
+		return false;
+	}
+	return true;
+};
Index: frontend/node_modules/webpack/lib/ModuleGraph.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1093 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const ExportsInfo = require("./ExportsInfo");
+const ModuleGraphConnection = require("./ModuleGraphConnection");
+const HarmonyImportDependency = require("./dependencies/HarmonyImportDependency");
+const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
+const SortableSet = require("./util/SortableSet");
+const WeakTupleMap = require("./util/WeakTupleMap");
+const { sortWithSourceOrder } = require("./util/comparators");
+
+/** @typedef {import("./Compilation").ModuleMemCaches} ModuleMemCaches */
+/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("./ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleProfile")} ModuleProfile */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
+/** @typedef {import("./dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
+/** @typedef {import("./util/comparators").DependencySourceOrder} DependencySourceOrder */
+
+/**
+ * Defines the optimization bailout function callback.
+ * @callback OptimizationBailoutFunction
+ * @param {RequestShortener} requestShortener
+ * @returns {string}
+ */
+
+/** @type {Iterable<ModuleGraphConnection>} */
+const EMPTY_SET = new Set();
+
+/**
+ * Gets connections by key.
+ * @template {Module | null | undefined} T
+ * @param {SortableSet<ModuleGraphConnection>} set input
+ * @param {(connection: ModuleGraphConnection) => T} getKey function to extract key from connection
+ * @returns {ReadonlyMap<T, ReadonlyArray<ModuleGraphConnection>>} mapped by key
+ */
+const getConnectionsByKey = (set, getKey) => {
+	/** @type {Map<T, ModuleGraphConnection[]>} */
+	const map = new Map();
+	/** @type {T | 0} */
+	let lastKey = 0;
+	/** @type {ModuleGraphConnection[] | undefined} */
+	let lastList;
+	for (const connection of set) {
+		const key = getKey(connection);
+		if (lastKey === key) {
+			/** @type {ModuleGraphConnection[]} */
+			(lastList).push(connection);
+		} else {
+			lastKey = key;
+			const list = map.get(key);
+			if (list !== undefined) {
+				lastList = list;
+				list.push(connection);
+			} else {
+				const list = [connection];
+				lastList = list;
+				map.set(key, list);
+			}
+		}
+	}
+	return map;
+};
+
+/**
+ * Gets connections by origin module.
+ * @param {SortableSet<ModuleGraphConnection>} set input
+ * @returns {ReadonlyMap<Module | undefined | null, ReadonlyArray<ModuleGraphConnection>>} mapped by origin module
+ */
+const getConnectionsByOriginModule = (set) =>
+	getConnectionsByKey(set, (connection) => connection.originModule);
+
+/**
+ * Gets connections by module.
+ * @param {SortableSet<ModuleGraphConnection>} set input
+ * @returns {ReadonlyMap<Module | undefined, ReadonlyArray<ModuleGraphConnection>>} mapped by module
+ */
+const getConnectionsByModule = (set) =>
+	getConnectionsByKey(set, (connection) => connection.module);
+
+/** @typedef {SortableSet<ModuleGraphConnection>} IncomingConnections */
+/** @typedef {SortableSet<ModuleGraphConnection>} OutgoingConnections */
+/** @typedef {Module | null | undefined} Issuer */
+/** @typedef {(string | OptimizationBailoutFunction)[]} OptimizationBailouts */
+
+class ModuleGraphModule {
+	constructor() {
+		/** @type {IncomingConnections} */
+		this.incomingConnections = new SortableSet();
+		/** @type {OutgoingConnections | undefined} */
+		this.outgoingConnections = undefined;
+		/** @type {Issuer} */
+		this.issuer = undefined;
+		/** @type {OptimizationBailouts} */
+		this.optimizationBailout = [];
+		/** @type {ExportsInfo} */
+		this.exports = new ExportsInfo();
+		/** @type {number | null} */
+		this.preOrderIndex = null;
+		/** @type {number | null} */
+		this.postOrderIndex = null;
+		/** @type {number | null} */
+		this.depth = null;
+		/** @type {ModuleProfile | undefined} */
+		this.profile = undefined;
+		/** @type {boolean} */
+		this.async = false;
+		/** @type {ModuleGraphConnection[] | undefined} */
+		this._unassignedConnections = undefined;
+	}
+}
+
+/** @typedef {(moduleGraphConnection: ModuleGraphConnection) => boolean} FilterConnection */
+
+/** @typedef {EXPECTED_OBJECT} MetaKey */
+
+/** @typedef {import("./dependencies/CommonJsExportRequireDependency").idsSymbol} CommonJsExportRequireDependencyIDsSymbol */
+/** @typedef {import("./dependencies/HarmonyImportSpecifierDependency").idsSymbol} HarmonyImportSpecifierDependencyIDsSymbol */
+/** @typedef {import("./dependencies/HarmonyExportImportedSpecifierDependency").idsSymbol} HarmonyExportImportedSpecifierDependencyIDsSymbol */
+
+/**
+ * Defines the known meta type used by this module.
+ * @typedef {object} KnownMeta
+ * @property {Map<Module, string>=} importVarMap
+ * @property {Map<Module, string>=} deferredImportVarMap
+ */
+
+/** @typedef {KnownMeta & Record<CommonJsExportRequireDependencyIDsSymbol | HarmonyImportSpecifierDependencyIDsSymbol | HarmonyExportImportedSpecifierDependencyIDsSymbol, string[]> & Record<string, EXPECTED_ANY>} Meta */
+
+class ModuleGraph {
+	constructor() {
+		/**
+		 * @type {WeakMap<Dependency, ModuleGraphConnection | null>}
+		 * @private
+		 */
+		this._dependencyMap = new WeakMap();
+		/**
+		 * @type {Map<Module, ModuleGraphModule>}
+		 * @private
+		 */
+		this._moduleMap = new Map();
+		/**
+		 * @type {WeakMap<MetaKey, Meta>}
+		 * @private
+		 */
+		this._metaMap = new WeakMap();
+		/**
+		 * @type {WeakTupleMap<EXPECTED_ANY[], EXPECTED_ANY> | undefined}
+		 * @private
+		 */
+		this._cache = undefined;
+		/**
+		 * @type {ModuleMemCaches | undefined}
+		 * @private
+		 */
+		this._moduleMemCaches = undefined;
+
+		/**
+		 * @type {string | undefined}
+		 * @private
+		 */
+		this._cacheStage = undefined;
+
+		/**
+		 * @type {WeakMap<Dependency, DependencySourceOrder>}
+		 * @private
+		 */
+		this._dependencySourceOrderMap = new WeakMap();
+
+		/**
+		 * @type {Set<Module>}
+		 * @private
+		 */
+		this._modulesNeedingSort = new Set();
+	}
+
+	/**
+	 * Get module graph module.
+	 * @param {Module} module the module
+	 * @returns {ModuleGraphModule} the internal module
+	 */
+	_getModuleGraphModule(module) {
+		let mgm = this._moduleMap.get(module);
+		if (mgm === undefined) {
+			mgm = new ModuleGraphModule();
+			this._moduleMap.set(module, mgm);
+		}
+		return mgm;
+	}
+
+	/**
+	 * Updates parents using the provided dependency.
+	 * @param {Dependency} dependency the dependency
+	 * @param {DependenciesBlock} block parent block
+	 * @param {Module} module parent module
+	 * @param {number=} indexInBlock position in block
+	 * @returns {void}
+	 */
+	setParents(dependency, block, module, indexInBlock = -1) {
+		dependency._parentDependenciesBlockIndex = indexInBlock;
+		dependency._parentDependenciesBlock = block;
+		dependency._parentModule = module;
+	}
+
+	/**
+	 * Sets parent dependencies block index.
+	 * @param {Dependency} dependency the dependency
+	 * @param {number} index the index
+	 * @returns {void}
+	 */
+	setParentDependenciesBlockIndex(dependency, index) {
+		dependency._parentDependenciesBlockIndex = index;
+	}
+
+	/**
+	 * Gets parent module.
+	 * @param {Dependency} dependency the dependency
+	 * @returns {Module | undefined} parent module
+	 */
+	getParentModule(dependency) {
+		return dependency._parentModule;
+	}
+
+	/**
+	 * Returns parent block.
+	 * @param {Dependency} dependency the dependency
+	 * @returns {DependenciesBlock | undefined} parent block
+	 */
+	getParentBlock(dependency) {
+		return dependency._parentDependenciesBlock;
+	}
+
+	/**
+	 * Gets parent block index.
+	 * @param {Dependency} dependency the dependency
+	 * @returns {number} index
+	 */
+	getParentBlockIndex(dependency) {
+		return dependency._parentDependenciesBlockIndex;
+	}
+
+	/**
+	 * Sets resolved module.
+	 * @param {Module | null} originModule the referencing module
+	 * @param {Dependency} dependency the referencing dependency
+	 * @param {Module} module the referenced module
+	 * @returns {void}
+	 */
+	setResolvedModule(originModule, dependency, module) {
+		const connection = new ModuleGraphConnection(
+			originModule,
+			dependency,
+			module,
+			undefined,
+			dependency.weak,
+			dependency.getCondition(this)
+		);
+		const connections = this._getModuleGraphModule(module).incomingConnections;
+		connections.add(connection);
+		if (originModule) {
+			const mgm = this._getModuleGraphModule(originModule);
+			if (mgm._unassignedConnections === undefined) {
+				mgm._unassignedConnections = [];
+			}
+			mgm._unassignedConnections.push(connection);
+			if (mgm.outgoingConnections === undefined) {
+				mgm.outgoingConnections = new SortableSet();
+			}
+			mgm.outgoingConnections.add(connection);
+		} else {
+			this._dependencyMap.set(dependency, connection);
+		}
+	}
+
+	/**
+	 * Updates module using the provided dependency.
+	 * @param {Dependency} dependency the referencing dependency
+	 * @param {Module} module the referenced module
+	 * @returns {void}
+	 */
+	updateModule(dependency, module) {
+		const connection =
+			/** @type {ModuleGraphConnection} */
+			(this.getConnection(dependency));
+		if (connection.module === module) return;
+		const newConnection = connection.clone();
+		newConnection.module = module;
+		this._dependencyMap.set(dependency, newConnection);
+		connection.setActive(false);
+		const originMgm = this._getModuleGraphModule(
+			/** @type {Module} */ (connection.originModule)
+		);
+		/** @type {OutgoingConnections} */
+		(originMgm.outgoingConnections).add(newConnection);
+		const targetMgm = this._getModuleGraphModule(module);
+		targetMgm.incomingConnections.add(newConnection);
+	}
+
+	/**
+	 * Updates parent using the provided dependency.
+	 * @param {Dependency} dependency the need update dependency
+	 * @param {ModuleGraphConnection=} connection the target connection
+	 * @param {Module=} parentModule the parent module
+	 * @returns {void}
+	 */
+	updateParent(dependency, connection, parentModule) {
+		if (this._dependencySourceOrderMap.has(dependency)) {
+			return;
+		}
+		if (!connection || !parentModule) {
+			return;
+		}
+		const originDependency = connection.dependency;
+
+		// src/index.js
+		// import { c } from "lib/c" -> c = 0
+		// import { a, b } from "lib" -> a and b have the same source order -> a = b = 1
+		// import { d } from "lib/d" -> d = 2
+		const currentSourceOrder =
+			/** @type {HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */
+			(dependency).sourceOrder;
+
+		// lib/index.js (reexport)
+		// import { a } from "lib/a" -> a = 0
+		// import { b } from "lib/b" -> b = 1
+		const originSourceOrder =
+			/** @type {HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */
+			(originDependency).sourceOrder;
+		if (
+			typeof currentSourceOrder === "number" &&
+			typeof originSourceOrder === "number"
+		) {
+			// src/index.js
+			// import { c } from "lib/c" -> c = 0
+			// import { a } from "lib/a" -> a = 1.0 = 1(main) + 0.0(sub)
+			// import { b } from "lib/b" -> b = 1.1 = 1(main) + 0.1(sub)
+			// import { d } from "lib/d" -> d = 2
+			this._dependencySourceOrderMap.set(dependency, {
+				main: currentSourceOrder,
+				sub: originSourceOrder
+			});
+
+			// Save for later batch sorting
+			this._modulesNeedingSort.add(parentModule);
+		}
+	}
+
+	/**
+	 * Finish update parent.
+	 * @returns {void}
+	 */
+	finishUpdateParent() {
+		if (this._modulesNeedingSort.size === 0) {
+			return;
+		}
+		for (const mod of this._modulesNeedingSort) {
+			// If dependencies like HarmonyImportSideEffectDependency and HarmonyImportSpecifierDependency have a SourceOrder,
+			// we sort based on it; otherwise, we preserve the original order.
+			sortWithSourceOrder(
+				mod.dependencies,
+				this._dependencySourceOrderMap,
+				(dep, index) => this.setParentDependenciesBlockIndex(dep, index)
+			);
+		}
+		this._modulesNeedingSort.clear();
+	}
+
+	/**
+	 * Removes connection.
+	 * @param {Dependency} dependency the referencing dependency
+	 * @returns {void}
+	 */
+	removeConnection(dependency) {
+		const connection =
+			/** @type {ModuleGraphConnection} */
+			(this.getConnection(dependency));
+		const targetMgm = this._getModuleGraphModule(connection.module);
+		targetMgm.incomingConnections.delete(connection);
+		const originMgm = this._getModuleGraphModule(
+			/** @type {Module} */ (connection.originModule)
+		);
+		/** @type {OutgoingConnections} */
+		(originMgm.outgoingConnections).delete(connection);
+		this._dependencyMap.set(dependency, null);
+	}
+
+	/**
+	 * Adds the provided dependency to the module graph.
+	 * @param {Dependency} dependency the referencing dependency
+	 * @param {string} explanation an explanation
+	 * @returns {void}
+	 */
+	addExplanation(dependency, explanation) {
+		const connection =
+			/** @type {ModuleGraphConnection} */
+			(this.getConnection(dependency));
+		connection.addExplanation(explanation);
+	}
+
+	/**
+	 * Clones module attributes.
+	 * @param {Module} sourceModule the source module
+	 * @param {Module} targetModule the target module
+	 * @returns {void}
+	 */
+	cloneModuleAttributes(sourceModule, targetModule) {
+		const oldMgm = this._getModuleGraphModule(sourceModule);
+		const newMgm = this._getModuleGraphModule(targetModule);
+		newMgm.postOrderIndex = oldMgm.postOrderIndex;
+		newMgm.preOrderIndex = oldMgm.preOrderIndex;
+		newMgm.depth = oldMgm.depth;
+		newMgm.exports = oldMgm.exports;
+		newMgm.async = oldMgm.async;
+	}
+
+	/**
+	 * Removes module attributes.
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	removeModuleAttributes(module) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.postOrderIndex = null;
+		mgm.preOrderIndex = null;
+		mgm.depth = null;
+		mgm.async = false;
+	}
+
+	/**
+	 * Removes all module attributes.
+	 * @returns {void}
+	 */
+	removeAllModuleAttributes() {
+		for (const mgm of this._moduleMap.values()) {
+			mgm.postOrderIndex = null;
+			mgm.preOrderIndex = null;
+			mgm.depth = null;
+			mgm.async = false;
+		}
+	}
+
+	/**
+	 * Move module connections.
+	 * @param {Module} oldModule the old referencing module
+	 * @param {Module} newModule the new referencing module
+	 * @param {FilterConnection} filterConnection filter predicate for replacement
+	 * @returns {void}
+	 */
+	moveModuleConnections(oldModule, newModule, filterConnection) {
+		if (oldModule === newModule) return;
+		const oldMgm = this._getModuleGraphModule(oldModule);
+		const newMgm = this._getModuleGraphModule(newModule);
+		// Outgoing connections
+		const oldConnections = oldMgm.outgoingConnections;
+		if (oldConnections !== undefined) {
+			if (newMgm.outgoingConnections === undefined) {
+				newMgm.outgoingConnections = new SortableSet();
+			}
+			const newConnections = newMgm.outgoingConnections;
+			for (const connection of oldConnections) {
+				if (filterConnection(connection)) {
+					connection.originModule = newModule;
+					newConnections.add(connection);
+					oldConnections.delete(connection);
+				}
+			}
+		}
+		// Incoming connections
+		const oldConnections2 = oldMgm.incomingConnections;
+		const newConnections2 = newMgm.incomingConnections;
+		for (const connection of oldConnections2) {
+			if (filterConnection(connection)) {
+				connection.module = newModule;
+				newConnections2.add(connection);
+				oldConnections2.delete(connection);
+			}
+		}
+	}
+
+	/**
+	 * Copies outgoing module connections.
+	 * @param {Module} oldModule the old referencing module
+	 * @param {Module} newModule the new referencing module
+	 * @param {FilterConnection} filterConnection filter predicate for replacement
+	 * @returns {void}
+	 */
+	copyOutgoingModuleConnections(oldModule, newModule, filterConnection) {
+		if (oldModule === newModule) return;
+		const oldMgm = this._getModuleGraphModule(oldModule);
+		const newMgm = this._getModuleGraphModule(newModule);
+		// Outgoing connections
+		const oldConnections = oldMgm.outgoingConnections;
+		if (oldConnections !== undefined) {
+			if (newMgm.outgoingConnections === undefined) {
+				newMgm.outgoingConnections = new SortableSet();
+			}
+			const newConnections = newMgm.outgoingConnections;
+			for (const connection of oldConnections) {
+				if (filterConnection(connection)) {
+					const newConnection = connection.clone();
+					newConnection.originModule = newModule;
+					newConnections.add(newConnection);
+					if (newConnection.module !== undefined) {
+						const otherMgm = this._getModuleGraphModule(newConnection.module);
+						otherMgm.incomingConnections.add(newConnection);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Adds the provided module to the module graph.
+	 * @param {Module} module the referenced module
+	 * @param {string} explanation an explanation why it's referenced
+	 * @returns {void}
+	 */
+	addExtraReason(module, explanation) {
+		const connections = this._getModuleGraphModule(module).incomingConnections;
+		connections.add(new ModuleGraphConnection(null, null, module, explanation));
+	}
+
+	/**
+	 * Gets resolved module.
+	 * @param {Dependency} dependency the dependency to look for a referenced module
+	 * @returns {Module | null} the referenced module
+	 */
+	getResolvedModule(dependency) {
+		const connection = this.getConnection(dependency);
+		return connection !== undefined ? connection.resolvedModule : null;
+	}
+
+	/**
+	 * Returns the connection.
+	 * @param {Dependency} dependency the dependency to look for a referenced module
+	 * @returns {ModuleGraphConnection | undefined} the connection
+	 */
+	getConnection(dependency) {
+		const connection = this._dependencyMap.get(dependency);
+		if (connection === undefined) {
+			const module = this.getParentModule(dependency);
+			if (module !== undefined) {
+				const mgm = this._getModuleGraphModule(module);
+				if (
+					mgm._unassignedConnections &&
+					mgm._unassignedConnections.length !== 0
+				) {
+					/** @type {undefined | ModuleGraphConnection} */
+					let foundConnection;
+					for (const connection of mgm._unassignedConnections) {
+						this._dependencyMap.set(
+							/** @type {Dependency} */ (connection.dependency),
+							connection
+						);
+						if (connection.dependency === dependency) {
+							foundConnection = connection;
+						}
+					}
+					mgm._unassignedConnections.length = 0;
+					if (foundConnection !== undefined) {
+						return foundConnection;
+					}
+				}
+			}
+			this._dependencyMap.set(dependency, null);
+			return;
+		}
+		return connection === null ? undefined : connection;
+	}
+
+	/**
+	 * Returns the referenced module.
+	 * @param {Dependency} dependency the dependency to look for a referenced module
+	 * @returns {Module | null} the referenced module
+	 */
+	getModule(dependency) {
+		const connection = this.getConnection(dependency);
+		return connection !== undefined ? connection.module : null;
+	}
+
+	/**
+	 * Returns the referencing module.
+	 * @param {Dependency} dependency the dependency to look for a referencing module
+	 * @returns {Module | null} the referencing module
+	 */
+	getOrigin(dependency) {
+		const connection = this.getConnection(dependency);
+		return connection !== undefined ? connection.originModule : null;
+	}
+
+	/**
+	 * Gets resolved origin.
+	 * @param {Dependency} dependency the dependency to look for a referencing module
+	 * @returns {Module | null} the original referencing module
+	 */
+	getResolvedOrigin(dependency) {
+		const connection = this.getConnection(dependency);
+		return connection !== undefined ? connection.resolvedOriginModule : null;
+	}
+
+	/**
+	 * Gets incoming connections.
+	 * @param {Module} module the module
+	 * @returns {Iterable<ModuleGraphConnection>} reasons why a module is included
+	 */
+	getIncomingConnections(module) {
+		const connections = this._getModuleGraphModule(module).incomingConnections;
+		return connections;
+	}
+
+	/**
+	 * Gets outgoing connections.
+	 * @param {Module} module the module
+	 * @returns {Iterable<ModuleGraphConnection>} list of outgoing connections
+	 */
+	getOutgoingConnections(module) {
+		const connections = this._getModuleGraphModule(module).outgoingConnections;
+		return connections === undefined ? EMPTY_SET : connections;
+	}
+
+	/**
+	 * Gets incoming connections by origin module.
+	 * @param {Module} module the module
+	 * @returns {ReadonlyMap<Module | undefined | null, ReadonlyArray<ModuleGraphConnection>>} reasons why a module is included, in a map by source module
+	 */
+	getIncomingConnectionsByOriginModule(module) {
+		const connections = this._getModuleGraphModule(module).incomingConnections;
+		return connections.getFromUnorderedCache(getConnectionsByOriginModule);
+	}
+
+	/**
+	 * Gets outgoing connections by module.
+	 * @param {Module} module the module
+	 * @returns {ReadonlyMap<Module | undefined, ReadonlyArray<ModuleGraphConnection>> | undefined} connections to modules, in a map by module
+	 */
+	getOutgoingConnectionsByModule(module) {
+		const connections = this._getModuleGraphModule(module).outgoingConnections;
+		return connections === undefined
+			? undefined
+			: connections.getFromUnorderedCache(getConnectionsByModule);
+	}
+
+	/**
+	 * Returns the module profile.
+	 * @param {Module} module the module
+	 * @returns {ModuleProfile | undefined} the module profile
+	 */
+	getProfile(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.profile;
+	}
+
+	/**
+	 * Updates profile using the provided module.
+	 * @param {Module} module the module
+	 * @param {ModuleProfile | undefined} profile the module profile
+	 * @returns {void}
+	 */
+	setProfile(module, profile) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.profile = profile;
+	}
+
+	/**
+	 * Returns the issuer module.
+	 * @param {Module} module the module
+	 * @returns {Issuer} the issuer module
+	 */
+	getIssuer(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.issuer;
+	}
+
+	/**
+	 * Updates issuer using the provided module.
+	 * @param {Module} module the module
+	 * @param {Module | null} issuer the issuer module
+	 * @returns {void}
+	 */
+	setIssuer(module, issuer) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.issuer = issuer;
+	}
+
+	/**
+	 * Sets issuer if unset.
+	 * @param {Module} module the module
+	 * @param {Module | null} issuer the issuer module
+	 * @returns {void}
+	 */
+	setIssuerIfUnset(module, issuer) {
+		const mgm = this._getModuleGraphModule(module);
+		if (mgm.issuer === undefined) mgm.issuer = issuer;
+	}
+
+	/**
+	 * Gets optimization bailout.
+	 * @param {Module} module the module
+	 * @returns {OptimizationBailouts} optimization bailouts
+	 */
+	getOptimizationBailout(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.optimizationBailout;
+	}
+
+	/**
+	 * Gets provided exports.
+	 * @param {Module} module the module
+	 * @returns {null | true | ExportInfoName[]} the provided exports
+	 */
+	getProvidedExports(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.exports.getProvidedExports();
+	}
+
+	/**
+	 * Checks whether this module graph is export provided.
+	 * @param {Module} module the module
+	 * @param {ExportInfoName | ExportInfoName[]} exportName a name of an export
+	 * @returns {boolean | null} true, if the export is provided by the module.
+	 * null, if it's unknown.
+	 * false, if it's not provided.
+	 */
+	isExportProvided(module, exportName) {
+		const mgm = this._getModuleGraphModule(module);
+		const result = mgm.exports.isExportProvided(exportName);
+		return result === undefined ? null : result;
+	}
+
+	/**
+	 * Returns info about the exports.
+	 * @param {Module} module the module
+	 * @returns {ExportsInfo} info about the exports
+	 */
+	getExportsInfo(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.exports;
+	}
+
+	/**
+	 * Returns info about the export.
+	 * @param {Module} module the module
+	 * @param {string} exportName the export
+	 * @returns {ExportInfo} info about the export
+	 */
+	getExportInfo(module, exportName) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.exports.getExportInfo(exportName);
+	}
+
+	/**
+	 * Gets read only export info.
+	 * @param {Module} module the module
+	 * @param {string} exportName the export
+	 * @returns {ExportInfo} info about the export (do not modify)
+	 */
+	getReadOnlyExportInfo(module, exportName) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.exports.getReadOnlyExportInfo(exportName);
+	}
+
+	/**
+	 * Returns the used exports.
+	 * @param {Module} module the module
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {false | true | SortableSet<string> | null} the used exports
+	 * false: module is not used at all.
+	 * true: the module namespace/object export is used.
+	 * SortableSet<string>: these export names are used.
+	 * empty SortableSet<string>: module is used but no export.
+	 * null: unknown, worst case should be assumed.
+	 */
+	getUsedExports(module, runtime) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.exports.getUsedExports(runtime);
+	}
+
+	/**
+	 * Gets pre order index.
+	 * @param {Module} module the module
+	 * @returns {number | null} the index of the module
+	 */
+	getPreOrderIndex(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.preOrderIndex;
+	}
+
+	/**
+	 * Gets post order index.
+	 * @param {Module} module the module
+	 * @returns {number | null} the index of the module
+	 */
+	getPostOrderIndex(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.postOrderIndex;
+	}
+
+	/**
+	 * Sets pre order index.
+	 * @param {Module} module the module
+	 * @param {number} index the index of the module
+	 * @returns {void}
+	 */
+	setPreOrderIndex(module, index) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.preOrderIndex = index;
+	}
+
+	/**
+	 * Sets pre order index if unset.
+	 * @param {Module} module the module
+	 * @param {number} index the index of the module
+	 * @returns {boolean} true, if the index was set
+	 */
+	setPreOrderIndexIfUnset(module, index) {
+		const mgm = this._getModuleGraphModule(module);
+		if (mgm.preOrderIndex === null) {
+			mgm.preOrderIndex = index;
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Sets post order index.
+	 * @param {Module} module the module
+	 * @param {number} index the index of the module
+	 * @returns {void}
+	 */
+	setPostOrderIndex(module, index) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.postOrderIndex = index;
+	}
+
+	/**
+	 * Sets post order index if unset.
+	 * @param {Module} module the module
+	 * @param {number} index the index of the module
+	 * @returns {boolean} true, if the index was set
+	 */
+	setPostOrderIndexIfUnset(module, index) {
+		const mgm = this._getModuleGraphModule(module);
+		if (mgm.postOrderIndex === null) {
+			mgm.postOrderIndex = index;
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the depth of the module.
+	 * @param {Module} module the module
+	 * @returns {number | null} the depth of the module
+	 */
+	getDepth(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.depth;
+	}
+
+	/**
+	 * Updates depth using the provided module.
+	 * @param {Module} module the module
+	 * @param {number} depth the depth of the module
+	 * @returns {void}
+	 */
+	setDepth(module, depth) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.depth = depth;
+	}
+
+	/**
+	 * Sets depth if lower.
+	 * @param {Module} module the module
+	 * @param {number} depth the depth of the module
+	 * @returns {boolean} true, if the depth was set
+	 */
+	setDepthIfLower(module, depth) {
+		const mgm = this._getModuleGraphModule(module);
+		if (mgm.depth === null || mgm.depth > depth) {
+			mgm.depth = depth;
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Checks whether this module graph is async.
+	 * @param {Module} module the module
+	 * @returns {boolean} true, if the module is async
+	 */
+	isAsync(module) {
+		const mgm = this._getModuleGraphModule(module);
+		return mgm.async;
+	}
+
+	/**
+	 * Checks whether this module graph is deferred.
+	 * @param {Module} module the module
+	 * @returns {boolean} true, if the module is used as a deferred module at least once
+	 */
+	isDeferred(module) {
+		if (this.isAsync(module)) return false;
+		const connections = this.getIncomingConnections(module);
+		for (const connection of connections) {
+			if (
+				!connection.dependency ||
+				!(connection.dependency instanceof HarmonyImportDependency)
+			) {
+				continue;
+			}
+			if (ImportPhaseUtils.isDefer(connection.dependency.phase)) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Updates async using the provided module.
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	setAsync(module) {
+		const mgm = this._getModuleGraphModule(module);
+		mgm.async = true;
+	}
+
+	/**
+	 * Returns metadata.
+	 * @param {MetaKey} thing any thing
+	 * @returns {Meta} metadata
+	 */
+	getMeta(thing) {
+		let meta = this._metaMap.get(thing);
+		if (meta === undefined) {
+			meta = /** @type {Meta} */ (Object.create(null));
+			this._metaMap.set(thing, meta);
+		}
+		return meta;
+	}
+
+	/**
+	 * Gets meta if existing.
+	 * @param {MetaKey} thing any thing
+	 * @returns {Meta | undefined} metadata
+	 */
+	getMetaIfExisting(thing) {
+		return this._metaMap.get(thing);
+	}
+
+	/**
+	 * Processes the provided cache stage.
+	 * @param {string=} cacheStage a persistent stage name for caching
+	 */
+	freeze(cacheStage) {
+		this._cache = new WeakTupleMap();
+		this._cacheStage = cacheStage;
+	}
+
+	unfreeze() {
+		this._cache = undefined;
+		this._cacheStage = undefined;
+	}
+
+	/**
+	 * Returns computed value or cached.
+	 * @template {EXPECTED_ANY[]} T
+	 * @template R
+	 * @param {(moduleGraph: ModuleGraph, ...args: T) => R} fn computer
+	 * @param {T} args arguments
+	 * @returns {R} computed value or cached
+	 */
+	cached(fn, ...args) {
+		if (this._cache === undefined) return fn(this, ...args);
+		return this._cache.provide(fn, ...args, () => fn(this, ...args));
+	}
+
+	/**
+	 * Sets module mem caches.
+	 * @param {ModuleMemCaches} moduleMemCaches mem caches for modules for better caching
+	 */
+	setModuleMemCaches(moduleMemCaches) {
+		this._moduleMemCaches = moduleMemCaches;
+	}
+
+	/**
+	 * Dependency cache provide.
+	 * @template {Dependency} D
+	 * @template {EXPECTED_ANY[]} ARGS
+	 * @template R
+	 * @param {D} dependency dependency
+	 * @param {[...ARGS, (moduleGraph: ModuleGraph, dependency: D, ...args: ARGS) => R]} args arguments, last argument is a function called with moduleGraph, dependency, ...args
+	 * @returns {R} computed value or cached
+	 */
+	dependencyCacheProvide(dependency, ...args) {
+		const fn =
+			/** @type {(moduleGraph: ModuleGraph, dependency: D, ...args: EXPECTED_ANY[]) => R} */
+			(args.pop());
+		if (this._moduleMemCaches && this._cacheStage) {
+			const memCache = this._moduleMemCaches.get(
+				/** @type {Module} */
+				(this.getParentModule(dependency))
+			);
+			if (memCache !== undefined) {
+				return memCache.provide(dependency, this._cacheStage, ...args, () =>
+					fn(this, dependency, ...args)
+				);
+			}
+		}
+		if (this._cache === undefined) return fn(this, dependency, ...args);
+		return this._cache.provide(dependency, ...args, () =>
+			fn(this, dependency, ...args)
+		);
+	}
+
+	// TODO remove in webpack 6
+	/**
+	 * Gets module graph for module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @param {string} deprecateMessage message for the deprecation message
+	 * @param {string} deprecationCode code for the deprecation
+	 * @returns {ModuleGraph} the module graph
+	 */
+	static getModuleGraphForModule(module, deprecateMessage, deprecationCode) {
+		const fn = deprecateMap.get(deprecateMessage);
+		if (fn) return fn(module);
+		const newFn = util.deprecate(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {Module} module the module
+			 * @returns {ModuleGraph} the module graph
+			 */
+			(module) => {
+				const moduleGraph = moduleGraphForModuleMap.get(module);
+				if (!moduleGraph) {
+					throw new Error(
+						`${
+							deprecateMessage
+						}There was no ModuleGraph assigned to the Module for backward-compat (Use the new API)`
+					);
+				}
+				return moduleGraph;
+			},
+			`${deprecateMessage}: Use new ModuleGraph API`,
+			deprecationCode
+		);
+		deprecateMap.set(deprecateMessage, newFn);
+		return newFn(module);
+	}
+
+	// TODO remove in webpack 6
+	/**
+	 * Sets module graph for module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {void}
+	 */
+	static setModuleGraphForModule(module, moduleGraph) {
+		moduleGraphForModuleMap.set(module, moduleGraph);
+	}
+
+	// TODO remove in webpack 6
+	/**
+	 * Clear module graph for module.
+	 * @deprecated
+	 * @param {Module} module the module
+	 * @returns {void}
+	 */
+	static clearModuleGraphForModule(module) {
+		moduleGraphForModuleMap.delete(module);
+	}
+}
+
+// TODO remove in webpack 6
+/** @type {WeakMap<Module, ModuleGraph>} */
+const moduleGraphForModuleMap = new WeakMap();
+
+// TODO remove in webpack 6
+/** @type {Map<string, (module: Module) => ModuleGraph>} */
+const deprecateMap = new Map();
+
+module.exports = ModuleGraph;
+module.exports.ModuleGraphConnection = ModuleGraphConnection;
Index: frontend/node_modules/webpack/lib/ModuleGraphConnection.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleGraphConnection.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleGraphConnection.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,208 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Module itself is not connected, but transitive modules are connected transitively.
+ */
+const TRANSITIVE_ONLY = Symbol("transitive only");
+
+/**
+ * While determining the active state, this flag is used to signal a circular connection.
+ */
+const CIRCULAR_CONNECTION = Symbol("circular connection");
+
+/** @typedef {boolean | typeof TRANSITIVE_ONLY | typeof CIRCULAR_CONNECTION} ConnectionState */
+
+/**
+ * Adds connection states.
+ * @param {ConnectionState} a first
+ * @param {ConnectionState} b second
+ * @returns {ConnectionState} merged
+ */
+const addConnectionStates = (a, b) => {
+	if (a === true || b === true) return true;
+	if (a === false) return b;
+	if (b === false) return a;
+	if (a === TRANSITIVE_ONLY) return b;
+	if (b === TRANSITIVE_ONLY) return a;
+	return a;
+};
+
+/**
+ * Intersect connection states.
+ * @param {ConnectionState} a first
+ * @param {ConnectionState} b second
+ * @returns {ConnectionState} intersected
+ */
+const intersectConnectionStates = (a, b) => {
+	if (a === false || b === false) return false;
+	if (a === true) return b;
+	if (b === true) return a;
+	if (a === CIRCULAR_CONNECTION) return b;
+	if (b === CIRCULAR_CONNECTION) return a;
+	return a;
+};
+
+class ModuleGraphConnection {
+	/**
+	 * Creates an instance of ModuleGraphConnection.
+	 * @param {Module | null} originModule the referencing module
+	 * @param {Dependency | null} dependency the referencing dependency
+	 * @param {Module} module the referenced module
+	 * @param {string=} explanation some extra detail
+	 * @param {boolean=} weak the reference is weak
+	 * @param {false | null | GetConditionFn=} condition condition for the connection
+	 */
+	constructor(
+		originModule,
+		dependency,
+		module,
+		explanation,
+		weak = false,
+		condition = undefined
+	) {
+		/** @type {Module | null} */
+		this.originModule = originModule;
+		/** @type {Module | null} */
+		this.resolvedOriginModule = originModule;
+		/** @type {Dependency | null} */
+		this.dependency = dependency;
+		/** @type {Module} */
+		this.resolvedModule = module;
+		/** @type {Module} */
+		this.module = module;
+		/** @type {boolean | undefined} */
+		this.weak = weak;
+		/** @type {boolean} */
+		this.conditional = Boolean(condition);
+		/** @type {boolean} */
+		this._active = condition !== false;
+		/** @type {false | null | GetConditionFn | undefined} */
+		this.condition = condition || undefined;
+		/** @type {Set<string> | undefined} */
+		this.explanations = undefined;
+		if (explanation) {
+			this.explanations = new Set();
+			this.explanations.add(explanation);
+		}
+	}
+
+	clone() {
+		const clone = new ModuleGraphConnection(
+			this.resolvedOriginModule,
+			this.dependency,
+			this.resolvedModule,
+			undefined,
+			this.weak,
+			this.condition
+		);
+		clone.originModule = this.originModule;
+		clone.module = this.module;
+		clone.conditional = this.conditional;
+		clone._active = this._active;
+		if (this.explanations) clone.explanations = new Set(this.explanations);
+		return clone;
+	}
+
+	/**
+	 * Adds the provided condition to the module graph connection.
+	 * @param {GetConditionFn} condition condition for the connection
+	 * @returns {void}
+	 */
+	addCondition(condition) {
+		if (this.conditional) {
+			const old =
+				/** @type {GetConditionFn} */
+				(this.condition);
+			/** @type {GetConditionFn} */
+			(this.condition) = (c, r) =>
+				intersectConnectionStates(old(c, r), condition(c, r));
+		} else if (this._active) {
+			this.conditional = true;
+			this.condition = condition;
+		}
+	}
+
+	/**
+	 * Adds the provided explanation to the module graph connection.
+	 * @param {string} explanation the explanation to add
+	 * @returns {void}
+	 */
+	addExplanation(explanation) {
+		if (this.explanations === undefined) {
+			this.explanations = new Set();
+		}
+		this.explanations.add(explanation);
+	}
+
+	get explanation() {
+		if (this.explanations === undefined) return "";
+		return [...this.explanations].join(" ");
+	}
+
+	/**
+	 * Checks whether this module graph connection is active.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, if the connection is active
+	 */
+	isActive(runtime) {
+		if (!this.conditional) return this._active;
+
+		return (
+			/** @type {GetConditionFn} */ (this.condition)(this, runtime) !== false
+		);
+	}
+
+	/**
+	 * Checks whether this module graph connection is target active.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {boolean} true, if the connection is active
+	 */
+	isTargetActive(runtime) {
+		if (!this.conditional) return this._active;
+		return (
+			/** @type {GetConditionFn} */ (this.condition)(this, runtime) === true
+		);
+	}
+
+	/**
+	 * Returns true: fully active, false: inactive, TRANSITIVE: direct module inactive, but transitive connection maybe active.
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {ConnectionState} true: fully active, false: inactive, TRANSITIVE: direct module inactive, but transitive connection maybe active
+	 */
+	getActiveState(runtime) {
+		if (!this.conditional) return this._active;
+		return /** @type {GetConditionFn} */ (this.condition)(this, runtime);
+	}
+
+	/**
+	 * Updates active using the provided value.
+	 * @param {boolean} value active or not
+	 * @returns {void}
+	 */
+	setActive(value) {
+		this.conditional = false;
+		this._active = value;
+	}
+}
+
+/** @typedef {typeof TRANSITIVE_ONLY} TRANSITIVE_ONLY */
+/** @typedef {typeof CIRCULAR_CONNECTION} CIRCULAR_CONNECTION */
+
+module.exports = ModuleGraphConnection;
+module.exports.CIRCULAR_CONNECTION = /** @type {typeof CIRCULAR_CONNECTION} */ (
+	CIRCULAR_CONNECTION
+);
+module.exports.TRANSITIVE_ONLY = /** @type {typeof TRANSITIVE_ONLY} */ (
+	TRANSITIVE_ONLY
+);
+module.exports.addConnectionStates = addConnectionStates;
Index: frontend/node_modules/webpack/lib/ModuleInfoHeaderPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleInfoHeaderPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleInfoHeaderPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,323 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { CachedSource, ConcatSource, RawSource } = require("webpack-sources");
+const { UsageState } = require("./ExportsInfo");
+const Template = require("./Template");
+const CssModulesPlugin = require("./css/CssModulesPlugin");
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./ExportsInfo")} ExportsInfo */
+/** @typedef {import("./ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").BuildMeta} BuildMeta */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+
+/**
+ * Join iterable with comma.
+ * @template T
+ * @param {Iterable<T>} iterable iterable
+ * @returns {string} joined with comma
+ */
+const joinIterableWithComma = (iterable) => {
+	// This is more performant than Array.from().join(", ")
+	// as it doesn't create an array
+	let str = "";
+	let first = true;
+	for (const item of iterable) {
+		if (first) {
+			first = false;
+		} else {
+			str += ", ";
+		}
+		str += item;
+	}
+	return str;
+};
+
+/**
+ * Print exports info to source.
+ * @param {ConcatSource} source output
+ * @param {string} indent spacing
+ * @param {ExportsInfo} exportsInfo data
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @param {RequestShortener} requestShortener requestShortener
+ * @param {Set<ExportInfo>} alreadyPrinted deduplication set
+ * @returns {void}
+ */
+const printExportsInfoToSource = (
+	source,
+	indent,
+	exportsInfo,
+	moduleGraph,
+	requestShortener,
+	alreadyPrinted = new Set()
+) => {
+	const otherExportsInfo = exportsInfo.otherExportsInfo;
+
+	let alreadyPrintedExports = 0;
+
+	// determine exports to print
+	/** @type {ExportInfo[]} */
+	const printedExports = [];
+	for (const exportInfo of exportsInfo.orderedExports) {
+		if (!alreadyPrinted.has(exportInfo)) {
+			alreadyPrinted.add(exportInfo);
+			printedExports.push(exportInfo);
+		} else {
+			alreadyPrintedExports++;
+		}
+	}
+	let showOtherExports = false;
+	if (!alreadyPrinted.has(otherExportsInfo)) {
+		alreadyPrinted.add(otherExportsInfo);
+		showOtherExports = true;
+	} else {
+		alreadyPrintedExports++;
+	}
+
+	// print the exports
+	for (const exportInfo of printedExports) {
+		const target = exportInfo.getTarget(moduleGraph);
+		source.add(
+			`${Template.toComment(
+				`${indent}export ${JSON.stringify(exportInfo.name).slice(
+					1,
+					-1
+				)} [${exportInfo.getProvidedInfo()}] [${exportInfo.getUsedInfo()}] [${exportInfo.getRenameInfo()}]${
+					target
+						? ` -> ${target.module.readableIdentifier(requestShortener)}${
+								target.export
+									? ` .${target.export
+											.map((e) => JSON.stringify(e).slice(1, -1))
+											.join(".")}`
+									: ""
+							}`
+						: ""
+				}`
+			)}\n`
+		);
+		if (exportInfo.exportsInfo) {
+			printExportsInfoToSource(
+				source,
+				`${indent}  `,
+				exportInfo.exportsInfo,
+				moduleGraph,
+				requestShortener,
+				alreadyPrinted
+			);
+		}
+	}
+
+	if (alreadyPrintedExports) {
+		source.add(
+			`${Template.toComment(
+				`${indent}... (${alreadyPrintedExports} already listed exports)`
+			)}\n`
+		);
+	}
+
+	if (showOtherExports) {
+		const target = otherExportsInfo.getTarget(moduleGraph);
+		if (
+			target ||
+			otherExportsInfo.provided !== false ||
+			otherExportsInfo.getUsed(undefined) !== UsageState.Unused
+		) {
+			const title =
+				printedExports.length > 0 || alreadyPrintedExports > 0
+					? "other exports"
+					: "exports";
+			source.add(
+				`${Template.toComment(
+					`${indent}${title} [${otherExportsInfo.getProvidedInfo()}] [${otherExportsInfo.getUsedInfo()}]${
+						target
+							? ` -> ${target.module.readableIdentifier(requestShortener)}`
+							: ""
+					}`
+				)}\n`
+			);
+		}
+	}
+};
+
+/** @typedef {{ header: RawSource | undefined, full: WeakMap<Source, CachedSource> }} CacheEntry */
+/** @type {WeakMap<RequestShortener, WeakMap<Module, CacheEntry>>} */
+const caches = new WeakMap();
+
+const PLUGIN_NAME = "ModuleInfoHeaderPlugin";
+
+class ModuleInfoHeaderPlugin {
+	/**
+	 * Creates an instance of ModuleInfoHeaderPlugin.
+	 * @param {boolean=} verbose add more information like exports, runtime requirements and bailouts
+	 */
+	constructor(verbose = true) {
+		/** @type {boolean} */
+		this._verbose = verbose;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _verbose: verbose } = this;
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const javascriptHooks =
+				JavascriptModulesPlugin.getCompilationHooks(compilation);
+			javascriptHooks.renderModulePackage.tap(
+				PLUGIN_NAME,
+				(
+					moduleSource,
+					module,
+					{ chunk, chunkGraph, moduleGraph, runtimeTemplate }
+				) => {
+					const { requestShortener } = runtimeTemplate;
+					/** @type {undefined | CacheEntry} */
+					let cacheEntry;
+					let cache = caches.get(requestShortener);
+					if (cache === undefined) {
+						caches.set(requestShortener, (cache = new WeakMap()));
+						cache.set(
+							module,
+							(cacheEntry = { header: undefined, full: new WeakMap() })
+						);
+					} else {
+						cacheEntry = cache.get(module);
+						if (cacheEntry === undefined) {
+							cache.set(
+								module,
+								(cacheEntry = { header: undefined, full: new WeakMap() })
+							);
+						} else if (!verbose) {
+							const cachedSource = cacheEntry.full.get(moduleSource);
+							if (cachedSource !== undefined) return cachedSource;
+						}
+					}
+					const source = new ConcatSource();
+					let header = cacheEntry.header;
+					if (header === undefined) {
+						header = this.generateHeader(module, requestShortener);
+						cacheEntry.header = header;
+					}
+					source.add(header);
+					if (verbose) {
+						const exportsType = /** @type {BuildMeta} */ (module.buildMeta)
+							.exportsType;
+						source.add(
+							`${Template.toComment(
+								exportsType
+									? `${exportsType} exports`
+									: "unknown exports (runtime-defined)"
+							)}\n`
+						);
+						if (exportsType) {
+							const exportsInfo = moduleGraph.getExportsInfo(module);
+							printExportsInfoToSource(
+								source,
+								"",
+								exportsInfo,
+								moduleGraph,
+								requestShortener
+							);
+						}
+						source.add(
+							`${Template.toComment(
+								`runtime requirements: ${joinIterableWithComma(
+									chunkGraph.getModuleRuntimeRequirements(module, chunk.runtime)
+								)}`
+							)}\n`
+						);
+						const optimizationBailout =
+							moduleGraph.getOptimizationBailout(module);
+						if (optimizationBailout) {
+							for (const text of optimizationBailout) {
+								const code =
+									typeof text === "function" ? text(requestShortener) : text;
+								source.add(`${Template.toComment(`${code}`)}\n`);
+							}
+						}
+						source.add(moduleSource);
+						return source;
+					}
+					source.add(moduleSource);
+					const cachedSource = new CachedSource(source);
+					cacheEntry.full.set(moduleSource, cachedSource);
+					return cachedSource;
+				}
+			);
+			javascriptHooks.chunkHash.tap(PLUGIN_NAME, (_chunk, hash) => {
+				hash.update(PLUGIN_NAME);
+				hash.update("1");
+			});
+			const cssHooks = CssModulesPlugin.getCompilationHooks(compilation);
+			cssHooks.renderModulePackage.tap(
+				PLUGIN_NAME,
+				(moduleSource, module, { runtimeTemplate }) => {
+					const { requestShortener } = runtimeTemplate;
+					/** @type {undefined | CacheEntry} */
+					let cacheEntry;
+					let cache = caches.get(requestShortener);
+					if (cache === undefined) {
+						caches.set(requestShortener, (cache = new WeakMap()));
+						cache.set(
+							module,
+							(cacheEntry = { header: undefined, full: new WeakMap() })
+						);
+					} else {
+						cacheEntry = cache.get(module);
+						if (cacheEntry === undefined) {
+							cache.set(
+								module,
+								(cacheEntry = { header: undefined, full: new WeakMap() })
+							);
+						} else if (!verbose) {
+							const cachedSource = cacheEntry.full.get(moduleSource);
+							if (cachedSource !== undefined) return cachedSource;
+						}
+					}
+					const source = new ConcatSource();
+					let header = cacheEntry.header;
+					if (header === undefined) {
+						header = this.generateHeader(module, requestShortener);
+						cacheEntry.header = header;
+					}
+					source.add(header);
+					source.add(moduleSource);
+					const cachedSource = new CachedSource(source);
+					cacheEntry.full.set(moduleSource, cachedSource);
+					return cachedSource;
+				}
+			);
+			cssHooks.chunkHash.tap(PLUGIN_NAME, (_chunk, hash) => {
+				hash.update(PLUGIN_NAME);
+				hash.update("1");
+			});
+		});
+	}
+
+	/**
+	 * Returns the header.
+	 * @param {Module} module the module
+	 * @param {RequestShortener} requestShortener request shortener
+	 * @returns {RawSource} the header
+	 */
+	generateHeader(module, requestShortener) {
+		const req = module.readableIdentifier(requestShortener);
+		const reqStr = req.replace(/\*\//g, "*_/");
+		const reqStrStar = "*".repeat(reqStr.length);
+		const headerStr = `/*!****${reqStrStar}****!*\\\n  !*** ${reqStr} ***!\n  \\****${reqStrStar}****/\n`;
+		return new RawSource(headerStr);
+	}
+}
+
+module.exports = ModuleInfoHeaderPlugin;
Index: frontend/node_modules/webpack/lib/ModuleNotFoundError.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleNotFoundError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleNotFoundError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,10 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+// TODO remove in webpack 6
+// Some old plugins use `require("webpack/lib/ModuleNotFoundError")`, in webpack@6 developer should migrate to `compiler.webpack.ModuleNotFoundError`
+module.exports = require("./errors/ModuleNotFoundError");
Index: frontend/node_modules/webpack/lib/ModuleProfile.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleProfile.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleProfile.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,108 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+class ModuleProfile {
+	constructor() {
+		this.startTime = Date.now();
+
+		this.factoryStartTime = 0;
+		this.factoryEndTime = 0;
+		this.factory = 0;
+		this.factoryParallelismFactor = 0;
+
+		this.restoringStartTime = 0;
+		this.restoringEndTime = 0;
+		this.restoring = 0;
+		this.restoringParallelismFactor = 0;
+
+		this.integrationStartTime = 0;
+		this.integrationEndTime = 0;
+		this.integration = 0;
+		this.integrationParallelismFactor = 0;
+
+		this.buildingStartTime = 0;
+		this.buildingEndTime = 0;
+		this.building = 0;
+		this.buildingParallelismFactor = 0;
+
+		this.storingStartTime = 0;
+		this.storingEndTime = 0;
+		this.storing = 0;
+		this.storingParallelismFactor = 0;
+
+		/** @type {{ start: number, end: number }[] | undefined} */
+		this.additionalFactoryTimes = undefined;
+		this.additionalFactories = 0;
+		this.additionalFactoriesParallelismFactor = 0;
+
+		/** @deprecated */
+		this.additionalIntegration = 0;
+	}
+
+	markFactoryStart() {
+		this.factoryStartTime = Date.now();
+	}
+
+	markFactoryEnd() {
+		this.factoryEndTime = Date.now();
+		this.factory = this.factoryEndTime - this.factoryStartTime;
+	}
+
+	markRestoringStart() {
+		this.restoringStartTime = Date.now();
+	}
+
+	markRestoringEnd() {
+		this.restoringEndTime = Date.now();
+		this.restoring = this.restoringEndTime - this.restoringStartTime;
+	}
+
+	markIntegrationStart() {
+		this.integrationStartTime = Date.now();
+	}
+
+	markIntegrationEnd() {
+		this.integrationEndTime = Date.now();
+		this.integration = this.integrationEndTime - this.integrationStartTime;
+	}
+
+	markBuildingStart() {
+		this.buildingStartTime = Date.now();
+	}
+
+	markBuildingEnd() {
+		this.buildingEndTime = Date.now();
+		this.building = this.buildingEndTime - this.buildingStartTime;
+	}
+
+	markStoringStart() {
+		this.storingStartTime = Date.now();
+	}
+
+	markStoringEnd() {
+		this.storingEndTime = Date.now();
+		this.storing = this.storingEndTime - this.storingStartTime;
+	}
+
+	// This depends on timing so we ignore it for coverage
+	/* istanbul ignore next */
+	/**
+	 * Merge this profile into another one
+	 * @param {ModuleProfile} realProfile the profile to merge into
+	 * @returns {void}
+	 */
+	mergeInto(realProfile) {
+		realProfile.additionalFactories = this.factory;
+		(realProfile.additionalFactoryTimes =
+			realProfile.additionalFactoryTimes || []).push({
+			start: this.factoryStartTime,
+			end: this.factoryEndTime
+		});
+	}
+}
+
+module.exports = ModuleProfile;
Index: frontend/node_modules/webpack/lib/ModuleSourceTypeConstants.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleSourceTypeConstants.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleSourceTypeConstants.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,212 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+/**
+ * @type {Readonly<"javascript">}
+ */
+const JAVASCRIPT_TYPE = "javascript";
+
+/**
+ * @type {Readonly<"runtime">}
+ */
+const RUNTIME_TYPE = "runtime";
+
+/**
+ * @type {Readonly<"webassembly">}
+ */
+const WEBASSEMBLY_TYPE = "webassembly";
+
+/**
+ * @type {Readonly<"asset">}
+ */
+const ASSET_TYPE = "asset";
+
+/**
+ * @type {Readonly<"asset-url">}
+ */
+const ASSET_URL_TYPE = "asset-url";
+
+/**
+ * @type {Readonly<"css">}
+ */
+const CSS_TYPE = "css";
+
+/**
+ * @type {Readonly<"css-import">}
+ */
+const CSS_IMPORT_TYPE = "css-import";
+
+/**
+ * @type {Readonly<"css-text">}
+ */
+const CSS_TEXT_TYPE = "css-text";
+
+/**
+ * @type {Readonly<"html">}
+ */
+const HTML_TYPE = "html";
+
+/**
+ * @type {Readonly<"share-init">}
+ */
+const SHARED_INIT_TYPE = "share-init";
+
+/**
+ * @type {Readonly<"remote">}
+ */
+const REMOTE_GENERATOR_TYPE = "remote";
+
+/**
+ * @type {Readonly<"consume-shared">}
+ */
+const CONSUME_SHARED_GENERATOR_TYPE = "consume-shared";
+
+/**
+ * @type {Readonly<"unknown">}
+ */
+const UNKNOWN_TYPE = "unknown";
+
+/**
+ * Defines the all types type used by this module.
+ * @typedef {JAVASCRIPT_TYPE | RUNTIME_TYPE | WEBASSEMBLY_TYPE | ASSET_TYPE | ASSET_URL_TYPE | CSS_TYPE | CSS_IMPORT_TYPE | CSS_TEXT_TYPE | HTML_TYPE | SHARED_INIT_TYPE | REMOTE_GENERATOR_TYPE | CONSUME_SHARED_GENERATOR_TYPE | UNKNOWN_TYPE} AllTypes
+ */
+
+/**
+ * @type {ReadonlySet<never>}
+ */
+const NO_TYPES = new Set();
+
+/**
+ * @type {ReadonlySet<"asset">}
+ */
+const ASSET_TYPES = new Set([ASSET_TYPE]);
+
+/**
+ * @type {ReadonlySet<"asset" | "javascript" | "asset">}
+ */
+const ASSET_AND_JAVASCRIPT_TYPES = new Set([ASSET_TYPE, JAVASCRIPT_TYPE]);
+
+/**
+ * @type {ReadonlySet<"asset-url" | "asset">}
+ */
+const ASSET_AND_ASSET_URL_TYPES = new Set([ASSET_TYPE, ASSET_URL_TYPE]);
+
+/**
+ * @type {ReadonlySet<"javascript" | "asset-url" | "asset">}
+ */
+const ASSET_AND_JAVASCRIPT_AND_ASSET_URL_TYPES = new Set([
+	ASSET_TYPE,
+	JAVASCRIPT_TYPE,
+	ASSET_URL_TYPE
+]);
+
+/**
+ * @type {ReadonlySet<"javascript">}
+ */
+const JAVASCRIPT_TYPES = new Set([JAVASCRIPT_TYPE]);
+
+/**
+ * @type {ReadonlySet<"javascript" | "asset-url">}
+ */
+const JAVASCRIPT_AND_ASSET_URL_TYPES = new Set([
+	JAVASCRIPT_TYPE,
+	ASSET_URL_TYPE
+]);
+
+/**
+ * @type {ReadonlySet<"javascript" | "css">}
+ */
+const JAVASCRIPT_AND_CSS_TYPES = new Set([JAVASCRIPT_TYPE, CSS_TYPE]);
+
+/**
+ * @type {ReadonlySet<"css">}
+ */
+const CSS_TYPES = new Set([CSS_TYPE]);
+
+/**
+ * @type {ReadonlySet<"asset-url">}
+ */
+const ASSET_URL_TYPES = new Set([ASSET_URL_TYPE]);
+
+/**
+ * @type {ReadonlySet<"css-text">}
+ */
+const CSS_TEXT_TYPES = new Set([CSS_TEXT_TYPE]);
+
+/**
+ * @type {ReadonlySet<"javascript" | "css-text">}
+ */
+const JAVASCRIPT_AND_CSS_TEXT_TYPES = new Set([JAVASCRIPT_TYPE, CSS_TEXT_TYPE]);
+/**
+ * @type {ReadonlySet<"css-import">}
+ */
+const CSS_IMPORT_TYPES = new Set([CSS_IMPORT_TYPE]);
+
+/**
+ * @type {ReadonlySet<"html">}
+ */
+const HTML_TYPES = new Set([HTML_TYPE]);
+
+/**
+ * @type {ReadonlySet<"webassembly">}
+ */
+const WEBASSEMBLY_TYPES = new Set([WEBASSEMBLY_TYPE]);
+
+/**
+ * @type {ReadonlySet<"runtime">}
+ */
+const RUNTIME_TYPES = new Set([RUNTIME_TYPE]);
+
+/**
+ * @type {ReadonlySet<"remote" | "share-init">}
+ */
+const REMOTE_AND_SHARE_INIT_TYPES = new Set([
+	REMOTE_GENERATOR_TYPE,
+	SHARED_INIT_TYPE
+]);
+
+/**
+ * @type {ReadonlySet<"consume-shared">}
+ */
+const CONSUME_SHARED_TYPES = new Set([CONSUME_SHARED_GENERATOR_TYPE]);
+
+/**
+ * @type {ReadonlySet<"share-init">}
+ */
+const SHARED_INIT_TYPES = new Set([SHARED_INIT_TYPE]);
+
+module.exports.ASSET_AND_ASSET_URL_TYPES = ASSET_AND_ASSET_URL_TYPES;
+module.exports.ASSET_AND_JAVASCRIPT_AND_ASSET_URL_TYPES =
+	ASSET_AND_JAVASCRIPT_AND_ASSET_URL_TYPES;
+module.exports.ASSET_AND_JAVASCRIPT_TYPES = ASSET_AND_JAVASCRIPT_TYPES;
+module.exports.ASSET_TYPE = ASSET_TYPE;
+module.exports.ASSET_TYPES = ASSET_TYPES;
+module.exports.ASSET_URL_TYPE = ASSET_URL_TYPE;
+module.exports.ASSET_URL_TYPES = ASSET_URL_TYPES;
+module.exports.CONSUME_SHARED_TYPES = CONSUME_SHARED_TYPES;
+module.exports.CSS_IMPORT_TYPE = CSS_IMPORT_TYPE;
+module.exports.CSS_IMPORT_TYPES = CSS_IMPORT_TYPES;
+module.exports.CSS_TEXT_TYPE = CSS_TEXT_TYPE;
+module.exports.CSS_TEXT_TYPES = CSS_TEXT_TYPES;
+module.exports.CSS_TYPE = CSS_TYPE;
+module.exports.CSS_TYPES = CSS_TYPES;
+module.exports.HTML_TYPE = HTML_TYPE;
+module.exports.HTML_TYPES = HTML_TYPES;
+module.exports.JAVASCRIPT_AND_ASSET_URL_TYPES = JAVASCRIPT_AND_ASSET_URL_TYPES;
+module.exports.JAVASCRIPT_AND_CSS_TEXT_TYPES = JAVASCRIPT_AND_CSS_TEXT_TYPES;
+module.exports.JAVASCRIPT_AND_CSS_TYPES = JAVASCRIPT_AND_CSS_TYPES;
+module.exports.JAVASCRIPT_TYPE = JAVASCRIPT_TYPE;
+module.exports.JAVASCRIPT_TYPES = JAVASCRIPT_TYPES;
+module.exports.NO_TYPES = NO_TYPES;
+module.exports.REMOTE_AND_SHARE_INIT_TYPES = REMOTE_AND_SHARE_INIT_TYPES;
+module.exports.RUNTIME_TYPE = RUNTIME_TYPE;
+module.exports.RUNTIME_TYPES = RUNTIME_TYPES;
+module.exports.SHARED_INIT_TYPE = SHARED_INIT_TYPE;
+module.exports.SHARED_INIT_TYPES = SHARED_INIT_TYPES;
+module.exports.UNKNOWN_TYPE = UNKNOWN_TYPE;
+module.exports.WEBASSEMBLY_TYPE = WEBASSEMBLY_TYPE;
+module.exports.WEBASSEMBLY_TYPES = WEBASSEMBLY_TYPES;
Index: frontend/node_modules/webpack/lib/ModuleTemplate.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,181 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("tapable").Tap} Tap */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").ModuleRenderContext}  ModuleRenderContext */
+/** @typedef {import("./util/Hash")} Hash */
+
+/**
+ * Defines the if set type used by this module.
+ * @template T
+ * @typedef {import("tapable").IfSet<T>} IfSet
+ */
+
+const getJavascriptModulesPlugin = memoize(() =>
+	require("./javascript/JavascriptModulesPlugin")
+);
+
+// TODO webpack 6: remove this class
+class ModuleTemplate {
+	/**
+	 * Creates an instance of ModuleTemplate.
+	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
+	 * @param {Compilation} compilation the compilation
+	 */
+	constructor(runtimeTemplate, compilation) {
+		this._runtimeTemplate = runtimeTemplate;
+		this.type = "javascript";
+		this.hooks = Object.freeze({
+			content: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, module: Module, moduleRenderContext: ModuleRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderModuleContent.tap(
+								options,
+								(source, module, renderContext) =>
+									fn(
+										source,
+										module,
+										renderContext,
+										renderContext.dependencyTemplates
+									)
+							);
+					},
+					"ModuleTemplate.hooks.content is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModuleContent instead)",
+					"DEP_MODULE_TEMPLATE_CONTENT"
+				)
+			},
+			module: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, module: Module, moduleRenderContext: ModuleRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderModuleContent.tap(
+								options,
+								(source, module, renderContext) =>
+									fn(
+										source,
+										module,
+										renderContext,
+										renderContext.dependencyTemplates
+									)
+							);
+					},
+					"ModuleTemplate.hooks.module is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModuleContent instead)",
+					"DEP_MODULE_TEMPLATE_MODULE"
+				)
+			},
+			render: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, module: Module, chunkRenderContext: ChunkRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderModuleContainer.tap(
+								options,
+								(source, module, renderContext) =>
+									fn(
+										source,
+										module,
+										renderContext,
+										renderContext.dependencyTemplates
+									)
+							);
+					},
+					"ModuleTemplate.hooks.render is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer instead)",
+					"DEP_MODULE_TEMPLATE_RENDER"
+				)
+			},
+			package: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(source: Source, module: Module, chunkRenderContext: ChunkRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
+					 */
+					(options, fn) => {
+						getJavascriptModulesPlugin()
+							.getCompilationHooks(compilation)
+							.renderModulePackage.tap(
+								options,
+								(source, module, renderContext) =>
+									fn(
+										source,
+										module,
+										renderContext,
+										renderContext.dependencyTemplates
+									)
+							);
+					},
+					"ModuleTemplate.hooks.package is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModulePackage instead)",
+					"DEP_MODULE_TEMPLATE_PACKAGE"
+				)
+			},
+			hash: {
+				tap: util.deprecate(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @template AdditionalOptions
+					 * @param {string | Tap & IfSet<AdditionalOptions>} options options
+					 * @param {(hash: Hash) => void} fn fn
+					 */
+					(options, fn) => {
+						compilation.hooks.fullHash.tap(options, fn);
+					},
+					"ModuleTemplate.hooks.hash is deprecated (use Compilation.hooks.fullHash instead)",
+					"DEP_MODULE_TEMPLATE_HASH"
+				)
+			}
+		});
+	}
+}
+
+Object.defineProperty(ModuleTemplate.prototype, "runtimeTemplate", {
+	get: util.deprecate(
+		/**
+		 * Returns output options.
+		 * @this {ModuleTemplate}
+		 * @returns {RuntimeTemplate} output options
+		 */
+		function runtimeTemplate() {
+			return this._runtimeTemplate;
+		},
+		"ModuleTemplate.runtimeTemplate is deprecated (use Compilation.runtimeTemplate instead)",
+		"DEP_WEBPACK_CHUNK_TEMPLATE_OUTPUT_OPTIONS"
+	)
+});
+
+module.exports = ModuleTemplate;
Index: frontend/node_modules/webpack/lib/ModuleTypeConstants.js
===================================================================
--- frontend/node_modules/webpack/lib/ModuleTypeConstants.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ModuleTypeConstants.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,199 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @TheLarkInn
+*/
+
+"use strict";
+
+/**
+ * @type {Readonly<"javascript/auto">}
+ */
+const JAVASCRIPT_MODULE_TYPE_AUTO = "javascript/auto";
+
+/**
+ * @type {Readonly<"javascript/dynamic">}
+ */
+const JAVASCRIPT_MODULE_TYPE_DYNAMIC = "javascript/dynamic";
+
+/**
+ * @type {Readonly<"javascript/esm">}
+ * This is the module type used for _strict_ ES Module syntax. This means that all legacy formats
+ * that webpack supports (CommonJS, AMD, SystemJS) are not supported.
+ */
+const JAVASCRIPT_MODULE_TYPE_ESM = "javascript/esm";
+
+/**
+ * @type {Readonly<"json">}
+ * This is the module type used for JSON files. JSON files are always parsed as ES Module.
+ */
+const JSON_MODULE_TYPE = "json";
+
+/**
+ * @type {Readonly<"webassembly/async">}
+ * This is the module type used for WebAssembly modules. In webpack 5 they are always treated as async modules.
+ */
+const WEBASSEMBLY_MODULE_TYPE_ASYNC = "webassembly/async";
+
+/**
+ * @type {Readonly<"webassembly/sync">}
+ * This is the module type used for WebAssembly modules. In webpack 4 they are always treated as sync modules.
+ * There is a legacy option to support this usage in webpack 5 and up.
+ */
+const WEBASSEMBLY_MODULE_TYPE_SYNC = "webassembly/sync";
+
+/**
+ * @type {Readonly<"css">}
+ * This is the module type used for CSS files.
+ */
+const CSS_MODULE_TYPE = "css";
+
+/**
+ * @type {Readonly<"css/global">}
+ * This is the module type used for CSS modules files where you need to use `:local` in selector list to hash classes.
+ */
+const CSS_MODULE_TYPE_GLOBAL = "css/global";
+
+/**
+ * @type {Readonly<"css/module">}
+ * This is the module type used for CSS modules files, by default all classes are hashed.
+ */
+const CSS_MODULE_TYPE_MODULE = "css/module";
+
+/**
+ * @type {Readonly<"css/auto">}
+ * This is the module type used for CSS files, the module will be parsed as CSS modules if it's filename contains `.module.` or `.modules.`.
+ */
+const CSS_MODULE_TYPE_AUTO = "css/auto";
+
+/**
+ * @type {Readonly<"html">}
+ * This is the module type used for HTML files when `experiments.html` is enabled.
+ * HTML modules are emitted as HTML assets and can be used as entry points.
+ */
+const HTML_MODULE_TYPE = "html";
+
+/**
+ * @type {Readonly<"asset">}
+ * This is the module type used for automatically choosing between `asset/inline`, `asset/resource` based on asset size limit (8096).
+ */
+const ASSET_MODULE_TYPE = "asset";
+
+/**
+ * @type {Readonly<"asset/inline">}
+ * This is the module type used for assets that are inlined as a data URI. This is the equivalent of `url-loader`.
+ */
+const ASSET_MODULE_TYPE_INLINE = "asset/inline";
+
+/**
+ * @type {Readonly<"asset/resource">}
+ * This is the module type used for assets that are copied to the output directory. This is the equivalent of `file-loader`.
+ */
+const ASSET_MODULE_TYPE_RESOURCE = "asset/resource";
+
+/**
+ * @type {Readonly<"asset/source">}
+ * This is the module type used for assets that are imported as source code. This is the equivalent of `raw-loader`.
+ */
+const ASSET_MODULE_TYPE_SOURCE = "asset/source";
+
+/**
+ * @type {Readonly<"asset/bytes">}
+ * This is the module type used for assets that are imported as Uint8Array.
+ */
+const ASSET_MODULE_TYPE_BYTES = "asset/bytes";
+
+/**
+ * @type {Readonly<"asset/raw-data-url">}
+ * This is the module type used for the ignored asset module.
+ */
+const ASSET_MODULE_TYPE_RAW_DATA_URL = "asset/raw-data-url";
+
+/**
+ * @type {Readonly<"runtime">}
+ * This is the module type used for the webpack runtime abstractions.
+ */
+const WEBPACK_MODULE_TYPE_RUNTIME = "runtime";
+
+/**
+ * @type {Readonly<"fallback-module">}
+ * This is the module type used for the ModuleFederation feature's FallbackModule class.
+ */
+const WEBPACK_MODULE_TYPE_FALLBACK = "fallback-module";
+
+/**
+ * @type {Readonly<"remote-module">}
+ * This is the module type used for the ModuleFederation feature's RemoteModule class.
+ */
+const WEBPACK_MODULE_TYPE_REMOTE = "remote-module";
+
+/**
+ * @type {Readonly<"provide-module">}
+ * This is the module type used for the ModuleFederation feature's ProvideModule class.
+ */
+const WEBPACK_MODULE_TYPE_PROVIDE = "provide-module";
+
+/**
+ * @type {Readonly<"consume-shared-module">}
+ * This is the module type used for the ModuleFederation feature's ConsumeSharedModule class.
+ */
+const WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE = "consume-shared-module";
+
+/**
+ * @type {Readonly<"lazy-compilation-proxy">}
+ * Module type used for `experiments.lazyCompilation` feature. See `LazyCompilationPlugin` for more information.
+ */
+const WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY = "lazy-compilation-proxy";
+
+/** @typedef {"javascript/auto" | "javascript/dynamic" | "javascript/esm"} JavaScriptModuleTypes */
+/** @typedef {"json"} JSONModuleType */
+/** @typedef {"webassembly/async" | "webassembly/sync"} WebAssemblyModuleTypes */
+/** @typedef {"css" | "css/global" | "css/module" | "css/auto"} CssModuleTypes */
+/** @typedef {"html"} HTMLModuleType */
+/** @typedef {"asset" | "asset/inline" | "asset/resource" | "asset/source" | "asset/raw-data-url"} AssetModuleTypes */
+/** @typedef {"runtime" | "fallback-module" | "remote-module" | "provide-module" | "consume-shared-module" | "lazy-compilation-proxy"} WebpackModuleTypes */
+/** @typedef {string} UnknownModuleTypes */
+/** @typedef {JavaScriptModuleTypes | JSONModuleType | WebAssemblyModuleTypes | CssModuleTypes | HTMLModuleType | AssetModuleTypes | WebpackModuleTypes | UnknownModuleTypes} ModuleTypes */
+
+module.exports.ASSET_MODULE_TYPE = ASSET_MODULE_TYPE;
+module.exports.ASSET_MODULE_TYPE_BYTES = ASSET_MODULE_TYPE_BYTES;
+module.exports.ASSET_MODULE_TYPE_INLINE = ASSET_MODULE_TYPE_INLINE;
+module.exports.ASSET_MODULE_TYPE_RAW_DATA_URL = ASSET_MODULE_TYPE_RAW_DATA_URL;
+module.exports.ASSET_MODULE_TYPE_RESOURCE = ASSET_MODULE_TYPE_RESOURCE;
+module.exports.ASSET_MODULE_TYPE_SOURCE = ASSET_MODULE_TYPE_SOURCE;
+/** @type {CssModuleTypes[]} */
+module.exports.CSS_MODULES = [
+	CSS_MODULE_TYPE,
+	CSS_MODULE_TYPE_GLOBAL,
+	CSS_MODULE_TYPE_MODULE,
+	CSS_MODULE_TYPE_AUTO
+];
+module.exports.CSS_MODULE_TYPE = CSS_MODULE_TYPE;
+module.exports.CSS_MODULE_TYPE_AUTO = CSS_MODULE_TYPE_AUTO;
+module.exports.CSS_MODULE_TYPE_GLOBAL = CSS_MODULE_TYPE_GLOBAL;
+module.exports.CSS_MODULE_TYPE_MODULE = CSS_MODULE_TYPE_MODULE;
+module.exports.HTML_MODULE_TYPE = HTML_MODULE_TYPE;
+/** @type {JavaScriptModuleTypes[]} */
+module.exports.JAVASCRIPT_MODULES = [
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+];
+module.exports.JAVASCRIPT_MODULE_TYPE_AUTO = JAVASCRIPT_MODULE_TYPE_AUTO;
+module.exports.JAVASCRIPT_MODULE_TYPE_DYNAMIC = JAVASCRIPT_MODULE_TYPE_DYNAMIC;
+module.exports.JAVASCRIPT_MODULE_TYPE_ESM = JAVASCRIPT_MODULE_TYPE_ESM;
+module.exports.JSON_MODULE_TYPE = JSON_MODULE_TYPE;
+/** @type {WebAssemblyModuleTypes[]} */
+module.exports.WEBASSEMBLY_MODULES = [
+	WEBASSEMBLY_MODULE_TYPE_ASYNC,
+	WEBASSEMBLY_MODULE_TYPE_SYNC
+];
+module.exports.WEBASSEMBLY_MODULE_TYPE_ASYNC = WEBASSEMBLY_MODULE_TYPE_ASYNC;
+module.exports.WEBASSEMBLY_MODULE_TYPE_SYNC = WEBASSEMBLY_MODULE_TYPE_SYNC;
+module.exports.WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE =
+	WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE;
+module.exports.WEBPACK_MODULE_TYPE_FALLBACK = WEBPACK_MODULE_TYPE_FALLBACK;
+module.exports.WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY =
+	WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY;
+module.exports.WEBPACK_MODULE_TYPE_PROVIDE = WEBPACK_MODULE_TYPE_PROVIDE;
+module.exports.WEBPACK_MODULE_TYPE_REMOTE = WEBPACK_MODULE_TYPE_REMOTE;
+module.exports.WEBPACK_MODULE_TYPE_RUNTIME = WEBPACK_MODULE_TYPE_RUNTIME;
Index: frontend/node_modules/webpack/lib/MultiCompiler.js
===================================================================
--- frontend/node_modules/webpack/lib/MultiCompiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/MultiCompiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,706 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const { MultiHook, SyncHook } = require("tapable");
+
+const MultiStats = require("./MultiStats");
+const MultiWatching = require("./MultiWatching");
+const ConcurrentCompilationError = require("./errors/ConcurrentCompilationError");
+const WebpackError = require("./errors/WebpackError");
+const ArrayQueue = require("./util/ArrayQueue");
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("tapable").AsyncSeriesHook<T>} AsyncSeriesHook<T>
+ */
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @template R
+ * @typedef {import("tapable").SyncBailHook<T, R>} SyncBailHook<T, R>
+ */
+/** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
+/** @typedef {import("../declarations/WebpackOptions").WatchOptions} WatchOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/**
+ * Defines the callback type used by this module.
+ * @template T
+ * @template [R=void]
+ * @typedef {import("./webpack").Callback<T, R>} Callback
+ */
+/** @typedef {import("./webpack").ErrorCallback} ErrorCallback */
+/** @typedef {import("./Stats")} Stats */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
+/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
+/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
+
+/**
+ * Defines the run with dependencies handler callback.
+ * @callback RunWithDependenciesHandler
+ * @param {Compiler} compiler
+ * @param {Callback<MultiStats>} callback
+ * @returns {void}
+ */
+
+/**
+ * Defines the multi compiler options type used by this module.
+ * @typedef {object} MultiCompilerOptions
+ * @property {number=} parallelism how many Compilers are allows to run at the same time in parallel
+ */
+
+/** @typedef {ReadonlyArray<WebpackOptions> & MultiCompilerOptions} MultiWebpackOptions */
+
+const CLASS_NAME = "MultiCompiler";
+
+module.exports = class MultiCompiler {
+	/**
+	 * Creates an instance of MultiCompiler.
+	 * @param {Compiler[] | Record<string, Compiler>} compilers child compilers
+	 * @param {MultiCompilerOptions} options options
+	 */
+	constructor(compilers, options) {
+		if (!Array.isArray(compilers)) {
+			/** @type {Compiler[]} */
+			compilers = Object.keys(compilers).map((name) => {
+				/** @type {Record<string, Compiler>} */
+				(compilers)[name].name = name;
+				return /** @type {Record<string, Compiler>} */ (compilers)[name];
+			});
+		}
+
+		this.hooks = Object.freeze({
+			/** @type {SyncHook<[MultiStats]>} */
+			done: new SyncHook(["stats"]),
+			/** @type {MultiHook<SyncHook<[string | null, number]>>} */
+			invalid: new MultiHook(compilers.map((c) => c.hooks.invalid)),
+			/** @type {MultiHook<AsyncSeriesHook<[Compiler]>>} */
+			run: new MultiHook(compilers.map((c) => c.hooks.run)),
+			/** @type {SyncHook<[]>} */
+			watchClose: new SyncHook([]),
+			/** @type {MultiHook<AsyncSeriesHook<[Compiler]>>} */
+			watchRun: new MultiHook(compilers.map((c) => c.hooks.watchRun)),
+			/** @type {MultiHook<SyncBailHook<[string, string, EXPECTED_ANY[] | undefined], true | void>>} */
+			infrastructureLog: new MultiHook(
+				compilers.map((c) => c.hooks.infrastructureLog)
+			)
+		});
+		this.compilers = compilers;
+		/** @type {MultiCompilerOptions} */
+		this._options = {
+			parallelism: options.parallelism || Infinity
+		};
+		/** @type {WeakMap<Compiler, string[]>} */
+		this.dependencies = new WeakMap();
+		this.running = false;
+
+		/** @type {(Stats | null)[]} */
+		const compilerStats = this.compilers.map(() => null);
+		let doneCompilers = 0;
+		for (let index = 0; index < this.compilers.length; index++) {
+			const compiler = this.compilers[index];
+			const compilerIndex = index;
+			let compilerDone = false;
+			// eslint-disable-next-line no-loop-func
+			compiler.hooks.done.tap(CLASS_NAME, (stats) => {
+				if (!compilerDone) {
+					compilerDone = true;
+					doneCompilers++;
+				}
+				compilerStats[compilerIndex] = stats;
+				if (doneCompilers === this.compilers.length) {
+					this.hooks.done.call(
+						new MultiStats(/** @type {Stats[]} */ (compilerStats))
+					);
+				}
+			});
+			// eslint-disable-next-line no-loop-func
+			compiler.hooks.invalid.tap(CLASS_NAME, () => {
+				if (compilerDone) {
+					compilerDone = false;
+					doneCompilers--;
+				}
+			});
+		}
+		this._validateCompilersOptions();
+	}
+
+	_validateCompilersOptions() {
+		if (this.compilers.length < 2) return;
+		/**
+		 * Adds the provided compiler to the multi compiler.
+		 * @param {Compiler} compiler compiler
+		 * @param {WebpackError} warning warning
+		 */
+		const addWarning = (compiler, warning) => {
+			compiler.hooks.thisCompilation.tap(CLASS_NAME, (compilation) => {
+				compilation.warnings.push(warning);
+			});
+		};
+		/** @type {Set<string>} */
+		const cacheNames = new Set();
+		for (const compiler of this.compilers) {
+			if (compiler.options.cache && "name" in compiler.options.cache) {
+				const name = /** @type {string} */ (compiler.options.cache.name);
+				if (cacheNames.has(name)) {
+					addWarning(
+						compiler,
+						new WebpackError(
+							`${
+								compiler.name
+									? `Compiler with name "${compiler.name}" doesn't use unique cache name. `
+									: ""
+							}Please set unique "cache.name" option. Name "${name}" already used.`
+						)
+					);
+				} else {
+					cacheNames.add(name);
+				}
+			}
+		}
+	}
+
+	get options() {
+		return Object.assign(
+			this.compilers.map((c) => c.options),
+			this._options
+		);
+	}
+
+	get outputPath() {
+		let commonPath = this.compilers[0].outputPath;
+		for (const compiler of this.compilers) {
+			while (
+				compiler.outputPath.indexOf(commonPath) !== 0 &&
+				/[/\\]/.test(commonPath)
+			) {
+				commonPath = commonPath.replace(/[/\\][^/\\]*$/, "");
+			}
+		}
+
+		if (!commonPath && this.compilers[0].outputPath[0] === "/") return "/";
+		return commonPath;
+	}
+
+	get inputFileSystem() {
+		throw new Error("Cannot read inputFileSystem of a MultiCompiler");
+	}
+
+	/**
+	 * Sets input file system.
+	 * @param {InputFileSystem} value the new input file system
+	 */
+	set inputFileSystem(value) {
+		for (const compiler of this.compilers) {
+			compiler.inputFileSystem = value;
+		}
+	}
+
+	get outputFileSystem() {
+		throw new Error("Cannot read outputFileSystem of a MultiCompiler");
+	}
+
+	/**
+	 * Sets output file system.
+	 * @param {OutputFileSystem} value the new output file system
+	 */
+	set outputFileSystem(value) {
+		for (const compiler of this.compilers) {
+			compiler.outputFileSystem = value;
+		}
+	}
+
+	get watchFileSystem() {
+		throw new Error("Cannot read watchFileSystem of a MultiCompiler");
+	}
+
+	/**
+	 * Sets watch file system.
+	 * @param {WatchFileSystem} value the new watch file system
+	 */
+	set watchFileSystem(value) {
+		for (const compiler of this.compilers) {
+			compiler.watchFileSystem = value;
+		}
+	}
+
+	/**
+	 * Sets intermediate file system.
+	 * @param {IntermediateFileSystem} value the new intermediate file system
+	 */
+	set intermediateFileSystem(value) {
+		for (const compiler of this.compilers) {
+			compiler.intermediateFileSystem = value;
+		}
+	}
+
+	get intermediateFileSystem() {
+		throw new Error("Cannot read outputFileSystem of a MultiCompiler");
+	}
+
+	/**
+	 * Gets infrastructure logger.
+	 * @param {string | (() => string)} name name of the logger, or function called once to get the logger name
+	 * @returns {Logger} a logger with that name
+	 */
+	getInfrastructureLogger(name) {
+		return this.compilers[0].getInfrastructureLogger(name);
+	}
+
+	/**
+	 * Updates dependencies using the provided compiler.
+	 * @param {Compiler} compiler the child compiler
+	 * @param {string[]} dependencies its dependencies
+	 * @returns {void}
+	 */
+	setDependencies(compiler, dependencies) {
+		this.dependencies.set(compiler, dependencies);
+	}
+
+	/**
+	 * Validate dependencies.
+	 * @param {Callback<MultiStats>} callback signals when the validation is complete
+	 * @returns {boolean} true if the dependencies are valid
+	 */
+	validateDependencies(callback) {
+		/** @type {Set<{ source: Compiler, target: Compiler }>} */
+		const edges = new Set();
+		/** @type {string[]} */
+		const missing = [];
+		/**
+		 * Returns target was found.
+		 * @param {Compiler} compiler compiler
+		 * @returns {boolean} target was found
+		 */
+		const targetFound = (compiler) => {
+			for (const edge of edges) {
+				if (edge.target === compiler) {
+					return true;
+				}
+			}
+			return false;
+		};
+		/**
+		 * Returns result.
+		 * @param {{ source: Compiler, target: Compiler }} e1 edge 1
+		 * @param {{ source: Compiler, target: Compiler }} e2 edge 2
+		 * @returns {number} result
+		 */
+		const sortEdges = (e1, e2) =>
+			/** @type {string} */
+			(e1.source.name).localeCompare(/** @type {string} */ (e2.source.name)) ||
+			/** @type {string} */
+			(e1.target.name).localeCompare(/** @type {string} */ (e2.target.name));
+		for (const source of this.compilers) {
+			const dependencies = this.dependencies.get(source);
+			if (dependencies) {
+				for (const dep of dependencies) {
+					const target = this.compilers.find((c) => c.name === dep);
+					if (!target) {
+						missing.push(dep);
+					} else {
+						edges.add({
+							source,
+							target
+						});
+					}
+				}
+			}
+		}
+		/** @type {string[]} */
+		const errors = missing.map(
+			(m) => `Compiler dependency \`${m}\` not found.`
+		);
+		const stack = this.compilers.filter((c) => !targetFound(c));
+		while (stack.length > 0) {
+			const current = stack.pop();
+			for (const edge of edges) {
+				if (edge.source === current) {
+					edges.delete(edge);
+					const target = edge.target;
+					if (!targetFound(target)) {
+						stack.push(target);
+					}
+				}
+			}
+		}
+		if (edges.size > 0) {
+			/** @type {string[]} */
+			const lines = [...edges]
+				.sort(sortEdges)
+				.map((edge) => `${edge.source.name} -> ${edge.target.name}`);
+			lines.unshift("Circular dependency found in compiler dependencies.");
+			errors.unshift(lines.join("\n"));
+		}
+		if (errors.length > 0) {
+			const message = errors.join("\n");
+			callback(new Error(message));
+			return false;
+		}
+		return true;
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Run with dependencies.
+	 * @deprecated This method should have been private
+	 * @param {Compiler[]} compilers the child compilers
+	 * @param {RunWithDependenciesHandler} fn a handler to run for each compiler
+	 * @param {Callback<Stats[]>} callback the compiler's handler
+	 * @returns {void}
+	 */
+	runWithDependencies(compilers, fn, callback) {
+		/** @type {Set<string>} */
+		const fulfilledNames = new Set();
+		let remainingCompilers = compilers;
+		/**
+		 * Checks whether this multi compiler is dependency fulfilled.
+		 * @param {string} d dependency
+		 * @returns {boolean} when dependency was fulfilled
+		 */
+		const isDependencyFulfilled = (d) => fulfilledNames.has(d);
+		/**
+		 * Gets ready compilers.
+		 * @returns {Compiler[]} compilers
+		 */
+		const getReadyCompilers = () => {
+			/** @type {Compiler[]} */
+			const readyCompilers = [];
+			const list = remainingCompilers;
+			remainingCompilers = [];
+			for (const c of list) {
+				const dependencies = this.dependencies.get(c);
+				const ready =
+					!dependencies || dependencies.every(isDependencyFulfilled);
+				if (ready) {
+					readyCompilers.push(c);
+				} else {
+					remainingCompilers.push(c);
+				}
+			}
+			return readyCompilers;
+		};
+		/**
+		 * Processes the provided stat.
+		 * @param {Callback<Stats[]>} callback callback
+		 * @returns {void}
+		 */
+		const runCompilers = (callback) => {
+			if (remainingCompilers.length === 0) return callback(null);
+			asyncLib.map(
+				getReadyCompilers(),
+				(compiler, callback) => {
+					fn(compiler, (err) => {
+						if (err) return callback(err);
+						fulfilledNames.add(/** @type {string} */ (compiler.name));
+						runCompilers(callback);
+					});
+				},
+				(err, results) => {
+					callback(/** @type {Error | null} */ (err), results);
+				}
+			);
+		};
+		runCompilers(callback);
+	}
+
+	/**
+	 * Returns result of setup.
+	 * @template SetupResult
+	 * @param {(compiler: Compiler, index: number, doneCallback: Callback<Stats>, isBlocked: () => boolean, setChanged: () => void, setInvalid: () => void) => SetupResult} setup setup a single compiler
+	 * @param {(compiler: Compiler, setupResult: SetupResult, callback: Callback<Stats>) => void} run run/continue a single compiler
+	 * @param {Callback<MultiStats>} callback callback when all compilers are done, result includes Stats of all changed compilers
+	 * @returns {SetupResult[]} result of setup
+	 */
+	_runGraph(setup, run, callback) {
+		/** @typedef {{ compiler: Compiler, setupResult: undefined | SetupResult, result: undefined | Stats, state: "pending" | "blocked" | "queued" | "starting" | "running" | "running-outdated" | "done", children: Node[], parents: Node[] }} Node */
+
+		// State transitions for nodes:
+		// -> blocked (initial)
+		// blocked -> starting [running++] (when all parents done)
+		// queued -> starting [running++] (when processing the queue)
+		// starting -> running (when run has been called)
+		// running -> done [running--] (when compilation is done)
+		// done -> pending (when invalidated from file change)
+		// pending -> blocked [add to queue] (when invalidated from aggregated changes)
+		// done -> blocked [add to queue] (when invalidated, from parent invalidation)
+		// running -> running-outdated (when invalidated, either from change or parent invalidation)
+		// running-outdated -> blocked [running--] (when compilation is done)
+
+		/** @type {Node[]} */
+		const nodes = this.compilers.map((compiler) => ({
+			compiler,
+			setupResult: undefined,
+			result: undefined,
+			state: "blocked",
+			children: [],
+			parents: []
+		}));
+		/** @type {Map<string, Node>} */
+		const compilerToNode = new Map();
+		for (const node of nodes) {
+			compilerToNode.set(/** @type {string} */ (node.compiler.name), node);
+		}
+		for (const node of nodes) {
+			const dependencies = this.dependencies.get(node.compiler);
+			if (!dependencies) continue;
+			for (const dep of dependencies) {
+				const parent = /** @type {Node} */ (compilerToNode.get(dep));
+				node.parents.push(parent);
+				parent.children.push(node);
+			}
+		}
+		/** @type {ArrayQueue<Node>} */
+		const queue = new ArrayQueue();
+		for (const node of nodes) {
+			if (node.parents.length === 0) {
+				node.state = "queued";
+				queue.enqueue(node);
+			}
+		}
+		let errored = false;
+		let running = 0;
+		const parallelism = /** @type {number} */ (this._options.parallelism);
+		/**
+		 * Processes the provided node.
+		 * @param {Node} node node
+		 * @param {(Error | null)=} err error
+		 * @param {Stats=} stats result
+		 * @returns {void}
+		 */
+		const nodeDone = (node, err, stats) => {
+			if (errored) return;
+			if (err) {
+				errored = true;
+				return asyncLib.each(
+					nodes,
+					(node, callback) => {
+						if (node.compiler.watching) {
+							node.compiler.watching.close(callback);
+						} else {
+							callback();
+						}
+					},
+					() => callback(err)
+				);
+			}
+			node.result = stats;
+			running--;
+			if (node.state === "running") {
+				node.state = "done";
+				for (const child of node.children) {
+					if (child.state === "blocked") queue.enqueue(child);
+				}
+			} else if (node.state === "running-outdated") {
+				node.state = "blocked";
+				queue.enqueue(node);
+			}
+			processQueue();
+		};
+		/**
+		 * Node invalid from parent.
+		 * @param {Node} node node
+		 * @returns {void}
+		 */
+		const nodeInvalidFromParent = (node) => {
+			if (node.state === "done") {
+				node.state = "blocked";
+			} else if (node.state === "running") {
+				node.state = "running-outdated";
+			}
+			for (const child of node.children) {
+				nodeInvalidFromParent(child);
+			}
+		};
+		/**
+		 * Processes the provided node.
+		 * @param {Node} node node
+		 * @returns {void}
+		 */
+		const nodeInvalid = (node) => {
+			if (node.state === "done") {
+				node.state = "pending";
+			} else if (node.state === "running") {
+				node.state = "running-outdated";
+			}
+			for (const child of node.children) {
+				nodeInvalidFromParent(child);
+			}
+		};
+		/**
+		 * Processes the provided node.
+		 * @param {Node} node node
+		 * @returns {void}
+		 */
+		const nodeChange = (node) => {
+			nodeInvalid(node);
+			if (node.state === "pending") {
+				node.state = "blocked";
+			}
+			if (node.state === "blocked") {
+				queue.enqueue(node);
+				processQueue();
+			}
+		};
+
+		/** @type {SetupResult[]} */
+		const setupResults = [];
+		for (const [i, node] of nodes.entries()) {
+			setupResults.push(
+				(node.setupResult = setup(
+					node.compiler,
+					i,
+					nodeDone.bind(null, node),
+					() => node.state !== "starting" && node.state !== "running",
+					() => nodeChange(node),
+					() => nodeInvalid(node)
+				))
+			);
+		}
+		let processing = true;
+		const processQueue = () => {
+			if (processing) return;
+			processing = true;
+			process.nextTick(processQueueWorker);
+		};
+		const processQueueWorker = () => {
+			// eslint-disable-next-line no-unmodified-loop-condition
+			while (running < parallelism && queue.length > 0 && !errored) {
+				const node = /** @type {Node} */ (queue.dequeue());
+				if (
+					node.state === "queued" ||
+					(node.state === "blocked" &&
+						node.parents.every((p) => p.state === "done"))
+				) {
+					running++;
+					node.state = "starting";
+					run(
+						node.compiler,
+						/** @type {SetupResult} */ (node.setupResult),
+						nodeDone.bind(null, node)
+					);
+					node.state = "running";
+				}
+			}
+			processing = false;
+			if (
+				!errored &&
+				running === 0 &&
+				nodes.every((node) => node.state === "done")
+			) {
+				/** @type {Stats[]} */
+				const stats = [];
+				for (const node of nodes) {
+					const result = node.result;
+					if (result) {
+						node.result = undefined;
+						stats.push(result);
+					}
+				}
+				if (stats.length > 0) {
+					callback(null, new MultiStats(stats));
+				}
+			}
+		};
+		processQueueWorker();
+		return setupResults;
+	}
+
+	/**
+	 * Returns a compiler watcher.
+	 * @param {WatchOptions | WatchOptions[]} watchOptions the watcher's options
+	 * @param {Callback<MultiStats>} handler signals when the call finishes
+	 * @returns {MultiWatching | undefined} a compiler watcher
+	 */
+	watch(watchOptions, handler) {
+		if (this.running) {
+			handler(new ConcurrentCompilationError());
+			return;
+		}
+		this.running = true;
+
+		if (this.validateDependencies(handler)) {
+			const watchings = this._runGraph(
+				(compiler, idx, callback, isBlocked, setChanged, setInvalid) => {
+					const watching = compiler.watch(
+						Array.isArray(watchOptions) ? watchOptions[idx] : watchOptions,
+						callback
+					);
+					if (watching) {
+						watching._onInvalid = setInvalid;
+						watching._onChange = setChanged;
+						watching._isBlocked = isBlocked;
+					}
+					return watching;
+				},
+				(compiler, watching, _callback) => {
+					if (compiler.watching !== watching) return;
+					if (!watching.running) watching.invalidate();
+				},
+				handler
+			);
+			return new MultiWatching(watchings, this);
+		}
+
+		return new MultiWatching([], this);
+	}
+
+	/**
+	 * Processes the provided multi stat.
+	 * @param {Callback<MultiStats>} callback signals when the call finishes
+	 * @returns {void}
+	 */
+	run(callback) {
+		if (this.running) {
+			callback(new ConcurrentCompilationError());
+			return;
+		}
+		this.running = true;
+
+		if (this.validateDependencies(callback)) {
+			this._runGraph(
+				() => {},
+				(compiler, setupResult, callback) => compiler.run(callback),
+				(err, stats) => {
+					this.running = false;
+
+					if (callback !== undefined) {
+						return callback(err, stats);
+					}
+				}
+			);
+		}
+	}
+
+	purgeInputFileSystem() {
+		for (const compiler of this.compilers) {
+			if (compiler.inputFileSystem && compiler.inputFileSystem.purge) {
+				compiler.inputFileSystem.purge();
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the compiler closes
+	 * @returns {void}
+	 */
+	close(callback) {
+		asyncLib.each(
+			this.compilers,
+			(compiler, callback) => {
+				compiler.close(callback);
+			},
+			(error) => {
+				callback(/** @type {Error | null} */ (error));
+			}
+		);
+	}
+};
Index: frontend/node_modules/webpack/lib/MultiStats.js
===================================================================
--- frontend/node_modules/webpack/lib/MultiStats.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/MultiStats.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,221 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const identifierUtils = require("./util/identifier");
+
+/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
+/** @typedef {import("../declarations/WebpackOptions").StatsValue} StatsValue */
+/** @typedef {import("./Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
+/** @typedef {import("./Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
+/** @typedef {import("./Stats")} Stats */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").KnownStatsCompilation} KnownStatsCompilation */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */
+
+/**
+ * Returns indent.
+ * @param {string} str string
+ * @param {string} prefix pref
+ * @returns {string} indent
+ */
+const indent = (str, prefix) => {
+	const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`);
+	return prefix + rem;
+};
+
+/** @typedef {StatsOptions} MultiStatsOptions */
+/** @typedef {{ version: boolean, hash: boolean, errorsCount: boolean, warningsCount: boolean, errors: boolean, warnings: boolean, children: NormalizedStatsOptions[] }} ChildOptions */
+
+class MultiStats {
+	/**
+	 * Creates an instance of MultiStats.
+	 * @param {Stats[]} stats the child stats
+	 */
+	constructor(stats) {
+		this.stats = stats;
+	}
+
+	get hash() {
+		return this.stats.map((stat) => stat.hash).join("");
+	}
+
+	/**
+	 * Checks whether this multi stats has errors.
+	 * @returns {boolean} true if a child compilation encountered an error
+	 */
+	hasErrors() {
+		return this.stats.some((stat) => stat.hasErrors());
+	}
+
+	/**
+	 * Checks whether this multi stats has warnings.
+	 * @returns {boolean} true if a child compilation had a warning
+	 */
+	hasWarnings() {
+		return this.stats.some((stat) => stat.hasWarnings());
+	}
+
+	/**
+	 * Create child options.
+	 * @param {undefined | StatsValue} options stats options
+	 * @param {CreateStatsOptionsContext} context context
+	 * @returns {ChildOptions} context context
+	 */
+	_createChildOptions(options, context) {
+		const getCreateStatsOptions = () => {
+			if (!options) {
+				options = {};
+			}
+
+			const { children: childrenOptions = undefined, ...baseOptions } =
+				typeof options === "string"
+					? { preset: options }
+					: /** @type {StatsOptions} */ (options);
+
+			return { childrenOptions, baseOptions };
+		};
+
+		const children = this.stats.map((stat, idx) => {
+			if (typeof options === "boolean") {
+				return stat.compilation.createStatsOptions(options, context);
+			}
+			const { childrenOptions, baseOptions } = getCreateStatsOptions();
+			const childOptions = Array.isArray(childrenOptions)
+				? childrenOptions[idx]
+				: childrenOptions;
+			if (typeof childOptions === "boolean") {
+				return stat.compilation.createStatsOptions(childOptions, context);
+			}
+			return stat.compilation.createStatsOptions(
+				{
+					...baseOptions,
+					...(typeof childOptions === "string"
+						? { preset: childOptions }
+						: childOptions && typeof childOptions === "object"
+							? childOptions
+							: undefined)
+				},
+				context
+			);
+		});
+		return {
+			version: children.every((o) => o.version),
+			hash: children.every((o) => o.hash),
+			errorsCount: children.every((o) => o.errorsCount),
+			warningsCount: children.every((o) => o.warningsCount),
+			errors: children.every((o) => o.errors),
+			warnings: children.every((o) => o.warnings),
+			children
+		};
+	}
+
+	/**
+	 * Returns json output.
+	 * @param {StatsValue=} options stats options
+	 * @returns {StatsCompilation} json output
+	 */
+	toJson(options) {
+		const childOptions = this._createChildOptions(options, {
+			forToString: false
+		});
+		/** @type {KnownStatsCompilation} */
+		const obj = {};
+		obj.children = this.stats.map((stat, idx) => {
+			const obj = stat.toJson(childOptions.children[idx]);
+			const compilationName = stat.compilation.name;
+			const name =
+				compilationName &&
+				identifierUtils.makePathsRelative(
+					stat.compilation.compiler.context,
+					compilationName,
+					stat.compilation.compiler.root
+				);
+			obj.name = name;
+			return obj;
+		});
+		if (childOptions.version) {
+			obj.version = obj.children[0].version;
+		}
+		if (childOptions.hash) {
+			obj.hash = obj.children.map((j) => j.hash).join("");
+		}
+		/**
+		 * Returns result.
+		 * @param {StatsCompilation} j stats error
+		 * @param {StatsError} obj Stats error
+		 * @returns {StatsError} result
+		 */
+		const mapError = (j, obj) => ({
+			...obj,
+			compilerPath: obj.compilerPath ? `${j.name}.${obj.compilerPath}` : j.name
+		});
+		if (childOptions.errors) {
+			obj.errors = [];
+			for (const j of obj.children) {
+				const errors =
+					/** @type {NonNullable<KnownStatsCompilation["errors"]>} */
+					(j.errors);
+				for (const i of errors) {
+					obj.errors.push(mapError(j, i));
+				}
+			}
+		}
+		if (childOptions.warnings) {
+			obj.warnings = [];
+			for (const j of obj.children) {
+				const warnings =
+					/** @type {NonNullable<KnownStatsCompilation["warnings"]>} */
+					(j.warnings);
+				for (const i of warnings) {
+					obj.warnings.push(mapError(j, i));
+				}
+			}
+		}
+		if (childOptions.errorsCount) {
+			obj.errorsCount = 0;
+			for (const j of obj.children) {
+				obj.errorsCount += /** @type {number} */ (j.errorsCount);
+			}
+		}
+		if (childOptions.warningsCount) {
+			obj.warningsCount = 0;
+			for (const j of obj.children) {
+				obj.warningsCount += /** @type {number} */ (j.warningsCount);
+			}
+		}
+		return obj;
+	}
+
+	/**
+	 * Returns a string representation.
+	 * @param {StatsValue=} options stats options
+	 * @returns {string} string output
+	 */
+	toString(options) {
+		const childOptions = this._createChildOptions(options, {
+			forToString: true
+		});
+		const results = this.stats.map((stat, idx) => {
+			const str = stat.toString(childOptions.children[idx]);
+			const compilationName = stat.compilation.name;
+			const name =
+				compilationName &&
+				identifierUtils
+					.makePathsRelative(
+						stat.compilation.compiler.context,
+						compilationName,
+						stat.compilation.compiler.root
+					)
+					.replace(/\|/g, " ");
+			if (!str) return str;
+			return name ? `${name}:\n${indent(str, "  ")}` : str;
+		});
+		return results.filter(Boolean).join("\n\n");
+	}
+}
+
+module.exports = MultiStats;
Index: frontend/node_modules/webpack/lib/MultiWatching.js
===================================================================
--- frontend/node_modules/webpack/lib/MultiWatching.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/MultiWatching.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,80 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+
+/** @typedef {import("./MultiCompiler")} MultiCompiler */
+/** @typedef {import("./Watching")} Watching */
+/** @typedef {import("./webpack").ErrorCallback} ErrorCallback */
+
+class MultiWatching {
+	/**
+	 * Creates an instance of MultiWatching.
+	 * @param {Watching[]} watchings child compilers' watchers
+	 * @param {MultiCompiler} compiler the compiler
+	 */
+	constructor(watchings, compiler) {
+		this.watchings = watchings;
+		this.compiler = compiler;
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback=} callback signals when the build has completed again
+	 * @returns {void}
+	 */
+	invalidate(callback) {
+		if (callback) {
+			asyncLib.each(
+				this.watchings,
+				(watching, callback) => watching.invalidate(callback),
+				(err) => {
+					callback(/** @type {Error | null} */ (err));
+				}
+			);
+		} else {
+			for (const watching of this.watchings) {
+				watching.invalidate();
+			}
+		}
+	}
+
+	suspend() {
+		for (const watching of this.watchings) {
+			watching.suspend();
+		}
+	}
+
+	resume() {
+		for (const watching of this.watchings) {
+			watching.resume();
+		}
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the watcher is closed
+	 * @returns {void}
+	 */
+	close(callback) {
+		asyncLib.each(
+			this.watchings,
+			(watching, finishedCallback) => {
+				watching.close(finishedCallback);
+			},
+			(err) => {
+				this.compiler.hooks.watchClose.call();
+				if (typeof callback === "function") {
+					this.compiler.running = false;
+					callback(/** @type {Error | null} */ (err));
+				}
+			}
+		);
+	}
+}
+
+module.exports = MultiWatching;
Index: frontend/node_modules/webpack/lib/NoEmitOnErrorsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/NoEmitOnErrorsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/NoEmitOnErrorsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "NoEmitOnErrorsPlugin";
+
+class NoEmitOnErrorsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.shouldEmit.tap(PLUGIN_NAME, (compilation) => {
+			if (compilation.getStats().hasErrors()) return false;
+		});
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.shouldRecord.tap(PLUGIN_NAME, () => {
+				if (compilation.getStats().hasErrors()) return false;
+			});
+		});
+	}
+}
+
+module.exports = NoEmitOnErrorsPlugin;
Index: frontend/node_modules/webpack/lib/NodeStuffPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/NodeStuffPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/NodeStuffPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,596 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const CachedConstDependency = require("./dependencies/CachedConstDependency");
+const ConstDependency = require("./dependencies/ConstDependency");
+const ExternalModuleDependency = require("./dependencies/ExternalModuleDependency");
+const ExternalModuleInitFragmentDependency = require("./dependencies/ExternalModuleInitFragmentDependency");
+const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
+const NodeStuffInWebError = require("./errors/NodeStuffInWebError");
+const { evaluateToString } = require("./javascript/JavascriptParserHelpers");
+const { relative } = require("./util/fs");
+const { parseResource } = require("./util/identifier");
+
+/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../declarations/WebpackOptions").NodeOptions} NodeOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./NormalModule")} NormalModule */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Expression} Expression */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+
+const PLUGIN_NAME = "NodeStuffPlugin";
+const URL_MODULE_CONSTANT_FUNCTION_NAME = "__webpack_fileURLToPath__";
+
+class NodeStuffPlugin {
+	/**
+	 * Creates an instance of NodeStuffPlugin.
+	 * @param {NodeOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { options } = this;
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					ExternalModuleDependency,
+					new ExternalModuleDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					ExternalModuleInitFragmentDependency,
+					new ExternalModuleInitFragmentDependency.Template()
+				);
+
+				/**
+				 * Processes the provided parser.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {NodeOptions} nodeOptions options
+				 * @returns {void}
+				 */
+				const globalHandler = (parser, nodeOptions) => {
+					/**
+					 * Returns const dependency.
+					 * @param {Expression} expr expression
+					 * @returns {ConstDependency} const dependency
+					 */
+					const getGlobalDep = (expr) => {
+						if (compilation.outputOptions.environment.globalThis) {
+							return new ConstDependency(
+								"globalThis",
+								/** @type {Range} */ (expr.range)
+							);
+						}
+
+						return new ConstDependency(
+							RuntimeGlobals.global,
+							/** @type {Range} */ (expr.range),
+							[RuntimeGlobals.global]
+						);
+					};
+
+					const withWarning = nodeOptions.global === "warn";
+
+					parser.hooks.expression.for("global").tap(PLUGIN_NAME, (expr) => {
+						const dep = getGlobalDep(expr);
+						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+						parser.state.module.addPresentationalDependency(dep);
+
+						if (withWarning) {
+							parser.state.module.addWarning(
+								new NodeStuffInWebError(
+									dep.loc,
+									"global",
+									"The global namespace object is a Node.js feature and isn't available in browsers."
+								)
+							);
+						}
+					});
+
+					parser.hooks.rename.for("global").tap(PLUGIN_NAME, (expr) => {
+						const dep = getGlobalDep(expr);
+						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+						parser.state.module.addPresentationalDependency(dep);
+						return false;
+					});
+				};
+
+				const hooks = ImportMetaPlugin.getCompilationHooks(compilation);
+
+				/**
+				 * Sets module constant.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
+				 * @param {(module: NormalModule) => string} fn function
+				 * @param {"filename" | "dirname"} property a property
+				 * @returns {void}
+				 */
+				const setModuleConstant = (parser, expressionName, fn, property) => {
+					parser.hooks.expression
+						.for(expressionName)
+						.tap(PLUGIN_NAME, (expr) => {
+							const dep = new ConstDependency(
+								fn(parser.state.module),
+								/** @type {Range} */
+								(expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+
+					if (
+						expressionName === "import.meta.filename" ||
+						expressionName === "import.meta.dirname"
+					) {
+						hooks.propertyInDestructuring.tap(PLUGIN_NAME, (usingProperty) => {
+							if (usingProperty.id === property) {
+								return `${property}: ${fn(parser.state.module)},`;
+							}
+						});
+					}
+				};
+
+				/**
+				 * Sets cached module constant.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
+				 * @param {(module: NormalModule) => string} fn function
+				 * @param {"filename" | "dirname"} property a property
+				 * @param {string=} warning warning
+				 * @returns {void}
+				 */
+				const setCachedModuleConstant = (
+					parser,
+					expressionName,
+					fn,
+					property,
+					warning
+				) => {
+					parser.hooks.expression
+						.for(expressionName)
+						.tap(PLUGIN_NAME, (expr) => {
+							const dep = new CachedConstDependency(
+								JSON.stringify(fn(parser.state.module)),
+								/** @type {Range} */
+								(expr.range),
+								`__webpack_${property}__`
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+
+							if (warning) {
+								parser.state.module.addWarning(
+									new NodeStuffInWebError(dep.loc, expressionName, warning)
+								);
+							}
+
+							return true;
+						});
+
+					if (
+						expressionName === "import.meta.filename" ||
+						expressionName === "import.meta.dirname"
+					) {
+						hooks.propertyInDestructuring.tap(PLUGIN_NAME, (usingProperty) => {
+							if (property === usingProperty.id) {
+								if (warning) {
+									parser.state.module.addWarning(
+										new NodeStuffInWebError(
+											usingProperty.loc,
+											expressionName,
+											warning
+										)
+									);
+								}
+
+								return `${property}: ${JSON.stringify(fn(parser.state.module))},`;
+							}
+						});
+					}
+				};
+
+				/**
+				 * Updates constant using the provided parser.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
+				 * @param {string} value value
+				 * @param {"filename" | "dirname"} property a property
+				 * @param {string=} warning warning
+				 * @returns {void}
+				 */
+				const setConstant = (
+					parser,
+					expressionName,
+					value,
+					property,
+					warning
+				) =>
+					setCachedModuleConstant(
+						parser,
+						expressionName,
+						() => value,
+						property,
+						warning
+					);
+
+				/**
+				 * Sets url module constant.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {"__filename" | "__dirname" | "import.meta.filename" | "import.meta.dirname"} expressionName expression name
+				 * @param {"dirname" | "filename"} property property
+				 * @param {() => string} value function to get value
+				 * @returns {void}
+				 */
+				const setUrlModuleConstant = (
+					parser,
+					expressionName,
+					property,
+					value
+				) => {
+					parser.hooks.expression
+						.for(expressionName)
+						.tap(PLUGIN_NAME, (expr) => {
+							// We use `CachedConstDependency` because of `eval` devtool, there is no `import.meta` inside `eval()`
+							const { importMetaName, environment, module } =
+								compilation.outputOptions;
+
+							// Generate `import.meta.dirname` and `import.meta.filename` when:
+							// - they are supported by the environment
+							// - it is a universal target, because we can't use `import mod from "node:url"; ` at the top file
+							if (
+								environment.importMetaDirnameAndFilename ||
+								(compiler.platform.web === null &&
+									compiler.platform.node === null &&
+									module)
+							) {
+								const dep = new CachedConstDependency(
+									`${importMetaName}.${property}`,
+									/** @type {Range} */
+									(expr.range),
+									`__webpack_${property}__`,
+									CachedConstDependency.PLACE_CHUNK
+								);
+
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+								return;
+							}
+
+							const dep = new ExternalModuleDependency(
+								"url",
+								[
+									{
+										name: "fileURLToPath",
+										value: URL_MODULE_CONSTANT_FUNCTION_NAME
+									}
+								],
+								undefined,
+								`${URL_MODULE_CONSTANT_FUNCTION_NAME}(${value()})`,
+								/** @type {Range} */ (expr.range),
+								`__webpack_${property}__`,
+								ExternalModuleDependency.PLACE_CHUNK
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+
+							return true;
+						});
+
+					if (
+						expressionName === "import.meta.filename" ||
+						expressionName === "import.meta.dirname"
+					) {
+						hooks.propertyInDestructuring.tap(PLUGIN_NAME, (usingProperty) => {
+							if (property === usingProperty.id) {
+								const { importMetaName, environment, module } =
+									compilation.outputOptions;
+
+								if (
+									environment.importMetaDirnameAndFilename ||
+									(compiler.platform.web === null &&
+										compiler.platform.node === null &&
+										module)
+								) {
+									const dep = new CachedConstDependency(
+										`${importMetaName}.${property}`,
+										null,
+										`__webpack_${property}__`,
+										CachedConstDependency.PLACE_CHUNK
+									);
+									dep.loc = /** @type {DependencyLocation} */ (
+										usingProperty.loc
+									);
+									parser.state.module.addPresentationalDependency(dep);
+									return `${property}: __webpack_${property}__,`;
+								}
+
+								const dep = new ExternalModuleDependency(
+									"url",
+									[
+										{
+											name: "fileURLToPath",
+											value: URL_MODULE_CONSTANT_FUNCTION_NAME
+										}
+									],
+									undefined,
+									`${URL_MODULE_CONSTANT_FUNCTION_NAME}(${value()})`,
+									null,
+									`__webpack_${property}__`,
+									ExternalModuleDependency.PLACE_CHUNK
+								);
+
+								dep.loc = /** @type {DependencyLocation} */ (usingProperty.loc);
+								parser.state.module.addPresentationalDependency(dep);
+
+								return `${property}: __webpack_${property}__,`;
+							}
+						});
+					}
+				};
+
+				/**
+				 * Dirname and filename handler.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {NodeOptions} nodeOptions options
+				 * @param {{ dirname: "__dirname" | "import.meta.dirname", filename: "__filename" | "import.meta.filename" }} identifiers options
+				 * @returns {void}
+				 */
+				const dirnameAndFilenameHandler = (
+					parser,
+					nodeOptions,
+					{ dirname, filename }
+				) => {
+					// Keep `import.meta.filename` in code
+					if (
+						nodeOptions.__filename === false &&
+						filename === "import.meta.filename"
+					) {
+						setModuleConstant(parser, filename, () => filename, "filename");
+					}
+
+					if (nodeOptions.__filename) {
+						switch (nodeOptions.__filename) {
+							case "mock":
+								setConstant(parser, filename, "/index.js", "filename");
+								break;
+							case "warn-mock":
+								setConstant(
+									parser,
+									filename,
+									"/index.js",
+									"filename",
+									"__filename is a Node.js feature and isn't available in browsers."
+								);
+								break;
+							case "node-module": {
+								const importMetaName = compilation.outputOptions.importMetaName;
+
+								setUrlModuleConstant(
+									parser,
+									filename,
+									"filename",
+									() => `${importMetaName}.url`
+								);
+								break;
+							}
+							case "eval-only":
+								// Keep `import.meta.filename` in the source code for the ES module output, or create a fallback using `import.meta.url` if possible
+								if (compilation.outputOptions.module) {
+									const { importMetaName } = compilation.outputOptions;
+
+									setUrlModuleConstant(
+										parser,
+										filename,
+										"filename",
+										() => `${importMetaName}.url`
+									);
+								}
+								// Replace `import.meta.filename` with `__filename` for the non-ES module output
+								else if (filename === "import.meta.filename") {
+									setModuleConstant(
+										parser,
+										filename,
+										() => "__filename",
+										"filename"
+									);
+								}
+								break;
+							case true:
+								setCachedModuleConstant(
+									parser,
+									filename,
+									(module) =>
+										relative(
+											/** @type {InputFileSystem} */ (compiler.inputFileSystem),
+											compiler.context,
+											module.resource
+										),
+									"filename"
+								);
+								break;
+						}
+
+						parser.hooks.evaluateIdentifier
+							.for("__filename")
+							.tap(PLUGIN_NAME, (expr) => {
+								if (!parser.state.module) return;
+								const resource = parseResource(parser.state.module.resource);
+								return evaluateToString(resource.path)(expr);
+							});
+					}
+
+					// Keep `import.meta.dirname` in code
+					if (
+						nodeOptions.__dirname === false &&
+						dirname === "import.meta.dirname"
+					) {
+						setModuleConstant(parser, dirname, () => dirname, "dirname");
+					}
+
+					if (nodeOptions.__dirname) {
+						switch (nodeOptions.__dirname) {
+							case "mock":
+								setConstant(parser, dirname, "/", "dirname");
+								break;
+							case "warn-mock":
+								setConstant(
+									parser,
+									dirname,
+									"/",
+									"dirname",
+									"__dirname is a Node.js feature and isn't available in browsers."
+								);
+								break;
+							case "node-module": {
+								const importMetaName = compilation.outputOptions.importMetaName;
+
+								setUrlModuleConstant(
+									parser,
+									dirname,
+									"dirname",
+									() => `${importMetaName}.url.replace(/\\/(?:[^\\/]*)$/, "")`
+								);
+								break;
+							}
+							case "eval-only":
+								// Keep `import.meta.dirname` in the source code for the ES module output and replace `__dirname` on `import.meta.dirname`
+								if (compilation.outputOptions.module) {
+									const { importMetaName } = compilation.outputOptions;
+
+									setUrlModuleConstant(
+										parser,
+										dirname,
+										"dirname",
+										() => `${importMetaName}.url.replace(/\\/(?:[^\\/]*)$/, "")`
+									);
+								}
+								// Replace `import.meta.dirname` with `__dirname` for the non-ES module output
+								else if (dirname === "import.meta.dirname") {
+									setModuleConstant(
+										parser,
+										dirname,
+										() => "__dirname",
+										"dirname"
+									);
+								}
+								break;
+							case true:
+								setCachedModuleConstant(
+									parser,
+									dirname,
+									(module) =>
+										relative(
+											/** @type {InputFileSystem} */ (compiler.inputFileSystem),
+											compiler.context,
+											/** @type {string} */ (module.context)
+										),
+									"dirname"
+								);
+								break;
+						}
+
+						parser.hooks.evaluateIdentifier
+							.for(dirname)
+							.tap(PLUGIN_NAME, (expr) => {
+								if (!parser.state.module) return;
+								return evaluateToString(
+									/** @type {string} */
+									(parser.state.module.context)
+								)(expr);
+							});
+					}
+				};
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {JavascriptParserOptions} parserOptions the javascript parser options
+				 * @param {boolean} a true when we need to handle `__filename` and `__dirname`, otherwise false
+				 * @param {boolean} b true when we need to handle `import.meta.filename` and `import.meta.dirname`, otherwise false
+				 */
+				const handler = (parser, parserOptions, a, b) => {
+					if (b && parserOptions.node === false) {
+						// Keep `import.meta.dirname` and `import.meta.filename` in code
+						setModuleConstant(
+							parser,
+							"import.meta.dirname",
+							() => "import.meta.dirname",
+							"dirname"
+						);
+						setModuleConstant(
+							parser,
+							"import.meta.filename",
+							() => "import.meta.filename",
+							"filename"
+						);
+						return;
+					}
+
+					let localOptions = options;
+
+					if (parserOptions.node) {
+						localOptions = { ...localOptions, ...parserOptions.node };
+					}
+
+					if (localOptions.global !== false) {
+						globalHandler(parser, localOptions);
+					}
+
+					if (a) {
+						dirnameAndFilenameHandler(parser, localOptions, {
+							dirname: "__dirname",
+							filename: "__filename"
+						});
+					}
+
+					if (b && parserOptions.importMeta !== false) {
+						dirnameAndFilenameHandler(parser, localOptions, {
+							dirname: "import.meta.dirname",
+							filename: "import.meta.filename"
+						});
+					}
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, (parser, parserOptions) => {
+						handler(parser, parserOptions, true, true);
+					});
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, (parser, parserOptions) => {
+						handler(parser, parserOptions, true, false);
+					});
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, (parser, parserOptions) => {
+						handler(parser, parserOptions, false, true);
+					});
+			}
+		);
+	}
+}
+
+module.exports = NodeStuffPlugin;
Index: frontend/node_modules/webpack/lib/NormalModule.js
===================================================================
--- frontend/node_modules/webpack/lib/NormalModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/NormalModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1872 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const querystring = require("querystring");
+const { getContext, runLoaders } = require("loader-runner");
+const {
+	AsyncSeriesBailHook,
+	HookMap,
+	SyncHook,
+	SyncWaterfallHook
+} = require("tapable");
+const {
+	CachedSource,
+	OriginalSource,
+	RawSource,
+	SourceMapSource
+} = require("webpack-sources");
+const Compilation = require("./Compilation");
+const Module = require("./Module");
+const ModuleGraphConnection = require("./ModuleGraphConnection");
+const { JAVASCRIPT_MODULE_TYPE_AUTO } = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const HookWebpackError = require("./errors/HookWebpackError");
+const ModuleBuildError = require("./errors/ModuleBuildError");
+const ModuleError = require("./errors/ModuleError");
+const ModuleParseError = require("./errors/ModuleParseError");
+const ModuleWarning = require("./errors/ModuleWarning");
+const NonErrorEmittedError = require("./errors/NonErrorEmittedError");
+const UnhandledSchemeError = require("./errors/UnhandledSchemeError");
+const LazySet = require("./util/LazySet");
+const { isSubset } = require("./util/SetHelpers");
+const { getScheme } = require("./util/URLAbsoluteSpecifier");
+const {
+	compareLocations,
+	compareSelect,
+	concatComparators,
+	keepOriginalOrder,
+	sortWithSourceOrder
+} = require("./util/comparators");
+const createHash = require("./util/createHash");
+const { createFakeHook } = require("./util/deprecation");
+const formatLocation = require("./util/formatLocation");
+const { join } = require("./util/fs");
+const {
+	absolutify,
+	contextify,
+	makePathsRelative
+} = require("./util/identifier");
+const makeSerializable = require("./util/makeSerializable");
+const memoize = require("./util/memoize");
+const parseJson = require("./util/parseJson");
+
+/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
+/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("../declarations/WebpackOptions").NoParse} NoParse */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("./Generator")} Generator */
+/** @typedef {import("./Generator").GenerateErrorFn} GenerateErrorFn */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./Module").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("./Module").BuildMeta} BuildMeta */
+/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("./Module").KnownBuildInfo} KnownBuildInfo */
+/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("./Module").LibIdent} LibIdent */
+/** @typedef {import("./Module").NameForCondition} NameForCondition */
+/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("./Module").BuildCallback} BuildCallback */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./Module").Sources} Sources */
+/** @typedef {import("./Module").SourceType} SourceType */
+/** @typedef {import("./Module").SourceTypes} SourceTypes */
+/** @typedef {import("./Module").UnsafeCacheData} UnsafeCacheData */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {Iterator<SideEffectsWalk, ConnectionState, ConnectionState>} SideEffectsWalk */
+/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
+/** @typedef {import("./NormalModuleFactory").NormalModuleTypes} NormalModuleTypes */
+/** @typedef {import("./NormalModuleFactory").ParserByType} ParserByType */
+/** @typedef {import("./NormalModuleFactory").ParserOptionsByType} ParserOptionsByType */
+/** @typedef {import("./NormalModuleFactory").GeneratorByType} GeneratorByType */
+/** @typedef {import("./NormalModuleFactory").GeneratorOptionsByType} GeneratorOptionsByType */
+/** @typedef {import("./NormalModuleFactory").ResourceSchemeData} ResourceSchemeData */
+/** @typedef {import("./Parser")} Parser */
+/** @typedef {import("./Parser").PreparsedAst} PreparsedAst */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+/**
+ * @template T
+ * @typedef {import("./util/deprecation").FakeHook<T>} FakeHook
+ */
+
+/** @typedef {{ [k: string]: EXPECTED_ANY }} ParserOptions */
+/** @typedef {{ [k: string]: EXPECTED_ANY }} GeneratorOptions */
+
+/**
+ * @template T
+ * @typedef {import("../declarations/LoaderContext").LoaderContext<T>} LoaderContext
+ */
+
+/**
+ * @template T
+ * @typedef {import("../declarations/LoaderContext").NormalModuleLoaderContext<T>} NormalModuleLoaderContext
+ */
+
+/** @typedef {(content: string) => boolean} NoParseFn */
+
+const getInvalidDependenciesModuleWarning = memoize(() =>
+	require("./errors/InvalidDependenciesModuleWarning")
+);
+
+const getExtractSourceMap = memoize(() => require("./util/extractSourceMap"));
+
+const getValidate = memoize(() => require("schema-utils").validate);
+
+const getHarmonyImportSideEffectDependency = memoize(() =>
+	require("./dependencies/HarmonyImportSideEffectDependency")
+);
+
+/**
+ * @param {NormalModule} mod the module
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {Dependency} dep the dep that triggered the bailout
+ */
+const recordSideEffectsBailout = (mod, moduleGraph, dep) => {
+	if (mod._addedSideEffectsBailout === undefined) {
+		mod._addedSideEffectsBailout = new WeakSet();
+	} else if (mod._addedSideEffectsBailout.has(moduleGraph)) {
+		return;
+	}
+	mod._addedSideEffectsBailout.add(moduleGraph);
+	moduleGraph
+		.getOptimizationBailout(mod)
+		.push(
+			() =>
+				`Dependency (${dep.type}) with side effects at ${formatLocation(dep.loc)}`
+		);
+};
+
+/**
+ * Generator form of `getSideEffectsConnectionState` — descends through
+ * `HarmonyImportSideEffectDependency` via `yield` so the trampoline in
+ * `getSideEffectsConnectionState` can drive the walk iteratively (#20986).
+ * @param {NormalModule} mod the module being evaluated
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @returns {SideEffectsWalk} the generator
+ */
+function* walkSideEffects(mod, moduleGraph) {
+	if (mod.factoryMeta !== undefined) {
+		if (mod.factoryMeta.sideEffectFree) return false;
+		if (mod.factoryMeta.sideEffectFree === false) return true;
+	}
+	if (!(mod.buildMeta !== undefined && mod.buildMeta.sideEffectFree)) {
+		return true;
+	}
+	if (mod._isEvaluatingSideEffects) {
+		return ModuleGraphConnection.CIRCULAR_CONNECTION;
+	}
+
+	const SideEffectDep = getHarmonyImportSideEffectDependency();
+	mod._isEvaluatingSideEffects = true;
+	/** @type {ConnectionState} */
+	let current = false;
+
+	for (const dep of mod.dependencies) {
+		/** @type {ConnectionState} */
+		let state;
+		if (dep instanceof SideEffectDep) {
+			const refModule = moduleGraph.getModule(dep);
+			if (!refModule) {
+				state = true;
+			} else if (refModule instanceof NormalModule) {
+				state = yield walkSideEffects(refModule, moduleGraph);
+			} else {
+				state = refModule.getSideEffectsConnectionState(moduleGraph);
+			}
+		} else {
+			state = dep.getModuleEvaluationSideEffectsState(moduleGraph);
+		}
+
+		if (state === true) {
+			recordSideEffectsBailout(mod, moduleGraph, dep);
+			mod._isEvaluatingSideEffects = false;
+			return true;
+		}
+		if (state !== ModuleGraphConnection.CIRCULAR_CONNECTION) {
+			current = ModuleGraphConnection.addConnectionStates(current, state);
+		}
+	}
+
+	mod._isEvaluatingSideEffects = false;
+	// When caching is implemented here, make sure to not cache when
+	// at least one circular connection was folded into `current`.
+	return current;
+}
+
+const ABSOLUTE_PATH_REGEX = /^(?:[a-z]:\\|\\\\|\/)/i;
+
+/**
+ * @typedef {object} LoaderItem
+ * @property {string} loader
+ * @property {string | null | undefined | Record<string, EXPECTED_ANY>} options
+ * @property {string | null=} ident
+ * @property {string | null=} type
+ */
+
+/**
+ * @param {string} context absolute context path
+ * @param {string} source a source path
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} new source path
+ */
+const contextifySourceUrl = (context, source, associatedObjectForCache) => {
+	if (source.startsWith("webpack://")) return source;
+	return `webpack://${makePathsRelative(
+		context,
+		source,
+		associatedObjectForCache
+	)}`;
+};
+
+/**
+ * @param {string} context absolute context path
+ * @param {string | RawSourceMap} sourceMap a source map
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string | RawSourceMap} new source map
+ */
+const contextifySourceMap = (context, sourceMap, associatedObjectForCache) => {
+	if (typeof sourceMap === "string" || !Array.isArray(sourceMap.sources)) {
+		return sourceMap;
+	}
+	const { sourceRoot } = sourceMap;
+	/** @type {(source: string) => string} */
+	const mapper = !sourceRoot
+		? (source) => source
+		: sourceRoot.endsWith("/")
+			? (source) =>
+					source.startsWith("/")
+						? `${sourceRoot.slice(0, -1)}${source}`
+						: `${sourceRoot}${source}`
+			: (source) =>
+					source.startsWith("/")
+						? `${sourceRoot}${source}`
+						: `${sourceRoot}/${source}`;
+	const newSources = sourceMap.sources.map((source) =>
+		contextifySourceUrl(context, mapper(source), associatedObjectForCache)
+	);
+	return {
+		...sourceMap,
+		file: "x",
+		sourceRoot: undefined,
+		sources: newSources
+	};
+};
+
+/**
+ * @param {string | Buffer} input the input
+ * @returns {string} the converted string
+ */
+const asString = (input) => {
+	if (Buffer.isBuffer(input)) {
+		return input.toString("utf8");
+	}
+	return input;
+};
+
+/**
+ * @param {string | Buffer} input the input
+ * @returns {Buffer} the converted buffer
+ */
+const asBuffer = (input) => {
+	if (!Buffer.isBuffer(input)) {
+		return Buffer.from(input, "utf8");
+	}
+	return input;
+};
+
+/** @typedef {[string | Buffer, string | RawSourceMap | undefined, PreparsedAst | undefined]}  Result */
+
+/** @typedef {LoaderContext<EXPECTED_ANY>} AnyLoaderContext */
+
+/**
+ * @deprecated Use the `readResource` hook instead.
+ * @typedef {HookMap<FakeHook<AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>>>} DeprecatedReadResourceForScheme
+ */
+
+/**
+ * @typedef {object} NormalModuleCompilationHooks
+ * @property {SyncHook<[AnyLoaderContext, NormalModule]>} loader
+ * @property {SyncHook<[LoaderItem[], NormalModule, AnyLoaderContext]>} beforeLoaders
+ * @property {SyncHook<[NormalModule]>} beforeParse
+ * @property {SyncHook<[NormalModule]>} beforeSnapshot
+ * @property {DeprecatedReadResourceForScheme} readResourceForScheme
+ * @property {HookMap<AsyncSeriesBailHook<[AnyLoaderContext], string | Buffer | null>>} readResource
+ * @property {SyncWaterfallHook<[Result, NormalModule]>} processResult
+ * @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild
+ */
+
+/**
+ * @template {NormalModuleTypes | ""} [T=NormalModuleTypes | ""]
+ * @typedef {object} NormalModuleCreateData
+ * @property {string=} layer an optional layer in which the module is
+ * @property {T} type module type. When deserializing, this is set to an empty string "".
+ * @property {string} request request string
+ * @property {string} userRequest request intended by user (without loaders from config)
+ * @property {string} rawRequest request without resolving
+ * @property {LoaderItem[]} loaders list of loaders
+ * @property {string} resource path + query of the real resource
+ * @property {(ResourceSchemeData & Partial<ResolveRequest>)=} resourceResolveData resource resolve data
+ * @property {string} context context directory for resolving
+ * @property {string=} matchResource path + query of the matched resource (virtual)
+ * @property {ParserByType[T]} parser the parser used
+ * @property {ParserOptionsByType[T]=} parserOptions the options of the parser used
+ * @property {GeneratorByType[T]} generator the generator used
+ * @property {GeneratorOptionsByType[T]=} generatorOptions the options of the generator used
+ * @property {ResolveOptions=} resolveOptions options used for resolving requests from this module
+ * @property {boolean} extractSourceMap enable/disable extracting source map
+ */
+
+/**
+ * @typedef {(resourcePath: string, getLoaderContext: (resourcePath: string) => AnyLoaderContext) => Promise<string | Buffer<ArrayBufferLike>>} ReadResource
+ */
+
+/** @type {WeakMap<Compilation, NormalModuleCompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class NormalModule extends Module {
+	/**
+	 * @param {Compilation} compilation the compilation
+	 * @returns {NormalModuleCompilationHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				loader: new SyncHook(["loaderContext", "module"]),
+				beforeLoaders: new SyncHook(["loaders", "module", "loaderContext"]),
+				beforeParse: new SyncHook(["module"]),
+				beforeSnapshot: new SyncHook(["module"]),
+				// TODO webpack 6 deprecate
+				readResourceForScheme: new HookMap((scheme) => {
+					const hook =
+						/** @type {NormalModuleCompilationHooks} */
+						(hooks).readResource.for(scheme);
+					return createFakeHook(
+						/** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>} */ ({
+							tap: (options, fn) =>
+								hook.tap(options, (loaderContext) =>
+									fn(
+										loaderContext.resource,
+										/** @type {NormalModule} */ (loaderContext._module)
+									)
+								),
+							tapAsync: (options, fn) =>
+								hook.tapAsync(options, (loaderContext, callback) =>
+									fn(
+										loaderContext.resource,
+										/** @type {NormalModule} */ (loaderContext._module),
+										callback
+									)
+								),
+							tapPromise: (options, fn) =>
+								hook.tapPromise(options, (loaderContext) =>
+									fn(
+										loaderContext.resource,
+										/** @type {NormalModule} */ (loaderContext._module)
+									)
+								)
+						})
+					);
+				}),
+				readResource: new HookMap(
+					() => new AsyncSeriesBailHook(["loaderContext"])
+				),
+				processResult: new SyncWaterfallHook(["result", "module"]),
+				needBuild: new AsyncSeriesBailHook(["module", "context"])
+			};
+			compilationHooksMap.set(
+				compilation,
+				/** @type {NormalModuleCompilationHooks} */ (hooks)
+			);
+		}
+		return /** @type {NormalModuleCompilationHooks} */ (hooks);
+	}
+
+	/**
+	 * @param {NormalModuleCreateData} options options object
+	 */
+	constructor({
+		layer,
+		type,
+		request,
+		userRequest,
+		rawRequest,
+		loaders,
+		resource,
+		resourceResolveData,
+		context,
+		matchResource,
+		parser,
+		parserOptions,
+		generator,
+		generatorOptions,
+		resolveOptions,
+		extractSourceMap
+	}) {
+		super(type, context || getContext(resource), layer);
+
+		// Info from Factory
+		/** @type {NormalModuleCreateData['request']} */
+		this.request = request;
+		/** @type {NormalModuleCreateData['userRequest']} */
+		this.userRequest = userRequest;
+		/** @type {NormalModuleCreateData['rawRequest']} */
+		this.rawRequest = rawRequest;
+		/** @type {boolean} */
+		this.binary = /^(?:asset|webassembly)\b/.test(type);
+		/** @type {NormalModuleCreateData['parser'] | undefined} */
+		this.parser = parser;
+		/** @type {NormalModuleCreateData['parserOptions']} */
+		this.parserOptions = parserOptions;
+		/** @type {NormalModuleCreateData['generator'] | undefined} */
+		this.generator = generator;
+		/** @type {NormalModuleCreateData['generatorOptions']} */
+		this.generatorOptions = generatorOptions;
+		/** @type {NormalModuleCreateData['resource']} */
+		this.resource = resource;
+		/** @type {NormalModuleCreateData['resourceResolveData']} */
+		this.resourceResolveData = resourceResolveData;
+		/** @type {NormalModuleCreateData['matchResource']} */
+		this.matchResource = matchResource;
+		/** @type {NormalModuleCreateData['loaders']} */
+		this.loaders = loaders;
+		if (resolveOptions !== undefined) {
+			// already declared in super class
+			/** @type {NormalModuleCreateData['resolveOptions']} */
+			this.resolveOptions = resolveOptions;
+		}
+		/** @type {NormalModuleCreateData['extractSourceMap']} */
+		this.extractSourceMap = extractSourceMap;
+
+		// Info from Build
+		/** @type {Error | null} */
+		this.error = null;
+		/**
+		 * @private
+		 * @type {Source | null}
+		 */
+		this._source = null;
+		/**
+		 * @private
+		 * @type {Map<undefined | SourceType, number> | undefined}
+		 */
+		this._sourceSizes = undefined;
+		/**
+		 * @private
+		 * @type {undefined | SourceTypes}
+		 */
+		this._sourceTypes = undefined;
+		// Cache
+		/**
+		 * @private
+		 * @type {BuildMeta}
+		 */
+		this._lastSuccessfulBuildMeta = {};
+		/**
+		 * @private
+		 * @type {boolean}
+		 */
+		this._forceBuild = true;
+		/**
+		 * @type {boolean}
+		 */
+		this._isEvaluatingSideEffects = false;
+		/**
+		 * @type {WeakSet<ModuleGraph> | undefined}
+		 */
+		this._addedSideEffectsBailout = undefined;
+		/**
+		 * @private
+		 * @type {CodeGenerationResultData}
+		 */
+		this._codeGeneratorData = new Map();
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		if (this.layer === null) {
+			if (this.type === JAVASCRIPT_MODULE_TYPE_AUTO) {
+				return this.request;
+			}
+			return `${this.type}|${this.request}`;
+		}
+		return `${this.type}|${this.request}|${this.layer}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return /** @type {string} */ (requestShortener.shorten(this.userRequest));
+	}
+
+	/**
+	 * @returns {string | null} return the resource path
+	 */
+	getResource() {
+		return this.matchResource || this.resource;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		let ident = contextify(
+			options.context,
+			this.userRequest,
+			options.associatedObjectForCache
+		);
+		if (this.layer) ident = `(${this.layer})/${ident}`;
+		return ident;
+	}
+
+	/**
+	 * Returns the path used when matching this module against rule conditions.
+	 * @returns {NameForCondition | null} absolute path which should be used for condition matching (usually the resource path)
+	 */
+	nameForCondition() {
+		const resource = /** @type {string} */ (this.getResource());
+		const idx = resource.indexOf("?");
+		if (idx >= 0) return resource.slice(0, idx);
+		return resource;
+	}
+
+	/**
+	 * 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 {NormalModule} */ (module);
+		this.binary = m.binary;
+		this.request = m.request;
+		this.userRequest = m.userRequest;
+		this.rawRequest = m.rawRequest;
+		this.parser = m.parser;
+		this.parserOptions = m.parserOptions;
+		this.generator = m.generator;
+		this.generatorOptions = m.generatorOptions;
+		this.resource = m.resource;
+		this.resourceResolveData = m.resourceResolveData;
+		this.context = m.context;
+		this.matchResource = m.matchResource;
+		this.loaders = m.loaders;
+		this.extractSourceMap = m.extractSourceMap;
+	}
+
+	/**
+	 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
+	 */
+	cleanupForCache() {
+		// Make sure to cache types and sizes before cleanup when this module has been built
+		// They are accessed by the stats and we don't want them to crash after cleanup
+		// TODO reconsider this for webpack 6
+		if (this.buildInfo) {
+			if (this._sourceTypes === undefined) this.getSourceTypes();
+			for (const type of /** @type {SourceTypes} */ (this._sourceTypes)) {
+				this.size(type);
+			}
+		}
+		super.cleanupForCache();
+		this.parser = undefined;
+		this.parserOptions = undefined;
+		this.generator = undefined;
+		this.generatorOptions = undefined;
+	}
+
+	/**
+	 * Module should be unsafe cached. Get data that's needed for that.
+	 * This data will be passed to restoreFromUnsafeCache later.
+	 * @returns {UnsafeCacheData} cached data
+	 */
+	getUnsafeCacheData() {
+		const data = super.getUnsafeCacheData();
+		data.parserOptions = this.parserOptions;
+		data.generatorOptions = this.generatorOptions;
+		return data;
+	}
+
+	/**
+	 * restore unsafe cache data
+	 * @param {UnsafeCacheData} unsafeCacheData data from getUnsafeCacheData
+	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
+	 */
+	restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
+		this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory);
+	}
+
+	/**
+	 * restore unsafe cache data
+	 * @param {UnsafeCacheData} unsafeCacheData data from getUnsafeCacheData
+	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
+	 */
+	_restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
+		super._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory);
+		this.parserOptions = unsafeCacheData.parserOptions;
+		this.parser = normalModuleFactory.getParser(this.type, this.parserOptions);
+		this.generatorOptions = unsafeCacheData.generatorOptions;
+		this.generator = normalModuleFactory.getGenerator(
+			this.type,
+			this.generatorOptions
+		);
+		// we assume the generator behaves identically and keep cached sourceTypes/Sizes
+	}
+
+	/**
+	 * @param {string} context the compilation context
+	 * @param {string} name the asset name
+	 * @param {string | Buffer} content the content
+	 * @param {(string | RawSourceMap)=} sourceMap an optional source map
+	 * @param {AssociatedObjectForCache=} associatedObjectForCache object for caching
+	 * @returns {Source} the created source
+	 */
+	createSourceForAsset(
+		context,
+		name,
+		content,
+		sourceMap,
+		associatedObjectForCache
+	) {
+		if (sourceMap) {
+			if (
+				typeof sourceMap === "string" &&
+				(this.useSourceMap || this.useSimpleSourceMap)
+			) {
+				return new OriginalSource(
+					content,
+					contextifySourceUrl(context, sourceMap, associatedObjectForCache)
+				);
+			}
+
+			if (this.useSourceMap) {
+				return new SourceMapSource(
+					content,
+					name,
+					contextifySourceMap(
+						context,
+						/** @type {RawSourceMap} */
+						(sourceMap),
+						associatedObjectForCache
+					)
+				);
+			}
+		}
+
+		return new RawSource(content);
+	}
+
+	/**
+	 * @private
+	 * @template T
+	 * @param {ResolverWithOptions} resolver a resolver
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {InputFileSystem} fs file system from reading
+	 * @param {NormalModuleCompilationHooks} hooks the hooks
+	 * @returns {import("../declarations/LoaderContext").LoaderContext<T>} loader context
+	 */
+	_createLoaderContext(resolver, options, compilation, fs, hooks) {
+		const { requestShortener } = compilation.runtimeTemplate;
+		const getCurrentLoaderName = () => {
+			const currentLoader = this.getCurrentLoader(
+				/** @type {AnyLoaderContext} */
+				(loaderContext)
+			);
+			if (!currentLoader) return "(not in loader scope)";
+			return requestShortener.shorten(currentLoader.loader);
+		};
+		/**
+		 * @returns {ResolveContext} resolve context
+		 */
+		const getResolveContext = () => ({
+			fileDependencies: {
+				add: (d) =>
+					/** @type {AnyLoaderContext} */
+					(loaderContext).addDependency(d)
+			},
+			contextDependencies: {
+				add: (d) =>
+					/** @type {AnyLoaderContext} */
+					(loaderContext).addContextDependency(d)
+			},
+			missingDependencies: {
+				add: (d) =>
+					/** @type {AnyLoaderContext} */
+					(loaderContext).addMissingDependency(d)
+			}
+		});
+		const getAbsolutify = memoize(() =>
+			absolutify.bindCache(compilation.compiler.root)
+		);
+		const getAbsolutifyInContext = memoize(() =>
+			absolutify.bindContextCache(
+				/** @type {string} */
+				(this.context),
+				compilation.compiler.root
+			)
+		);
+		const getContextify = memoize(() =>
+			contextify.bindCache(compilation.compiler.root)
+		);
+		const getContextifyInContext = memoize(() =>
+			contextify.bindContextCache(
+				/** @type {string} */
+				(this.context),
+				compilation.compiler.root
+			)
+		);
+		const utils = {
+			/**
+			 * @param {string} context context
+			 * @param {string} request request
+			 * @returns {string} result
+			 */
+			absolutify: (context, request) =>
+				context === this.context
+					? getAbsolutifyInContext()(request)
+					: getAbsolutify()(context, request),
+			/**
+			 * @param {string} context context
+			 * @param {string} request request
+			 * @returns {string} result
+			 */
+			contextify: (context, request) =>
+				context === this.context
+					? getContextifyInContext()(request)
+					: getContextify()(context, request),
+			/**
+			 * @param {HashFunction=} type type
+			 * @returns {Hash} hash
+			 */
+			createHash: (type) =>
+				createHash(type || compilation.outputOptions.hashFunction)
+		};
+		/** @type {NormalModuleLoaderContext<T>} */
+		const loaderContext = {
+			version: 2,
+			/**
+			 * @param {import("../declarations/LoaderContext").Schema=} schema schema
+			 * @returns {T} options
+			 */
+			getOptions: (schema) => {
+				const loader = this.getCurrentLoader(
+					/** @type {AnyLoaderContext} */
+					(loaderContext)
+				);
+
+				let { options } = /** @type {LoaderItem} */ (loader);
+
+				if (typeof options === "string") {
+					if (options.startsWith("{") && options.endsWith("}")) {
+						try {
+							options =
+								/** @type {LoaderItem["options"]} */
+								(parseJson(options));
+						} catch (err) {
+							throw new Error(
+								`Cannot parse string options: ${/** @type {Error} */ (err).message}`,
+								{ cause: err }
+							);
+						}
+					} else {
+						options = querystring.parse(options, "&", "=", {
+							maxKeys: 0
+						});
+					}
+				}
+
+				if (options === null || options === undefined) {
+					options = {};
+				}
+
+				if (schema && compilation.options.validate) {
+					let name = "Loader";
+					let baseDataPath = "options";
+					/** @type {RegExpExecArray | null} */
+					let match;
+					if (schema.title && (match = /^(.+) (.+)$/.exec(schema.title))) {
+						[, name, baseDataPath] = match;
+					}
+					getValidate()(schema, /** @type {EXPECTED_OBJECT} */ (options), {
+						name,
+						baseDataPath
+					});
+				}
+
+				return /** @type {T} */ (options);
+			},
+			emitWarning: (warning) => {
+				if (!(warning instanceof Error)) {
+					warning = new NonErrorEmittedError(warning);
+				}
+				this.addWarning(
+					new ModuleWarning(warning, {
+						from: getCurrentLoaderName()
+					})
+				);
+			},
+			emitError: (error) => {
+				if (!(error instanceof Error)) {
+					error = new NonErrorEmittedError(error);
+				}
+				this.addError(
+					new ModuleError(error, {
+						from: getCurrentLoaderName()
+					})
+				);
+			},
+			getLogger: (name) => {
+				const currentLoader = this.getCurrentLoader(
+					/** @type {AnyLoaderContext} */
+					(loaderContext)
+				);
+				return compilation.getLogger(() =>
+					[currentLoader && currentLoader.loader, name, this.identifier()]
+						.filter(Boolean)
+						.join("|")
+				);
+			},
+			resolve(context, request, callback) {
+				resolver.resolve({}, context, request, getResolveContext(), callback);
+			},
+			getResolve(options) {
+				const child = options ? resolver.withOptions(options) : resolver;
+				return /** @type {ReturnType<import("../declarations/LoaderContext").NormalModuleLoaderContext<T>["getResolve"]>} */ (
+					(context, request, callback) => {
+						if (callback) {
+							child.resolve(
+								{},
+								context,
+								request,
+								getResolveContext(),
+								callback
+							);
+						} else {
+							return new Promise((resolve, reject) => {
+								child.resolve(
+									{},
+									context,
+									request,
+									getResolveContext(),
+									(err, result) => {
+										if (err) reject(err);
+										else resolve(result);
+									}
+								);
+							});
+						}
+					}
+				);
+			},
+			emitFile: (name, content, sourceMap, assetInfo) => {
+				const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
+
+				if (!buildInfo.assets) {
+					buildInfo.assets = Object.create(null);
+					buildInfo.assetsInfo = new Map();
+				}
+
+				const assets =
+					/** @type {NonNullable<KnownBuildInfo["assets"]>} */
+					(buildInfo.assets);
+				const assetsInfo =
+					/** @type {NonNullable<KnownBuildInfo["assetsInfo"]>} */
+					(buildInfo.assetsInfo);
+
+				assets[name] = this.createSourceForAsset(
+					options.context,
+					name,
+					content,
+					sourceMap,
+					compilation.compiler.root
+				);
+				assetsInfo.set(name, assetInfo);
+			},
+			addBuildDependency: (dep) => {
+				const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
+
+				if (buildInfo.buildDependencies === undefined) {
+					buildInfo.buildDependencies = new LazySet();
+				}
+				buildInfo.buildDependencies.add(dep);
+			},
+			utils,
+			rootContext: options.context,
+			webpack: true,
+			sourceMap: Boolean(this.useSourceMap),
+			mode: options.mode || "production",
+			hashFunction: options.output.hashFunction,
+			hashDigest: options.output.hashDigest,
+			hashDigestLength: options.output.hashDigestLength,
+			hashSalt: options.output.hashSalt,
+			_module: this,
+			_compilation: compilation,
+			_compiler: compilation.compiler,
+			fs
+		};
+
+		Object.assign(loaderContext, options.loader);
+
+		hooks.loader.call(
+			/** @type {AnyLoaderContext} */
+			(loaderContext),
+			this
+		);
+
+		return /** @type {AnyLoaderContext} */ (loaderContext);
+	}
+
+	/**
+	 * @param {AnyLoaderContext} loaderContext loader context
+	 * @param {number} index index
+	 * @returns {LoaderItem | null} loader
+	 */
+	getCurrentLoader(loaderContext, index = loaderContext.loaderIndex) {
+		if (
+			this.loaders &&
+			this.loaders.length &&
+			index < this.loaders.length &&
+			index >= 0 &&
+			this.loaders[index]
+		) {
+			return this.loaders[index];
+		}
+		return null;
+	}
+
+	/**
+	 * @param {string} context the compilation context
+	 * @param {string | Buffer} content the content
+	 * @param {(string | RawSourceMap | null)=} sourceMap an optional source map
+	 * @param {AssociatedObjectForCache=} associatedObjectForCache object for caching
+	 * @returns {Source} the created source
+	 */
+	createSource(context, content, sourceMap, associatedObjectForCache) {
+		if (Buffer.isBuffer(content)) {
+			return new RawSource(content);
+		}
+
+		// if there is no identifier return raw source
+		if (!this.identifier) {
+			return new RawSource(content);
+		}
+
+		// from here on we assume we have an identifier
+		const identifier = this.identifier();
+
+		if (this.useSourceMap && sourceMap) {
+			return new SourceMapSource(
+				content,
+				contextifySourceUrl(context, identifier, associatedObjectForCache),
+				contextifySourceMap(context, sourceMap, associatedObjectForCache)
+			);
+		}
+
+		if (this.useSourceMap || this.useSimpleSourceMap) {
+			return new OriginalSource(
+				content,
+				contextifySourceUrl(context, identifier, associatedObjectForCache)
+			);
+		}
+
+		return new RawSource(content);
+	}
+
+	/**
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {NormalModuleCompilationHooks} hooks the hooks
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	_doBuild(options, compilation, resolver, fs, hooks, callback) {
+		const loaderContext = this._createLoaderContext(
+			resolver,
+			options,
+			compilation,
+			fs,
+			hooks
+		);
+
+		/**
+		 * @param {Error | null} err err
+		 * @param {(Result | null)=} result_ result
+		 * @returns {void}
+		 */
+		const processResult = (err, result_) => {
+			if (err) {
+				if (!(err instanceof Error)) {
+					err = new NonErrorEmittedError(err);
+				}
+				const currentLoader = this.getCurrentLoader(loaderContext);
+				const error = new ModuleBuildError(err, {
+					from:
+						currentLoader &&
+						compilation.runtimeTemplate.requestShortener.shorten(
+							currentLoader.loader
+						)
+				});
+				return callback(error);
+			}
+			const result = hooks.processResult.call(
+				/** @type {Result} */
+				(result_),
+				this
+			);
+			const source = result[0];
+			const sourceMap = result.length >= 1 ? result[1] : null;
+			const extraInfo = result.length >= 2 ? result[2] : null;
+
+			if (!Buffer.isBuffer(source) && typeof source !== "string") {
+				const currentLoader = this.getCurrentLoader(loaderContext, 0);
+				const err = new Error(
+					`Final loader (${
+						currentLoader
+							? compilation.runtimeTemplate.requestShortener.shorten(
+									currentLoader.loader
+								)
+							: "unknown"
+					}) didn't return a Buffer or String`
+				);
+				const error = new ModuleBuildError(err);
+				return callback(error);
+			}
+
+			const isBinaryModule =
+				this.generatorOptions && this.generatorOptions.binary !== undefined
+					? this.generatorOptions.binary
+					: this.binary;
+
+			this._source = this.createSource(
+				options.context,
+				isBinaryModule ? asBuffer(source) : asString(source),
+				sourceMap,
+				compilation.compiler.root
+			);
+			if (this._sourceSizes !== undefined) this._sourceSizes.clear();
+			/** @type {PreparsedAst | null} */
+			this._ast =
+				typeof extraInfo === "object" &&
+				extraInfo !== null &&
+				extraInfo.webpackAST !== undefined
+					? extraInfo.webpackAST
+					: null;
+			return callback();
+		};
+
+		const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
+
+		buildInfo.fileDependencies = new LazySet();
+		buildInfo.contextDependencies = new LazySet();
+		buildInfo.missingDependencies = new LazySet();
+		buildInfo.cacheable = true;
+
+		try {
+			hooks.beforeLoaders.call(
+				this.loaders,
+				this,
+				/** @type {AnyLoaderContext} */
+				(loaderContext)
+			);
+		} catch (err) {
+			processResult(/** @type {Error} */ (err));
+			return;
+		}
+
+		if (this.loaders.length > 0) {
+			/** @type {BuildInfo} */
+			(this.buildInfo).buildDependencies = new LazySet();
+		}
+
+		runLoaders(
+			{
+				resource: this.resource,
+				loaders: this.loaders,
+				context: loaderContext,
+				/**
+				 * @param {AnyLoaderContext} loaderContext the loader context
+				 * @param {string} resourcePath the resource Path
+				 * @param {(err: Error | null, result?: string | Buffer, sourceMap?: Result[1]) => void} callback callback
+				 * @returns {Promise<void>}
+				 */
+				processResource: async (loaderContext, resourcePath, callback) => {
+					/** @type {ReadResource} */
+					const readResource = (resourcePath, getLoaderContext) => {
+						const scheme = getScheme(resourcePath);
+						return new Promise((resolve, reject) => {
+							hooks.readResource
+								.for(scheme)
+								.callAsync(getLoaderContext(resourcePath), (err, result) => {
+									if (err) {
+										reject(err);
+									} else {
+										if (typeof result !== "string" && !result) {
+											return reject(
+												new UnhandledSchemeError(
+													/** @type {string} */
+													(scheme),
+													resourcePath
+												)
+											);
+										}
+										resolve(result);
+									}
+								});
+						});
+					};
+					try {
+						const result = await readResource(
+							resourcePath,
+							() => loaderContext
+						);
+						if (
+							this.extractSourceMap &&
+							(this.useSourceMap || this.useSimpleSourceMap)
+						) {
+							try {
+								const { source, sourceMap } = await getExtractSourceMap()(
+									result,
+									resourcePath,
+									/** @type {ReadResource} */
+									(resourcePath) =>
+										readResource(
+											resourcePath,
+											(resourcePath) =>
+												/** @type {AnyLoaderContext} */
+												({
+													addDependency(dependency) {
+														loaderContext.addDependency(dependency);
+													},
+													fs: loaderContext.fs,
+													_module: undefined,
+													resourcePath,
+													resource: resourcePath
+												})
+										).catch((err) => {
+											throw new Error(
+												`Failed to parse source map. ${/** @type {Error} */ (err).message}`
+											);
+										})
+								);
+								return callback(null, source, sourceMap);
+							} catch (err) {
+								this.addWarning(new ModuleWarning(/** @type {Error} */ (err)));
+								return callback(null, result);
+							}
+						}
+						return callback(null, result);
+					} catch (error) {
+						return callback(/** @type {Error} */ (error));
+					}
+				}
+			},
+			(err, result) => {
+				// Cleanup loaderContext to avoid leaking memory in ICs
+				loaderContext._compilation =
+					loaderContext._compiler =
+					loaderContext._module =
+					loaderContext.fs =
+						/** @type {EXPECTED_ANY} */
+						(undefined);
+
+				if (!result) {
+					/** @type {BuildInfo} */
+					(this.buildInfo).cacheable = false;
+					return processResult(
+						err || new Error("No result from loader-runner processing"),
+						null
+					);
+				}
+
+				const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
+
+				const fileDependencies =
+					/** @type {NonNullable<KnownBuildInfo["fileDependencies"]>} */
+					(buildInfo.fileDependencies);
+				const contextDependencies =
+					/** @type {NonNullable<KnownBuildInfo["contextDependencies"]>} */
+					(buildInfo.contextDependencies);
+				const missingDependencies =
+					/** @type {NonNullable<KnownBuildInfo["missingDependencies"]>} */
+					(buildInfo.missingDependencies);
+
+				fileDependencies.addAll(result.fileDependencies);
+				contextDependencies.addAll(result.contextDependencies);
+				missingDependencies.addAll(result.missingDependencies);
+				for (const loader of this.loaders) {
+					const buildDependencies =
+						/** @type {NonNullable<KnownBuildInfo["buildDependencies"]>} */
+						(buildInfo.buildDependencies);
+
+					buildDependencies.add(loader.loader);
+				}
+				buildInfo.cacheable = buildInfo.cacheable && result.cacheable;
+				processResult(err, result.result);
+			}
+		);
+	}
+
+	/**
+	 * @param {Error} error the error
+	 * @returns {void}
+	 */
+	markModuleAsErrored(error) {
+		// Restore build meta from successful build to keep importing state
+		this.buildMeta = { ...this._lastSuccessfulBuildMeta };
+		this.error = error;
+		this.addError(error);
+	}
+
+	/**
+	 * @param {Exclude<NoParse, EXPECTED_ANY[]>} rule rule
+	 * @param {string} content content
+	 * @returns {boolean} result
+	 */
+	applyNoParseRule(rule, content) {
+		// must start with "rule" if rule is a string
+		if (typeof rule === "string") {
+			return content.startsWith(rule);
+		}
+
+		if (typeof rule === "function") {
+			return rule(content);
+		}
+		// we assume rule is a regexp
+		return rule.test(content);
+	}
+
+	/**
+	 * @param {undefined | NoParse} noParseRule no parse rule
+	 * @param {string} request request
+	 * @returns {boolean} check if module should not be parsed, returns "true" if the module should !not! be parsed, returns "false" if the module !must! be parsed
+	 */
+	shouldPreventParsing(noParseRule, request) {
+		// if no noParseRule exists, return false
+		// the module !must! be parsed.
+		if (!noParseRule) {
+			return false;
+		}
+
+		// we only have one rule to check
+		if (!Array.isArray(noParseRule)) {
+			// returns "true" if the module is !not! to be parsed
+			return this.applyNoParseRule(noParseRule, request);
+		}
+
+		for (let i = 0; i < noParseRule.length; i++) {
+			const rule = noParseRule[i];
+			// early exit on first truthy match
+			// this module is !not! to be parsed
+			if (this.applyNoParseRule(rule, request)) {
+				return true;
+			}
+		}
+		// no match found, so this module !should! be parsed
+		return false;
+	}
+
+	/**
+	 * @param {Compilation} compilation compilation
+	 * @private
+	 */
+	_initBuildHash(compilation) {
+		const hash = createHash(compilation.outputOptions.hashFunction);
+		if (this._source) {
+			hash.update("source");
+			this._source.updateHash(hash);
+		}
+		hash.update("meta");
+		hash.update(JSON.stringify(this.buildMeta));
+		/** @type {BuildInfo} */
+		(this.buildInfo).hash = hash.digest("hex");
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this._forceBuild = false;
+		this._source = null;
+		if (this._sourceSizes !== undefined) this._sourceSizes.clear();
+		this._sourceTypes = undefined;
+		this._ast = null;
+		this.error = null;
+		this.clearWarningsAndErrors();
+		this.clearDependenciesAndBlocks();
+		this.buildMeta = {};
+		this.buildInfo = {
+			cacheable: false,
+			parsed: true,
+			fileDependencies: undefined,
+			contextDependencies: undefined,
+			missingDependencies: undefined,
+			buildDependencies: undefined,
+			valueDependencies: undefined,
+			hash: undefined,
+			assets: undefined,
+			assetsInfo: undefined
+		};
+
+		const startTime = compilation.compiler.fsStartTime || Date.now();
+
+		const hooks = NormalModule.getCompilationHooks(compilation);
+
+		return this._doBuild(options, compilation, resolver, fs, hooks, (err) => {
+			// if we have an error mark module as failed and exit
+			if (err) {
+				this.markModuleAsErrored(err);
+				this._initBuildHash(compilation);
+				return callback();
+			}
+
+			/**
+			 * @param {Error} e error
+			 * @returns {void}
+			 */
+			const handleParseError = (e) => {
+				const source = /** @type {Source} */ (this._source).source();
+				const loaders = this.loaders.map((item) =>
+					contextify(options.context, item.loader, compilation.compiler.root)
+				);
+				const error = new ModuleParseError(source, e, loaders, this.type);
+				this.markModuleAsErrored(error);
+				this._initBuildHash(compilation);
+				return callback();
+			};
+
+			const handleParseResult = () => {
+				this.dependencies.sort(
+					concatComparators(
+						compareSelect((a) => a.loc, compareLocations),
+						keepOriginalOrder(this.dependencies)
+					)
+				);
+				sortWithSourceOrder(this.dependencies, new WeakMap());
+				this._initBuildHash(compilation);
+				this._lastSuccessfulBuildMeta =
+					/** @type {BuildMeta} */
+					(this.buildMeta);
+				return handleBuildDone();
+			};
+
+			const handleBuildDone = () => {
+				try {
+					hooks.beforeSnapshot.call(this);
+				} catch (err) {
+					this.markModuleAsErrored(/** @type {Error} */ (err));
+					return callback();
+				}
+
+				const snapshotOptions = compilation.options.snapshot.module;
+				const { cacheable } = /** @type {BuildInfo} */ (this.buildInfo);
+				if (!cacheable || !snapshotOptions) {
+					return callback();
+				}
+				// add warning for all non-absolute paths in fileDependencies, etc
+				// This makes it easier to find problems with watching and/or caching
+				/** @type {undefined | Set<string>} */
+				let nonAbsoluteDependencies;
+				/**
+				 * @param {FileSystemDependencies} deps deps
+				 */
+				const checkDependencies = (deps) => {
+					for (const dep of deps) {
+						if (!ABSOLUTE_PATH_REGEX.test(dep)) {
+							if (nonAbsoluteDependencies === undefined) {
+								nonAbsoluteDependencies = new Set();
+							}
+							nonAbsoluteDependencies.add(dep);
+							deps.delete(dep);
+							try {
+								const depWithoutGlob = dep.replace(/[\\/]?\*.*$/, "");
+								const absolute = join(
+									compilation.fileSystemInfo.fs,
+									/** @type {string} */
+									(this.context),
+									depWithoutGlob
+								);
+								if (absolute !== dep && ABSOLUTE_PATH_REGEX.test(absolute)) {
+									(depWithoutGlob !== dep
+										? /** @type {NonNullable<KnownBuildInfo["contextDependencies"]>} */
+											(
+												/** @type {BuildInfo} */
+												(this.buildInfo).contextDependencies
+											)
+										: deps
+									).add(absolute);
+								}
+							} catch (_err) {
+								// ignore
+							}
+						}
+					}
+				};
+				const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
+				const fileDependencies =
+					/** @type {NonNullable<KnownBuildInfo["fileDependencies"]>} */
+					(buildInfo.fileDependencies);
+				const contextDependencies =
+					/** @type {NonNullable<KnownBuildInfo["contextDependencies"]>} */
+					(buildInfo.contextDependencies);
+				const missingDependencies =
+					/** @type {NonNullable<KnownBuildInfo["missingDependencies"]>} */
+					(buildInfo.missingDependencies);
+				checkDependencies(fileDependencies);
+				checkDependencies(missingDependencies);
+				checkDependencies(contextDependencies);
+				if (nonAbsoluteDependencies !== undefined) {
+					const InvalidDependenciesModuleWarning =
+						getInvalidDependenciesModuleWarning();
+					this.addWarning(
+						new InvalidDependenciesModuleWarning(this, nonAbsoluteDependencies)
+					);
+				}
+				// convert file/context/missingDependencies into filesystem snapshot
+				compilation.fileSystemInfo.createSnapshot(
+					startTime,
+					fileDependencies,
+					contextDependencies,
+					missingDependencies,
+					snapshotOptions,
+					(err, snapshot) => {
+						if (err) {
+							this.markModuleAsErrored(err);
+							return;
+						}
+						buildInfo.fileDependencies = undefined;
+						buildInfo.contextDependencies = undefined;
+						buildInfo.missingDependencies = undefined;
+						buildInfo.snapshot = snapshot;
+						return callback();
+					}
+				);
+			};
+
+			try {
+				hooks.beforeParse.call(this);
+			} catch (err) {
+				this.markModuleAsErrored(/** @type {Error} */ (err));
+				this._initBuildHash(compilation);
+				return callback();
+			}
+
+			// check if this module should !not! be parsed.
+			// if so, exit here;
+			const noParseRule = options.module && options.module.noParse;
+			if (this.shouldPreventParsing(noParseRule, this.request)) {
+				// We assume that we need module and exports
+				/** @type {BuildInfo} */
+				(this.buildInfo).parsed = false;
+				this._initBuildHash(compilation);
+				return handleBuildDone();
+			}
+
+			try {
+				const source = /** @type {Source} */ (this._source).source();
+				/** @type {Parser} */
+				(this.parser).parse(this._ast || source, {
+					source,
+					current: this,
+					module: this,
+					compilation,
+					options
+				});
+			} catch (parseErr) {
+				handleParseError(/** @type {Error} */ (parseErr));
+				return;
+			}
+			handleParseResult();
+		});
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(context) {
+		return /** @type {Generator} */ (
+			this.generator
+		).getConcatenationBailoutReason(this, context);
+	}
+
+	/**
+	 * Gets side effects connection state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only
+	 */
+	getSideEffectsConnectionState(moduleGraph) {
+		// Trampoline `walkSideEffects` so the descent doesn't consume the
+		// call stack (#20986).
+		const stack = [walkSideEffects(this, moduleGraph)];
+		/** @type {ConnectionState} */
+		let r = false;
+		while (stack.length > 0) {
+			const step = stack[stack.length - 1].next(r);
+			if (step.done) {
+				stack.pop();
+				r = step.value;
+			} else {
+				stack.push(step.value);
+			}
+		}
+		return r;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		if (this._sourceTypes === undefined) {
+			this._sourceTypes = /** @type {Generator} */ (this.generator).getTypes(
+				this
+			);
+		}
+		return this._sourceTypes;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({
+		dependencyTemplates,
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime,
+		concatenationScope,
+		codeGenerationResults,
+		sourceTypes
+	}) {
+		/** @type {RuntimeRequirements} */
+		const runtimeRequirements = new Set();
+
+		const { parsed } = /** @type {BuildInfo} */ (this.buildInfo);
+
+		if (!parsed) {
+			runtimeRequirements.add(RuntimeGlobals.module);
+			runtimeRequirements.add(RuntimeGlobals.exports);
+			runtimeRequirements.add(RuntimeGlobals.thisAsExports);
+		}
+
+		const getData = () => this._codeGeneratorData;
+
+		/** @type {Sources} */
+		const sources = new Map();
+		for (const type of sourceTypes || chunkGraph.getModuleSourceTypes(this)) {
+			// TODO webpack@6 make generateError required
+			const generator =
+				/** @type {Generator & { generateError?: GenerateErrorFn }} */
+				(this.generator);
+			const source = this.error
+				? generator.generateError
+					? generator.generateError(this.error, this, {
+							dependencyTemplates,
+							runtimeTemplate,
+							moduleGraph,
+							chunkGraph,
+							runtimeRequirements,
+							runtime,
+							concatenationScope,
+							codeGenerationResults,
+							getData,
+							type
+						})
+					: new RawSource(
+							`throw new Error(${JSON.stringify(this.error.message)});`
+						)
+				: generator.generate(this, {
+						dependencyTemplates,
+						runtimeTemplate,
+						moduleGraph,
+						chunkGraph,
+						runtimeRequirements,
+						runtime,
+						concatenationScope,
+						codeGenerationResults,
+						getData,
+						type
+					});
+
+			if (source) {
+				sources.set(type, new CachedSource(source));
+			}
+		}
+
+		/** @type {CodeGenerationResult} */
+		const resultEntry = {
+			sources,
+			runtimeRequirements,
+			data: this._codeGeneratorData
+		};
+		return resultEntry;
+	}
+
+	/**
+	 * Gets the original source.
+	 * @returns {Source | null} the original source for the module before webpack transformation
+	 */
+	originalSource() {
+		return this._source;
+	}
+
+	/**
+	 * Invalidates the cached state associated with this value.
+	 * @returns {void}
+	 */
+	invalidateBuild() {
+		this._forceBuild = true;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		const { fileSystemInfo, compilation, valueCacheVersions } = context;
+		// build if enforced
+		if (this._forceBuild) return callback(null, true);
+
+		// always try to build in case of an error
+		if (this.error) return callback(null, true);
+
+		const { cacheable, snapshot, valueDependencies } =
+			/** @type {BuildInfo} */ (this.buildInfo);
+
+		// always build when module is not cacheable
+		if (!cacheable) return callback(null, true);
+
+		// build when there is no snapshot to check
+		if (!snapshot) return callback(null, true);
+
+		// build when valueDependencies have changed
+		if (valueDependencies) {
+			if (!valueCacheVersions) return callback(null, true);
+			for (const [key, value] of valueDependencies) {
+				if (value === undefined) return callback(null, true);
+				const current = valueCacheVersions.get(key);
+				if (
+					value !== current &&
+					(typeof value === "string" ||
+						typeof current === "string" ||
+						current === undefined ||
+						!isSubset(value, current))
+				) {
+					return callback(null, true);
+				}
+			}
+		}
+
+		// check snapshot for validity
+		fileSystemInfo.checkSnapshotValid(snapshot, (err, valid) => {
+			if (err) return callback(err);
+			if (!valid) return callback(null, true);
+			const hooks = NormalModule.getCompilationHooks(compilation);
+			hooks.needBuild.callAsync(this, context, (err, needBuild) => {
+				if (err) {
+					return callback(
+						HookWebpackError.makeWebpackError(
+							err,
+							"NormalModule.getCompilationHooks().needBuild"
+						)
+					);
+				}
+				callback(null, Boolean(needBuild));
+			});
+		});
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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) {
+		const cachedSize =
+			this._sourceSizes === undefined ? undefined : this._sourceSizes.get(type);
+		if (cachedSize !== undefined) {
+			return cachedSize;
+		}
+		const size = Math.max(
+			1,
+			/** @type {Generator} */ (this.generator).getSize(this, type)
+		);
+		if (this._sourceSizes === undefined) {
+			this._sourceSizes = new Map();
+		}
+		this._sourceSizes.set(type, size);
+		return size;
+	}
+
+	/**
+	 * Adds the provided file dependencies to the module.
+	 * @param {FileSystemDependencies} fileDependencies set where file dependencies are added to
+	 * @param {FileSystemDependencies} contextDependencies set where context dependencies are added to
+	 * @param {FileSystemDependencies} missingDependencies set where missing dependencies are added to
+	 * @param {FileSystemDependencies} buildDependencies set where build dependencies are added to
+	 */
+	addCacheDependencies(
+		fileDependencies,
+		contextDependencies,
+		missingDependencies,
+		buildDependencies
+	) {
+		const { snapshot, buildDependencies: buildDeps } =
+			/** @type {BuildInfo} */ (this.buildInfo);
+		if (snapshot) {
+			fileDependencies.addAll(snapshot.getFileIterable());
+			contextDependencies.addAll(snapshot.getContextIterable());
+			missingDependencies.addAll(snapshot.getMissingIterable());
+		} else {
+			const {
+				fileDependencies: fileDeps,
+				contextDependencies: contextDeps,
+				missingDependencies: missingDeps
+			} = /** @type {BuildInfo} */ (this.buildInfo);
+			if (fileDeps !== undefined) fileDependencies.addAll(fileDeps);
+			if (contextDeps !== undefined) contextDependencies.addAll(contextDeps);
+			if (missingDeps !== undefined) missingDependencies.addAll(missingDeps);
+		}
+		if (buildDeps !== undefined) {
+			buildDependencies.addAll(buildDeps);
+		}
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);
+		hash.update(
+			/** @type {string} */
+			(buildInfo.hash)
+		);
+		// Clear cached source types and re-compute so that changes in incoming
+		// connections (e.g. asset module newly referenced from JS via lazy
+		// compilation) are reflected in the hash and trigger code generation
+		// cache invalidation.
+		// https://github.com/webpack/webpack/issues/20800
+		this._sourceTypes = undefined;
+		for (const type of this.getSourceTypes()) {
+			hash.update(type);
+		}
+		/** @type {Generator} */
+		(this.generator).updateHash(hash, {
+			module: this,
+			...context
+		});
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		// deserialize
+		write(this._source);
+		write(this.error);
+		write(this._lastSuccessfulBuildMeta);
+		write(this._forceBuild);
+		write(this._codeGeneratorData);
+		super.serialize(context);
+	}
+
+	/**
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {NormalModule} module
+	 */
+	static deserialize(context) {
+		const obj = new NormalModule({
+			// will be deserialized by Module
+			layer: /** @type {EXPECTED_ANY} */ (null),
+			type: "",
+			// will be filled by updateCacheModule
+			resource: "",
+			context: "",
+			request: /** @type {EXPECTED_ANY} */ (null),
+			userRequest: /** @type {EXPECTED_ANY} */ (null),
+			rawRequest: /** @type {EXPECTED_ANY} */ (null),
+			loaders: /** @type {EXPECTED_ANY} */ (null),
+			matchResource: /** @type {EXPECTED_ANY} */ (null),
+			parser: /** @type {EXPECTED_ANY} */ (null),
+			parserOptions: /** @type {EXPECTED_ANY} */ (null),
+			generator: /** @type {EXPECTED_ANY} */ (null),
+			generatorOptions: /** @type {EXPECTED_ANY} */ (null),
+			resolveOptions: /** @type {EXPECTED_ANY} */ (null),
+			extractSourceMap: /** @type {EXPECTED_ANY} */ (null)
+		});
+		obj.deserialize(context);
+		return obj;
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this._source = read();
+		this.error = read();
+		this._lastSuccessfulBuildMeta = read();
+		this._forceBuild = read();
+		this._codeGeneratorData = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(NormalModule, "webpack/lib/NormalModule");
+
+module.exports = NormalModule;
Index: frontend/node_modules/webpack/lib/NormalModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/NormalModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/NormalModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1519 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { getContext } = require("loader-runner");
+const asyncLib = require("neo-async");
+const {
+	AsyncSeriesBailHook,
+	HookMap,
+	SyncBailHook,
+	SyncHook,
+	SyncWaterfallHook
+} = require("tapable");
+const ChunkGraph = require("./ChunkGraph");
+const Module = require("./Module");
+const ModuleFactory = require("./ModuleFactory");
+const ModuleGraph = require("./ModuleGraph");
+const { JAVASCRIPT_MODULE_TYPE_AUTO } = require("./ModuleTypeConstants");
+const NormalModule = require("./NormalModule");
+const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
+const BasicEffectRulePlugin = require("./rules/BasicEffectRulePlugin");
+const BasicMatcherRulePlugin = require("./rules/BasicMatcherRulePlugin");
+const ObjectMatcherRulePlugin = require("./rules/ObjectMatcherRulePlugin");
+const RuleSetCompiler = require("./rules/RuleSetCompiler");
+const UseEffectRulePlugin = require("./rules/UseEffectRulePlugin");
+const LazySet = require("./util/LazySet");
+const { getScheme } = require("./util/URLAbsoluteSpecifier");
+const { cachedCleverMerge, cachedSetProperty } = require("./util/cleverMerge");
+const { join } = require("./util/fs");
+const {
+	escapeHashInPathRequest,
+	parseResource,
+	parseResourceWithoutFragment
+} = require("./util/identifier");
+
+/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
+/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
+/** @typedef {import("../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("./Compilation").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("./Generator")} Generator */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
+/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
+/** @typedef {import("./NormalModule").GeneratorOptions} GeneratorOptions */
+/** @typedef {import("./NormalModule").LoaderItem} LoaderItem */
+/** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */
+/** @typedef {import("./NormalModule").ParserOptions} ParserOptions */
+/** @typedef {import("./Parser")} Parser */
+/** @typedef {import("./ResolverFactory")} ResolverFactory */
+/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
+/** @typedef {import("./dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
+/** @typedef {import("./dependencies/ImportPhase").ImportPhaseName} ImportPhaseName */
+/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("./rules/RuleSetCompiler").RuleSetRules} RuleSetRules */
+/** @typedef {import("./rules/RuleSetCompiler").RuleSet} RuleSet */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+
+/**
+ * Defines the callback type used by this module.
+ * @template T
+ * @typedef {import("./Compiler").Callback<T>} Callback
+ */
+
+/** @typedef {Pick<RuleSetRule, "type" | "sideEffects" | "parser" | "generator" | "resolve" | "layer" | "extractSourceMap">} ModuleSettings */
+/** @typedef {NormalModuleCreateData & { settings: ModuleSettings }} CreateData */
+
+/**
+ * Defines the resolve data type used by this module.
+ * @typedef {object} ResolveData
+ * @property {ModuleFactoryCreateData["contextInfo"]} contextInfo
+ * @property {ModuleFactoryCreateData["resolveOptions"]} resolveOptions
+ * @property {string} context
+ * @property {string} request
+ * @property {ImportPhaseName=} phase
+ * @property {ImportAttributes=} attributes
+ * @property {ModuleDependency[]} dependencies
+ * @property {string} dependencyType
+ * @property {Partial<CreateData>} createData
+ * @property {FileSystemDependencies} fileDependencies
+ * @property {FileSystemDependencies} missingDependencies
+ * @property {FileSystemDependencies} contextDependencies
+ * @property {Module=} ignoredModule
+ * @property {boolean} cacheable allow to use the unsafe cache
+ */
+
+/**
+ * Defines the resource data type used by this module.
+ * @typedef {object} ResourceData
+ * @property {string} resource
+ * @property {string=} path
+ * @property {string=} query
+ * @property {string=} fragment
+ * @property {string=} context
+ */
+
+/**
+ * Defines the resource scheme data type used by this module.
+ * @typedef {object} ResourceSchemeData
+ * @property {string=} mimetype mime type of the resource
+ * @property {string=} parameters additional parameters for the resource
+ * @property {"base64" | false=} encoding encoding of the resource
+ * @property {string=} encodedContent encoded content of the resource
+ */
+
+/** @typedef {ResourceData & { data: ResourceSchemeData & Partial<ResolveRequest> }} ResourceDataWithData */
+
+/**
+ * Defines the parsed loader request type used by this module.
+ * @typedef {object} ParsedLoaderRequest
+ * @property {string} loader loader
+ * @property {string | undefined} options options
+ */
+
+/** @typedef {import("./ModuleTypeConstants").JAVASCRIPT_MODULE_TYPE_AUTO} JAVASCRIPT_MODULE_TYPE_AUTO */
+/** @typedef {import("./ModuleTypeConstants").JAVASCRIPT_MODULE_TYPE_DYNAMIC} JAVASCRIPT_MODULE_TYPE_DYNAMIC */
+/** @typedef {import("./ModuleTypeConstants").JAVASCRIPT_MODULE_TYPE_ESM} JAVASCRIPT_MODULE_TYPE_ESM */
+/** @typedef {import("./ModuleTypeConstants").JSON_MODULE_TYPE} JSON_MODULE_TYPE */
+/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE} ASSET_MODULE_TYPE */
+/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_INLINE} ASSET_MODULE_TYPE_INLINE */
+/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_RESOURCE} ASSET_MODULE_TYPE_RESOURCE */
+/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_SOURCE} ASSET_MODULE_TYPE_SOURCE */
+/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_BYTES} ASSET_MODULE_TYPE_BYTES */
+/** @typedef {import("./ModuleTypeConstants").WEBASSEMBLY_MODULE_TYPE_ASYNC} WEBASSEMBLY_MODULE_TYPE_ASYNC */
+/** @typedef {import("./ModuleTypeConstants").WEBASSEMBLY_MODULE_TYPE_SYNC} WEBASSEMBLY_MODULE_TYPE_SYNC */
+/** @typedef {import("./ModuleTypeConstants").CSS_MODULE_TYPE} CSS_MODULE_TYPE */
+/** @typedef {import("./ModuleTypeConstants").CSS_MODULE_TYPE_GLOBAL} CSS_MODULE_TYPE_GLOBAL */
+/** @typedef {import("./ModuleTypeConstants").CSS_MODULE_TYPE_MODULE} CSS_MODULE_TYPE_MODULE */
+/** @typedef {import("./ModuleTypeConstants").CSS_MODULE_TYPE_AUTO} CSS_MODULE_TYPE_AUTO */
+/** @typedef {import("./ModuleTypeConstants").HTML_MODULE_TYPE} HTML_MODULE_TYPE */
+
+/** @typedef {JAVASCRIPT_MODULE_TYPE_AUTO | JAVASCRIPT_MODULE_TYPE_DYNAMIC | JAVASCRIPT_MODULE_TYPE_ESM | JSON_MODULE_TYPE | ASSET_MODULE_TYPE | ASSET_MODULE_TYPE_INLINE | ASSET_MODULE_TYPE_RESOURCE | ASSET_MODULE_TYPE_SOURCE | WEBASSEMBLY_MODULE_TYPE_ASYNC | WEBASSEMBLY_MODULE_TYPE_SYNC | CSS_MODULE_TYPE | CSS_MODULE_TYPE_GLOBAL | CSS_MODULE_TYPE_MODULE | CSS_MODULE_TYPE_AUTO | HTML_MODULE_TYPE} KnownNormalModuleTypes */
+/** @typedef {KnownNormalModuleTypes | string} NormalModuleTypes */
+
+const EMPTY_RESOLVE_OPTIONS = {};
+/** @type {ParserOptions} */
+const EMPTY_PARSER_OPTIONS = {};
+/** @type {GeneratorOptions} */
+const EMPTY_GENERATOR_OPTIONS = {};
+/** @type {ParsedLoaderRequest[]} */
+const EMPTY_ELEMENTS = [];
+
+const MATCH_RESOURCE_REGEX = /^([^!]+)!=!/;
+const LEADING_DOT_EXTENSION_REGEX = /^[^.]/;
+
+/**
+ * Returns ident.
+ * @param {LoaderItem} data data
+ * @returns {string} ident
+ */
+const loaderToIdent = (data) => {
+	if (!data.options) {
+		return data.loader;
+	}
+	if (typeof data.options === "string") {
+		return `${data.loader}?${data.options}`;
+	}
+	if (typeof data.options !== "object") {
+		throw new Error("loader options must be string or object");
+	}
+	if (data.ident) {
+		return `${data.loader}??${data.ident}`;
+	}
+	return `${data.loader}?${JSON.stringify(data.options)}`;
+};
+
+/**
+ * Stringify loaders and resource.
+ * @param {LoaderItem[]} loaders loaders
+ * @param {string} resource resource
+ * @returns {string} stringified loaders and resource
+ */
+const stringifyLoadersAndResource = (loaders, resource) => {
+	let str = "";
+	for (const loader of loaders) {
+		str += `${loaderToIdent(loader)}!`;
+	}
+	return str + resource;
+};
+
+/**
+ * Checks whether it needs calls.
+ * @param {number} times times
+ * @param {(err?: null | Error) => void} callback callback
+ * @returns {(err?: null | Error) => void} callback
+ */
+const needCalls = (times, callback) => (err) => {
+	if (--times === 0) {
+		return callback(err);
+	}
+	if (err && times > 0) {
+		times = Number.NaN;
+		return callback(err);
+	}
+};
+
+/**
+ * Merges global options.
+ * @template T
+ * @template O
+ * @param {T} globalOptions global options
+ * @param {string} type type
+ * @param {O} localOptions local options
+ * @returns {T & O | T | O} result
+ */
+const mergeGlobalOptions = (globalOptions, type, localOptions) => {
+	const parts = type.split("/");
+	/** @type {undefined | T} */
+	let result;
+	let current = "";
+	for (const part of parts) {
+		current = current ? `${current}/${part}` : part;
+		const options =
+			/** @type {T} */
+			(globalOptions[/** @type {keyof T} */ (current)]);
+		if (typeof options === "object") {
+			result =
+				result === undefined ? options : cachedCleverMerge(result, options);
+		}
+	}
+	if (result === undefined) {
+		return localOptions;
+	}
+	return cachedCleverMerge(result, localOptions);
+};
+
+// TODO webpack 6 remove
+/**
+ * Deprecation changed hook message.
+ * @template {import("tapable").Hook<EXPECTED_ANY, EXPECTED_ANY>} T
+ * @param {string} name name
+ * @param {T} hook hook
+ * @returns {string} result
+ */
+const deprecationChangedHookMessage = (name, hook) => {
+	const names = hook.taps.map((tapped) => tapped.name).join(", ");
+
+	return (
+		`NormalModuleFactory.${name} (${names}) is no longer a waterfall hook, but a bailing hook instead. ` +
+		"Do not return the passed object, but modify it instead. " +
+		"Returning false will ignore the request and results in no module created."
+	);
+};
+
+const ruleSetCompiler = new RuleSetCompiler([
+	new BasicMatcherRulePlugin("test", "resource"),
+	new BasicMatcherRulePlugin("scheme"),
+	new BasicMatcherRulePlugin("mimetype"),
+	new BasicMatcherRulePlugin("dependency"),
+	new BasicMatcherRulePlugin("include", "resource"),
+	new BasicMatcherRulePlugin("exclude", "resource", true),
+	new BasicMatcherRulePlugin("resource"),
+	new BasicMatcherRulePlugin("resourceQuery"),
+	new BasicMatcherRulePlugin("resourceFragment"),
+	new BasicMatcherRulePlugin("realResource"),
+	new BasicMatcherRulePlugin("issuer"),
+	new BasicMatcherRulePlugin("compiler"),
+	new BasicMatcherRulePlugin("issuerLayer"),
+	new BasicMatcherRulePlugin("phase"),
+	new ObjectMatcherRulePlugin("assert", "attributes", (value) => {
+		if (value) {
+			return (
+				/** @type {ImportAttributes} */ (value)._isLegacyAssert !== undefined
+			);
+		}
+
+		return false;
+	}),
+	new ObjectMatcherRulePlugin("with", "attributes", (value) => {
+		if (value) {
+			return !(/** @type {ImportAttributes} */ (value)._isLegacyAssert);
+		}
+		return false;
+	}),
+	new ObjectMatcherRulePlugin("descriptionData"),
+	new BasicEffectRulePlugin("type"),
+	new BasicEffectRulePlugin("sideEffects"),
+	new BasicEffectRulePlugin("parser"),
+	new BasicEffectRulePlugin("resolve"),
+	new BasicEffectRulePlugin("generator"),
+	new BasicEffectRulePlugin("layer"),
+	new BasicEffectRulePlugin("extractSourceMap"),
+	new UseEffectRulePlugin()
+]);
+
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("./javascript/JavascriptGenerator")} JavascriptGenerator */
+/** @typedef {import("../declarations/WebpackOptions").EmptyGeneratorOptions} EmptyGeneratorOptions */
+
+/** @typedef {import("./json/JsonParser")} JsonParser */
+/** @typedef {import("../declarations/WebpackOptions").JsonParserOptions} JsonParserOptions */
+/** @typedef {import("./json/JsonGenerator")} JsonGenerator */
+/** @typedef {import("../declarations/WebpackOptions").JsonGeneratorOptions} JsonGeneratorOptions */
+
+/** @typedef {import("./asset/AssetParser")} AssetParser */
+/** @typedef {import("./asset/AssetSourceParser")} AssetSourceParser */
+/** @typedef {import("./asset/AssetBytesParser")} AssetBytesParser */
+/** @typedef {import("../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */
+/** @typedef {import("../declarations/WebpackOptions").EmptyParserOptions} EmptyParserOptions */
+/** @typedef {import("./asset/AssetGenerator")} AssetGenerator */
+/** @typedef {import("../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
+/** @typedef {import("../declarations/WebpackOptions").AssetInlineGeneratorOptions} AssetInlineGeneratorOptions */
+/** @typedef {import("../declarations/WebpackOptions").AssetResourceGeneratorOptions} AssetResourceGeneratorOptions */
+/** @typedef {import("./asset/AssetSourceGenerator")} AssetSourceGenerator */
+/** @typedef {import("./asset/AssetBytesGenerator")} AssetBytesGenerator */
+
+/** @typedef {import("./wasm-async/AsyncWebAssemblyParser")} AsyncWebAssemblyParser */
+/** @typedef {import("./wasm-sync/WebAssemblyParser")} WebAssemblyParser */
+
+/** @typedef {import("./css/CssParser")} CssParser */
+/** @typedef {import("../declarations/WebpackOptions").CssParserOptions} CssParserOptions */
+/** @typedef {import("../declarations/WebpackOptions").CssModuleParserOptions} CssModuleParserOptions */
+/** @typedef {import("./css/CssGenerator")} CssGenerator */
+/** @typedef {import("../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */
+/** @typedef {import("../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */
+
+/** @typedef {import("./html/HtmlParser")} HtmlParser */
+/** @typedef {import("../declarations/WebpackOptions").EmptyParserOptions} HtmlParserOptions */
+/** @typedef {import("./html/HtmlGenerator")} HtmlGenerator */
+/** @typedef {import("../declarations/WebpackOptions").HtmlGeneratorOptions} HtmlGeneratorOptions */
+
+/* eslint-disable jsdoc/type-formatting */
+/**
+ * Defines the shared type used by this module.
+ * @typedef {[
+ * [JAVASCRIPT_MODULE_TYPE_AUTO, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
+ * [JAVASCRIPT_MODULE_TYPE_DYNAMIC, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
+ * [JAVASCRIPT_MODULE_TYPE_ESM, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
+ * [JSON_MODULE_TYPE, JsonParser, JsonParserOptions, JsonGenerator, JsonGeneratorOptions],
+ * [ASSET_MODULE_TYPE, AssetParser, AssetParserOptions, AssetGenerator, AssetGeneratorOptions],
+ * [ASSET_MODULE_TYPE_INLINE, AssetParser, EmptyParserOptions, AssetGenerator, AssetGeneratorOptions],
+ * [ASSET_MODULE_TYPE_RESOURCE, AssetParser, EmptyParserOptions, AssetGenerator, AssetGeneratorOptions],
+ * [ASSET_MODULE_TYPE_SOURCE, AssetSourceParser, EmptyParserOptions, AssetSourceGenerator, EmptyGeneratorOptions],
+ * [ASSET_MODULE_TYPE_BYTES, AssetBytesParser, EmptyParserOptions, AssetBytesGenerator, EmptyGeneratorOptions],
+ * [WEBASSEMBLY_MODULE_TYPE_ASYNC, AsyncWebAssemblyParser, EmptyParserOptions, Generator, EmptyGeneratorOptions],
+ * [WEBASSEMBLY_MODULE_TYPE_SYNC, WebAssemblyParser, EmptyParserOptions, Generator, EmptyGeneratorOptions],
+ * [CSS_MODULE_TYPE, CssParser, CssParserOptions, CssGenerator, CssGeneratorOptions],
+ * [CSS_MODULE_TYPE_AUTO, CssParser, CssModuleParserOptions, CssGenerator, CssModuleGeneratorOptions],
+ * [CSS_MODULE_TYPE_MODULE, CssParser, CssModuleParserOptions, CssGenerator, CssModuleGeneratorOptions],
+ * [CSS_MODULE_TYPE_GLOBAL, CssParser, CssModuleParserOptions, CssGenerator, CssModuleGeneratorOptions],
+ * [HTML_MODULE_TYPE, HtmlParser, HtmlParserOptions, HtmlGenerator, HtmlGeneratorOptions],
+ * [string, Parser, ParserOptions, Generator, GeneratorOptions],
+ * ]} ParsersAndGeneratorsByTypes
+ */
+/* eslint-enable jsdoc/type-formatting */
+
+/**
+ * Defines the extract tuple elements type used by this module.
+ * @template {unknown[]} T
+ * @template {number[]} I
+ * @typedef {{ [K in keyof I]: K extends keyof I ? I[K] extends keyof T ? T[I[K]] : never : never }} ExtractTupleElements
+ */
+
+/**
+ * Represents the normal module factory runtime component.
+ * @template {unknown[]} T
+ * @template {number[]} A
+ * @template [R=void]
+ * @typedef {T extends [infer Head extends [string, ...unknown[]], ...infer Tail extends [string, ...unknown[]][]] ? Record<Head[0], SyncBailHook<ExtractTupleElements<Head, A>, R extends number ? Head[R] : R>> & RecordFactoryFromTuple<Tail, A, R> : unknown } RecordFactoryFromTuple
+ */
+
+/**
+ * Maps each tuple in `T` to a record from its `[0]` key to its `[I]` value.
+ * @template {unknown[]} T
+ * @template {number} I
+ * @typedef {T extends [infer Head extends [string, ...unknown[]], ...infer Tail extends [string, ...unknown[]][]] ? Record<Head[0], I extends keyof Head ? Head[I] : never> & TupleToTypeMap<Tail, I> : unknown } TupleToTypeMap
+ */
+
+/** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 1>} ParserByType */
+/** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 2>} ParserOptionsByType */
+/** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 3>} GeneratorByType */
+/** @typedef {TupleToTypeMap<ParsersAndGeneratorsByTypes, 4>} GeneratorOptionsByType */
+
+class NormalModuleFactory extends ModuleFactory {
+	/**
+	 * Creates an instance of NormalModuleFactory.
+	 * @param {object} param params
+	 * @param {string=} param.context context
+	 * @param {InputFileSystem} param.fs file system
+	 * @param {ResolverFactory} param.resolverFactory resolverFactory
+	 * @param {ModuleOptions} param.options options
+	 * @param {AssociatedObjectForCache} param.associatedObjectForCache an object to which the cache will be attached
+	 */
+	constructor({
+		context,
+		fs,
+		resolverFactory,
+		options,
+		associatedObjectForCache
+	}) {
+		super();
+		this.hooks = Object.freeze({
+			/** @type {AsyncSeriesBailHook<[ResolveData], Module | false | void>} */
+			resolve: new AsyncSeriesBailHook(["resolveData"]),
+			/** @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>} */
+			resolveForScheme: new HookMap(
+				() => new AsyncSeriesBailHook(["resourceData", "resolveData"])
+			),
+			/** @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>} */
+			resolveInScheme: new HookMap(
+				() => new AsyncSeriesBailHook(["resourceData", "resolveData"])
+			),
+			/** @type {AsyncSeriesBailHook<[ResolveData], Module | undefined>} */
+			factorize: new AsyncSeriesBailHook(["resolveData"]),
+			/** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */
+			beforeResolve: new AsyncSeriesBailHook(["resolveData"]),
+			/** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */
+			afterResolve: new AsyncSeriesBailHook(["resolveData"]),
+			/** @type {AsyncSeriesBailHook<[CreateData, ResolveData], Module | void>} */
+			createModule: new AsyncSeriesBailHook(["createData", "resolveData"]),
+			/** @type {SyncWaterfallHook<[Module, CreateData, ResolveData]>} */
+			module: new SyncWaterfallHook(["module", "createData", "resolveData"]),
+			/** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [2], 1>>} */
+			createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
+			/** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [1, 2]>>} */
+			parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
+			/** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [4], 3>>} */
+			createGenerator: new HookMap(
+				() => new SyncBailHook(["generatorOptions"])
+			),
+			/** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [3, 4]>>} */
+			generator: new HookMap(
+				() => new SyncHook(["generator", "generatorOptions"])
+			),
+			/** @type {HookMap<SyncBailHook<[CreateData, ResolveData], Module | void>>} */
+			createModuleClass: new HookMap(
+				() => new SyncBailHook(["createData", "resolveData"])
+			)
+		});
+		/** @type {ResolverFactory} */
+		this.resolverFactory = resolverFactory;
+		/** @type {RuleSet} */
+		this.ruleSet = ruleSetCompiler.compile([
+			{
+				rules: /** @type {RuleSetRules} */ (options.defaultRules)
+			},
+			{
+				rules: /** @type {RuleSetRules} */ (options.rules)
+			}
+		]);
+		/** @type {string} */
+		this.context = context || "";
+		/** @type {InputFileSystem} */
+		this.fs = fs;
+		this._globalParserOptions = options.parser;
+		this._globalGeneratorOptions = options.generator;
+		/** @type {Map<string, WeakMap<ParserOptions, Parser>>} */
+		this.parserCache = new Map();
+		/** @type {Map<string, WeakMap<GeneratorOptions, Generator>>} */
+		this.generatorCache = new Map();
+		/** @type {Set<Module>} */
+		this._restoredUnsafeCacheEntries = new Set();
+
+		/** @type {(resource: string) => import("./util/identifier").ParsedResource} */
+		const cacheParseResource = parseResource.bindCache(
+			associatedObjectForCache
+		);
+		const cachedParseResourceWithoutFragment =
+			parseResourceWithoutFragment.bindCache(associatedObjectForCache);
+		this._parseResourceWithoutFragment = cachedParseResourceWithoutFragment;
+
+		this.hooks.factorize.tapAsync(
+			{
+				name: "NormalModuleFactory",
+				stage: 100
+			},
+			(resolveData, callback) => {
+				this.hooks.resolve.callAsync(resolveData, (err, result) => {
+					if (err) return callback(err);
+
+					// Ignored
+					if (result === false) return callback();
+
+					// direct module
+					if (result instanceof Module) return callback(null, result);
+
+					if (typeof result === "object") {
+						throw new Error(
+							`${deprecationChangedHookMessage(
+								"resolve",
+								this.hooks.resolve
+							)} Returning a Module object will result in this module used as result.`
+						);
+					}
+
+					this.hooks.afterResolve.callAsync(resolveData, (err, result) => {
+						if (err) return callback(err);
+
+						if (typeof result === "object") {
+							throw new Error(
+								deprecationChangedHookMessage(
+									"afterResolve",
+									this.hooks.afterResolve
+								)
+							);
+						}
+
+						// Ignored
+						if (result === false) return callback();
+
+						const createData =
+							/** @type {CreateData} */
+							(resolveData.createData);
+
+						this.hooks.createModule.callAsync(
+							createData,
+							resolveData,
+							(err, createdModule) => {
+								if (!createdModule) {
+									if (!resolveData.request) {
+										return callback(new Error("Empty dependency (no request)"));
+									}
+
+									// TODO webpack 6 make it required and move javascript/wasm/asset properties to own module
+									createdModule = this.hooks.createModuleClass
+										.for(createData.settings.type)
+										.call(createData, resolveData);
+
+									if (!createdModule) {
+										createdModule = /** @type {Module} */ (
+											new NormalModule(createData)
+										);
+									}
+								}
+
+								createdModule = this.hooks.module.call(
+									createdModule,
+									createData,
+									resolveData
+								);
+
+								return callback(null, createdModule);
+							}
+						);
+					});
+				});
+			}
+		);
+		this.hooks.resolve.tapAsync(
+			{
+				name: "NormalModuleFactory",
+				stage: 100
+			},
+			(data, callback) => {
+				const {
+					contextInfo,
+					context,
+					dependencies,
+					dependencyType,
+					request,
+					phase,
+					attributes,
+					resolveOptions,
+					fileDependencies,
+					missingDependencies,
+					contextDependencies
+				} = data;
+				const loaderResolver = this.getResolver("loader");
+
+				/** @type {ResourceData | undefined} */
+				let matchResourceData;
+				/** @type {string} */
+				let unresolvedResource;
+				/** @type {ParsedLoaderRequest[]} */
+				let elements;
+				let noPreAutoLoaders = false;
+				let noAutoLoaders = false;
+				let noPrePostAutoLoaders = false;
+
+				const contextScheme = getScheme(context);
+				/** @type {string | undefined} */
+				let scheme = getScheme(request);
+
+				if (!scheme) {
+					/** @type {string} */
+					let requestWithoutMatchResource = request;
+					const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request);
+					if (matchResourceMatch) {
+						let matchResource = matchResourceMatch[1];
+						// Check if matchResource starts with ./ or ../
+						if (matchResource.charCodeAt(0) === 46) {
+							// 46 is "."
+							const secondChar = matchResource.charCodeAt(1);
+							if (
+								secondChar === 47 || // 47 is "/"
+								(secondChar === 46 && matchResource.charCodeAt(2) === 47) // "../"
+							) {
+								// Resolve relative path against context
+								matchResource = join(this.fs, context, matchResource);
+							}
+						}
+
+						matchResourceData = {
+							...cacheParseResource(matchResource),
+							resource: matchResource
+						};
+						requestWithoutMatchResource = request.slice(
+							matchResourceMatch[0].length
+						);
+					}
+
+					scheme = getScheme(requestWithoutMatchResource);
+
+					if (!scheme && !contextScheme) {
+						const firstChar = requestWithoutMatchResource.charCodeAt(0);
+						const secondChar = requestWithoutMatchResource.charCodeAt(1);
+						noPreAutoLoaders = firstChar === 45 && secondChar === 33; // startsWith "-!"
+						noAutoLoaders = noPreAutoLoaders || firstChar === 33; // startsWith "!"
+						noPrePostAutoLoaders = firstChar === 33 && secondChar === 33; // startsWith "!!";
+						const rawElements = requestWithoutMatchResource
+							.slice(
+								noPreAutoLoaders || noPrePostAutoLoaders
+									? 2
+									: noAutoLoaders
+										? 1
+										: 0
+							)
+							.split(/!+/);
+						unresolvedResource = /** @type {string} */ (rawElements.pop());
+						elements = rawElements.map((el) => {
+							const { path, query } = cachedParseResourceWithoutFragment(el);
+							return {
+								loader: path,
+								options: query ? query.slice(1) : undefined
+							};
+						});
+						scheme = getScheme(unresolvedResource);
+					} else {
+						unresolvedResource = requestWithoutMatchResource;
+						elements = EMPTY_ELEMENTS;
+					}
+				} else {
+					unresolvedResource = request;
+					elements = EMPTY_ELEMENTS;
+				}
+
+				/** @type {ResolveContext} */
+				const resolveContext = {
+					fileDependencies,
+					missingDependencies,
+					contextDependencies
+				};
+
+				/** @type {ResourceDataWithData} */
+				let resourceData;
+
+				/** @type {undefined | LoaderItem[]} */
+				let loaders;
+
+				const continueCallback = needCalls(2, (err) => {
+					if (err) return callback(err);
+
+					// translate option idents
+					try {
+						for (const item of /** @type {LoaderItem[]} */ (loaders)) {
+							if (typeof item.options === "string" && item.options[0] === "?") {
+								const ident = item.options.slice(1);
+								if (ident === "[[missing ident]]") {
+									throw new Error(
+										"No ident is provided by referenced loader. " +
+											"When using a function for Rule.use in config you need to " +
+											"provide an 'ident' property for referenced loader options."
+									);
+								}
+								item.options = this.ruleSet.references.get(ident);
+								if (item.options === undefined) {
+									throw new Error(
+										"Invalid ident is provided by referenced loader"
+									);
+								}
+								item.ident = ident;
+							}
+						}
+					} catch (identErr) {
+						return callback(/** @type {Error} */ (identErr));
+					}
+
+					if (!resourceData) {
+						// ignored
+						return callback(null, dependencies[0].createIgnoredModule(context));
+					}
+
+					const userRequest =
+						(matchResourceData !== undefined
+							? `${matchResourceData.resource}!=!`
+							: "") +
+						stringifyLoadersAndResource(
+							/** @type {LoaderItem[]} */ (loaders),
+							resourceData.resource
+						);
+
+					/** @type {ModuleSettings} */
+					const settings = {};
+					/** @type {LoaderItem[]} */
+					const useLoadersPost = [];
+					/** @type {LoaderItem[]} */
+					const useLoaders = [];
+					/** @type {LoaderItem[]} */
+					const useLoadersPre = [];
+
+					// handle .webpack[] suffix
+					/** @type {string} */
+					let resource;
+					/** @type {RegExpExecArray | null} */
+					let match;
+					if (
+						matchResourceData &&
+						typeof (resource = matchResourceData.resource) === "string" &&
+						(match = /\.webpack\[([^\]]+)\]$/.exec(resource))
+					) {
+						settings.type = match[1];
+						matchResourceData.resource = matchResourceData.resource.slice(
+							0,
+							-settings.type.length - 10
+						);
+					} else {
+						settings.type = JAVASCRIPT_MODULE_TYPE_AUTO;
+						const resourceDataForRules = matchResourceData || resourceData;
+
+						const result = this.ruleSet.exec({
+							resource: resourceDataForRules.path,
+							realResource: resourceData.path,
+							resourceQuery: resourceDataForRules.query,
+							resourceFragment: resourceDataForRules.fragment,
+							scheme,
+							phase,
+							attributes,
+							mimetype: matchResourceData
+								? ""
+								: resourceData.data.mimetype || "",
+							dependency: dependencyType,
+							descriptionData: matchResourceData
+								? undefined
+								: resourceData.data.descriptionFileData,
+							issuer: contextInfo.issuer,
+							compiler: contextInfo.compiler,
+							issuerLayer: contextInfo.issuerLayer || ""
+						});
+						for (const r of result) {
+							// https://github.com/webpack/webpack/issues/16466
+							// if a request exists PrePostAutoLoaders, should disable modifying Rule.type
+							if (r.type === "type" && noPrePostAutoLoaders) {
+								continue;
+							}
+							if (r.type === "use") {
+								if (!noAutoLoaders && !noPrePostAutoLoaders) {
+									useLoaders.push(r.value);
+								}
+							} else if (r.type === "use-post") {
+								if (!noPrePostAutoLoaders) {
+									useLoadersPost.push(r.value);
+								}
+							} else if (r.type === "use-pre") {
+								if (!noPreAutoLoaders && !noPrePostAutoLoaders) {
+									useLoadersPre.push(r.value);
+								}
+							} else if (
+								typeof r.value === "object" &&
+								r.value !== null &&
+								typeof settings[
+									/** @type {keyof ModuleSettings} */
+									(r.type)
+								] === "object" &&
+								settings[/** @type {keyof ModuleSettings} */ (r.type)] !== null
+							) {
+								const type = /** @type {keyof ModuleSettings} */ (r.type);
+								settings[type] = cachedCleverMerge(settings[type], r.value);
+							} else {
+								const type = /** @type {keyof ModuleSettings} */ (r.type);
+								settings[type] = r.value;
+							}
+						}
+					}
+
+					/** @type {undefined | LoaderItem[]} */
+					let postLoaders;
+					/** @type {undefined | LoaderItem[]} */
+					let normalLoaders;
+					/** @type {undefined | LoaderItem[]} */
+					let preLoaders;
+
+					const continueCallback = needCalls(3, (err) => {
+						if (err) {
+							return callback(err);
+						}
+						const allLoaders = /** @type {LoaderItem[]} */ (postLoaders);
+						if (matchResourceData === undefined) {
+							for (const loader of /** @type {LoaderItem[]} */ (loaders)) {
+								allLoaders.push(loader);
+							}
+							for (const loader of /** @type {LoaderItem[]} */ (
+								normalLoaders
+							)) {
+								allLoaders.push(loader);
+							}
+						} else {
+							for (const loader of /** @type {LoaderItem[]} */ (
+								normalLoaders
+							)) {
+								allLoaders.push(loader);
+							}
+							for (const loader of /** @type {LoaderItem[]} */ (loaders)) {
+								allLoaders.push(loader);
+							}
+						}
+						for (const loader of /** @type {LoaderItem[]} */ (preLoaders)) {
+							allLoaders.push(loader);
+						}
+						const type = /** @type {NormalModuleTypes} */ (settings.type);
+						const resolveOptions = settings.resolve;
+						const layer = settings.layer;
+
+						try {
+							Object.assign(data.createData, {
+								layer:
+									layer === undefined ? contextInfo.issuerLayer || null : layer,
+								request: stringifyLoadersAndResource(
+									allLoaders,
+									resourceData.resource
+								),
+								userRequest,
+								rawRequest: request,
+								loaders: allLoaders,
+								resource: resourceData.resource,
+								context:
+									resourceData.context || getContext(resourceData.resource),
+								matchResource: matchResourceData
+									? matchResourceData.resource
+									: undefined,
+								resourceResolveData: resourceData.data,
+								settings,
+								type,
+								parser: this.getParser(type, settings.parser),
+								parserOptions: settings.parser,
+								generator: this.getGenerator(type, settings.generator),
+								generatorOptions: settings.generator,
+								resolveOptions,
+								extractSourceMap: settings.extractSourceMap || false
+							});
+						} catch (createDataErr) {
+							return callback(/** @type {Error} */ (createDataErr));
+						}
+						callback();
+					});
+					this.resolveRequestArray(
+						contextInfo,
+						this.context,
+						useLoadersPost,
+						loaderResolver,
+						resolveContext,
+						(err, result) => {
+							postLoaders = result;
+							continueCallback(err);
+						}
+					);
+					this.resolveRequestArray(
+						contextInfo,
+						this.context,
+						useLoaders,
+						loaderResolver,
+						resolveContext,
+						(err, result) => {
+							normalLoaders = result;
+							continueCallback(err);
+						}
+					);
+					this.resolveRequestArray(
+						contextInfo,
+						this.context,
+						useLoadersPre,
+						loaderResolver,
+						resolveContext,
+						(err, result) => {
+							preLoaders = result;
+							continueCallback(err);
+						}
+					);
+				});
+
+				this.resolveRequestArray(
+					contextInfo,
+					contextScheme ? this.context : context,
+					/** @type {LoaderItem[]} */ (elements),
+					loaderResolver,
+					resolveContext,
+					(err, result) => {
+						if (err) return continueCallback(err);
+						loaders = result;
+						continueCallback();
+					}
+				);
+
+				/**
+				 * Processes the provided string.
+				 * @param {string} context context
+				 */
+				const defaultResolve = (context) => {
+					if (/^(?:$|\?)/.test(unresolvedResource)) {
+						resourceData = {
+							...cacheParseResource(unresolvedResource),
+							resource: unresolvedResource,
+							data: {}
+						};
+						continueCallback();
+					}
+
+					// resource without scheme and with path
+					else {
+						const normalResolver = this.getResolver(
+							"normal",
+							dependencyType
+								? cachedSetProperty(
+										resolveOptions || EMPTY_RESOLVE_OPTIONS,
+										"dependencyType",
+										dependencyType
+									)
+								: resolveOptions
+						);
+						this.resolveResource(
+							contextInfo,
+							context,
+							escapeHashInPathRequest(unresolvedResource),
+							normalResolver,
+							resolveContext,
+							(err, _resolvedResource, resolvedResourceResolveData) => {
+								if (err) return continueCallback(err);
+								if (_resolvedResource !== false) {
+									const resolvedResource =
+										/** @type {string} */
+										(_resolvedResource);
+									resourceData = {
+										...cacheParseResource(resolvedResource),
+										resource: resolvedResource,
+										data:
+											/** @type {ResolveRequest} */
+											(resolvedResourceResolveData)
+									};
+								}
+								continueCallback();
+							}
+						);
+					}
+				};
+
+				// resource with scheme
+				if (scheme) {
+					resourceData = {
+						resource: unresolvedResource,
+						data: {},
+						path: undefined,
+						query: undefined,
+						fragment: undefined,
+						context: undefined
+					};
+					this.hooks.resolveForScheme
+						.for(scheme)
+						.callAsync(resourceData, data, (err) => {
+							if (err) return continueCallback(err);
+							continueCallback();
+						});
+				}
+
+				// resource within scheme
+				else if (contextScheme) {
+					resourceData = {
+						resource: unresolvedResource,
+						data: {},
+						path: undefined,
+						query: undefined,
+						fragment: undefined,
+						context: undefined
+					};
+					this.hooks.resolveInScheme
+						.for(contextScheme)
+						.callAsync(resourceData, data, (err, handled) => {
+							if (err) return continueCallback(err);
+							if (!handled) return defaultResolve(this.context);
+							continueCallback();
+						});
+				}
+
+				// resource without scheme and without path
+				else {
+					defaultResolve(context);
+				}
+			}
+		);
+	}
+
+	cleanupForCache() {
+		for (const module of this._restoredUnsafeCacheEntries) {
+			ChunkGraph.clearChunkGraphForModule(module);
+			ModuleGraph.clearModuleGraphForModule(module);
+			module.cleanupForCache();
+		}
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const dependencies = /** @type {ModuleDependency[]} */ (data.dependencies);
+		const context = data.context || this.context;
+		const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
+		const dependency = dependencies[0];
+		const request = dependency.request;
+		const attributes =
+			/** @type {ModuleDependency & { attributes: ImportAttributes }} */
+			(dependency).attributes;
+		const phase =
+			typeof (
+				/** @type {ModuleDependency & { phase?: ImportPhaseType }} */
+				(dependency).phase
+			) === "number"
+				? ImportPhaseUtils.stringify(
+						/** @type {ModuleDependency & { phase?: ImportPhaseType }} */
+						(dependency).phase
+					)
+				: "evaluation";
+		const dependencyType = dependency.category || "";
+		const contextInfo = data.contextInfo;
+		/** @type {FileSystemDependencies} */
+		const fileDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		const missingDependencies = new LazySet();
+		/** @type {FileSystemDependencies} */
+		const contextDependencies = new LazySet();
+		/** @type {ResolveData} */
+		const resolveData = {
+			contextInfo,
+			resolveOptions,
+			context,
+			request,
+			phase,
+			attributes,
+			dependencies,
+			dependencyType,
+			fileDependencies,
+			missingDependencies,
+			contextDependencies,
+			createData: {},
+			cacheable: true
+		};
+		this.hooks.beforeResolve.callAsync(resolveData, (err, result) => {
+			if (err) {
+				return callback(err, {
+					fileDependencies,
+					missingDependencies,
+					contextDependencies,
+					cacheable: false
+				});
+			}
+
+			// Ignored
+			if (result === false) {
+				/** @type {ModuleFactoryResult} * */
+				const factoryResult = {
+					fileDependencies,
+					missingDependencies,
+					contextDependencies,
+					cacheable: resolveData.cacheable
+				};
+
+				if (resolveData.ignoredModule) {
+					factoryResult.module = resolveData.ignoredModule;
+				}
+
+				return callback(null, factoryResult);
+			}
+
+			if (typeof result === "object") {
+				throw new Error(
+					deprecationChangedHookMessage(
+						"beforeResolve",
+						this.hooks.beforeResolve
+					)
+				);
+			}
+
+			this.hooks.factorize.callAsync(resolveData, (err, module) => {
+				if (err) {
+					return callback(err, {
+						fileDependencies,
+						missingDependencies,
+						contextDependencies,
+						cacheable: false
+					});
+				}
+
+				/** @type {ModuleFactoryResult} * */
+				const factoryResult = {
+					module,
+					fileDependencies,
+					missingDependencies,
+					contextDependencies,
+					cacheable: resolveData.cacheable
+				};
+
+				callback(null, factoryResult);
+			});
+		});
+	}
+
+	/**
+	 * Processes the provided context info.
+	 * @param {ModuleFactoryCreateDataContextInfo} contextInfo context info
+	 * @param {string} context context
+	 * @param {string} unresolvedResource unresolved resource
+	 * @param {ResolverWithOptions} resolver resolver
+	 * @param {ResolveContext} resolveContext resolver context
+	 * @param {(err: null | Error, res?: string | false, req?: ResolveRequest) => void} callback callback
+	 */
+	resolveResource(
+		contextInfo,
+		context,
+		unresolvedResource,
+		resolver,
+		resolveContext,
+		callback
+	) {
+		resolver.resolve(
+			contextInfo,
+			context,
+			unresolvedResource,
+			resolveContext,
+			(err, resolvedResource, resolvedResourceResolveData) => {
+				if (err) {
+					return this._resolveResourceErrorHints(
+						err,
+						contextInfo,
+						context,
+						unresolvedResource,
+						resolver,
+						resolveContext,
+						(err2, hints) => {
+							if (err2) {
+								err.message += `
+A fatal error happened during resolving additional hints for this error: ${err2.message}`;
+								err.stack += `
+
+A fatal error happened during resolving additional hints for this error:
+${err2.stack}`;
+								return callback(err);
+							}
+							if (hints && hints.length > 0) {
+								err.message += `
+${hints.join("\n\n")}`;
+							}
+
+							// Check if the extension is missing a leading dot (e.g. "js" instead of ".js")
+							let appendResolveExtensionsHint = false;
+							const specifiedExtensions = [...resolver.options.extensions];
+							const expectedExtensions = specifiedExtensions.map(
+								(extension) => {
+									if (LEADING_DOT_EXTENSION_REGEX.test(extension)) {
+										appendResolveExtensionsHint = true;
+										return `.${extension}`;
+									}
+									return extension;
+								}
+							);
+							if (appendResolveExtensionsHint) {
+								err.message += `\nDid you miss the leading dot in 'resolve.extensions'? Did you mean '${JSON.stringify(
+									expectedExtensions
+								)}' instead of '${JSON.stringify(specifiedExtensions)}'?`;
+							}
+
+							callback(err);
+						}
+					);
+				}
+				callback(err, resolvedResource, resolvedResourceResolveData);
+			}
+		);
+	}
+
+	/**
+	 * Resolve resource error hints.
+	 * @param {Error} error error
+	 * @param {ModuleFactoryCreateDataContextInfo} contextInfo context info
+	 * @param {string} context context
+	 * @param {string} unresolvedResource unresolved resource
+	 * @param {ResolverWithOptions} resolver resolver
+	 * @param {ResolveContext} resolveContext resolver context
+	 * @param {Callback<string[]>} callback callback
+	 * @private
+	 */
+	_resolveResourceErrorHints(
+		error,
+		contextInfo,
+		context,
+		unresolvedResource,
+		resolver,
+		resolveContext,
+		callback
+	) {
+		asyncLib.parallel(
+			[
+				(callback) => {
+					if (!resolver.options.fullySpecified) return callback();
+					resolver
+						.withOptions({
+							fullySpecified: false
+						})
+						.resolve(
+							contextInfo,
+							context,
+							unresolvedResource,
+							resolveContext,
+							(err, resolvedResource) => {
+								if (!err && resolvedResource) {
+									const resource = parseResource(resolvedResource).path.replace(
+										/^.*[\\/]/,
+										""
+									);
+									return callback(
+										null,
+										`Did you mean '${resource}'?
+BREAKING CHANGE: The request '${unresolvedResource}' failed to resolve only because it was resolved as fully specified
+(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
+The extension in the request is mandatory for it to be fully specified.
+Add the extension to the request.`
+									);
+								}
+								callback();
+							}
+						);
+				},
+				(callback) => {
+					if (!resolver.options.enforceExtension) return callback();
+					resolver
+						.withOptions({
+							enforceExtension: false,
+							extensions: []
+						})
+						.resolve(
+							contextInfo,
+							context,
+							unresolvedResource,
+							resolveContext,
+							(err, resolvedResource) => {
+								if (!err && resolvedResource) {
+									let hint = "";
+									const match = /\.[^.]+(?:\?|$)/.exec(unresolvedResource);
+									if (match) {
+										const fixedRequest = unresolvedResource.replace(
+											/(\.[^.]+)(\?|$)/,
+											"$2"
+										);
+										hint = resolver.options.extensions.has(match[1])
+											? `Did you mean '${fixedRequest}'?`
+											: `Did you mean '${fixedRequest}'? Also note that '${match[1]}' is not in 'resolve.extensions' yet and need to be added for this to work?`;
+									} else {
+										hint =
+											"Did you mean to omit the extension or to remove 'resolve.enforceExtension'?";
+									}
+									return callback(
+										null,
+										`The request '${unresolvedResource}' failed to resolve only because 'resolve.enforceExtension' was specified.
+${hint}
+Including the extension in the request is no longer possible. Did you mean to enforce including the extension in requests with 'resolve.extensions: []' instead?`
+									);
+								}
+								callback();
+							}
+						);
+				},
+				(callback) => {
+					if (
+						/^\.\.?\//.test(unresolvedResource) ||
+						resolver.options.preferRelative
+					) {
+						return callback();
+					}
+					resolver.resolve(
+						contextInfo,
+						context,
+						`./${unresolvedResource}`,
+						resolveContext,
+						(err, resolvedResource) => {
+							if (err || !resolvedResource) return callback();
+							const moduleDirectories = resolver.options.modules
+								.map((m) => (Array.isArray(m) ? m.join(", ") : m))
+								.join(", ");
+							callback(
+								null,
+								`Did you mean './${unresolvedResource}'?
+Requests that should resolve in the current directory need to start with './'.
+Requests that start with a name are treated as module requests and resolve within module directories (${moduleDirectories}).
+If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.`
+							);
+						}
+					);
+				}
+			],
+			(err, hints) => {
+				if (err) return callback(err);
+				callback(null, /** @type {string[]} */ (hints).filter(Boolean));
+			}
+		);
+	}
+
+	/**
+	 * Resolves request array.
+	 * @param {ModuleFactoryCreateDataContextInfo} contextInfo context info
+	 * @param {string} context context
+	 * @param {LoaderItem[]} array array
+	 * @param {ResolverWithOptions} resolver resolver
+	 * @param {ResolveContext} resolveContext resolve context
+	 * @param {Callback<LoaderItem[]>} callback callback
+	 * @returns {void} result
+	 */
+	resolveRequestArray(
+		contextInfo,
+		context,
+		array,
+		resolver,
+		resolveContext,
+		callback
+	) {
+		// LoaderItem
+		if (array.length === 0) return callback(null, array);
+		asyncLib.map(
+			array,
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {LoaderItem} item item
+			 * @param {Callback<LoaderItem>} callback callback
+			 */
+			(item, callback) => {
+				resolver.resolve(
+					contextInfo,
+					context,
+					item.loader,
+					resolveContext,
+					(err, result, resolveRequest) => {
+						if (
+							err &&
+							/^[^/]*$/.test(item.loader) &&
+							!item.loader.endsWith("-loader")
+						) {
+							return resolver.resolve(
+								contextInfo,
+								context,
+								`${item.loader}-loader`,
+								resolveContext,
+								(err2) => {
+									if (!err2) {
+										err.message =
+											`${err.message}\n` +
+											"BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.\n" +
+											`                 You need to specify '${item.loader}-loader' instead of '${item.loader}',\n` +
+											"                 see https://webpack.js.org/migrate/3/#automatic-loader-module-name-extension-removed";
+									}
+									callback(err);
+								}
+							);
+						}
+						if (err) return callback(err);
+
+						const parsedResult = this._parseResourceWithoutFragment(
+							/** @type {string} */
+							(result)
+						);
+
+						const type = /\.mjs$/i.test(parsedResult.path)
+							? "module"
+							: /\.cjs$/i.test(parsedResult.path)
+								? "commonjs"
+								: /** @type {ResolveRequest} */
+									(resolveRequest).descriptionFileData === undefined
+									? undefined
+									: /** @type {string} */
+										(
+											/** @type {ResolveRequest} */
+											(resolveRequest).descriptionFileData.type
+										);
+						/** @type {LoaderItem} */
+						const resolved = {
+							loader: parsedResult.path,
+							type,
+							options:
+								item.options === undefined
+									? parsedResult.query
+										? parsedResult.query.slice(1)
+										: undefined
+									: item.options,
+							ident: item.options === undefined ? undefined : item.ident
+						};
+
+						return callback(null, resolved);
+					}
+				);
+			},
+			(err, value) => {
+				callback(
+					/** @type {Error | null} */ (err),
+					/** @type {(LoaderItem)[]} */ (value)
+				);
+			}
+		);
+	}
+
+	/**
+	 * Returns parser.
+	 * @template {string} T
+	 * @param {T} type type
+	 * @param {ParserOptions} parserOptions parser options
+	 * @returns {ParserByType[T]} parser
+	 */
+	getParser(type, parserOptions = EMPTY_PARSER_OPTIONS) {
+		let cache = this.parserCache.get(type);
+
+		if (cache === undefined) {
+			cache = new WeakMap();
+			this.parserCache.set(type, cache);
+		}
+
+		let parser = cache.get(parserOptions);
+
+		if (parser === undefined) {
+			parser = this.createParser(type, parserOptions);
+			cache.set(parserOptions, parser);
+		}
+
+		return /** @type {ParserByType[T]} */ (parser);
+	}
+
+	/**
+	 * Creates a parser from the provided type.
+	 * @template {string} T
+	 * @param {T} type type
+	 * @param {ParserOptions} parserOptions parser options
+	 * @returns {ParserByType[T]} parser
+	 */
+	createParser(type, parserOptions = {}) {
+		parserOptions = mergeGlobalOptions(
+			this._globalParserOptions,
+			type,
+			parserOptions
+		);
+		const parser = this.hooks.createParser.for(type).call(parserOptions);
+		if (!parser) {
+			throw new Error(`No parser registered for ${type}`);
+		}
+		this.hooks.parser.for(type).call(parser, parserOptions);
+		return /** @type {ParserByType[T]} */ (parser);
+	}
+
+	/**
+	 * Returns generator.
+	 * @template {string} T
+	 * @param {T} type type of generator
+	 * @param {GeneratorOptions} generatorOptions generator options
+	 * @returns {GeneratorByType[T]} generator
+	 */
+	getGenerator(type, generatorOptions = EMPTY_GENERATOR_OPTIONS) {
+		let cache = this.generatorCache.get(type);
+
+		if (cache === undefined) {
+			cache = new WeakMap();
+			this.generatorCache.set(type, cache);
+		}
+
+		let generator = cache.get(generatorOptions);
+
+		if (generator === undefined) {
+			generator = this.createGenerator(type, generatorOptions);
+			cache.set(generatorOptions, generator);
+		}
+
+		return /** @type {GeneratorByType[T]} */ (generator);
+	}
+
+	/**
+	 * Creates a generator.
+	 * @template {string} T
+	 * @param {T} type type of generator
+	 * @param {GeneratorOptions} generatorOptions generator options
+	 * @returns {GeneratorByType[T]} generator
+	 */
+	createGenerator(type, generatorOptions = {}) {
+		generatorOptions = mergeGlobalOptions(
+			this._globalGeneratorOptions,
+			type,
+			generatorOptions
+		);
+		const generator = this.hooks.createGenerator
+			.for(type)
+			.call(generatorOptions);
+		if (!generator) {
+			throw new Error(`No generator registered for ${type}`);
+		}
+		this.hooks.generator.for(type).call(generator, generatorOptions);
+		return /** @type {GeneratorByType[T]} */ (generator);
+	}
+
+	/**
+	 * Returns the resolver.
+	 * @param {Parameters<ResolverFactory["get"]>[0]} type type of resolver
+	 * @param {Parameters<ResolverFactory["get"]>[1]=} resolveOptions options
+	 * @returns {ReturnType<ResolverFactory["get"]>} the resolver
+	 */
+	getResolver(type, resolveOptions) {
+		return this.resolverFactory.get(type, resolveOptions);
+	}
+}
+
+module.exports = NormalModuleFactory;
Index: frontend/node_modules/webpack/lib/NormalModuleReplacementPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/NormalModuleReplacementPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/NormalModuleReplacementPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { dirname, join } = require("./util/fs");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+
+/** @typedef {(resolveData: ResolveData) => void} ModuleReplacer */
+
+const PLUGIN_NAME = "NormalModuleReplacementPlugin";
+
+class NormalModuleReplacementPlugin {
+	/**
+	 * Create an instance of the plugin
+	 * @param {RegExp} resourceRegExp the resource matcher
+	 * @param {string | ModuleReplacer} newResource the resource replacement
+	 */
+	constructor(resourceRegExp, newResource) {
+		this.resourceRegExp = resourceRegExp;
+		this.newResource = newResource;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const resourceRegExp = this.resourceRegExp;
+		const newResource = this.newResource;
+		compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, (nmf) => {
+			nmf.hooks.beforeResolve.tap(PLUGIN_NAME, (result) => {
+				if (resourceRegExp.test(result.request)) {
+					if (typeof newResource === "function") {
+						newResource(result);
+					} else {
+						result.request = newResource;
+					}
+				}
+			});
+			nmf.hooks.afterResolve.tap(PLUGIN_NAME, (result) => {
+				const createData = result.createData;
+				if (resourceRegExp.test(/** @type {string} */ (createData.resource))) {
+					if (typeof newResource === "function") {
+						newResource(result);
+					} else {
+						const fs =
+							/** @type {InputFileSystem} */
+							(compiler.inputFileSystem);
+						if (
+							newResource.startsWith("/") ||
+							(newResource.length > 1 && newResource[1] === ":")
+						) {
+							createData.resource = newResource;
+						} else {
+							createData.resource = join(
+								fs,
+								dirname(fs, /** @type {string} */ (createData.resource)),
+								newResource
+							);
+						}
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = NormalModuleReplacementPlugin;
Index: frontend/node_modules/webpack/lib/NullFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/NullFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/NullFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,25 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleFactory = require("./ModuleFactory");
+
+/** @typedef {import("./ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+
+class NullFactory extends ModuleFactory {
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		return callback();
+	}
+}
+
+module.exports = NullFactory;
Index: frontend/node_modules/webpack/lib/OptimizationStages.js
===================================================================
--- frontend/node_modules/webpack/lib/OptimizationStages.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/OptimizationStages.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,10 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+module.exports.STAGE_ADVANCED = 10;
+module.exports.STAGE_BASIC = -10;
+module.exports.STAGE_DEFAULT = 0;
Index: frontend/node_modules/webpack/lib/OptionsApply.js
===================================================================
--- frontend/node_modules/webpack/lib/OptionsApply.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/OptionsApply.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,25 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./config/normalization").WebpackOptionsInterception} WebpackOptionsInterception */
+/** @typedef {import("./Compiler")} Compiler */
+
+class OptionsApply {
+	/**
+	 * Returns options object.
+	 * @param {WebpackOptions} options options object
+	 * @param {Compiler} compiler compiler object
+	 * @param {WebpackOptionsInterception=} interception intercepted options
+	 * @returns {WebpackOptions} options object
+	 */
+	process(options, compiler, interception) {
+		return options;
+	}
+}
+
+module.exports = OptionsApply;
Index: frontend/node_modules/webpack/lib/Parser.js
===================================================================
--- frontend/node_modules/webpack/lib/Parser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Parser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./NormalModule")} NormalModule */
+
+/** @typedef {Record<string, EXPECTED_ANY>} PreparsedAst */
+
+/**
+ * Defines the parser state base type used by this module.
+ * @typedef {object} ParserStateBase
+ * @property {string | Buffer} source
+ * @property {NormalModule} current
+ * @property {NormalModule} module
+ * @property {Compilation} compilation
+ * @property {WebpackOptions} options
+ */
+
+/** @typedef {ParserStateBase & Record<string, EXPECTED_ANY>} ParserState */
+
+class Parser {
+	/* istanbul ignore next */
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @abstract
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+}
+
+module.exports = Parser;
Index: frontend/node_modules/webpack/lib/PlatformPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/PlatformPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/PlatformPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Authors Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./config/target").PlatformTargetProperties} PlatformTargetProperties */
+
+const PLUGIN_NAME = "PlatformPlugin";
+
+/**
+ * Should be used only for "target === false" or
+ * when you want to overwrite platform target properties
+ */
+class PlatformPlugin {
+	/**
+	 * Creates an instance of PlatformPlugin.
+	 * @param {Partial<PlatformTargetProperties>} platform target properties
+	 */
+	constructor(platform) {
+		/** @type {Partial<PlatformTargetProperties>} */
+		this.platform = platform;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.environment.tap(PLUGIN_NAME, () => {
+			compiler.platform = {
+				...compiler.platform,
+				...this.platform
+			};
+		});
+	}
+}
+
+module.exports = PlatformPlugin;
Index: frontend/node_modules/webpack/lib/PrefetchPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/PrefetchPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/PrefetchPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,57 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const PrefetchDependency = require("./dependencies/PrefetchDependency");
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "PrefetchPlugin";
+
+class PrefetchPlugin {
+	/**
+	 * Creates an instance of PrefetchPlugin.
+	 * @param {string} context context or request if context is not set
+	 * @param {string=} request request
+	 */
+	constructor(context, request) {
+		if (request) {
+			this.context = context;
+			this.request = request;
+		} else {
+			this.context = null;
+			this.request = context;
+		}
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					PrefetchDependency,
+					normalModuleFactory
+				);
+			}
+		);
+		compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
+			compilation.addModuleChain(
+				this.context || compiler.context,
+				new PrefetchDependency(this.request),
+				(err) => {
+					callback(err);
+				}
+			);
+		});
+	}
+}
+
+module.exports = PrefetchPlugin;
Index: frontend/node_modules/webpack/lib/ProgressPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ProgressPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ProgressPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,812 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Compiler = require("./Compiler");
+const MultiCompiler = require("./MultiCompiler");
+const NormalModule = require("./NormalModule");
+const { contextify } = require("./util/identifier");
+const memoize = require("./util/memoize");
+
+const getColors = memoize(() => {
+	const cli = require("./cli");
+
+	return cli.createColors({ useColor: cli.isColorSupported() });
+});
+
+const BAR_LENGTH = 25;
+const BLOCK_CHAR = "━";
+const BULLET_ICON = "●";
+
+/** @typedef {import("tapable").Tap} Tap */
+/**
+ * Defines the hook type used by this module.
+ * @template T, R, AdditionalOptions
+ * @typedef {import("tapable").Hook<T, R, AdditionalOptions>} Hook
+ */
+/** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginArgument} ProgressPluginArgument */
+/** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginOptions} ProgressPluginOptions */
+/** @typedef {import("./Compilation").FactorizeModuleOptions} FactorizeModuleOptions */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./cli").Colors} Colors */
+
+/**
+ * Defines the async queue type used by this module.
+ * @template T, K, R
+ * @typedef {import("./util/AsyncQueue")<T, K, R>} AsyncQueue
+ */
+
+/**
+ * Defines the counts data type used by this module.
+ * @typedef {object} CountsData
+ * @property {number} modulesCount modules count
+ * @property {number} dependenciesCount dependencies count
+ */
+
+/**
+ * Returns median.
+ * @param {number} a a
+ * @param {number} b b
+ * @param {number} c c
+ * @returns {number} median
+ */
+const median3 = (a, b, c) => a + b + c - Math.max(a, b, c) - Math.min(a, b, c);
+
+/** @typedef {(percentage: number, msg: string, ...args: string[]) => void} HandlerFn */
+
+/**
+ * @param {Logger} logger logger
+ * @param {{ value: string | undefined, time: number }[]} lastStateInfo mutable state
+ * @param {number} percentage percentage
+ * @param {string} msg msg
+ * @param {string[]} args args
+ */
+const reportProfile = (logger, lastStateInfo, percentage, msg, args) => {
+	if (percentage === 0) {
+		lastStateInfo.length = 0;
+	}
+	const fullState = [msg, ...args];
+	const state = fullState.map((s) => s.replace(/\d+\/\d+ /g, ""));
+	const now = Date.now();
+	const len = Math.max(state.length, lastStateInfo.length);
+	for (let i = len; i >= 0; i--) {
+		const stateItem = i < state.length ? state[i] : undefined;
+		const lastStateItem =
+			i < lastStateInfo.length ? lastStateInfo[i] : undefined;
+		if (lastStateItem) {
+			if (stateItem !== lastStateItem.value) {
+				const diff = now - lastStateItem.time;
+				if (lastStateItem.value) {
+					let reportState = lastStateItem.value;
+					if (i > 0) {
+						reportState = `${lastStateInfo[i - 1].value} > ${reportState}`;
+					}
+					const stateMsg = `${" | ".repeat(i)}${diff} ms ${reportState}`;
+					const d = diff;
+					// This depends on timing so we ignore it for coverage
+					/* eslint-disable no-lone-blocks */
+					/* istanbul ignore next */
+					{
+						if (d > 10000) {
+							logger.error(stateMsg);
+						} else if (d > 1000) {
+							logger.warn(stateMsg);
+						} else if (d > 10) {
+							logger.info(stateMsg);
+						} else if (d > 5) {
+							logger.log(stateMsg);
+						} else {
+							logger.debug(stateMsg);
+						}
+					}
+					/* eslint-enable no-lone-blocks */
+				}
+				if (stateItem === undefined) {
+					lastStateInfo.length = i;
+				} else {
+					lastStateItem.value = stateItem;
+					lastStateItem.time = now;
+					lastStateInfo.length = i + 1;
+				}
+			}
+		} else {
+			lastStateInfo[i] = {
+				value: stateItem,
+				time: now
+			};
+		}
+	}
+};
+
+/**
+ * @param {string} name progress bar name
+ * @param {string} color progress bar color
+ * @returns {(percentage: number) => string} bar renderer
+ */
+const createReportBar = (name, color) => {
+	const c = getColors();
+
+	return (percentage) => {
+		const w = Math.round(percentage * BAR_LENGTH);
+		const filled = BLOCK_CHAR.repeat(w);
+		const empty = BLOCK_CHAR.repeat(BAR_LENGTH - w);
+		const colorFn =
+			color in c ? c[/** @type {keyof Colors} */ (color)] : c.green;
+
+		return `${[BULLET_ICON, name, filled].map(colorFn).join(" ")}${c.white(empty)}`;
+	};
+};
+
+/** @typedef {Required<Exclude<NonNullable<ProgressPluginOptions["progressBar"]>, boolean>>} ProgressBarOptions */
+
+/**
+ * Creates a default handler.
+ * @param {boolean | null | undefined} profile need profile
+ * @param {Logger} logger logger
+ * @param {ProgressBarOptions | false} progressBar render bar
+ * @returns {HandlerFn} default handler
+ */
+const createDefaultHandler = (profile, logger, progressBar) => {
+	/** @type {{ value: string | undefined, time: number }[]} */
+	const lastStateInfo = [];
+
+	/** @type {HandlerFn} */
+	const defaultHandler = (percentage, msg, ...args) => {
+		if (profile) {
+			reportProfile(logger, lastStateInfo, percentage, msg, args);
+		}
+
+		if (progressBar) {
+			const reportBar = createReportBar(progressBar.name, progressBar.color);
+			const c = getColors();
+			/** @type {string} */
+			const currentBar = reportBar(percentage);
+
+			if (percentage === 1) {
+				logger.status();
+			} else if (msg) {
+				logger.status(
+					`${currentBar} (${Math.floor(percentage * 100)}%)`,
+					`\n${[msg, ...args].map(c.gray).join(" ")}`
+				);
+			} else {
+				logger.status(`${currentBar} (${Math.floor(percentage * 100)}%)`);
+			}
+			return;
+		}
+
+		logger.status(`${Math.floor(percentage * 100)}%`, msg, ...args);
+		if (percentage === 1 || (!msg && args.length === 0)) logger.status();
+	};
+
+	return defaultHandler;
+};
+
+const SKIPPED_QUEUE_CONTEXTS = ["import-module", "load-module"];
+
+/**
+ * Defines the report progress callback.
+ * @callback ReportProgress
+ * @param {number} p percentage
+ * @param {...string} args additional arguments
+ * @returns {void}
+ */
+
+/** @type {WeakMap<Compiler, ReportProgress | undefined>} */
+const progressReporters = new WeakMap();
+
+const PLUGIN_NAME = "ProgressPlugin";
+
+/** @type {Required<Omit<ProgressPluginOptions, "handler">>} */
+const DEFAULT_OPTIONS = {
+	profile: false,
+	modulesCount: 5000,
+	dependenciesCount: 10000,
+	modules: true,
+	dependencies: true,
+	activeModules: false,
+	entries: true,
+	percentBy: null,
+	progressBar: false
+};
+
+class ProgressPlugin {
+	/**
+	 * Returns a progress reporter, if any.
+	 * @param {Compiler} compiler the current compiler
+	 * @returns {ReportProgress | undefined} a progress reporter, if any
+	 */
+	static getReporter(compiler) {
+		return progressReporters.get(compiler);
+	}
+
+	/**
+	 * Creates an instance of ProgressPlugin.
+	 * @param {ProgressPluginArgument} options options
+	 */
+	constructor(options = {}) {
+		if (typeof options === "function") {
+			options = {
+				handler: options
+			};
+		}
+
+		/** @type {ProgressPluginOptions} */
+		this.options = options;
+
+		const merged = { ...DEFAULT_OPTIONS, ...options };
+		this.profile = merged.profile;
+		this.handler = merged.handler;
+		this.modulesCount = merged.modulesCount;
+		this.dependenciesCount = merged.dependenciesCount;
+		this.showEntries = merged.entries;
+		this.showModules = merged.modules;
+		this.showDependencies = merged.dependencies;
+		this.showActiveModules = merged.activeModules;
+		this.percentBy = merged.percentBy;
+
+		const progressBar = merged.progressBar === true ? {} : merged.progressBar;
+		/** @type {ProgressBarOptions | false} */
+		this.progressBar = progressBar
+			? { name: "Build", color: "green", ...progressBar }
+			: false;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler | MultiCompiler} compiler webpack compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const handler =
+			this.handler ||
+			createDefaultHandler(
+				this.profile,
+				compiler.getInfrastructureLogger("webpack.Progress"),
+				this.progressBar
+			);
+		if (compiler instanceof MultiCompiler) {
+			this._applyOnMultiCompiler(compiler, handler);
+		} else if (compiler instanceof Compiler) {
+			this._applyOnCompiler(compiler, handler);
+		}
+	}
+
+	/**
+	 * Apply on multi compiler.
+	 * @param {MultiCompiler} compiler webpack multi-compiler
+	 * @param {HandlerFn} handler function that executes for every progress step
+	 * @returns {void}
+	 */
+	_applyOnMultiCompiler(compiler, handler) {
+		const states = compiler.compilers.map(
+			() => /** @type {[number, ...string[]]} */ ([0])
+		);
+		for (const [idx, item] of compiler.compilers.entries()) {
+			new ProgressPlugin((p, msg, ...args) => {
+				states[idx] = [p, msg, ...args];
+				let sum = 0;
+				for (const [p] of states) sum += p;
+				handler(sum / states.length, `[${idx}] ${msg}`, ...args);
+			}).apply(item);
+		}
+	}
+
+	/**
+	 * Processes the provided compiler.
+	 * @param {Compiler} compiler webpack compiler
+	 * @param {HandlerFn} handler function that executes for every progress step
+	 * @returns {void}
+	 */
+	_applyOnCompiler(compiler, handler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../schemas/plugins/ProgressPlugin.json"),
+				this.options,
+				{
+					name: "Progress Plugin",
+					baseDataPath: "options"
+				},
+				(options) => require("../schemas/plugins/ProgressPlugin.check")(options)
+			);
+		});
+
+		const showEntries = this.showEntries;
+		const showModules = this.showModules;
+		const showDependencies = this.showDependencies;
+		const showActiveModules = this.showActiveModules;
+		let lastActiveModule = "";
+		let currentLoader = "";
+		let lastModulesCount = 0;
+		let lastDependenciesCount = 0;
+		let lastEntriesCount = 0;
+		let modulesCount = 0;
+		let skippedModulesCount = 0;
+		let dependenciesCount = 0;
+		let skippedDependenciesCount = 0;
+		let entriesCount = 1;
+		let doneModules = 0;
+		let doneDependencies = 0;
+		let doneEntries = 0;
+		/** @type {Set<string>} */
+		const activeModules = new Set();
+		let lastUpdate = 0;
+
+		const updateThrottled = () => {
+			if (lastUpdate + 500 < Date.now()) update();
+		};
+
+		const update = () => {
+			/** @type {string[]} */
+			const items = [];
+			const percentByModules =
+				doneModules /
+				Math.max(lastModulesCount || this.modulesCount || 1, modulesCount);
+			const percentByEntries =
+				doneEntries /
+				Math.max(lastEntriesCount || this.dependenciesCount || 1, entriesCount);
+			const percentByDependencies =
+				doneDependencies /
+				Math.max(lastDependenciesCount || 1, dependenciesCount);
+			/** @type {number} */
+			let percentageFactor;
+
+			switch (this.percentBy) {
+				case "entries":
+					percentageFactor = percentByEntries;
+					break;
+				case "dependencies":
+					percentageFactor = percentByDependencies;
+					break;
+				case "modules":
+					percentageFactor = percentByModules;
+					break;
+				default:
+					percentageFactor = median3(
+						percentByModules,
+						percentByEntries,
+						percentByDependencies
+					);
+			}
+
+			const percentage = 0.1 + percentageFactor * 0.55;
+
+			if (currentLoader) {
+				items.push(
+					`import loader ${contextify(
+						compiler.context,
+						currentLoader,
+						compiler.root
+					)}`
+				);
+			} else {
+				/** @type {string[]} */
+				const statItems = [];
+				if (showEntries) {
+					statItems.push(`${doneEntries}/${entriesCount} entries`);
+				}
+				if (showDependencies) {
+					statItems.push(
+						`${doneDependencies}/${dependenciesCount} dependencies`
+					);
+				}
+				if (showModules) {
+					statItems.push(`${doneModules}/${modulesCount} modules`);
+				}
+				if (showActiveModules) {
+					statItems.push(`${activeModules.size} active`);
+				}
+				if (statItems.length > 0) {
+					items.push(statItems.join(" "));
+				}
+				if (showActiveModules) {
+					items.push(lastActiveModule);
+				}
+			}
+			handler(percentage, "building", ...items);
+			lastUpdate = Date.now();
+		};
+
+		/**
+		 * Processes the provided factorize queue.
+		 * @template T
+		 * @param {AsyncQueue<FactorizeModuleOptions, string, Module | ModuleFactoryResult>} factorizeQueue async queue
+		 * @param {T} _item item
+		 */
+		const factorizeAdd = (factorizeQueue, _item) => {
+			if (SKIPPED_QUEUE_CONTEXTS.includes(factorizeQueue.getContext())) {
+				skippedDependenciesCount++;
+			}
+			dependenciesCount++;
+			if (dependenciesCount < 50 || dependenciesCount % 100 === 0) {
+				updateThrottled();
+			}
+		};
+
+		const factorizeDone = () => {
+			doneDependencies++;
+			if (doneDependencies < 50 || doneDependencies % 100 === 0) {
+				updateThrottled();
+			}
+		};
+
+		/**
+		 * Processes the provided add module queue.
+		 * @template T
+		 * @param {AsyncQueue<Module, string, Module>} addModuleQueue async queue
+		 * @param {T} _item item
+		 */
+		const moduleAdd = (addModuleQueue, _item) => {
+			if (SKIPPED_QUEUE_CONTEXTS.includes(addModuleQueue.getContext())) {
+				skippedModulesCount++;
+			}
+			modulesCount++;
+			if (modulesCount < 50 || modulesCount % 100 === 0) updateThrottled();
+		};
+
+		// only used when showActiveModules is set
+		/**
+		 * Processes the provided module.
+		 * @param {Module} module the module
+		 */
+		const moduleBuild = (module) => {
+			const ident = module.identifier();
+			if (ident) {
+				activeModules.add(ident);
+				lastActiveModule = ident;
+				update();
+			}
+		};
+
+		/**
+		 * Processes the provided entry.
+		 * @param {Dependency} entry entry dependency
+		 * @param {EntryOptions} options options object
+		 */
+		const entryAdd = (entry, options) => {
+			entriesCount++;
+			if (entriesCount < 5 || entriesCount % 10 === 0) updateThrottled();
+		};
+
+		/**
+		 * Processes the provided module.
+		 * @param {Module} module the module
+		 */
+		const moduleDone = (module) => {
+			doneModules++;
+			if (showActiveModules) {
+				const ident = module.identifier();
+				if (ident) {
+					activeModules.delete(ident);
+					if (lastActiveModule === ident) {
+						lastActiveModule = "";
+						for (const m of activeModules) {
+							lastActiveModule = m;
+						}
+						update();
+						return;
+					}
+				}
+			}
+			if (doneModules < 50 || doneModules % 100 === 0) updateThrottled();
+		};
+
+		/**
+		 * Processes the provided entry.
+		 * @param {Dependency} entry entry dependency
+		 * @param {EntryOptions} options options object
+		 */
+		const entryDone = (entry, options) => {
+			doneEntries++;
+			update();
+		};
+
+		const cache = compiler.getCache(PLUGIN_NAME).getItemCache("counts", null);
+
+		/** @type {Promise<CountsData> | undefined} */
+		let cacheGetPromise;
+
+		compiler.hooks.beforeCompile.tap(PLUGIN_NAME, () => {
+			if (!cacheGetPromise) {
+				cacheGetPromise = cache.getPromise().then(
+					(data) => {
+						if (data) {
+							lastModulesCount = lastModulesCount || data.modulesCount;
+							lastDependenciesCount =
+								lastDependenciesCount || data.dependenciesCount;
+						}
+						return data;
+					},
+					(_err) => {
+						// Ignore error
+					}
+				);
+			}
+		});
+
+		compiler.hooks.afterCompile.tapPromise(PLUGIN_NAME, (compilation) => {
+			if (compilation.compiler.isChild()) return Promise.resolve();
+			return /** @type {Promise<CountsData>} */ (cacheGetPromise).then(
+				async (oldData) => {
+					const realModulesCount = modulesCount - skippedModulesCount;
+					const realDependenciesCount =
+						dependenciesCount - skippedDependenciesCount;
+
+					if (
+						!oldData ||
+						oldData.modulesCount !== realModulesCount ||
+						oldData.dependenciesCount !== realDependenciesCount
+					) {
+						await cache.storePromise({
+							modulesCount: realModulesCount,
+							dependenciesCount: realDependenciesCount
+						});
+					}
+				}
+			);
+		});
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			if (compilation.compiler.isChild()) return;
+			lastModulesCount = modulesCount;
+			lastEntriesCount = entriesCount;
+			lastDependenciesCount = dependenciesCount;
+			modulesCount =
+				skippedModulesCount =
+				dependenciesCount =
+				skippedDependenciesCount =
+				entriesCount =
+					0;
+			doneModules = doneDependencies = doneEntries = 0;
+
+			compilation.factorizeQueue.hooks.added.tap(PLUGIN_NAME, (item) =>
+				factorizeAdd(compilation.factorizeQueue, item)
+			);
+			compilation.factorizeQueue.hooks.result.tap(PLUGIN_NAME, factorizeDone);
+
+			compilation.addModuleQueue.hooks.added.tap(PLUGIN_NAME, (item) =>
+				moduleAdd(compilation.addModuleQueue, item)
+			);
+			compilation.processDependenciesQueue.hooks.result.tap(
+				PLUGIN_NAME,
+				moduleDone
+			);
+
+			if (showActiveModules) {
+				compilation.hooks.buildModule.tap(PLUGIN_NAME, moduleBuild);
+			}
+
+			compilation.hooks.addEntry.tap(PLUGIN_NAME, entryAdd);
+			compilation.hooks.failedEntry.tap(PLUGIN_NAME, entryDone);
+			compilation.hooks.succeedEntry.tap(PLUGIN_NAME, entryDone);
+
+			// @ts-expect-error avoid dynamic require if bundled with webpack
+			if (typeof __webpack_require__ !== "function") {
+				/** @type {Set<string>} */
+				const requiredLoaders = new Set();
+				NormalModule.getCompilationHooks(compilation).beforeLoaders.tap(
+					PLUGIN_NAME,
+					(loaders) => {
+						for (const loader of loaders) {
+							if (
+								loader.type !== "module" &&
+								!requiredLoaders.has(loader.loader)
+							) {
+								requiredLoaders.add(loader.loader);
+								currentLoader = loader.loader;
+								update();
+								require(loader.loader);
+							}
+						}
+						if (currentLoader) {
+							currentLoader = "";
+							update();
+						}
+					}
+				);
+			}
+
+			const hooks = {
+				finishModules: "finish module graph",
+				seal: "plugins",
+				optimizeDependencies: "dependencies optimization",
+				afterOptimizeDependencies: "after dependencies optimization",
+				beforeChunks: "chunk graph",
+				afterChunks: "after chunk graph",
+				optimize: "optimizing",
+				optimizeModules: "module optimization",
+				afterOptimizeModules: "after module optimization",
+				optimizeChunks: "chunk optimization",
+				afterOptimizeChunks: "after chunk optimization",
+				optimizeTree: "module and chunk tree optimization",
+				afterOptimizeTree: "after module and chunk tree optimization",
+				optimizeChunkModules: "chunk modules optimization",
+				afterOptimizeChunkModules: "after chunk modules optimization",
+				reviveModules: "module reviving",
+				beforeModuleIds: "before module ids",
+				moduleIds: "module ids",
+				optimizeModuleIds: "module id optimization",
+				afterOptimizeModuleIds: "module id optimization",
+				reviveChunks: "chunk reviving",
+				beforeChunkIds: "before chunk ids",
+				chunkIds: "chunk ids",
+				optimizeChunkIds: "chunk id optimization",
+				afterOptimizeChunkIds: "after chunk id optimization",
+				recordModules: "record modules",
+				recordChunks: "record chunks",
+				beforeModuleHash: "module hashing",
+				beforeCodeGeneration: "code generation",
+				beforeRuntimeRequirements: "runtime requirements",
+				beforeHash: "hashing",
+				afterHash: "after hashing",
+				recordHash: "record hash",
+				beforeModuleAssets: "module assets processing",
+				beforeChunkAssets: "chunk assets processing",
+				processAssets: "asset processing",
+				afterProcessAssets: "after asset optimization",
+				record: "recording",
+				afterSeal: "after seal"
+			};
+			const numberOfHooks = Object.keys(hooks).length;
+			for (const [idx, name] of Object.keys(hooks).entries()) {
+				const title = hooks[/** @type {keyof typeof hooks} */ (name)];
+				const percentage = (idx / numberOfHooks) * 0.25 + 0.7;
+				compilation.hooks[/** @type {keyof typeof hooks} */ (name)].intercept({
+					name: PLUGIN_NAME,
+					call() {
+						handler(percentage, "sealing", title);
+					},
+					done() {
+						progressReporters.set(compiler, undefined);
+						handler(percentage, "sealing", title);
+					},
+					result() {
+						handler(percentage, "sealing", title);
+					},
+					error() {
+						handler(percentage, "sealing", title);
+					},
+					tap(tap) {
+						// p is percentage from 0 to 1
+						// args is any number of messages in a hierarchical matter
+						progressReporters.set(compilation.compiler, (p, ...args) => {
+							handler(percentage, "sealing", title, tap.name, ...args);
+						});
+						handler(percentage, "sealing", title, tap.name);
+					}
+				});
+			}
+		});
+		compiler.hooks.make.intercept({
+			name: PLUGIN_NAME,
+			call() {
+				handler(0.1, "building");
+			},
+			done() {
+				handler(0.65, "building");
+			}
+		});
+		/**
+		 * Processes the provided hook.
+		 * @template {Hook<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>} T
+		 * @param {T} hook hook
+		 * @param {number} progress progress from 0 to 1
+		 * @param {string} category category
+		 * @param {string} name name
+		 */
+		const interceptHook = (hook, progress, category, name) => {
+			hook.intercept({
+				name: PLUGIN_NAME,
+				call() {
+					handler(progress, category, name);
+				},
+				done() {
+					progressReporters.set(compiler, undefined);
+					handler(progress, category, name);
+				},
+				result() {
+					handler(progress, category, name);
+				},
+				error() {
+					handler(progress, category, name);
+				},
+				/**
+				 * Processes the provided tap.
+				 * @param {Tap} tap tap
+				 */
+				tap(tap) {
+					progressReporters.set(compiler, (p, ...args) => {
+						handler(progress, category, name, tap.name, ...args);
+					});
+					handler(progress, category, name, tap.name);
+				}
+			});
+		};
+		compiler.cache.hooks.endIdle.intercept({
+			name: PLUGIN_NAME,
+			call() {
+				handler(0, "");
+			}
+		});
+		interceptHook(compiler.cache.hooks.endIdle, 0.01, "cache", "end idle");
+		compiler.hooks.beforeRun.intercept({
+			name: PLUGIN_NAME,
+			call() {
+				handler(0, "");
+			}
+		});
+		interceptHook(compiler.hooks.beforeRun, 0.01, "setup", "before run");
+		interceptHook(compiler.hooks.run, 0.02, "setup", "run");
+		interceptHook(compiler.hooks.watchRun, 0.03, "setup", "watch run");
+		interceptHook(
+			compiler.hooks.normalModuleFactory,
+			0.04,
+			"setup",
+			"normal module factory"
+		);
+		interceptHook(
+			compiler.hooks.contextModuleFactory,
+			0.05,
+			"setup",
+			"context module factory"
+		);
+		interceptHook(
+			compiler.hooks.beforeCompile,
+			0.06,
+			"setup",
+			"before compile"
+		);
+		interceptHook(compiler.hooks.compile, 0.07, "setup", "compile");
+		interceptHook(compiler.hooks.thisCompilation, 0.08, "setup", "compilation");
+		interceptHook(compiler.hooks.compilation, 0.09, "setup", "compilation");
+		interceptHook(compiler.hooks.finishMake, 0.69, "building", "finish");
+		interceptHook(compiler.hooks.emit, 0.95, "emitting", "emit");
+		interceptHook(compiler.hooks.afterEmit, 0.98, "emitting", "after emit");
+		interceptHook(compiler.hooks.done, 0.99, "done", "plugins");
+		compiler.hooks.done.intercept({
+			name: PLUGIN_NAME,
+			done() {
+				handler(0.99, "");
+			}
+		});
+		interceptHook(
+			compiler.cache.hooks.storeBuildDependencies,
+			0.99,
+			"cache",
+			"store build dependencies"
+		);
+		interceptHook(compiler.cache.hooks.shutdown, 0.99, "cache", "shutdown");
+		interceptHook(compiler.cache.hooks.beginIdle, 0.99, "cache", "begin idle");
+		interceptHook(
+			compiler.hooks.watchClose,
+			0.99,
+			"end",
+			"closing watch compilation"
+		);
+		compiler.cache.hooks.beginIdle.intercept({
+			name: PLUGIN_NAME,
+			done() {
+				handler(1, "");
+			}
+		});
+		compiler.cache.hooks.shutdown.intercept({
+			name: PLUGIN_NAME,
+			done() {
+				handler(1, "");
+			}
+		});
+	}
+}
+
+ProgressPlugin.defaultOptions = DEFAULT_OPTIONS;
+
+ProgressPlugin.createDefaultHandler = createDefaultHandler;
+
+module.exports = ProgressPlugin;
Index: frontend/node_modules/webpack/lib/ProvidePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ProvidePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ProvidePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,123 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const ConstDependency = require("./dependencies/ConstDependency");
+const ProvidedDependency = require("./dependencies/ProvidedDependency");
+const { approve } = require("./javascript/JavascriptParserHelpers");
+
+/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "ProvidePlugin";
+
+class ProvidePlugin {
+	/**
+	 * Creates an instance of ProvidePlugin.
+	 * @param {Record<string, string | string[]>} definitions the provided identifiers
+	 */
+	constructor(definitions) {
+		this.definitions = definitions;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const definitions = this.definitions;
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					ConstDependency,
+					new ConstDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					ProvidedDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ProvidedDependency,
+					new ProvidedDependency.Template()
+				);
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {JavascriptParserOptions} parserOptions options
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					for (const name of Object.keys(definitions)) {
+						const request = [
+							...(Array.isArray(definitions[name])
+								? definitions[name]
+								: [definitions[name]])
+						];
+						const splittedName = name.split(".");
+						if (splittedName.length > 0) {
+							for (const [i, _] of splittedName.slice(1).entries()) {
+								const name = splittedName.slice(0, i + 1).join(".");
+								parser.hooks.canRename.for(name).tap(PLUGIN_NAME, approve);
+							}
+						}
+
+						parser.hooks.expression.for(name).tap(PLUGIN_NAME, (expr) => {
+							const nameIdentifier = name.includes(".")
+								? `__webpack_provided_${name.replace(/\./g, "_dot_")}`
+								: name;
+							const dep = new ProvidedDependency(
+								request[0],
+								nameIdentifier,
+								request.slice(1),
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addDependency(dep);
+							return true;
+						});
+
+						parser.hooks.call.for(name).tap(PLUGIN_NAME, (expr) => {
+							const nameIdentifier = name.includes(".")
+								? `__webpack_provided_${name.replace(/\./g, "_dot_")}`
+								: name;
+							const dep = new ProvidedDependency(
+								request[0],
+								nameIdentifier,
+								request.slice(1),
+								/** @type {Range} */ (expr.callee.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.callee.loc);
+							parser.state.module.addDependency(dep);
+							parser.walkExpressions(expr.arguments);
+							return true;
+						});
+					}
+				};
+				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);
+			}
+		);
+	}
+}
+
+module.exports = ProvidePlugin;
Index: frontend/node_modules/webpack/lib/RawModule.js
===================================================================
--- frontend/node_modules/webpack/lib/RawModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RawModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,192 @@
+/*
+	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_TYPE,
+	JAVASCRIPT_TYPES
+} = require("./ModuleSourceTypeConstants");
+const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
+const makeSerializable = require("./util/makeSerializable");
+
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("./Generator").SourceTypes} SourceTypes */
+/** @typedef {import("./Module").BuildCallback} BuildCallback */
+/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("./Module").Sources} Sources */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+
+class RawModule extends Module {
+	/**
+	 * Creates an instance of RawModule.
+	 * @param {string} source source code
+	 * @param {string} identifier unique identifier
+	 * @param {string=} readableIdentifier readable identifier
+	 * @param {ReadOnlyRuntimeRequirements=} runtimeRequirements runtime requirements needed for the source code
+	 */
+	constructor(source, identifier, readableIdentifier, runtimeRequirements) {
+		super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);
+		this.sourceStr = source;
+		this.identifierStr = identifier || this.sourceStr;
+		this.readableIdentifierStr = readableIdentifier || this.identifierStr;
+		this.runtimeRequirements = runtimeRequirements || null;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this.identifierStr;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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 Math.max(1, this.sourceStr.length);
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return /** @type {string} */ (
+			requestShortener.shorten(this.readableIdentifierStr)
+		);
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, !this.buildMeta);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {
+			cacheable: true
+		};
+		callback();
+	}
+
+	/**
+	 * Gets side effects connection state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only
+	 */
+	getSideEffectsConnectionState(moduleGraph) {
+		if (this.factoryMeta !== undefined) {
+			if (this.factoryMeta.sideEffectFree) return false;
+			if (this.factoryMeta.sideEffectFree === false) return true;
+		}
+		return true;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration(context) {
+		/** @type {Sources} */
+		const sources = new Map();
+		if (this.useSourceMap || this.useSimpleSourceMap) {
+			sources.set(
+				JAVASCRIPT_TYPE,
+				new OriginalSource(this.sourceStr, this.identifier())
+			);
+		} else {
+			sources.set(JAVASCRIPT_TYPE, new RawSource(this.sourceStr));
+		}
+		return { sources, runtimeRequirements: this.runtimeRequirements };
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		hash.update(this.sourceStr);
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.sourceStr);
+		write(this.identifierStr);
+		write(this.readableIdentifierStr);
+		write(this.runtimeRequirements);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.sourceStr = read();
+		this.identifierStr = read();
+		this.readableIdentifierStr = read();
+		this.runtimeRequirements = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(RawModule, "webpack/lib/RawModule");
+
+module.exports = RawModule;
Index: frontend/node_modules/webpack/lib/RecordIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/RecordIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RecordIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,224 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { compareNumbers } = require("./util/comparators");
+const identifierUtils = require("./util/identifier");
+
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Module")} Module */
+
+/**
+ * Defines the records chunks type used by this module.
+ * @typedef {object} RecordsChunks
+ * @property {Record<string, number>=} byName
+ * @property {Record<string, number>=} bySource
+ * @property {number[]=} usedIds
+ */
+
+/**
+ * Defines the records modules type used by this module.
+ * @typedef {object} RecordsModules
+ * @property {Record<string, number>=} byIdentifier
+ * @property {number[]=} usedIds
+ */
+
+/**
+ * Defines the records type used by this module.
+ * @typedef {object} Records
+ * @property {RecordsChunks=} chunks
+ * @property {RecordsModules=} modules
+ */
+
+/**
+ * Defines the record ids plugin options type used by this module.
+ * @typedef {object} RecordIdsPluginOptions
+ * @property {boolean=} portableIds true, when ids need to be portable
+ */
+
+/** @typedef {Set<number>} UsedIds */
+
+const PLUGIN_NAME = "RecordIdsPlugin";
+
+class RecordIdsPlugin {
+	/**
+	 * Creates an instance of RecordIdsPlugin.
+	 * @param {RecordIdsPluginOptions=} options object
+	 */
+	constructor(options) {
+		this.options = options || {};
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the Compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const portableIds = this.options.portableIds;
+
+		const makePathsRelative =
+			identifierUtils.makePathsRelative.bindContextCache(
+				compiler.context,
+				compiler.root
+			);
+
+		/**
+		 * Gets module identifier.
+		 * @param {Module} module the module
+		 * @returns {string} the (portable) identifier
+		 */
+		const getModuleIdentifier = (module) => {
+			if (portableIds) {
+				return makePathsRelative(module.identifier());
+			}
+			return module.identifier();
+		};
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.recordModules.tap(PLUGIN_NAME, (modules, records) => {
+				const chunkGraph = compilation.chunkGraph;
+				if (!records.modules) records.modules = {};
+				if (!records.modules.byIdentifier) records.modules.byIdentifier = {};
+				/** @type {UsedIds} */
+				const usedIds = new Set();
+				for (const module of modules) {
+					const moduleId = chunkGraph.getModuleId(module);
+					if (typeof moduleId !== "number") continue;
+					const identifier = getModuleIdentifier(module);
+					records.modules.byIdentifier[identifier] = moduleId;
+					usedIds.add(moduleId);
+				}
+				records.modules.usedIds = [...usedIds].sort(compareNumbers);
+			});
+			compilation.hooks.reviveModules.tap(PLUGIN_NAME, (modules, records) => {
+				if (!records.modules) return;
+				if (records.modules.byIdentifier) {
+					const chunkGraph = compilation.chunkGraph;
+					/** @type {UsedIds} */
+					const usedIds = new Set();
+					for (const module of modules) {
+						const moduleId = chunkGraph.getModuleId(module);
+						if (moduleId !== null) continue;
+						const identifier = getModuleIdentifier(module);
+						const id = records.modules.byIdentifier[identifier];
+						if (id === undefined) continue;
+						if (usedIds.has(id)) continue;
+						usedIds.add(id);
+						chunkGraph.setModuleId(module, id);
+					}
+				}
+				if (Array.isArray(records.modules.usedIds)) {
+					compilation.usedModuleIds = new Set(records.modules.usedIds);
+				}
+			});
+
+			/** @typedef {string[]} ChunkSources */
+
+			/**
+			 * Gets chunk sources.
+			 * @param {Chunk} chunk the chunk
+			 * @returns {ChunkSources} sources of the chunk
+			 */
+			const getChunkSources = (chunk) => {
+				/** @type {ChunkSources} */
+				const sources = [];
+				for (const chunkGroup of chunk.groupsIterable) {
+					const index = chunkGroup.chunks.indexOf(chunk);
+					if (chunkGroup.name) {
+						sources.push(`${index} ${chunkGroup.name}`);
+					} else {
+						for (const origin of chunkGroup.origins) {
+							if (origin.module) {
+								if (origin.request) {
+									sources.push(
+										`${index} ${getModuleIdentifier(origin.module)} ${
+											origin.request
+										}`
+									);
+								} else if (typeof origin.loc === "string") {
+									sources.push(
+										`${index} ${getModuleIdentifier(origin.module)} ${
+											origin.loc
+										}`
+									);
+								} else if (
+									origin.loc &&
+									typeof origin.loc === "object" &&
+									"start" in origin.loc
+								) {
+									sources.push(
+										`${index} ${getModuleIdentifier(
+											origin.module
+										)} ${JSON.stringify(origin.loc.start)}`
+									);
+								}
+							}
+						}
+					}
+				}
+				return sources;
+			};
+
+			compilation.hooks.recordChunks.tap(PLUGIN_NAME, (chunks, records) => {
+				if (!records.chunks) records.chunks = {};
+				if (!records.chunks.byName) records.chunks.byName = {};
+				if (!records.chunks.bySource) records.chunks.bySource = {};
+				/** @type {UsedIds} */
+				const usedIds = new Set();
+				for (const chunk of chunks) {
+					if (typeof chunk.id !== "number") continue;
+					const name = chunk.name;
+					if (name) records.chunks.byName[name] = chunk.id;
+					const sources = getChunkSources(chunk);
+					for (const source of sources) {
+						records.chunks.bySource[source] = chunk.id;
+					}
+					usedIds.add(chunk.id);
+				}
+				records.chunks.usedIds = [...usedIds].sort(compareNumbers);
+			});
+			compilation.hooks.reviveChunks.tap(PLUGIN_NAME, (chunks, records) => {
+				if (!records.chunks) return;
+				/** @type {UsedIds} */
+				const usedIds = new Set();
+				if (records.chunks.byName) {
+					for (const chunk of chunks) {
+						if (chunk.id !== null) continue;
+						if (!chunk.name) continue;
+						const id = records.chunks.byName[chunk.name];
+						if (id === undefined) continue;
+						if (usedIds.has(id)) continue;
+						usedIds.add(id);
+						chunk.id = id;
+						chunk.ids = [id];
+					}
+				}
+				if (records.chunks.bySource) {
+					for (const chunk of chunks) {
+						if (chunk.id !== null) continue;
+						const sources = getChunkSources(chunk);
+						for (const source of sources) {
+							const id = records.chunks.bySource[source];
+							if (id === undefined) continue;
+							if (usedIds.has(id)) continue;
+							usedIds.add(id);
+							chunk.id = id;
+							chunk.ids = [id];
+							break;
+						}
+					}
+				}
+				if (Array.isArray(records.chunks.usedIds)) {
+					compilation.usedChunkIds = new Set(records.chunks.usedIds);
+				}
+			});
+		});
+	}
+}
+
+module.exports = RecordIdsPlugin;
Index: frontend/node_modules/webpack/lib/RequestShortener.js
===================================================================
--- frontend/node_modules/webpack/lib/RequestShortener.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RequestShortener.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { contextify } = require("./util/identifier");
+
+/** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+
+/**
+ * Shortens absolute or verbose request strings so diagnostics and stats output
+ * can be rendered relative to a chosen base directory.
+ */
+class RequestShortener {
+	/**
+	 * Binds a context-aware shortening function to the provided directory and
+	 * optional cache owner.
+	 * @param {string} dir the directory
+	 * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+	 */
+	constructor(dir, associatedObjectForCache) {
+		this.contextify = contextify.bindContextCache(
+			dir,
+			associatedObjectForCache
+		);
+	}
+
+	/**
+	 * Returns a request string rewritten relative to the configured directory
+	 * when one is provided.
+	 * @param {string | undefined | null} request the request to shorten
+	 * @returns {string | undefined | null} the shortened request
+	 */
+	shorten(request) {
+		if (!request) {
+			return request;
+		}
+		return this.contextify(request);
+	}
+}
+
+module.exports = RequestShortener;
Index: frontend/node_modules/webpack/lib/ResolverFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/ResolverFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ResolverFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,161 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Factory = require("enhanced-resolve").ResolverFactory;
+const { HookMap, SyncHook, SyncWaterfallHook } = require("tapable");
+const {
+	cachedCleverMerge,
+	removeOperations,
+	resolveByProperty
+} = require("./util/cleverMerge");
+
+/** @typedef {import("enhanced-resolve").ResolveOptions} ResolveOptions */
+/** @typedef {import("enhanced-resolve").Resolver} Resolver */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} WebpackResolveOptions */
+/** @typedef {import("../declarations/WebpackOptions").ResolvePluginInstance} ResolvePluginInstance */
+
+/** @typedef {WebpackResolveOptions & { dependencyType?: string, resolveToContext?: boolean }} ResolveOptionsWithDependencyType */
+/**
+ * Defines the with options type used by this module.
+ * @typedef {object} WithOptions
+ * @property {(options: Partial<ResolveOptionsWithDependencyType>) => ResolverWithOptions} withOptions create a resolver with additional/different options
+ */
+
+/** @typedef {Resolver & WithOptions} ResolverWithOptions */
+
+// need to be hoisted on module level for caching identity
+/** @type {ResolveOptionsWithDependencyType} */
+const EMPTY_RESOLVE_OPTIONS = {};
+
+/**
+ * Convert to resolve options.
+ * @param {ResolveOptionsWithDependencyType} resolveOptionsWithDepType enhanced options
+ * @returns {ResolveOptions} merged options
+ */
+const convertToResolveOptions = (resolveOptionsWithDepType) => {
+	const { dependencyType, plugins, ...remaining } = resolveOptionsWithDepType;
+
+	// check type compat
+	/** @type {Partial<ResolveOptionsWithDependencyType>} */
+	const partialOptions = {
+		...remaining,
+		plugins:
+			plugins &&
+			/** @type {ResolvePluginInstance[]} */ (
+				plugins.filter((item) => item !== "...")
+			)
+	};
+
+	if (!partialOptions.fileSystem) {
+		throw new Error(
+			"fileSystem is missing in resolveOptions, but it's required for enhanced-resolve"
+		);
+	}
+	// These weird types validate that we checked all non-optional properties
+	const options =
+		/** @type {Partial<ResolveOptionsWithDependencyType> & Pick<ResolveOptionsWithDependencyType, "fileSystem">} */ (
+			partialOptions
+		);
+
+	return /** @type {ResolveOptions} */ (
+		removeOperations(
+			resolveByProperty(options, "byDependency", dependencyType),
+			// Keep the `unsafeCache` because it can be a `Proxy`
+			["unsafeCache"]
+		)
+	);
+};
+
+/**
+ * Represents the resolver factory runtime component.
+ * @typedef {object} ResolverCache
+ * @property {WeakMap<ResolveOptionsWithDependencyType, ResolverWithOptions>} direct
+ * @property {Map<string, ResolverWithOptions>} stringified
+ */
+
+module.exports = class ResolverFactory {
+	constructor() {
+		this.hooks = Object.freeze({
+			/** @type {HookMap<SyncWaterfallHook<[ResolveOptionsWithDependencyType]>>} */
+			resolveOptions: new HookMap(
+				() => new SyncWaterfallHook(["resolveOptions"])
+			),
+			/** @type {HookMap<SyncHook<[Resolver, ResolveOptions, ResolveOptionsWithDependencyType]>>} */
+			resolver: new HookMap(
+				() => new SyncHook(["resolver", "resolveOptions", "userResolveOptions"])
+			)
+		});
+		/** @type {Map<string, ResolverCache>} */
+		this.cache = new Map();
+	}
+
+	/**
+	 * Returns the resolver.
+	 * @param {string} type type of resolver
+	 * @param {ResolveOptionsWithDependencyType=} resolveOptions options
+	 * @returns {ResolverWithOptions} the resolver
+	 */
+	get(type, resolveOptions = EMPTY_RESOLVE_OPTIONS) {
+		let typedCaches = this.cache.get(type);
+		if (!typedCaches) {
+			typedCaches = {
+				direct: new WeakMap(),
+				stringified: new Map()
+			};
+			this.cache.set(type, typedCaches);
+		}
+		const cachedResolver = typedCaches.direct.get(resolveOptions);
+		if (cachedResolver) {
+			return cachedResolver;
+		}
+		const ident = JSON.stringify(resolveOptions);
+		const resolver = typedCaches.stringified.get(ident);
+		if (resolver) {
+			typedCaches.direct.set(resolveOptions, resolver);
+			return resolver;
+		}
+		const newResolver = this._create(type, resolveOptions);
+		typedCaches.direct.set(resolveOptions, newResolver);
+		typedCaches.stringified.set(ident, newResolver);
+		return newResolver;
+	}
+
+	/**
+	 * Returns the resolver.
+	 * @param {string} type type of resolver
+	 * @param {ResolveOptionsWithDependencyType} resolveOptionsWithDepType options
+	 * @returns {ResolverWithOptions} the resolver
+	 */
+	_create(type, resolveOptionsWithDepType) {
+		/** @type {ResolveOptionsWithDependencyType} */
+		const originalResolveOptions = { ...resolveOptionsWithDepType };
+
+		const resolveOptions = convertToResolveOptions(
+			this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType)
+		);
+		const resolver = /** @type {ResolverWithOptions} */ (
+			Factory.createResolver(resolveOptions)
+		);
+		if (!resolver) {
+			throw new Error("No resolver created");
+		}
+		/** @type {WeakMap<Partial<ResolveOptionsWithDependencyType>, ResolverWithOptions>} */
+		const childCache = new WeakMap();
+		resolver.withOptions = (options) => {
+			const cacheEntry = childCache.get(options);
+			if (cacheEntry !== undefined) return cacheEntry;
+			const mergedOptions = cachedCleverMerge(originalResolveOptions, options);
+			const resolver = this.get(type, mergedOptions);
+			childCache.set(options, resolver);
+			return resolver;
+		};
+		this.hooks.resolver
+			.for(type)
+			.call(resolver, resolveOptions, originalResolveOptions);
+		return resolver;
+	}
+};
Index: frontend/node_modules/webpack/lib/RuntimeGlobals.js
===================================================================
--- frontend/node_modules/webpack/lib/RuntimeGlobals.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RuntimeGlobals.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,457 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * the AMD define function
+ */
+module.exports.amdDefine = "__webpack_require__.amdD";
+
+/**
+ * the AMD options
+ */
+module.exports.amdOptions = "__webpack_require__.amdO";
+
+/**
+ * Creates an async module. The body function must be a async function.
+ * "module.exports" will be decorated with an AsyncModulePromise.
+ * The body function will be called.
+ * To handle async dependencies correctly do this: "([a, b, c] = await handleDependencies([a, b, c]));".
+ * If "hasAwaitAfterDependencies" is truthy, "handleDependencies()" must be called at the end of the body function.
+ * Signature: function(
+ * module: Module,
+ * body: (handleDependencies: (deps: AsyncModulePromise[]) => Promise<any[]> & () => void,
+ * hasAwaitAfterDependencies?: boolean
+ * ) => void
+ */
+module.exports.asyncModule = "__webpack_require__.a";
+
+/**
+ * The internal symbol that asyncModule is using.
+ */
+module.exports.asyncModuleDoneSymbol = "__webpack_require__.aD";
+
+/**
+ * The internal symbol that asyncModule is using.
+ */
+module.exports.asyncModuleExportSymbol = "__webpack_require__.aE";
+
+/**
+ * the baseURI of current document
+ */
+module.exports.baseURI = "__webpack_require__.b";
+
+/**
+ * global callback functions for installing chunks
+ */
+module.exports.chunkCallback = "webpackChunk";
+
+/**
+ * the chunk name of the chunk with the runtime
+ */
+module.exports.chunkName = "__webpack_require__.cn";
+
+/**
+ * compatibility get default export
+ */
+module.exports.compatGetDefaultExport = "__webpack_require__.n";
+
+/**
+ * compile a wasm module from id and hash, returning WebAssembly.Module
+ */
+module.exports.compileWasm = "__webpack_require__.vs";
+
+/**
+ * create a fake namespace object
+ */
+module.exports.createFakeNamespaceObject = "__webpack_require__.t";
+
+/**
+ * function to promote a string to a TrustedScript using webpack's Trusted
+ * Types policy
+ * Arguments: (script: string) => TrustedScript
+ */
+module.exports.createScript = "__webpack_require__.ts";
+
+/**
+ * function to promote a string to a TrustedScriptURL using webpack's Trusted
+ * Types policy
+ * Arguments: (url: string) => TrustedScriptURL
+ */
+module.exports.createScriptUrl = "__webpack_require__.tu";
+
+module.exports.cssInjectStyle = "__webpack_require__.is";
+
+/**
+ * The current scope when getting a module from a remote
+ */
+module.exports.currentRemoteGetScope = "__webpack_require__.R";
+
+/**
+ * resolve async transitive dependencies for deferred module
+ */
+module.exports.deferredModuleAsyncTransitiveDependencies =
+	"__webpack_require__.zT";
+
+/**
+ * the internal symbol for getting the async transitive dependencies for deferred module
+ */
+module.exports.deferredModuleAsyncTransitiveDependenciesSymbol =
+	"__webpack_require__.zS";
+
+/**
+ * the exported property define getters function
+ */
+module.exports.definePropertyGetters = "__webpack_require__.d";
+
+/**
+ * the chunk ensure function
+ */
+module.exports.ensureChunk = "__webpack_require__.e";
+
+/**
+ * an object with handlers to ensure a chunk
+ */
+module.exports.ensureChunkHandlers = "__webpack_require__.f";
+
+/**
+ * a runtime requirement if ensureChunkHandlers should include loading of chunk needed for entries
+ */
+module.exports.ensureChunkIncludeEntries =
+	"__webpack_require__.f (include entries)";
+
+/**
+ * the module id of the entry point
+ */
+module.exports.entryModuleId = "__webpack_require__.s";
+
+/**
+ * esm module id
+ */
+module.exports.esmId = "__webpack_esm_id__";
+
+/**
+ * esm module ids
+ */
+module.exports.esmIds = "__webpack_esm_ids__";
+
+/**
+ * esm modules
+ */
+module.exports.esmModules = "__webpack_esm_modules__";
+
+/**
+ * esm runtime
+ */
+module.exports.esmRuntime = "__webpack_esm_runtime__";
+
+/**
+ * the internal exports object
+ */
+module.exports.exports = "__webpack_exports__";
+
+/**
+ * method to install a chunk that was loaded somehow
+ * Signature: ({ id, ids, modules, runtime }) => void
+ */
+module.exports.externalInstallChunk = "__webpack_require__.C";
+
+/**
+ * the filename of the css part of the chunk
+ */
+module.exports.getChunkCssFilename = "__webpack_require__.k";
+
+/**
+ * the filename of the script part of the chunk
+ */
+module.exports.getChunkScriptFilename = "__webpack_require__.u";
+
+/**
+ * the filename of the css part of the hot update chunk
+ */
+module.exports.getChunkUpdateCssFilename = "__webpack_require__.hk";
+
+/**
+ * the filename of the script part of the hot update chunk
+ */
+module.exports.getChunkUpdateScriptFilename = "__webpack_require__.hu";
+
+/**
+ * the webpack hash
+ */
+module.exports.getFullHash = "__webpack_require__.h";
+
+/**
+ * function to return webpack's Trusted Types policy
+ * Arguments: () => TrustedTypePolicy
+ */
+module.exports.getTrustedTypesPolicy = "__webpack_require__.tt";
+
+/**
+ * the filename of the HMR manifest
+ */
+module.exports.getUpdateManifestFilename = "__webpack_require__.hmrF";
+
+/**
+ * the global object
+ */
+module.exports.global = "__webpack_require__.g";
+
+/**
+ * harmony module decorator
+ */
+module.exports.harmonyModuleDecorator = "__webpack_require__.hmd";
+
+/**
+ * a flag when a module/chunk/tree has css modules
+ */
+module.exports.hasCssModules = "has css modules";
+
+/**
+ * a flag when a chunk has a fetch priority
+ */
+module.exports.hasFetchPriority = "has fetch priority";
+
+/**
+ * the shorthand for Object.prototype.hasOwnProperty
+ * using of it decreases the compiled bundle size
+ */
+module.exports.hasOwnProperty = "__webpack_require__.o";
+
+/**
+ * function downloading the update manifest
+ */
+module.exports.hmrDownloadManifest = "__webpack_require__.hmrM";
+
+/**
+ * array with handler functions to download chunk updates
+ */
+module.exports.hmrDownloadUpdateHandlers = "__webpack_require__.hmrC";
+
+/**
+ * array with handler functions when a module should be invalidated
+ */
+module.exports.hmrInvalidateModuleHandlers = "__webpack_require__.hmrI";
+
+/**
+ * object with all hmr module data for all modules
+ */
+module.exports.hmrModuleData = "__webpack_require__.hmrD";
+
+/**
+ * the prefix for storing state of runtime modules when hmr is enabled
+ */
+module.exports.hmrRuntimeStatePrefix = "__webpack_require__.hmrS";
+
+/**
+ * The sharing init sequence function (only runs once per share scope).
+ * Has one argument, the name of the share scope.
+ * Creates a share scope if not existing
+ */
+module.exports.initializeSharing = "__webpack_require__.I";
+
+/**
+ * instantiate a wasm instance from module exports object, id, hash and importsObject
+ */
+module.exports.instantiateWasm = "__webpack_require__.v";
+
+/**
+ * interceptor for module executions
+ */
+module.exports.interceptModuleExecution = "__webpack_require__.i";
+
+/**
+ * function to load a script tag.
+ * Arguments: (url: string, done: (event) => void), key?: string | number, chunkId?: string | number) => void
+ * done function is called when loading has finished or timeout occurred.
+ * It will attach to existing script tags with data-webpack == uniqueName + ":" + key or src == url.
+ */
+module.exports.loadScript = "__webpack_require__.l";
+
+/**
+ * make a deferred namespace object
+ */
+module.exports.makeDeferredNamespaceObject = "__webpack_require__.z";
+
+/**
+ * define compatibility on export
+ */
+module.exports.makeNamespaceObject = "__webpack_require__.r";
+
+/**
+ * make a optimized deferred namespace object
+ */
+module.exports.makeOptimizedDeferredNamespaceObject = "__webpack_require__.zO";
+
+/**
+ * the internal module object
+ */
+module.exports.module = "module";
+
+/**
+ * the module cache
+ */
+module.exports.moduleCache = "__webpack_require__.c";
+
+/**
+ * the module functions
+ */
+module.exports.moduleFactories = "__webpack_require__.m";
+
+/**
+ * the module functions, with only write access
+ */
+module.exports.moduleFactoriesAddOnly = "__webpack_require__.m (add only)";
+
+/**
+ * the internal module object
+ */
+module.exports.moduleId = "module.id";
+
+/**
+ * the internal module object
+ */
+module.exports.moduleLoaded = "module.loaded";
+
+/**
+ * node.js module decorator
+ */
+module.exports.nodeModuleDecorator = "__webpack_require__.nmd";
+
+/**
+ * register deferred code, which will run when certain
+ * chunks are loaded.
+ * Signature: (chunkIds: Id[], fn: () => any, priority: int >= 0 = 0) => any
+ * Returned value will be returned directly when all chunks are already loaded
+ * When (priority & 1) it will wait for all other handlers with lower priority to
+ * be executed before itself is executed
+ */
+module.exports.onChunksLoaded = "__webpack_require__.O";
+
+/**
+ * the chunk prefetch function
+ */
+module.exports.prefetchChunk = "__webpack_require__.E";
+
+/**
+ * an object with handlers to prefetch a chunk
+ */
+module.exports.prefetchChunkHandlers = "__webpack_require__.F";
+
+/**
+ * the chunk preload function
+ */
+module.exports.preloadChunk = "__webpack_require__.G";
+
+/**
+ * an object with handlers to preload a chunk
+ */
+module.exports.preloadChunkHandlers = "__webpack_require__.H";
+
+/**
+ * the bundle public path
+ */
+module.exports.publicPath = "__webpack_require__.p";
+
+/**
+ * a RelativeURL class when relative URLs are used
+ */
+module.exports.relativeUrl = "__webpack_require__.U";
+
+/**
+ * the internal require function
+ */
+module.exports.require = "__webpack_require__";
+
+/**
+ * access to properties of the internal require function/object
+ */
+module.exports.requireScope = "__webpack_require__.*";
+
+/**
+ * runtime need to return the exports of the last entry module
+ */
+module.exports.returnExportsFromRuntime = "return-exports-from-runtime";
+
+/**
+ * the runtime id of the current runtime
+ */
+module.exports.runtimeId = "__webpack_require__.j";
+
+/**
+ * the script nonce
+ */
+module.exports.scriptNonce = "__webpack_require__.nc";
+
+/**
+ * set .name to "default" for anonymous default exports per ES spec
+ */
+module.exports.setAnonymousDefaultName = "__webpack_require__.dn";
+
+/**
+ * an object with all share scopes
+ */
+module.exports.shareScopeMap = "__webpack_require__.S";
+
+/**
+ * startup signal from runtime
+ * This will be called when the runtime chunk has been loaded.
+ */
+module.exports.startup = "__webpack_require__.x";
+
+/**
+ * method to startup an entrypoint with needed chunks.
+ * Signature: (moduleId: Id, chunkIds: Id[]) => any.
+ * Returns the exports of the module or a Promise
+ */
+module.exports.startupEntrypoint = "__webpack_require__.X";
+
+/**
+ * Describes how this item operation behaves.
+ * @deprecated
+ * creating a default startup function with the entry modules
+ */
+module.exports.startupNoDefault = "__webpack_require__.x (no default handler)";
+
+/**
+ * startup signal from runtime but only used to add logic after the startup
+ */
+module.exports.startupOnlyAfter = "__webpack_require__.x (only after)";
+
+/**
+ * startup signal from runtime but only used to add sync logic before the startup
+ */
+module.exports.startupOnlyBefore = "__webpack_require__.x (only before)";
+
+/**
+ * the System polyfill object
+ */
+module.exports.system = "__webpack_require__.System";
+
+/**
+ * the System.register context object
+ */
+module.exports.systemContext = "__webpack_require__.y";
+
+/**
+ * top-level this need to be the exports object
+ */
+module.exports.thisAsExports = "top-level-this-exports";
+
+/**
+ * to binary helper, convert base64 to Uint8Array
+ */
+module.exports.toBinary = "__webpack_require__.tb";
+
+/**
+ * the uncaught error handler for the webpack runtime
+ */
+module.exports.uncaughtErrorHandler = "__webpack_require__.oe";
+
+/**
+ * an object containing all installed WebAssembly.Instance export objects keyed by module id
+ */
+module.exports.wasmInstances = "__webpack_require__.w";
Index: frontend/node_modules/webpack/lib/RuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/RuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,257 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const OriginalSource = require("webpack-sources").OriginalSource;
+const Module = require("./Module");
+const {
+	JAVASCRIPT_TYPES,
+	RUNTIME_TYPES
+} = require("./ModuleSourceTypeConstants");
+const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
+
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("./Generator").SourceTypes} SourceTypes */
+/** @typedef {import("./Module").BuildMeta} BuildMeta */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./Module").BuildCallback} BuildCallback */
+/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("./Module").Sources} Sources */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("./util/Hash")} Hash */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./Module").BasicSourceTypes} BasicSourceTypes */
+
+class RuntimeModule extends Module {
+	/**
+	 * Creates an instance of RuntimeModule.
+	 * @param {string} name a readable name
+	 * @param {number=} stage an optional stage
+	 */
+	constructor(name, stage = 0) {
+		super(WEBPACK_MODULE_TYPE_RUNTIME);
+		/** @type {string} */
+		this.name = name;
+		/** @type {number} */
+		this.stage = stage;
+		/** @type {BuildMeta} */
+		this.buildMeta = {};
+		/** @type {BuildInfo} */
+		this.buildInfo = {};
+		/** @type {Compilation | undefined} */
+		this.compilation = undefined;
+		/** @type {Chunk | undefined} */
+		this.chunk = undefined;
+		/** @type {ChunkGraph | undefined} */
+		this.chunkGraph = undefined;
+		/** @type {boolean} */
+		this.fullHash = false;
+		/** @type {boolean} */
+		this.dependentHash = false;
+		/** @type {string | undefined | null} */
+		this._cachedGeneratedCode = undefined;
+	}
+
+	/**
+	 * Processes the provided compilation.
+	 * @param {Compilation} compilation the compilation
+	 * @param {Chunk} chunk the chunk
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @returns {void}
+	 */
+	attach(compilation, chunk, chunkGraph = compilation.chunkGraph) {
+		this.compilation = compilation;
+		this.chunk = chunk;
+		this.chunkGraph = chunkGraph;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return `webpack/runtime/${this.name}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `webpack/runtime/${this.name}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, false);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		// do nothing
+		// should not be called as runtime modules are added later to the compilation
+		callback();
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		hash.update(this.name);
+		hash.update(`${this.stage}`);
+		try {
+			const code =
+				this.fullHash || this.dependentHash
+					? // Do not use getGeneratedCode here, because i. e. compilation hash might be not
+						// ready at this point. We will cache it later instead.
+						this.generate()
+					: this.getGeneratedCode();
+			if (code !== null && code !== undefined) {
+				hash.update(code);
+			}
+		} catch (err) {
+			hash.update(/** @type {Error} */ (err).message);
+		}
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return RUNTIME_TYPES;
+	}
+
+	/**
+	 * Basic source types are high-level categories like javascript, css, webassembly, etc.
+	 * We only have built-in knowledge about the javascript basic type here; other basic types may be
+	 * added or changed over time by generators and do not need to be handled or detected here.
+	 *
+	 * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
+	 * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
+	 * @returns {BasicSourceTypes} types available (do not mutate)
+	 */
+	getSourceBasicTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration(context) {
+		/** @type {Sources} */
+		const sources = new Map();
+		const generatedCode = this.getGeneratedCode();
+		if (generatedCode) {
+			sources.set(
+				WEBPACK_MODULE_TYPE_RUNTIME,
+				this.useSourceMap || this.useSimpleSourceMap
+					? new OriginalSource(generatedCode, this.identifier())
+					: new RawSource(generatedCode)
+			);
+		}
+		return {
+			sources,
+			runtimeRequirements: null
+		};
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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) {
+		try {
+			const source = this.getGeneratedCode();
+			return source ? source.length : 0;
+		} catch (_err) {
+			return 0;
+		}
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @abstract
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const AbstractMethodError = require("./errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/**
+	 * Gets generated code.
+	 * @returns {string | null} runtime code
+	 */
+	getGeneratedCode() {
+		if (this._cachedGeneratedCode) {
+			return this._cachedGeneratedCode;
+		}
+		return (this._cachedGeneratedCode = this.generate());
+	}
+
+	/**
+	 * Returns true, if the runtime module should get it's own scope.
+	 * @returns {boolean} true, if the runtime module should get it's own scope
+	 */
+	shouldIsolate() {
+		return true;
+	}
+}
+
+/**
+ * Runtime modules without any dependencies to other runtime modules
+ */
+RuntimeModule.STAGE_NORMAL = 0;
+
+/**
+ * Runtime modules with simple dependencies on other runtime modules
+ */
+RuntimeModule.STAGE_BASIC = 5;
+
+/**
+ * Runtime modules which attach to handlers of other runtime modules
+ */
+RuntimeModule.STAGE_ATTACH = 10;
+
+/**
+ * Runtime modules which trigger actions on bootstrap
+ */
+RuntimeModule.STAGE_TRIGGER = 20;
+
+module.exports = RuntimeModule;
Index: frontend/node_modules/webpack/lib/RuntimePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/RuntimePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RuntimePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,560 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("./RuntimeGlobals");
+const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
+const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
+const BaseUriRuntimeModule = require("./runtime/BaseUriRuntimeModule");
+const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
+const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
+const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
+const CreateScriptRuntimeModule = require("./runtime/CreateScriptRuntimeModule");
+const CreateScriptUrlRuntimeModule = require("./runtime/CreateScriptUrlRuntimeModule");
+const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
+const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
+const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
+const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
+const GetTrustedTypesPolicyRuntimeModule = require("./runtime/GetTrustedTypesPolicyRuntimeModule");
+const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
+const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
+const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
+const {
+	MakeDeferredNamespaceObjectRuntimeModule,
+	MakeOptimizedDeferredNamespaceObjectRuntimeModule
+} = require("./runtime/MakeDeferredNamespaceObjectRuntime");
+const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
+const NonceRuntimeModule = require("./runtime/NonceRuntimeModule");
+const OnChunksLoadedRuntimeModule = require("./runtime/OnChunksLoadedRuntimeModule");
+const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
+const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule");
+const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
+const SetAnonymousDefaultNameRuntimeModule = require("./runtime/SetAnonymousDefaultNameRuntimeModule");
+const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
+const ToBinaryRuntimeModule = require("./runtime/ToBinaryRuntimeModule");
+const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
+const StringXor = require("./util/StringXor");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Compiler")} Compiler */
+
+const getJavascriptModulesPlugin = memoize(() =>
+	require("./javascript/JavascriptModulesPlugin")
+);
+const getCssModulesPlugin = memoize(() => require("./css/CssModulesPlugin"));
+
+const GLOBALS_ON_REQUIRE = [
+	RuntimeGlobals.chunkName,
+	RuntimeGlobals.runtimeId,
+	RuntimeGlobals.compatGetDefaultExport,
+	RuntimeGlobals.createFakeNamespaceObject,
+	RuntimeGlobals.createScript,
+	RuntimeGlobals.createScriptUrl,
+	RuntimeGlobals.getTrustedTypesPolicy,
+	RuntimeGlobals.definePropertyGetters,
+	RuntimeGlobals.ensureChunk,
+	RuntimeGlobals.entryModuleId,
+	RuntimeGlobals.getFullHash,
+	RuntimeGlobals.global,
+	RuntimeGlobals.makeNamespaceObject,
+	RuntimeGlobals.moduleCache,
+	RuntimeGlobals.moduleFactories,
+	RuntimeGlobals.moduleFactoriesAddOnly,
+	RuntimeGlobals.interceptModuleExecution,
+	RuntimeGlobals.publicPath,
+	RuntimeGlobals.baseURI,
+	RuntimeGlobals.relativeUrl,
+	// TODO webpack 6 - rename to nonce, because we use it for CSS too
+	RuntimeGlobals.scriptNonce,
+	RuntimeGlobals.uncaughtErrorHandler,
+	RuntimeGlobals.asyncModule,
+	RuntimeGlobals.wasmInstances,
+	RuntimeGlobals.instantiateWasm,
+	RuntimeGlobals.shareScopeMap,
+	RuntimeGlobals.initializeSharing,
+	RuntimeGlobals.loadScript,
+	RuntimeGlobals.setAnonymousDefaultName,
+	RuntimeGlobals.systemContext,
+	RuntimeGlobals.onChunksLoaded,
+	RuntimeGlobals.makeOptimizedDeferredNamespaceObject,
+	RuntimeGlobals.makeDeferredNamespaceObject
+];
+
+const MODULE_DEPENDENCIES = {
+	[RuntimeGlobals.moduleLoaded]: [RuntimeGlobals.module],
+	[RuntimeGlobals.moduleId]: [RuntimeGlobals.module]
+};
+
+const TREE_DEPENDENCIES = {
+	[RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
+	[RuntimeGlobals.compatGetDefaultExport]: [
+		RuntimeGlobals.definePropertyGetters
+	],
+	[RuntimeGlobals.createFakeNamespaceObject]: [
+		RuntimeGlobals.definePropertyGetters,
+		RuntimeGlobals.makeNamespaceObject,
+		RuntimeGlobals.require
+	],
+	[RuntimeGlobals.makeOptimizedDeferredNamespaceObject]: [
+		RuntimeGlobals.require
+	],
+	[RuntimeGlobals.makeDeferredNamespaceObject]: [
+		RuntimeGlobals.createFakeNamespaceObject,
+		RuntimeGlobals.require
+	],
+	[RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap],
+	[RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
+};
+
+const FULLHASH_REGEXP = /\[(?:full)?hash(?::\d+)?\]/;
+
+const PLUGIN_NAME = "RuntimePlugin";
+
+class RuntimePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the Compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalChunkLoading = compilation.outputOptions.chunkLoading;
+			/**
+			 * Checks whether this runtime plugin is chunk loading disabled for chunk.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, when chunk loading is disabled for the chunk
+			 */
+			const isChunkLoadingDisabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const chunkLoading =
+					options && options.chunkLoading !== undefined
+						? options.chunkLoading
+						: globalChunkLoading;
+				return chunkLoading === false;
+			};
+			compilation.dependencyTemplates.set(
+				RuntimeRequirementsDependency,
+				new RuntimeRequirementsDependency.Template()
+			);
+			for (const req of GLOBALS_ON_REQUIRE) {
+				compilation.hooks.runtimeRequirementInModule
+					.for(req)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.requireScope);
+					});
+				compilation.hooks.runtimeRequirementInTree
+					.for(req)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.requireScope);
+					});
+			}
+			for (const req of Object.keys(TREE_DEPENDENCIES)) {
+				const deps =
+					TREE_DEPENDENCIES[/** @type {keyof TREE_DEPENDENCIES} */ (req)];
+				compilation.hooks.runtimeRequirementInTree
+					.for(req)
+					.tap(PLUGIN_NAME, (chunk, set) => {
+						for (const dep of deps) set.add(dep);
+					});
+			}
+			for (const req of Object.keys(MODULE_DEPENDENCIES)) {
+				const deps =
+					MODULE_DEPENDENCIES[/** @type {keyof MODULE_DEPENDENCIES} */ (req)];
+				compilation.hooks.runtimeRequirementInModule
+					.for(req)
+					.tap(PLUGIN_NAME, (chunk, set) => {
+						for (const dep of deps) set.add(dep);
+					});
+			}
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.definePropertyGetters)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new DefinePropertyGettersRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.makeNamespaceObject)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new MakeNamespaceObjectRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.createFakeNamespaceObject)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new CreateFakeNamespaceObjectRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.makeOptimizedDeferredNamespaceObject)
+				.tap("RuntimePlugin", (chunk, runtimeRequirement) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new MakeOptimizedDeferredNamespaceObjectRuntimeModule(
+							runtimeRequirement.has(RuntimeGlobals.asyncModule)
+						)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.makeDeferredNamespaceObject)
+				.tap("RuntimePlugin", (chunk, runtimeRequirement) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new MakeDeferredNamespaceObjectRuntimeModule(
+							runtimeRequirement.has(RuntimeGlobals.asyncModule)
+						)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hasOwnProperty)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new HasOwnPropertyRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.compatGetDefaultExport)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new CompatGetDefaultExportRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.setAnonymousDefaultName)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new SetAnonymousDefaultNameRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.runtimeId)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(chunk, new RuntimeIdRuntimeModule());
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.publicPath)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					const { outputOptions } = compilation;
+					const { publicPath: globalPublicPath, scriptType } = outputOptions;
+					const entryOptions = chunk.getEntryOptions();
+					const publicPath =
+						entryOptions && entryOptions.publicPath !== undefined
+							? entryOptions.publicPath
+							: globalPublicPath;
+
+					if (publicPath === "auto") {
+						const module = new AutoPublicPathRuntimeModule();
+						if (
+							scriptType !== "module" &&
+							!outputOptions.environment.globalThis
+						) {
+							set.add(RuntimeGlobals.global);
+						}
+
+						compilation.addRuntimeModule(chunk, module);
+					} else {
+						const module = new PublicPathRuntimeModule(publicPath);
+
+						if (
+							typeof publicPath !== "string" ||
+							FULLHASH_REGEXP.test(publicPath)
+						) {
+							module.fullHash = true;
+						}
+
+						compilation.addRuntimeModule(chunk, module);
+					}
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.global)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(chunk, new GlobalRuntimeModule());
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.asyncModule)
+				.tap(PLUGIN_NAME, (chunk) => {
+					const experiments = compilation.options.experiments;
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncModuleRuntimeModule(experiments.deferImport)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.systemContext)
+				.tap(PLUGIN_NAME, (chunk) => {
+					const entryOptions = chunk.getEntryOptions();
+					const libraryType =
+						entryOptions && entryOptions.library !== undefined
+							? entryOptions.library.type
+							: /** @type {LibraryOptions} */
+								(compilation.outputOptions.library).type;
+
+					if (libraryType === "system") {
+						compilation.addRuntimeModule(
+							chunk,
+							new SystemContextRuntimeModule()
+						);
+					}
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.getChunkScriptFilename)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (
+						typeof compilation.outputOptions.chunkFilename === "string" &&
+						FULLHASH_REGEXP.test(compilation.outputOptions.chunkFilename)
+					) {
+						set.add(RuntimeGlobals.getFullHash);
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new GetChunkFilenameRuntimeModule(
+							"javascript",
+							"javascript",
+							RuntimeGlobals.getChunkScriptFilename,
+							(chunk) =>
+								getJavascriptModulesPlugin().chunkHasJs(chunk, chunkGraph) &&
+								(chunk.filenameTemplate ||
+									(chunk.canBeInitial()
+										? compilation.outputOptions.filename
+										: compilation.outputOptions.chunkFilename)),
+							set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
+						)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.getChunkCssFilename)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (
+						typeof compilation.outputOptions.cssChunkFilename === "string" &&
+						FULLHASH_REGEXP.test(compilation.outputOptions.cssChunkFilename)
+					) {
+						set.add(RuntimeGlobals.getFullHash);
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new GetChunkFilenameRuntimeModule(
+							"css",
+							"css",
+							RuntimeGlobals.getChunkCssFilename,
+							(chunk) => {
+								const cssModulePlugin = getCssModulesPlugin();
+
+								return (
+									cssModulePlugin.chunkHasCss(chunk, chunkGraph) &&
+									cssModulePlugin.getChunkFilenameTemplate(
+										chunk,
+										compilation.outputOptions
+									)
+								);
+							},
+							set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
+						)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.getChunkUpdateScriptFilename)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (
+						FULLHASH_REGEXP.test(
+							compilation.outputOptions.hotUpdateChunkFilename
+						)
+					) {
+						set.add(RuntimeGlobals.getFullHash);
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new GetChunkFilenameRuntimeModule(
+							"javascript",
+							"javascript update",
+							RuntimeGlobals.getChunkUpdateScriptFilename,
+							(_chunk) => compilation.outputOptions.hotUpdateChunkFilename,
+							true
+						)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.getUpdateManifestFilename)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (
+						FULLHASH_REGEXP.test(
+							compilation.outputOptions.hotUpdateMainFilename
+						)
+					) {
+						set.add(RuntimeGlobals.getFullHash);
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new GetMainFilenameRuntimeModule(
+							"update manifest",
+							RuntimeGlobals.getUpdateManifestFilename,
+							compilation.outputOptions.hotUpdateMainFilename
+						)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunk)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					const hasAsyncChunks = chunk.hasAsyncChunks();
+					if (hasAsyncChunks) {
+						set.add(RuntimeGlobals.ensureChunkHandlers);
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new EnsureChunkRuntimeModule(set)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkIncludeEntries)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					set.add(RuntimeGlobals.ensureChunkHandlers);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.shareScopeMap)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					compilation.addRuntimeModule(chunk, new ShareRuntimeModule());
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.loadScript)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					const withCreateScriptUrl = Boolean(
+						compilation.outputOptions.trustedTypes
+					);
+					if (withCreateScriptUrl) {
+						set.add(RuntimeGlobals.createScriptUrl);
+					}
+					const withFetchPriority = set.has(RuntimeGlobals.hasFetchPriority);
+					compilation.addRuntimeModule(
+						chunk,
+						new LoadScriptRuntimeModule(withCreateScriptUrl, withFetchPriority)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.createScript)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (compilation.outputOptions.trustedTypes) {
+						set.add(RuntimeGlobals.getTrustedTypesPolicy);
+					}
+					compilation.addRuntimeModule(chunk, new CreateScriptRuntimeModule());
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.createScriptUrl)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (compilation.outputOptions.trustedTypes) {
+						set.add(RuntimeGlobals.getTrustedTypesPolicy);
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new CreateScriptUrlRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.getTrustedTypesPolicy)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new GetTrustedTypesPolicyRuntimeModule(set)
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.relativeUrl)
+				.tap(PLUGIN_NAME, (chunk, _set) => {
+					compilation.addRuntimeModule(chunk, new RelativeUrlRuntimeModule());
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.onChunksLoaded)
+				.tap(PLUGIN_NAME, (chunk, _set) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new OnChunksLoadedRuntimeModule()
+					);
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.baseURI)
+				.tap(PLUGIN_NAME, (chunk) => {
+					if (isChunkLoadingDisabledForChunk(chunk)) {
+						compilation.addRuntimeModule(chunk, new BaseUriRuntimeModule());
+						return true;
+					}
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.scriptNonce)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(chunk, new NonceRuntimeModule());
+					return true;
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.toBinary)
+				.tap(PLUGIN_NAME, (chunk) => {
+					compilation.addRuntimeModule(chunk, new ToBinaryRuntimeModule());
+					return true;
+				});
+			// TODO webpack 6: remove CompatRuntimeModule
+			compilation.hooks.additionalTreeRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, _set) => {
+					const { mainTemplate } = compilation;
+					if (
+						mainTemplate.hooks.bootstrap.isUsed() ||
+						mainTemplate.hooks.localVars.isUsed() ||
+						mainTemplate.hooks.requireEnsure.isUsed() ||
+						mainTemplate.hooks.requireExtensions.isUsed()
+					) {
+						compilation.addRuntimeModule(chunk, new CompatRuntimeModule());
+					}
+				}
+			);
+			JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(
+				PLUGIN_NAME,
+				(chunk, hash, { chunkGraph }) => {
+					const xor = new StringXor();
+					for (const m of chunkGraph.getChunkRuntimeModulesIterable(chunk)) {
+						xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
+					}
+					xor.updateHash(hash);
+				}
+			);
+		});
+	}
+}
+
+module.exports = RuntimePlugin;
Index: frontend/node_modules/webpack/lib/RuntimeTemplate.js
===================================================================
--- frontend/node_modules/webpack/lib/RuntimeTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/RuntimeTemplate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1322 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const InitFragment = require("./InitFragment");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const Template = require("./Template");
+const {
+	getOutgoingAsyncModules
+} = require("./async-modules/AsyncModuleHelpers");
+const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
+const {
+	getMakeDeferredNamespaceModeFromExportsType,
+	getOptimizedDeferredModule
+} = require("./runtime/MakeDeferredNamespaceObjectRuntime");
+const { equals } = require("./util/ArrayHelpers");
+const compileBooleanMatcher = require("./util/compileBooleanMatcher");
+const memoize = require("./util/memoize");
+const { propertyAccess } = require("./util/property");
+const { forEachRuntime, subtractRuntime } = require("./util/runtime");
+
+const getHarmonyImportDependency = memoize(() =>
+	require("./dependencies/HarmonyImportDependency")
+);
+const getImportDependency = memoize(() =>
+	require("./dependencies/ImportDependency")
+);
+
+/** @typedef {import("./config/defaults").OutputNormalizedWithDefaults} OutputOptions */
+/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Dependency")} Dependency */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./Module").BuildMeta} BuildMeta */
+/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./RequestShortener")} RequestShortener */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
+/** @typedef {import("./NormalModuleFactory").ModuleDependency} ModuleDependency */
+
+/**
+ * No module id error message.
+ * @param {Module} module the module
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @returns {string} error message
+ */
+const noModuleIdErrorMessage = (
+	module,
+	chunkGraph
+) => `Module ${module.identifier()} has no id assigned.
+This should not happen.
+It's in these chunks: ${
+	Array.from(
+		chunkGraph.getModuleChunksIterable(module),
+		(c) => c.name || c.id || c.debugId
+	).join(", ") || "none"
+} (If module is in no chunk this indicates a bug in some chunk/module optimization logic)
+Module has these incoming connections: ${Array.from(
+	chunkGraph.moduleGraph.getIncomingConnections(module),
+	(connection) =>
+		`\n - ${
+			connection.originModule && connection.originModule.identifier()
+		} ${connection.dependency && connection.dependency.type} ${
+			(connection.explanations && [...connection.explanations].join(", ")) || ""
+		}`
+).join("")}`;
+
+/**
+ * Gets global object.
+ * @param {string | undefined} definition global object definition
+ * @returns {string | undefined} save to use global object
+ */
+function getGlobalObject(definition) {
+	if (!definition) return definition;
+	const trimmed = definition.trim();
+
+	if (
+		// identifier, we do not need real identifier regarding ECMAScript/Unicode
+		/^[_\p{L}][_0-9\p{L}]*$/iu.test(trimmed) ||
+		// iife
+		// call expression
+		// expression in parentheses
+		/^(?:[_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu.test(trimmed)
+	) {
+		return trimmed;
+	}
+
+	return `Object(${trimmed})`;
+}
+
+class RuntimeTemplate {
+	/**
+	 * Creates an instance of RuntimeTemplate.
+	 * @param {Compilation} compilation the compilation
+	 * @param {OutputOptions} outputOptions the compilation output options
+	 * @param {RequestShortener} requestShortener the request shortener
+	 */
+	constructor(compilation, outputOptions, requestShortener) {
+		this.compilation = compilation;
+		this.outputOptions = /** @type {OutputOptions} */ (outputOptions || {});
+		this.requestShortener = requestShortener;
+		this.globalObject =
+			/** @type {string} */
+			(getGlobalObject(outputOptions.globalObject));
+		this.contentHashReplacement = "X".repeat(outputOptions.hashDigestLength);
+	}
+
+	isIIFE() {
+		return this.outputOptions.iife;
+	}
+
+	isModule() {
+		return this.outputOptions.module;
+	}
+
+	isNeutralPlatform() {
+		return (
+			!this.compilation.compiler.platform.web &&
+			!this.compilation.compiler.platform.node
+		);
+	}
+
+	supportsConst() {
+		return this.outputOptions.environment.const;
+	}
+
+	supportsMethodShorthand() {
+		return this.outputOptions.environment.methodShorthand;
+	}
+
+	supportsArrowFunction() {
+		return this.outputOptions.environment.arrowFunction;
+	}
+
+	supportsAsyncFunction() {
+		return this.outputOptions.environment.asyncFunction;
+	}
+
+	supportsOptionalChaining() {
+		return this.outputOptions.environment.optionalChaining;
+	}
+
+	supportsForOf() {
+		return this.outputOptions.environment.forOf;
+	}
+
+	supportsDestructuring() {
+		return this.outputOptions.environment.destructuring;
+	}
+
+	supportsBigIntLiteral() {
+		return this.outputOptions.environment.bigIntLiteral;
+	}
+
+	supportsDynamicImport() {
+		return this.outputOptions.environment.dynamicImport;
+	}
+
+	supportsEcmaScriptModuleSyntax() {
+		return this.outputOptions.environment.module;
+	}
+
+	supportTemplateLiteral() {
+		return this.outputOptions.environment.templateLiteral;
+	}
+
+	supportNodePrefixForCoreModules() {
+		return this.outputOptions.environment.nodePrefixForCoreModules;
+	}
+
+	/**
+	 * Renders node prefix for core module.
+	 * @param {string} mod a module
+	 * @returns {string} a module with `node:` prefix when supported, otherwise an original name
+	 */
+	renderNodePrefixForCoreModule(mod) {
+		return this.outputOptions.environment.nodePrefixForCoreModules
+			? `"node:${mod}"`
+			: `"${mod}"`;
+	}
+
+	/**
+	 * Renders return const when it is supported, otherwise var.
+	 * @returns {"const" | "var"} return `const` when it is supported, otherwise `var`
+	 */
+	renderConst() {
+		return this.supportsConst() ? "const" : "var";
+	}
+
+	/**
+	 * Returning function.
+	 * @param {string} returnValue return value
+	 * @param {string} args arguments
+	 * @returns {string} returning function
+	 */
+	returningFunction(returnValue, args = "") {
+		return this.supportsArrowFunction()
+			? `(${args}) => (${returnValue})`
+			: `function(${args}) { return ${returnValue}; }`;
+	}
+
+	/**
+	 * Returns basic function.
+	 * @param {string} args arguments
+	 * @param {string | string[]} body body
+	 * @returns {string} basic function
+	 */
+	basicFunction(args, body) {
+		return this.supportsArrowFunction()
+			? `(${args}) => {\n${Template.indent(body)}\n}`
+			: `function(${args}) {\n${Template.indent(body)}\n}`;
+	}
+
+	/**
+	 * Returns result expression.
+	 * @param {(string | { expr: string })[]} args args
+	 * @returns {string} result expression
+	 */
+	concatenation(...args) {
+		const len = args.length;
+
+		if (len === 2) return this._es5Concatenation(args);
+		if (len === 0) return '""';
+		if (len === 1) {
+			return typeof args[0] === "string"
+				? JSON.stringify(args[0])
+				: `"" + ${args[0].expr}`;
+		}
+		if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);
+
+		// cost comparison between template literal and concatenation:
+		// both need equal surroundings: `xxx` vs "xxx"
+		// template literal has constant cost of 3 chars for each expression
+		// es5 concatenation has cost of 3 + n chars for n expressions in row
+		// when a es5 concatenation ends with an expression it reduces cost by 3
+		// when a es5 concatenation starts with an single expression it reduces cost by 3
+		// e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3)
+		// e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12)
+
+		let templateCost = 0;
+		let concatenationCost = 0;
+
+		let lastWasExpr = false;
+		for (const arg of args) {
+			const isExpr = typeof arg !== "string";
+			if (isExpr) {
+				templateCost += 3;
+				concatenationCost += lastWasExpr ? 1 : 4;
+			}
+			lastWasExpr = isExpr;
+		}
+		if (lastWasExpr) concatenationCost -= 3;
+		if (typeof args[0] !== "string" && typeof args[1] === "string") {
+			concatenationCost -= 3;
+		}
+
+		if (concatenationCost <= templateCost) return this._es5Concatenation(args);
+
+		return `\`${args
+			.map((arg) => (typeof arg === "string" ? arg : `\${${arg.expr}}`))
+			.join("")}\``;
+	}
+
+	/**
+	 * Returns result expression.
+	 * @param {(string | { expr: string })[]} args args (len >= 2)
+	 * @returns {string} result expression
+	 * @private
+	 */
+	_es5Concatenation(args) {
+		const str = args
+			.map((arg) => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr))
+			.join(" + ");
+
+		// when the first two args are expression, we need to prepend "" + to force string
+		// concatenation instead of number addition.
+		return typeof args[0] !== "string" && typeof args[1] !== "string"
+			? `"" + ${str}`
+			: str;
+	}
+
+	/**
+	 * Expression function.
+	 * @param {string} expression expression
+	 * @param {string} args arguments
+	 * @returns {string} expression function code
+	 */
+	expressionFunction(expression, args = "") {
+		return this.supportsArrowFunction()
+			? `(${args}) => (${expression})`
+			: `function(${args}) { ${expression}; }`;
+	}
+
+	/**
+	 * Returns empty function code.
+	 * @returns {string} empty function code
+	 */
+	emptyFunction() {
+		return this.supportsArrowFunction() ? "x => {}" : "function() {}";
+	}
+
+	/**
+	 * Returns destructure array code.
+	 * @param {string[]} items items
+	 * @param {string} value value
+	 * @returns {string} destructure array code
+	 */
+	destructureArray(items, value) {
+		return this.supportsDestructuring()
+			? `var [${items.join(", ")}] = ${value};`
+			: Template.asString(
+					items.map((item, i) => `var ${item} = ${value}[${i}];`)
+				);
+	}
+
+	/**
+	 * Destructure object.
+	 * @param {string[]} items items
+	 * @param {string} value value
+	 * @returns {string} destructure object code
+	 */
+	destructureObject(items, value) {
+		return this.supportsDestructuring()
+			? `var {${items.join(", ")}} = ${value};`
+			: Template.asString(
+					items.map(
+						(item) => `var ${item} = ${value}${propertyAccess([item])};`
+					)
+				);
+	}
+
+	/**
+	 * Returns iIFE code.
+	 * @param {string} args arguments
+	 * @param {string} body body
+	 * @returns {string} IIFE code
+	 */
+	iife(args, body) {
+		return `(${this.basicFunction(args, body)})()`;
+	}
+
+	/**
+	 * Returns for each code.
+	 * @param {string} variable variable
+	 * @param {string} array array
+	 * @param {string | string[]} body body
+	 * @returns {string} for each code
+	 */
+	forEach(variable, array, body) {
+		return this.supportsForOf()
+			? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`
+			: `${array}.forEach(function(${variable}) {\n${Template.indent(
+					body
+				)}\n});`;
+	}
+
+	/**
+	 * Returns comment.
+	 * @param {object} options Information content of the comment
+	 * @param {string=} options.request request string used originally
+	 * @param {(string | null)=} options.chunkName name of the chunk referenced
+	 * @param {string=} options.chunkReason reason information of the chunk
+	 * @param {string=} options.message additional message
+	 * @param {string=} options.exportName name of the export
+	 * @returns {string} comment
+	 */
+	comment({ request, chunkName, chunkReason, message, exportName }) {
+		/** @type {string} */
+		let content;
+		if (this.outputOptions.pathinfo) {
+			content = [message, request, chunkName, chunkReason]
+				.filter(Boolean)
+				.map((item) => this.requestShortener.shorten(item))
+				.join(" | ");
+		} else {
+			content = [message, chunkName, chunkReason]
+				.filter(Boolean)
+				.map((item) => this.requestShortener.shorten(item))
+				.join(" | ");
+		}
+		if (!content) return "";
+		if (this.outputOptions.pathinfo) {
+			return `${Template.toComment(content)} `;
+		}
+		return `${Template.toNormalComment(content)} `;
+	}
+
+	/**
+	 * Throw missing module error block.
+	 * @param {object} options generation options
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} generated error block
+	 */
+	throwMissingModuleErrorBlock({ request }) {
+		const err = `Cannot find module '${request}'`;
+		return `var e = new Error(${JSON.stringify(
+			err
+		)}); e.code = 'MODULE_NOT_FOUND'; throw e;`;
+	}
+
+	/**
+	 * Throw missing module error function.
+	 * @param {object} options generation options
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} generated error function
+	 */
+	throwMissingModuleErrorFunction({ request }) {
+		return `function webpackMissingModule() { ${this.throwMissingModuleErrorBlock(
+			{ request }
+		)} }`;
+	}
+
+	/**
+	 * Returns generated error IIFE.
+	 * @param {object} options generation options
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} generated error IIFE
+	 */
+	missingModule({ request }) {
+		return `Object(${this.throwMissingModuleErrorFunction({ request })}())`;
+	}
+
+	/**
+	 * Missing module statement.
+	 * @param {object} options generation options
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} generated error statement
+	 */
+	missingModuleStatement({ request }) {
+		return `${this.missingModule({ request })};\n`;
+	}
+
+	/**
+	 * Missing module promise.
+	 * @param {object} options generation options
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} generated error code
+	 */
+	missingModulePromise({ request }) {
+		return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({
+			request
+		})})`;
+	}
+
+	/**
+	 * Returns the code.
+	 * @param {object} options options object
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {Module} options.module the module
+	 * @param {string=} options.request the request that should be printed as comment
+	 * @param {string=} options.idExpr expression to use as id expression
+	 * @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned
+	 * @returns {string} the code
+	 */
+	weakError({ module, chunkGraph, request, idExpr, type }) {
+		const moduleId = chunkGraph.getModuleId(module);
+		const errorMessage =
+			moduleId === null
+				? JSON.stringify("Module is not available (weak dependency)")
+				: idExpr
+					? `"Module '" + ${idExpr} + "' is not available (weak dependency)"`
+					: JSON.stringify(
+							`Module '${moduleId}' is not available (weak dependency)`
+						);
+		const comment = request ? `${Template.toNormalComment(request)} ` : "";
+		const errorStatements = `var e = new Error(${errorMessage}); ${
+			comment
+		}e.code = 'MODULE_NOT_FOUND'; throw e;`;
+		switch (type) {
+			case "statements":
+				return errorStatements;
+			case "promise":
+				return `Promise.resolve().then(${this.basicFunction(
+					"",
+					errorStatements
+				)})`;
+			case "expression":
+				return this.iife("", errorStatements);
+		}
+	}
+
+	/**
+	 * Returns the expression.
+	 * @param {object} options options object
+	 * @param {Module} options.module the module
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {string=} options.request the request that should be printed as comment
+	 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
+	 * @returns {string} the expression
+	 */
+	moduleId({ module, chunkGraph, request, weak }) {
+		if (!module) {
+			return this.missingModule({
+				request
+			});
+		}
+		const moduleId = chunkGraph.getModuleId(module);
+		if (moduleId === null) {
+			if (weak) {
+				return "null /* weak dependency, without id */";
+			}
+			throw new Error(
+				`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(
+					module,
+					chunkGraph
+				)}`
+			);
+		}
+		return `${this.comment({ request })}${JSON.stringify(moduleId)}`;
+	}
+
+	/**
+	 * Returns the expression.
+	 * @param {object} options options object
+	 * @param {Module | null} options.module the module
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {string=} options.request the request that should be printed as comment
+	 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} the expression
+	 */
+	moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements }) {
+		if (!module) {
+			return this.missingModule({
+				request
+			});
+		}
+		const moduleId = chunkGraph.getModuleId(module);
+		if (moduleId === null) {
+			if (weak) {
+				// only weak referenced modules don't get an id
+				// we can always emit an error emitting code here
+				return this.weakError({
+					module,
+					chunkGraph,
+					request,
+					type: "expression"
+				});
+			}
+			throw new Error(
+				`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(
+					module,
+					chunkGraph
+				)}`
+			);
+		}
+		runtimeRequirements.add(RuntimeGlobals.require);
+		return `${RuntimeGlobals.require}(${this.moduleId({
+			module,
+			chunkGraph,
+			request,
+			weak
+		})})`;
+	}
+
+	/**
+	 * Returns the expression.
+	 * @param {object} options options object
+	 * @param {Module | null} options.module the module
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {string} options.request the request that should be printed as comment
+	 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} the expression
+	 */
+	moduleExports({ module, chunkGraph, request, weak, runtimeRequirements }) {
+		return this.moduleRaw({
+			module,
+			chunkGraph,
+			request,
+			weak,
+			runtimeRequirements
+		});
+	}
+
+	/**
+	 * Returns the expression.
+	 * @param {object} options options object
+	 * @param {Module} options.module the module
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {string} options.request the request that should be printed as comment
+	 * @param {boolean=} options.strict if the current module is in strict esm mode
+	 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} the expression
+	 */
+	moduleNamespace({
+		module,
+		chunkGraph,
+		request,
+		strict,
+		weak,
+		runtimeRequirements
+	}) {
+		if (!module) {
+			return this.missingModule({
+				request
+			});
+		}
+		if (chunkGraph.getModuleId(module) === null) {
+			if (weak) {
+				// only weak referenced modules don't get an id
+				// we can always emit an error emitting code here
+				return this.weakError({
+					module,
+					chunkGraph,
+					request,
+					type: "expression"
+				});
+			}
+			throw new Error(
+				`RuntimeTemplate.moduleNamespace(): ${noModuleIdErrorMessage(
+					module,
+					chunkGraph
+				)}`
+			);
+		}
+		const moduleId = this.moduleId({
+			module,
+			chunkGraph,
+			request,
+			weak
+		});
+		const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
+		switch (exportsType) {
+			case "namespace":
+				return this.moduleRaw({
+					module,
+					chunkGraph,
+					request,
+					weak,
+					runtimeRequirements
+				});
+			case "default-with-named":
+				runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+				return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 3)`;
+			case "default-only":
+				runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+				return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 1)`;
+			case "dynamic":
+				runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+				return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 7)`;
+		}
+	}
+
+	/**
+	 * Module namespace promise.
+	 * @param {object} options options object
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {AsyncDependenciesBlock=} options.block the current dependencies block
+	 * @param {Module} options.module the module
+	 * @param {string} options.request the request that should be printed as comment
+	 * @param {string} options.message a message for the comment
+	 * @param {boolean=} options.strict if the current module is in strict esm mode
+	 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
+	 * @param {Dependency} options.dependency dependency
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} the promise expression
+	 */
+	moduleNamespacePromise({
+		chunkGraph,
+		block,
+		module,
+		request,
+		message,
+		strict,
+		weak,
+		dependency,
+		runtimeRequirements
+	}) {
+		if (!module) {
+			return this.missingModulePromise({
+				request
+			});
+		}
+		const moduleId = chunkGraph.getModuleId(module);
+		if (moduleId === null) {
+			if (weak) {
+				// only weak referenced modules don't get an id
+				// we can always emit an error emitting code here
+				return this.weakError({
+					module,
+					chunkGraph,
+					request,
+					type: "promise"
+				});
+			}
+			throw new Error(
+				`RuntimeTemplate.moduleNamespacePromise(): ${noModuleIdErrorMessage(
+					module,
+					chunkGraph
+				)}`
+			);
+		}
+		const promise = this.blockPromise({
+			chunkGraph,
+			block,
+			message,
+			runtimeRequirements
+		});
+
+		/** @type {string} */
+		let appending;
+		let idExpr = JSON.stringify(chunkGraph.getModuleId(module));
+		const comment = this.comment({
+			request
+		});
+		let header = "";
+		if (weak) {
+			if (idExpr.length > 8) {
+				// 'var x="nnnnnn";x,"+x+",x' vs '"nnnnnn",nnnnnn,"nnnnnn"'
+				header += `var id = ${idExpr}; `;
+				idExpr = "id";
+			}
+			runtimeRequirements.add(RuntimeGlobals.moduleFactories);
+			header += `if(!${
+				RuntimeGlobals.moduleFactories
+			}[${idExpr}]) { ${this.weakError({
+				module,
+				chunkGraph,
+				request,
+				idExpr,
+				type: "statements"
+			})} } `;
+		}
+		const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
+
+		const isModuleDeferred =
+			(dependency instanceof getHarmonyImportDependency() ||
+				dependency instanceof getImportDependency()) &&
+			ImportPhaseUtils.isDefer(dependency.phase) &&
+			!(/** @type {BuildMeta} */ (module.buildMeta).async);
+
+		if (isModuleDeferred) {
+			runtimeRequirements.add(RuntimeGlobals.makeDeferredNamespaceObject);
+
+			let mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
+			if (mode) mode = `${mode} | 16`;
+
+			const asyncDeps = Array.from(
+				getOutgoingAsyncModules(chunkGraph.moduleGraph, module),
+				(m) => chunkGraph.getModuleId(m)
+			).filter((id) => id !== null);
+			if (asyncDeps.length) {
+				if (header) {
+					appending = `.then(${this.basicFunction(
+						"",
+						`${header}return ${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies}(${JSON.stringify(asyncDeps)});`
+					)})`;
+				} else {
+					runtimeRequirements.add(RuntimeGlobals.require);
+					appending = `.then(${this.returningFunction(`${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies}(${JSON.stringify(asyncDeps)})`)})`;
+				}
+				appending += `.then(${RuntimeGlobals.makeDeferredNamespaceObject}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}, ${mode}))`;
+			} else if (header) {
+				appending = `.then(${this.basicFunction(
+					"",
+					`${header}return ${RuntimeGlobals.makeDeferredNamespaceObject}(${comment}${idExpr}, ${mode});`
+				)})`;
+			} else {
+				runtimeRequirements.add(RuntimeGlobals.require);
+				appending = `.then(${RuntimeGlobals.makeDeferredNamespaceObject}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}, ${mode}))`;
+			}
+		} else {
+			let fakeType = 16;
+			switch (exportsType) {
+				case "namespace":
+					if (header) {
+						const rawModule = this.moduleRaw({
+							module,
+							chunkGraph,
+							request,
+							weak,
+							runtimeRequirements
+						});
+						appending = `.then(${this.basicFunction(
+							"",
+							`${header}return ${rawModule};`
+						)})`;
+					} else {
+						runtimeRequirements.add(RuntimeGlobals.require);
+						appending = `.then(${RuntimeGlobals.require}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}))`;
+					}
+					break;
+				case "dynamic":
+					fakeType |= 4;
+				/* fall through */
+				case "default-with-named":
+					fakeType |= 2;
+				/* fall through */
+				case "default-only":
+					runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+					if (chunkGraph.moduleGraph.isAsync(module)) {
+						if (header) {
+							const rawModule = this.moduleRaw({
+								module,
+								chunkGraph,
+								request,
+								weak,
+								runtimeRequirements
+							});
+							appending = `.then(${this.basicFunction(
+								"",
+								`${header}return ${rawModule};`
+							)})`;
+						} else {
+							runtimeRequirements.add(RuntimeGlobals.require);
+							appending = `.then(${RuntimeGlobals.require}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}))`;
+						}
+						appending += `.then(${this.returningFunction(
+							`${RuntimeGlobals.createFakeNamespaceObject}(m, ${fakeType})`,
+							"m"
+						)})`;
+					} else {
+						fakeType |= 1;
+						if (header) {
+							const moduleIdExpr = this.moduleId({
+								module,
+								chunkGraph,
+								request,
+								weak
+							});
+							const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, ${fakeType})`;
+							appending = `.then(${this.basicFunction(
+								"",
+								`${header}return ${returnExpression};`
+							)})`;
+						} else {
+							appending = `.then(${RuntimeGlobals.createFakeNamespaceObject}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}, ${fakeType}))`;
+						}
+					}
+					break;
+			}
+		}
+
+		return `${promise || "Promise.resolve()"}${appending}`;
+	}
+
+	/**
+	 * Runtime condition expression.
+	 * @param {object} options options object
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {RuntimeSpec=} options.runtime runtime for which this code will be generated
+	 * @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} expression
+	 */
+	runtimeConditionExpression({
+		chunkGraph,
+		runtimeCondition,
+		runtime,
+		runtimeRequirements
+	}) {
+		if (runtimeCondition === undefined) return "true";
+		if (typeof runtimeCondition === "boolean") return `${runtimeCondition}`;
+		/** @type {Set<string>} */
+		const positiveRuntimeIds = new Set();
+		forEachRuntime(runtimeCondition, (runtime) =>
+			positiveRuntimeIds.add(
+				`${chunkGraph.getRuntimeId(/** @type {string} */ (runtime))}`
+			)
+		);
+		/** @type {Set<string>} */
+		const negativeRuntimeIds = new Set();
+		forEachRuntime(subtractRuntime(runtime, runtimeCondition), (runtime) =>
+			negativeRuntimeIds.add(
+				`${chunkGraph.getRuntimeId(/** @type {string} */ (runtime))}`
+			)
+		);
+		runtimeRequirements.add(RuntimeGlobals.runtimeId);
+		return compileBooleanMatcher.fromLists(
+			[...positiveRuntimeIds],
+			[...negativeRuntimeIds]
+		)(RuntimeGlobals.runtimeId);
+	}
+
+	/**
+	 * Returns the import statement and the compat statement.
+	 * @param {object} options options object
+	 * @param {boolean=} options.update whether a new variable should be created or the existing one updated
+	 * @param {Module} options.module the module
+	 * @param {Module} options.originModule module in which the statement is emitted
+	 * @param {ModuleGraph} options.moduleGraph the module graph
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @param {string} options.importVar name of the import variable
+	 * @param {string=} options.request the request that should be printed as comment
+	 * @param {boolean=} options.weak true, if this is a weak dependency
+	 * @param {ModuleDependency=} options.dependency module dependency
+	 * @returns {[string, string]} the import statement and the compat statement
+	 */
+	importStatement({
+		update,
+		module,
+		moduleGraph,
+		chunkGraph,
+		request,
+		importVar,
+		originModule,
+		weak,
+		dependency,
+		runtimeRequirements
+	}) {
+		if (!module) {
+			return [
+				this.missingModuleStatement({
+					request
+				}),
+				""
+			];
+		}
+
+		if (chunkGraph.getModuleId(module) === null) {
+			if (weak) {
+				// only weak referenced modules don't get an id
+				// we can always emit an error emitting code here
+				return [
+					this.weakError({
+						module,
+						chunkGraph,
+						request,
+						type: "statements"
+					}),
+					""
+				];
+			}
+			throw new Error(
+				`RuntimeTemplate.importStatement(): ${noModuleIdErrorMessage(
+					module,
+					chunkGraph
+				)}`
+			);
+		}
+		const moduleId = this.moduleId({
+			module,
+			chunkGraph,
+			request,
+			weak
+		});
+		const optDeclaration = update ? "" : "var ";
+
+		const exportsType = module.getExportsType(
+			chunkGraph.moduleGraph,
+			/** @type {BuildMeta} */
+			(originModule.buildMeta).strictHarmonyModule
+		);
+		runtimeRequirements.add(RuntimeGlobals.require);
+
+		/** @type {string} */
+		let importContent;
+
+		const isModuleDeferred =
+			(dependency instanceof getHarmonyImportDependency() ||
+				dependency instanceof getImportDependency()) &&
+			ImportPhaseUtils.isDefer(dependency.phase) &&
+			!(/** @type {BuildMeta} */ (module.buildMeta).async);
+
+		if (isModuleDeferred) {
+			/** @type {Set<Module>} */
+			const outgoingAsyncModules = getOutgoingAsyncModules(moduleGraph, module);
+
+			importContent = `/* deferred harmony import */ ${optDeclaration}${importVar} = ${getOptimizedDeferredModule(
+				moduleId,
+				exportsType,
+				Array.from(outgoingAsyncModules, (mod) => chunkGraph.getModuleId(mod)),
+				runtimeRequirements
+			)};\n`;
+
+			return [importContent, ""];
+		}
+		importContent = `/* harmony import */ ${optDeclaration}${importVar} = ${RuntimeGlobals.require}(${moduleId});\n`;
+
+		if (exportsType === "dynamic") {
+			runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport);
+			return [
+				importContent,
+				`/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/${RuntimeGlobals.compatGetDefaultExport}(${importVar});\n`
+			];
+		}
+		return [importContent, ""];
+	}
+
+	/**
+	 * Export from import.
+	 * @template GenerateContext
+	 * @param {object} options options
+	 * @param {ModuleGraph} options.moduleGraph the module graph
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {Module} options.module the module
+	 * @param {string} options.request the request
+	 * @param {string | string[]} options.exportName the export name
+	 * @param {Module} options.originModule the origin module
+	 * @param {boolean | undefined} options.asiSafe true, if location is safe for ASI, a bracket can be emitted
+	 * @param {boolean | undefined} options.isCall true, if expression will be called
+	 * @param {boolean | null} options.callContext when false, call context will not be preserved
+	 * @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated
+	 * @param {string} options.importVar the identifier name of the import variable
+	 * @param {InitFragment<GenerateContext>[]} options.initFragments init fragments will be added here
+	 * @param {RuntimeSpec} options.runtime runtime for which this code will be generated
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @param {ModuleDependency} options.dependency module dependency
+	 * @returns {string} expression
+	 */
+	exportFromImport({
+		moduleGraph,
+		chunkGraph,
+		module,
+		request,
+		exportName,
+		originModule,
+		asiSafe,
+		isCall,
+		callContext,
+		defaultInterop,
+		importVar,
+		initFragments,
+		runtime,
+		runtimeRequirements,
+		dependency
+	}) {
+		if (!module) {
+			return this.missingModule({
+				request
+			});
+		}
+		if (!Array.isArray(exportName)) {
+			exportName = exportName ? [exportName] : [];
+		}
+		const exportsType = module.getExportsType(
+			moduleGraph,
+			/** @type {BuildMeta} */
+			(originModule.buildMeta).strictHarmonyModule
+		);
+
+		const isModuleDeferred =
+			(dependency instanceof getHarmonyImportDependency() ||
+				dependency instanceof getImportDependency()) &&
+			ImportPhaseUtils.isDefer(dependency.phase) &&
+			!(/** @type {BuildMeta} */ (module.buildMeta).async);
+
+		if (defaultInterop) {
+			// when the defaultInterop is used (when a ESM imports a CJS module),
+			if (exportName.length > 0 && exportName[0] === "default") {
+				if (isModuleDeferred && exportsType !== "namespace") {
+					const exportsInfo = moduleGraph.getExportsInfo(module);
+					const name = exportName.slice(1);
+					const used = exportsInfo.getUsedName(name, runtime);
+					if (!used) {
+						const comment = Template.toNormalComment(
+							`unused export ${propertyAccess(exportName)}`
+						);
+						return `${comment} undefined`;
+					}
+					const access = `${importVar}.a${propertyAccess(used)}`;
+					if (isCall || asiSafe === undefined) {
+						return access;
+					}
+					return asiSafe ? `(${access})` : `;(${access})`;
+				}
+				// accessing the .default property is same thing as `require()` the module.
+
+				// For example:
+				// import mod from "cjs";    mod.default.x;
+				// is translated to
+				// var mod = require("cjs"); mod.x;
+				switch (exportsType) {
+					case "dynamic":
+						if (isCall) {
+							return `${importVar}_default()${propertyAccess(exportName, 1)}`;
+						}
+						return asiSafe
+							? `(${importVar}_default()${propertyAccess(exportName, 1)})`
+							: asiSafe === false
+								? `;(${importVar}_default()${propertyAccess(exportName, 1)})`
+								: `${importVar}_default.a${propertyAccess(exportName, 1)}`;
+
+					case "default-only":
+					case "default-with-named":
+						exportName = exportName.slice(1);
+						break;
+				}
+			} else if (exportName.length > 0) {
+				// the property used is not .default.
+				// For example:
+				// import * as ns from "cjs"; cjs.prop;
+				if (exportsType === "default-only") {
+					// in the strictest case, it is a runtime error (e.g. NodeJS behavior of CJS-ESM interop).
+					return `/* non-default import from non-esm module */undefined${propertyAccess(
+						exportName,
+						1
+					)}`;
+				} else if (
+					exportsType !== "namespace" &&
+					exportName[0] === "__esModule"
+				) {
+					return "/* __esModule */true";
+				}
+			} else if (isModuleDeferred) {
+				// now exportName.length is 0
+				// fall through to the end of this function, create the namespace there.
+			} else if (
+				exportsType === "default-only" ||
+				exportsType === "default-with-named"
+			) {
+				// now exportName.length is 0, which means the namespace object is used in an unknown way
+				// for example:
+				// import * as ns from "cjs"; console.log(ns);
+				// we will need to createFakeNamespaceObject that simulates ES Module namespace object
+				runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+				initFragments.push(
+					new InitFragment(
+						`var ${importVar}_namespace_cache;\n`,
+						InitFragment.STAGE_CONSTANTS,
+						-1,
+						`${importVar}_namespace_cache`
+					)
+				);
+				return `/*#__PURE__*/ ${
+					asiSafe ? "" : asiSafe === false ? ";" : "Object"
+				}(${importVar}_namespace_cache || (${importVar}_namespace_cache = ${
+					RuntimeGlobals.createFakeNamespaceObject
+				}(${importVar}${exportsType === "default-only" ? "" : ", 2"})))`;
+			}
+		}
+
+		if (exportName.length > 0) {
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+			// in some case the exported item is renamed (get this by getUsedName). for example,
+			// x.default might be emitted as x.Z (default is renamed to Z)
+			const used = exportsInfo.getUsedName(exportName, runtime);
+			if (!used) {
+				const comment = Template.toNormalComment(
+					`unused export ${propertyAccess(exportName)}`
+				);
+				return `${comment} undefined`;
+			}
+			const comment = equals(used, exportName)
+				? ""
+				: `${Template.toNormalComment(propertyAccess(exportName))} `;
+			const access = `${importVar}${
+				isModuleDeferred ? ".a" : ""
+			}${comment}${propertyAccess(used)}`;
+			if (isCall && callContext === false) {
+				return asiSafe
+					? `(0,${access})`
+					: asiSafe === false
+						? `;(0,${access})`
+						: `/*#__PURE__*/Object(${access})`;
+			}
+			return access;
+		}
+		if (isModuleDeferred) {
+			initFragments.push(
+				new InitFragment(
+					`var ${importVar}_deferred_namespace_cache;\n`,
+					InitFragment.STAGE_CONSTANTS,
+					-1,
+					`${importVar}_deferred_namespace_cache`
+				)
+			);
+
+			runtimeRequirements.add(RuntimeGlobals.makeDeferredNamespaceObject);
+			const id = chunkGraph.getModuleId(module);
+			const type = getMakeDeferredNamespaceModeFromExportsType(exportsType);
+			const init = `${
+				RuntimeGlobals.makeDeferredNamespaceObject
+			}(${JSON.stringify(id)}, ${type})`;
+
+			return `/*#__PURE__*/ ${
+				asiSafe ? "" : asiSafe === false ? ";" : "Object"
+			}(${importVar}_deferred_namespace_cache || (${importVar}_deferred_namespace_cache = ${init}))`;
+		}
+		// if we hit here, the importVar is either
+		// - already a ES module namespace object
+		// - or imported by a way that does not need interop.
+		return importVar;
+	}
+
+	/**
+	 * Returns expression.
+	 * @param {object} options options
+	 * @param {AsyncDependenciesBlock | undefined} options.block the async block
+	 * @param {string} options.message the message
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} expression
+	 */
+	blockPromise({ block, message, chunkGraph, runtimeRequirements }) {
+		if (!block) {
+			const comment = this.comment({
+				message
+			});
+			return `Promise.resolve(${comment.trim()})`;
+		}
+		const chunkGroup = chunkGraph.getBlockChunkGroup(block);
+		if (!chunkGroup || chunkGroup.chunks.length === 0) {
+			const comment = this.comment({
+				message
+			});
+			return `Promise.resolve(${comment.trim()})`;
+		}
+		const chunks = chunkGroup.chunks.filter(
+			(chunk) => !chunk.hasRuntime() && chunk.id !== null
+		);
+		const comment = this.comment({
+			message,
+			chunkName: block.chunkName
+		});
+		if (chunks.length === 1) {
+			const chunkId = JSON.stringify(chunks[0].id);
+			runtimeRequirements.add(RuntimeGlobals.ensureChunk);
+
+			const fetchPriority = chunkGroup.options.fetchPriority;
+
+			if (fetchPriority) {
+				runtimeRequirements.add(RuntimeGlobals.hasFetchPriority);
+			}
+
+			return `${RuntimeGlobals.ensureChunk}(${comment}${chunkId}${
+				fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : ""
+			})`;
+		} else if (chunks.length > 0) {
+			runtimeRequirements.add(RuntimeGlobals.ensureChunk);
+
+			const fetchPriority = chunkGroup.options.fetchPriority;
+
+			if (fetchPriority) {
+				runtimeRequirements.add(RuntimeGlobals.hasFetchPriority);
+			}
+
+			/**
+			 * Returns require chunk id code.
+			 * @param {Chunk} chunk chunk
+			 * @returns {string} require chunk id code
+			 */
+			const requireChunkId = (chunk) =>
+				`${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)}${
+					fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : ""
+				})`;
+			return `Promise.all(${comment.trim()}[${chunks
+				.map(requireChunkId)
+				.join(", ")}])`;
+		}
+		return `Promise.resolve(${comment.trim()})`;
+	}
+
+	/**
+	 * Async module factory.
+	 * @param {object} options options
+	 * @param {AsyncDependenciesBlock} options.block the async block
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} expression
+	 */
+	asyncModuleFactory({ block, chunkGraph, runtimeRequirements, request }) {
+		const dep = block.dependencies[0];
+		const module = chunkGraph.moduleGraph.getModule(dep);
+		const ensureChunk = this.blockPromise({
+			block,
+			message: "",
+			chunkGraph,
+			runtimeRequirements
+		});
+		const factory = this.returningFunction(
+			this.moduleRaw({
+				module,
+				chunkGraph,
+				request,
+				runtimeRequirements
+			})
+		);
+		return this.returningFunction(
+			ensureChunk.startsWith("Promise.resolve(")
+				? `${factory}`
+				: `${ensureChunk}.then(${this.returningFunction(factory)})`
+		);
+	}
+
+	/**
+	 * Sync module factory.
+	 * @param {object} options options
+	 * @param {Dependency} options.dependency the dependency
+	 * @param {ChunkGraph} options.chunkGraph the chunk graph
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @param {string=} options.request request string used originally
+	 * @returns {string} expression
+	 */
+	syncModuleFactory({ dependency, chunkGraph, runtimeRequirements, request }) {
+		const module = chunkGraph.moduleGraph.getModule(dependency);
+		const factory = this.returningFunction(
+			this.moduleRaw({
+				module,
+				chunkGraph,
+				request,
+				runtimeRequirements
+			})
+		);
+		return this.returningFunction(factory);
+	}
+
+	/**
+	 * Define es module flag statement.
+	 * @param {object} options options
+	 * @param {string} options.exportsArgument the name of the exports object
+	 * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
+	 * @returns {string} statement
+	 */
+	defineEsModuleFlagStatement({ exportsArgument, runtimeRequirements }) {
+		runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`;
+	}
+}
+
+module.exports = RuntimeTemplate;
Index: frontend/node_modules/webpack/lib/SelfModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/SelfModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/SelfModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+
+class SelfModuleFactory {
+	/**
+	 * Creates an instance of SelfModuleFactory.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 */
+	constructor(moduleGraph) {
+		this.moduleGraph = moduleGraph;
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const module = this.moduleGraph.getParentModule(data.dependencies[0]);
+		callback(null, {
+			module
+		});
+	}
+}
+
+module.exports = SelfModuleFactory;
Index: frontend/node_modules/webpack/lib/SingleEntryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/SingleEntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/SingleEntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,8 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+module.exports = require("./EntryPlugin");
Index: frontend/node_modules/webpack/lib/SourceMapDevToolModuleOptionsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/SourceMapDevToolModuleOptionsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/SourceMapDevToolModuleOptionsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,54 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+
+/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
+/** @typedef {import("./Compilation")} Compilation */
+
+const PLUGIN_NAME = "SourceMapDevToolModuleOptionsPlugin";
+
+class SourceMapDevToolModuleOptionsPlugin {
+	/**
+	 * Creates an instance of SourceMapDevToolModuleOptionsPlugin.
+	 * @param {SourceMapDevToolPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {SourceMapDevToolPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compilation} compilation the compiler instance
+	 * @returns {void}
+	 */
+	apply(compilation) {
+		const options = this.options;
+		if (options.module !== false) {
+			compilation.hooks.buildModule.tap(PLUGIN_NAME, (module) => {
+				module.useSourceMap = true;
+			});
+			compilation.hooks.runtimeModule.tap(PLUGIN_NAME, (module) => {
+				module.useSourceMap = true;
+			});
+		} else {
+			compilation.hooks.buildModule.tap(PLUGIN_NAME, (module) => {
+				module.useSimpleSourceMap = true;
+			});
+			compilation.hooks.runtimeModule.tap(PLUGIN_NAME, (module) => {
+				module.useSimpleSourceMap = true;
+			});
+		}
+		JavascriptModulesPlugin.getCompilationHooks(compilation).useSourceMap.tap(
+			PLUGIN_NAME,
+			() => true
+		);
+	}
+}
+
+module.exports = SourceMapDevToolModuleOptionsPlugin;
Index: frontend/node_modules/webpack/lib/SourceMapDevToolPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/SourceMapDevToolPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/SourceMapDevToolPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,851 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const { ConcatSource, RawSource } = require("webpack-sources");
+const Compilation = require("./Compilation");
+const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
+const ProgressPlugin = require("./ProgressPlugin");
+const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin");
+const createHash = require("./util/createHash");
+const { dirname, relative } = require("./util/fs");
+const generateDebugId = require("./util/generateDebugId");
+const { makePathsAbsolute } = require("./util/identifier");
+
+/** @typedef {import("webpack-sources").MapOptions} MapOptions */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolNamespace} DevtoolNamespace */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolModuleFilenameTemplate} DevtoolModuleFilenameTemplate */
+/** @typedef {import("../declarations/WebpackOptions").DevtoolFallbackModuleFilenameTemplate} DevtoolFallbackModuleFilenameTemplate */
+/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
+/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").Rules} Rules */
+/** @typedef {import("./CacheFacade").ItemCacheFacade} ItemCacheFacade */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./Compilation").Asset} Asset */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./NormalModule").RawSourceMap} RawSourceMap */
+/** @typedef {import("./TemplatedPathPlugin").TemplatePath} SourceMappingURLComment */
+/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
+
+/**
+ * Defines the source map task type used by this module.
+ * @typedef {object} SourceMapTask
+ * @property {Source} asset
+ * @property {AssetInfo} assetInfo
+ * @property {(string | Module)[]} modules
+ * @property {string} source
+ * @property {string} file
+ * @property {RawSourceMap} sourceMap
+ * @property {ItemCacheFacade} cacheItem cache item
+ */
+
+const METACHARACTERS_REGEXP = /[-[\]\\/{}()*+?.^$|]/g;
+const CONTENT_HASH_DETECT_REGEXP = /\[contenthash(?::\w+)?\]/;
+const CSS_AND_JS_MODULE_EXTENSIONS_REGEXP = /\.((c|m)?js|css)($|\?)/i;
+const CSS_EXTENSION_DETECT_REGEXP = /\.css(?:$|\?)/i;
+const MAP_URL_COMMENT_REGEXP = /\[map\]/g;
+const URL_COMMENT_REGEXP = /\[url\]/g;
+const URL_FORMATTING_REGEXP = /^\n\/\/(.*)$/;
+
+/**
+ * Reset's .lastIndex of stateful Regular Expressions
+ * For when `test` or `exec` is called on them
+ * @param {RegExp} regexp Stateful Regular Expression to be reset
+ * @returns {void}
+ */
+const resetRegexpState = (regexp) => {
+	regexp.lastIndex = -1;
+};
+
+/**
+ * Escapes regular expression metacharacters
+ * @param {string} str String to quote
+ * @returns {string} Escaped string
+ */
+const quoteMeta = (str) => str.replace(METACHARACTERS_REGEXP, "\\$&");
+
+/**
+ * Compilation-scoped registry of original asset sources for multi-plugin
+ * cooperation. The first SourceMapDevToolPlugin instance to see a file pins a
+ * reference to the asset's still-unwrapped {@link Source} object; later
+ * instances whose `asset.source.sourceAndMap()` would now return `null` (the
+ * earlier instance replaced the asset with a `RawSource`) can re-extract the
+ * map from this pinned reference. We keep the registry on a module-scoped
+ * `WeakMap` so the entries are reclaimed automatically when the compilation
+ * itself becomes unreachable; we never store anything on the compilation
+ * object directly.
+ *
+ * Stashing the `Source` object itself rather than an extracted map keeps the
+ * fast path free of cloning and source-map serialization work — the
+ * extraction only happens if a subsequent plugin actually needs the map.
+ * @type {WeakMap<Compilation, Map<string, Source>>}
+ */
+const originalSourceRegistry = new WeakMap();
+
+/**
+ * Returns (creating if necessary) the per-compilation registry of original
+ * asset {@link Source} objects.
+ * @param {Compilation} compilation compilation
+ * @returns {Map<string, Source>} registry
+ */
+const getOriginalSourceRegistry = (compilation) => {
+	let registry = originalSourceRegistry.get(compilation);
+	if (registry === undefined) {
+		registry = new Map();
+		originalSourceRegistry.set(compilation, registry);
+	}
+	return registry;
+};
+
+/**
+ * Extracts source and source map from a Source object, falling back to a
+ * registered original source for assets that another SourceMapDevToolPlugin
+ * instance has already wrapped (whose internal map is now `null`).
+ *
+ * The returned source is read from the asset as it currently stands — that way
+ * any `sourceMappingURL` comments appended by earlier plugin instances survive
+ * — while the map is taken from the pinned original Source when the current
+ * one no longer carries it.
+ * @param {string} file file name
+ * @param {Source} asset source object as currently held by the compilation
+ * @param {MapOptions} options map extraction options
+ * @param {Map<string, Source>} registry compilation-scoped original-source registry
+ * @returns {{ source: string, sourceMap: RawSourceMap } | undefined} extracted pair or `undefined` when no map is recoverable
+ */
+const extractSourceAndMap = (file, asset, options, registry) => {
+	/** @type {string | Buffer} */
+	let source;
+	/** @type {null | RawSourceMap} */
+	let sourceMap;
+	if (asset.sourceAndMap) {
+		const sourceAndMap = asset.sourceAndMap(options);
+		source = sourceAndMap.source;
+		sourceMap = sourceAndMap.map;
+	} else {
+		source = asset.source();
+		sourceMap = asset.map(options);
+	}
+	// Bail before touching the registry if we can't return a usable string
+	// source — pinning a non-string-producing asset would only waste the slot.
+	if (typeof source !== "string") return;
+	if (sourceMap) {
+		// The current asset still owns the original map — pin a reference so
+		// that a later plugin instance (which will see a rewrapped asset
+		// without a map) can recover it on demand.
+		if (!registry.has(file)) registry.set(file, asset);
+	} else {
+		// The current asset (typically a `RawSource` left by an earlier
+		// SourceMapDevToolPlugin instance) has no internal map. Re-extract
+		// the map from the original Source we pinned earlier. We keep using
+		// `source` from the current asset so that any prior wrappers (e.g.
+		// appended sourceMappingURL comments) are preserved.
+		const original = registry.get(file);
+		if (!original) return;
+		sourceMap = original.sourceAndMap
+			? original.sourceAndMap(options).map
+			: original.map(options);
+		if (!sourceMap) return;
+	}
+	return { source, sourceMap };
+};
+
+/**
+ * Creating {@link SourceMapTask} for given file
+ * @param {string} file current compiled file
+ * @param {Source} asset the asset
+ * @param {AssetInfo} assetInfo the asset info
+ * @param {MapOptions} options source map options
+ * @param {Compilation} compilation compilation instance
+ * @param {ItemCacheFacade} cacheItem cache item
+ * @param {Map<string, Source>} registry compilation-scoped original-source registry
+ * @returns {SourceMapTask | undefined} created task instance or `undefined`
+ */
+const getTaskForFile = (
+	file,
+	asset,
+	assetInfo,
+	options,
+	compilation,
+	cacheItem,
+	registry
+) => {
+	const extracted = extractSourceAndMap(file, asset, options, registry);
+	if (!extracted) return;
+	const { source, sourceMap } = extracted;
+	const context = compilation.options.context;
+	const root = compilation.compiler.root;
+	const cachedAbsolutify = makePathsAbsolute.bindContextCache(context, root);
+	const modules = sourceMap.sources.map((source) => {
+		if (!source.startsWith("webpack://")) return source;
+		source = cachedAbsolutify(source.slice(10));
+		const module = compilation.findModule(source);
+		return module || source;
+	});
+
+	return {
+		file,
+		asset,
+		source: /** @type {string} */ (source),
+		assetInfo,
+		sourceMap,
+		modules,
+		cacheItem
+	};
+};
+
+const PLUGIN_NAME = "SourceMapDevToolPlugin";
+
+/**
+ * Maps a configuration value (string, RegExp, function, nullish, or array of
+ * such) into a JSON-serializable form. Functions and RegExps are turned into
+ * their `.toString()` representation so that changes to inline callbacks
+ * invalidate caches; everything else is returned as-is so that the surrounding
+ * `JSON.stringify` does the escaping.
+ *
+ * The result is used through `JSON.stringify` to build cache identifiers, so
+ * we deliberately avoid any homemade `|` / `,` separators that could collide
+ * with characters appearing inside user-provided values such as `publicPath`,
+ * template strings, or `sourceRoot`.
+ * @param {EXPECTED_ANY} value option value
+ * @returns {EXPECTED_ANY} JSON-serializable representation
+ */
+const toCacheKeyValue = (value) => {
+	if (value === undefined || value === null) return value;
+	if (Array.isArray(value)) return value.map(toCacheKeyValue);
+	if (value instanceof RegExp || typeof value === "function") {
+		return value.toString();
+	}
+	return value;
+};
+
+class SourceMapDevToolPlugin {
+	/**
+	 * Creates an instance of SourceMapDevToolPlugin.
+	 * @param {SourceMapDevToolPluginOptions=} options options object
+	 * @throws {Error} throws error, if got more than 1 arguments
+	 */
+	constructor(options = {}) {
+		/** @type {undefined | null | false | string} */
+		this.sourceMapFilename = options.filename;
+		/** @type {false | SourceMappingURLComment} */
+		this.sourceMappingURLComment =
+			options.append === false
+				? false
+				: // eslint-disable-next-line no-useless-concat
+					options.append || "\n//# source" + "MappingURL=[url]";
+		/** @type {DevtoolModuleFilenameTemplate} */
+		this.moduleFilenameTemplate =
+			options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]";
+		/** @type {DevtoolFallbackModuleFilenameTemplate} */
+		this.fallbackModuleFilenameTemplate =
+			options.fallbackModuleFilenameTemplate ||
+			"webpack://[namespace]/[resourcePath]?[hash]";
+		/** @type {DevtoolNamespace} */
+		this.namespace = options.namespace || "";
+		/** @type {SourceMapDevToolPluginOptions} */
+		this.options = options;
+		// Cache salt derived from output-affecting options, so that two
+		// SourceMapDevToolPlugin instances (or `devtool` + a plugin) operating
+		// on the same asset don't share a cache entry. We serialize via
+		// `JSON.stringify` rather than a homemade separator so that any
+		// special characters (e.g. `|` inside a publicPath or sourceRoot)
+		// can't accidentally make two different option sets collide.
+		/** @type {string} */
+		this._cacheSalt = JSON.stringify([
+			toCacheKeyValue(options.filename),
+			toCacheKeyValue(options.append),
+			toCacheKeyValue(this.moduleFilenameTemplate),
+			toCacheKeyValue(this.fallbackModuleFilenameTemplate),
+			toCacheKeyValue(this.namespace),
+			options.module !== false,
+			options.columns !== false,
+			Boolean(options.noSources),
+			Boolean(options.debugIds),
+			options.sourceRoot || "",
+			toCacheKeyValue(options.ignoreList),
+			options.publicPath || "",
+			options.fileContext || ""
+		]);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../schemas/plugins/SourceMapDevToolPlugin.json"),
+				this.options,
+				{
+					name: "SourceMap DevTool Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../schemas/plugins/SourceMapDevToolPlugin.check")(options)
+			);
+		});
+
+		const outputFs =
+			/** @type {OutputFileSystem} */
+			(compiler.outputFileSystem);
+		const sourceMapFilename = this.sourceMapFilename;
+		const sourceMappingURLComment = this.sourceMappingURLComment;
+		const moduleFilenameTemplate = this.moduleFilenameTemplate;
+		const namespace = this.namespace;
+		const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate;
+		const requestShortener = compiler.requestShortener;
+		const options = this.options;
+		options.test = options.test || CSS_AND_JS_MODULE_EXTENSIONS_REGEXP;
+
+		/** @type {(filename: string) => boolean} */
+		const matchObject = ModuleFilenameHelpers.matchObject.bind(
+			undefined,
+			options
+		);
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation);
+
+			// All SourceMapDevToolPlugin instances on the same compilation share
+			// a registry of pristine asset sources, so the second instance to
+			// run can still recover the original map after the first instance
+			// has replaced the asset with a `RawSource`. The registry lives on a
+			// module-scoped `WeakMap` keyed by compilation so it is released
+			// automatically and never pollutes the compilation object.
+			const originalSources = getOriginalSourceRegistry(compilation);
+
+			compilation.hooks.processAssets.tapAsync(
+				{
+					name: PLUGIN_NAME,
+					stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
+					additionalAssets: true
+				},
+				(assets, callback) => {
+					const chunkGraph = compilation.chunkGraph;
+					const cache = compilation.getCache(PLUGIN_NAME);
+					/** @type {Map<string | Module, string>} */
+					const moduleToSourceNameMapping = new Map();
+					const reportProgress =
+						ProgressPlugin.getReporter(compilation.compiler) || (() => {});
+
+					/** @type {Map<string, Chunk>} */
+					const fileToChunk = new Map();
+					for (const chunk of compilation.chunks) {
+						for (const file of chunk.files) {
+							fileToChunk.set(file, chunk);
+						}
+						for (const file of chunk.auxiliaryFiles) {
+							fileToChunk.set(file, chunk);
+						}
+					}
+
+					/** @type {string[]} */
+					const files = [];
+					for (const file of Object.keys(assets)) {
+						if (matchObject(file)) {
+							files.push(file);
+						}
+					}
+
+					reportProgress(0);
+					/** @type {SourceMapTask[]} */
+					const tasks = [];
+					let fileIndex = 0;
+
+					asyncLib.each(
+						files,
+						(file, callback) => {
+							const asset =
+								/** @type {Readonly<Asset>} */
+								(compilation.getAsset(file));
+
+							const chunk = fileToChunk.get(file);
+							const sourceMapNamespace = compilation.getPath(this.namespace, {
+								chunk
+							});
+
+							// The cache item identifier must include the per-instance
+							// salt so two SourceMapDevToolPlugin instances that target
+							// the same `file` don't collide in the persistent cache —
+							// they'd otherwise write different content to the same key
+							// and invalidate every pack on each build. We encode via
+							// `JSON.stringify` so that special characters (e.g. `|`)
+							// in an asset filename can't be spoofed to collide with the
+							// salt portion of the identifier.
+							const cacheItem = cache.getItemCache(
+								JSON.stringify([file, this._cacheSalt]),
+								cache.mergeEtags(
+									cache.getLazyHashedEtag(asset.source),
+									sourceMapNamespace
+								)
+							);
+
+							cacheItem.get((err, cacheEntry) => {
+								if (err) {
+									return callback(err);
+								}
+								/**
+								 * If presented in cache, reassigns assets. Cache assets already have source maps.
+								 */
+								if (cacheEntry) {
+									// Pin the still-unwrapped asset source in the registry
+									// before `compilation.updateAsset` replaces it. This is a
+									// pointer assignment — no source-map extraction work — and
+									// it lets a subsequent SourceMapDevToolPlugin instance
+									// extract the original map on demand even though the
+									// persistent cache hit lets us skip processing here.
+									if (!originalSources.has(file)) {
+										originalSources.set(file, asset.source);
+									}
+
+									const { assets, assetsInfo } = cacheEntry;
+									for (const cachedFile of Object.keys(assets)) {
+										if (cachedFile === file) {
+											compilation.updateAsset(
+												cachedFile,
+												assets[cachedFile],
+												assetsInfo[cachedFile]
+											);
+										} else {
+											compilation.emitAsset(
+												cachedFile,
+												assets[cachedFile],
+												assetsInfo[cachedFile]
+											);
+										}
+										/**
+										 * Add file to chunk, if not presented there
+										 */
+										if (cachedFile !== file && chunk !== undefined) {
+											chunk.auxiliaryFiles.add(cachedFile);
+										}
+									}
+
+									reportProgress(
+										(0.5 * ++fileIndex) / files.length,
+										file,
+										"restored cached SourceMap"
+									);
+
+									return callback();
+								}
+
+								reportProgress(
+									(0.5 * fileIndex) / files.length,
+									file,
+									"generate SourceMap"
+								);
+
+								/** @type {SourceMapTask | undefined} */
+								const task = getTaskForFile(
+									file,
+									asset.source,
+									asset.info,
+									{
+										module: options.module,
+										columns: options.columns
+									},
+									compilation,
+									cacheItem,
+									originalSources
+								);
+
+								if (task) {
+									const modules = task.modules;
+
+									for (let idx = 0; idx < modules.length; idx++) {
+										const module = modules[idx];
+
+										if (
+											typeof module === "string" &&
+											/^(?:data|https?):/.test(module)
+										) {
+											moduleToSourceNameMapping.set(module, module);
+											continue;
+										}
+
+										if (!moduleToSourceNameMapping.get(module)) {
+											moduleToSourceNameMapping.set(
+												module,
+												ModuleFilenameHelpers.createFilename(
+													module,
+													{
+														moduleFilenameTemplate,
+														namespace: sourceMapNamespace
+													},
+													{
+														requestShortener,
+														chunkGraph,
+														hashFunction: compilation.outputOptions.hashFunction
+													}
+												)
+											);
+										}
+									}
+
+									tasks.push(task);
+								}
+
+								reportProgress(
+									(0.5 * ++fileIndex) / files.length,
+									file,
+									"generated SourceMap"
+								);
+
+								callback();
+							});
+						},
+						(err) => {
+							if (err) {
+								return callback(err);
+							}
+
+							reportProgress(0.5, "resolve sources");
+							/** @type {Set<string>} */
+							const usedNamesSet = new Set(moduleToSourceNameMapping.values());
+							/** @type {Set<string>} */
+							const conflictDetectionSet = new Set();
+
+							/**
+							 * all modules in defined order (longest identifier first)
+							 * @type {(string | Module)[]}
+							 */
+							const allModules = [...moduleToSourceNameMapping.keys()].sort(
+								(a, b) => {
+									const ai = typeof a === "string" ? a : a.identifier();
+									const bi = typeof b === "string" ? b : b.identifier();
+									return ai.length - bi.length;
+								}
+							);
+
+							// find modules with conflicting source names
+							for (let idx = 0; idx < allModules.length; idx++) {
+								const module = allModules[idx];
+								let sourceName =
+									/** @type {string} */
+									(moduleToSourceNameMapping.get(module));
+								let hasName = conflictDetectionSet.has(sourceName);
+								if (!hasName) {
+									conflictDetectionSet.add(sourceName);
+									continue;
+								}
+
+								// try the fallback name first
+								sourceName = ModuleFilenameHelpers.createFilename(
+									module,
+									{
+										moduleFilenameTemplate: fallbackModuleFilenameTemplate,
+										namespace
+									},
+									{
+										requestShortener,
+										chunkGraph,
+										hashFunction: compilation.outputOptions.hashFunction
+									}
+								);
+								hasName = usedNamesSet.has(sourceName);
+								if (!hasName) {
+									moduleToSourceNameMapping.set(module, sourceName);
+									usedNamesSet.add(sourceName);
+									continue;
+								}
+
+								// otherwise just append stars until we have a valid name
+								while (hasName) {
+									sourceName += "*";
+									hasName = usedNamesSet.has(sourceName);
+								}
+								moduleToSourceNameMapping.set(module, sourceName);
+								usedNamesSet.add(sourceName);
+							}
+
+							let taskIndex = 0;
+
+							asyncLib.each(
+								tasks,
+								(task, callback) => {
+									/** @type {Record<string, Source>} */
+									const assets = Object.create(null);
+									/** @type {Record<string, AssetInfo | undefined>} */
+									const assetsInfo = Object.create(null);
+									const file = task.file;
+									const chunk = fileToChunk.get(file);
+									const sourceMap = task.sourceMap;
+									const source = task.source;
+									const modules = task.modules;
+
+									reportProgress(
+										0.5 + (0.5 * taskIndex) / tasks.length,
+										file,
+										"attach SourceMap"
+									);
+
+									const moduleFilenames =
+										/** @type {string[]} */
+										(modules.map((m) => moduleToSourceNameMapping.get(m)));
+									// We deliberately do NOT mutate `sourceMap` in place: the
+									// task's `sourceMap` reference may be shared with a
+									// `SourceMapSource` whose internal map cache is the same
+									// object (webpack-sources keeps it cached). A second
+									// `SourceMapDevToolPlugin` instance that reads the original
+									// source through the registry would otherwise see our
+									// rewrites. Instead we build a fresh `outputSourceMap` for
+									// the .map file and leave the original alone.
+									/** @type {number[] | undefined} */
+									let ignoreList;
+									if (options.ignoreList) {
+										const list = moduleFilenames.reduce(
+											/** @type {(acc: number[], sourceName: string, idx: number) => number[]} */ (
+												(acc, sourceName, idx) => {
+													const rule = /** @type {Rules} */ (
+														options.ignoreList
+													);
+													if (
+														ModuleFilenameHelpers.matchPart(sourceName, rule)
+													) {
+														acc.push(idx);
+													}
+													return acc;
+												}
+											),
+											[]
+										);
+										if (list.length > 0) ignoreList = list;
+									}
+
+									const usesContentHash =
+										sourceMapFilename &&
+										CONTENT_HASH_DETECT_REGEXP.test(sourceMapFilename);
+
+									resetRegexpState(CONTENT_HASH_DETECT_REGEXP);
+
+									let outputFile = file;
+									// If SourceMap and asset uses contenthash, avoid a circular dependency by hiding hash in `file`
+									if (usesContentHash && task.assetInfo.contenthash) {
+										const contenthash = task.assetInfo.contenthash;
+										const pattern = Array.isArray(contenthash)
+											? contenthash.map(quoteMeta).join("|")
+											: quoteMeta(contenthash);
+										outputFile = outputFile.replace(
+											new RegExp(pattern, "g"),
+											(m) => "x".repeat(m.length)
+										);
+									}
+
+									/** @type {false | SourceMappingURLComment} */
+									let currentSourceMappingURLComment = sourceMappingURLComment;
+									const cssExtensionDetected =
+										CSS_EXTENSION_DETECT_REGEXP.test(file);
+									resetRegexpState(CSS_EXTENSION_DETECT_REGEXP);
+									if (
+										currentSourceMappingURLComment !== false &&
+										typeof currentSourceMappingURLComment !== "function" &&
+										cssExtensionDetected
+									) {
+										currentSourceMappingURLComment =
+											currentSourceMappingURLComment.replace(
+												URL_FORMATTING_REGEXP,
+												"\n/*$1*/"
+											);
+									}
+
+									/** @type {string | undefined} */
+									let debugIdValue;
+									if (options.debugIds) {
+										const debugId = generateDebugId(source, outputFile);
+										debugIdValue = debugId;
+
+										const debugIdComment = `\n//# debugId=${debugId}`;
+										if (currentSourceMappingURLComment === false) {
+											currentSourceMappingURLComment = debugIdComment;
+										} else if (
+											typeof currentSourceMappingURLComment === "function"
+										) {
+											// Wrap the user's append function so the debug-id
+											// comment is prepended at call time. Template-string
+											// concatenation would coerce the function to a string
+											// and lose its dynamic behavior.
+											const wrappedFn = currentSourceMappingURLComment;
+											currentSourceMappingURLComment = (pathData, assetInfo) =>
+												`${debugIdComment}${wrappedFn(pathData, assetInfo)}`;
+										} else {
+											currentSourceMappingURLComment = `${debugIdComment}${currentSourceMappingURLComment}`;
+										}
+									}
+
+									/** @type {RawSourceMap} */
+									const outputSourceMap = {
+										...sourceMap,
+										sources: moduleFilenames,
+										sourceRoot: options.sourceRoot || "",
+										file: outputFile
+									};
+									if (ignoreList !== undefined) {
+										outputSourceMap.ignoreList = ignoreList;
+									}
+									if (options.noSources) {
+										outputSourceMap.sourcesContent = undefined;
+									}
+									if (debugIdValue !== undefined) {
+										outputSourceMap.debugId = debugIdValue;
+									}
+
+									const sourceMapString = JSON.stringify(outputSourceMap);
+									if (sourceMapFilename) {
+										const filename = file;
+										const sourceMapContentHash = usesContentHash
+											? createHash(compilation.outputOptions.hashFunction)
+													.update(sourceMapString)
+													.digest("hex")
+											: undefined;
+
+										const pathParams = {
+											chunk,
+											filename: options.fileContext
+												? relative(
+														outputFs,
+														`/${options.fileContext}`,
+														`/${filename}`
+													)
+												: filename,
+											contentHash: sourceMapContentHash
+										};
+										const { path: sourceMapFile, info: sourceMapInfo } =
+											compilation.getPathWithInfo(
+												sourceMapFilename,
+												pathParams
+											);
+										const sourceMapUrl = options.publicPath
+											? options.publicPath + sourceMapFile
+											: relative(
+													outputFs,
+													dirname(outputFs, `/${file}`),
+													`/${sourceMapFile}`
+												);
+										/** @type {Source} */
+										let asset = new RawSource(source);
+										if (currentSourceMappingURLComment !== false) {
+											// Add source map url to compilation asset, if currentSourceMappingURLComment is set
+											asset = new ConcatSource(
+												asset,
+												compilation.getPath(currentSourceMappingURLComment, {
+													url: sourceMapUrl,
+													...pathParams
+												})
+											);
+										}
+										// Preserve any existing related.sourceMap entries from
+										// earlier SourceMapDevToolPlugin runs on the same asset so
+										// that all generated maps remain discoverable via asset
+										// info (the schema allows string or string[]).
+										const existingSourceMap =
+											task.assetInfo.related &&
+											task.assetInfo.related.sourceMap;
+										/** @type {string | string[]} */
+										let relatedSourceMap;
+										if (
+											existingSourceMap === undefined ||
+											existingSourceMap === null
+										) {
+											relatedSourceMap = sourceMapFile;
+										} else if (Array.isArray(existingSourceMap)) {
+											relatedSourceMap = existingSourceMap.includes(
+												sourceMapFile
+											)
+												? existingSourceMap
+												: [...existingSourceMap, sourceMapFile];
+										} else {
+											relatedSourceMap =
+												existingSourceMap === sourceMapFile
+													? existingSourceMap
+													: [existingSourceMap, sourceMapFile];
+										}
+										const assetInfo = {
+											related: { sourceMap: relatedSourceMap }
+										};
+										assets[file] = asset;
+										assetsInfo[file] = assetInfo;
+										compilation.updateAsset(file, asset, assetInfo);
+										// Add source map file to compilation assets and chunk files
+										const sourceMapAsset = new RawSource(sourceMapString);
+										const sourceMapAssetInfo = {
+											...sourceMapInfo,
+											development: true
+										};
+										assets[sourceMapFile] = sourceMapAsset;
+										assetsInfo[sourceMapFile] = sourceMapAssetInfo;
+										compilation.emitAsset(
+											sourceMapFile,
+											sourceMapAsset,
+											sourceMapAssetInfo
+										);
+										if (chunk !== undefined) {
+											chunk.auxiliaryFiles.add(sourceMapFile);
+										}
+									} else {
+										if (currentSourceMappingURLComment === false) {
+											throw new Error(
+												`${PLUGIN_NAME}: append can't be false when no filename is provided`
+											);
+										}
+										if (typeof currentSourceMappingURLComment === "function") {
+											throw new Error(
+												`${PLUGIN_NAME}: append can't be a function when no filename is provided`
+											);
+										}
+										/**
+										 * Add source map as data url to asset
+										 */
+										const asset = new ConcatSource(
+											new RawSource(source),
+											currentSourceMappingURLComment
+												.replace(MAP_URL_COMMENT_REGEXP, () => sourceMapString)
+												.replace(
+													URL_COMMENT_REGEXP,
+													() =>
+														`data:application/json;charset=utf-8;base64,${Buffer.from(
+															sourceMapString,
+															"utf8"
+														).toString("base64")}`
+												)
+										);
+										assets[file] = asset;
+										assetsInfo[file] = undefined;
+										compilation.updateAsset(file, asset);
+									}
+
+									task.cacheItem.store({ assets, assetsInfo }, (err) => {
+										reportProgress(
+											0.5 + (0.5 * ++taskIndex) / tasks.length,
+											task.file,
+											"attached SourceMap"
+										);
+
+										if (err) {
+											return callback(err);
+										}
+										callback();
+									});
+								},
+								(err) => {
+									reportProgress(1);
+									callback(err);
+								}
+							);
+						}
+					);
+				}
+			);
+		});
+	}
+}
+
+module.exports = SourceMapDevToolPlugin;
Index: frontend/node_modules/webpack/lib/Stats.js
===================================================================
--- frontend/node_modules/webpack/lib/Stats.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Stats.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,94 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
+/** @typedef {import("../declarations/WebpackOptions").StatsValue} StatsValue */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
+
+class Stats {
+	/**
+	 * Creates an instance of Stats.
+	 * @param {Compilation} compilation webpack compilation
+	 */
+	constructor(compilation) {
+		this.compilation = compilation;
+	}
+
+	get hash() {
+		return this.compilation.hash;
+	}
+
+	get startTime() {
+		return this.compilation.startTime;
+	}
+
+	get endTime() {
+		return this.compilation.endTime;
+	}
+
+	/**
+	 * Checks whether this stats has warnings.
+	 * @returns {boolean} true if the compilation had a warning
+	 */
+	hasWarnings() {
+		return (
+			this.compilation.getWarnings().length > 0 ||
+			this.compilation.children.some((child) => child.getStats().hasWarnings())
+		);
+	}
+
+	/**
+	 * Checks whether this stats has errors.
+	 * @returns {boolean} true if the compilation encountered an error
+	 */
+	hasErrors() {
+		return (
+			this.compilation.errors.length > 0 ||
+			this.compilation.children.some((child) => child.getStats().hasErrors())
+		);
+	}
+
+	/**
+	 * Returns json output.
+	 * @param {StatsValue=} options stats options
+	 * @returns {StatsCompilation} json output
+	 */
+	toJson(options) {
+		const normalizedOptions = this.compilation.createStatsOptions(options, {
+			forToString: false
+		});
+
+		const statsFactory = this.compilation.createStatsFactory(normalizedOptions);
+
+		return statsFactory.create("compilation", this.compilation, {
+			compilation: this.compilation
+		});
+	}
+
+	/**
+	 * Returns a string representation.
+	 * @param {StatsValue=} options stats options
+	 * @returns {string} string output
+	 */
+	toString(options) {
+		const normalizedOptions = this.compilation.createStatsOptions(options, {
+			forToString: true
+		});
+
+		const statsFactory = this.compilation.createStatsFactory(normalizedOptions);
+		const statsPrinter = this.compilation.createStatsPrinter(normalizedOptions);
+
+		const data = statsFactory.create("compilation", this.compilation, {
+			compilation: this.compilation
+		});
+		const result = statsPrinter.print("compilation", data);
+		return result === undefined ? "" : result;
+	}
+}
+
+module.exports = Stats;
Index: frontend/node_modules/webpack/lib/Template.js
===================================================================
--- frontend/node_modules/webpack/lib/Template.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Template.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,447 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, PrefixSource } = require("webpack-sources");
+const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./config/defaults").OutputNormalizedWithDefaults} OutputOptions */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compilation").PathData} PathData */
+/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
+/** @typedef {import("./RuntimeModule")} RuntimeModule */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
+/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+
+const START_LOWERCASE_ALPHABET_CODE = "a".charCodeAt(0);
+const START_UPPERCASE_ALPHABET_CODE = "A".charCodeAt(0);
+const DELTA_A_TO_Z = "z".charCodeAt(0) - START_LOWERCASE_ALPHABET_CODE + 1;
+const NUMBER_OF_IDENTIFIER_START_CHARS = DELTA_A_TO_Z * 2 + 2; // a-z A-Z _ $
+const NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS =
+	NUMBER_OF_IDENTIFIER_START_CHARS + 10; // a-z A-Z _ $ 0-9
+const FUNCTION_CONTENT_REGEX = /^function\s?\(\)\s?\{\r?\n?|\r?\n?\}$/g;
+const INDENT_MULTILINE_REGEX = /^\t/gm;
+const LINE_SEPARATOR_REGEX = /\r?\n/g;
+const IDENTIFIER_NAME_REPLACE_REGEX = /^([^a-z$_])/i;
+const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-z0-9$]+/gi;
+const COMMENT_END_REGEX = /\*\//g;
+const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-z0-9_!§$()=\-^°]+/gi;
+const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
+
+/**
+ * Defines the render manifest options type used by this module.
+ * @typedef {object} RenderManifestOptions
+ * @property {Chunk} chunk the chunk used to render
+ * @property {string} hash
+ * @property {string} fullHash
+ * @property {OutputOptions} outputOptions
+ * @property {CodeGenerationResults} codeGenerationResults
+ * @property {{ javascript: ModuleTemplate }} moduleTemplates
+ * @property {DependencyTemplates} dependencyTemplates
+ * @property {RuntimeTemplate} runtimeTemplate
+ * @property {ModuleGraph} moduleGraph
+ * @property {ChunkGraph} chunkGraph
+ */
+
+/** @typedef {RenderManifestEntryTemplated | RenderManifestEntryStatic} RenderManifestEntry */
+
+/**
+ * Defines the render manifest entry templated type used by this module.
+ * @typedef {object} RenderManifestEntryTemplated
+ * @property {() => Source} render
+ * @property {string | import("./TemplatedPathPlugin").TemplatePathFn<EXPECTED_ANY>} filenameTemplate
+ * @property {PathData=} pathOptions
+ * @property {AssetInfo=} info
+ * @property {string} identifier
+ * @property {string=} hash
+ * @property {boolean=} auxiliary
+ */
+
+/**
+ * Defines the render manifest entry static type used by this module.
+ * @typedef {object} RenderManifestEntryStatic
+ * @property {() => Source} render
+ * @property {string} filename
+ * @property {AssetInfo} info
+ * @property {string} identifier
+ * @property {string=} hash
+ * @property {boolean=} auxiliary
+ */
+
+/**
+ * Defines the module filter predicate type used by this module.
+ * @typedef {(module: Module) => boolean} ModuleFilterPredicate
+ */
+
+/**
+ * Represents the template runtime component.
+ * @typedef {object} Stringable
+ * @property {() => string} toString
+ */
+
+class Template {
+	/**
+	 * Gets function content.
+	 * @param {Stringable} fn a runtime function (.runtime.js) "template"
+	 * @returns {string} the updated and normalized function string
+	 */
+	static getFunctionContent(fn) {
+		return fn
+			.toString()
+			.replace(FUNCTION_CONTENT_REGEX, "")
+			.replace(INDENT_MULTILINE_REGEX, "")
+			.replace(LINE_SEPARATOR_REGEX, "\n");
+	}
+
+	/**
+	 * Returns created identifier.
+	 * @param {string} str the string converted to identifier
+	 * @returns {string} created identifier
+	 */
+	static toIdentifier(str) {
+		if (typeof str !== "string") return "";
+		return str
+			.replace(IDENTIFIER_NAME_REPLACE_REGEX, "_$1")
+			.replace(IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX, "_");
+	}
+
+	/**
+	 * Returns a commented version of string.
+	 * @param {string} str string to be converted to commented in bundle code
+	 * @returns {string} returns a commented version of string
+	 */
+	static toComment(str) {
+		if (!str) return "";
+		return `/*! ${str.replace(COMMENT_END_REGEX, "* /")} */`;
+	}
+
+	/**
+	 * Returns a commented version of string.
+	 * @param {string} str string to be converted to "normal comment"
+	 * @returns {string} returns a commented version of string
+	 */
+	static toNormalComment(str) {
+		if (!str) return "";
+		return `/* ${str.replace(COMMENT_END_REGEX, "* /")} */`;
+	}
+
+	/**
+	 * Returns normalized bundle-safe path.
+	 * @param {string} str string path to be normalized
+	 * @returns {string} normalized bundle-safe path
+	 */
+	static toPath(str) {
+		if (typeof str !== "string") return "";
+		return str
+			.replace(PATH_NAME_NORMALIZE_REPLACE_REGEX, "-")
+			.replace(MATCH_PADDED_HYPHENS_REPLACE_REGEX, "");
+	}
+
+	// map number to a single character a-z, A-Z or multiple characters if number is too big
+	/**
+	 * Number to identifier.
+	 * @param {number} n number to convert to ident
+	 * @returns {string} returns single character ident
+	 */
+	static numberToIdentifier(n) {
+		if (n >= NUMBER_OF_IDENTIFIER_START_CHARS) {
+			// use multiple letters
+			return (
+				Template.numberToIdentifier(n % NUMBER_OF_IDENTIFIER_START_CHARS) +
+				Template.numberToIdentifierContinuation(
+					Math.floor(n / NUMBER_OF_IDENTIFIER_START_CHARS)
+				)
+			);
+		}
+
+		// lower case
+		if (n < DELTA_A_TO_Z) {
+			return String.fromCharCode(START_LOWERCASE_ALPHABET_CODE + n);
+		}
+		n -= DELTA_A_TO_Z;
+
+		// upper case
+		if (n < DELTA_A_TO_Z) {
+			return String.fromCharCode(START_UPPERCASE_ALPHABET_CODE + n);
+		}
+
+		if (n === DELTA_A_TO_Z) return "_";
+		return "$";
+	}
+
+	/**
+	 * Number to identifier continuation.
+	 * @param {number} n number to convert to ident
+	 * @returns {string} returns single character ident
+	 */
+	static numberToIdentifierContinuation(n) {
+		if (n >= NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS) {
+			// use multiple letters
+			return (
+				Template.numberToIdentifierContinuation(
+					n % NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS
+				) +
+				Template.numberToIdentifierContinuation(
+					Math.floor(n / NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS)
+				)
+			);
+		}
+
+		// lower case
+		if (n < DELTA_A_TO_Z) {
+			return String.fromCharCode(START_LOWERCASE_ALPHABET_CODE + n);
+		}
+		n -= DELTA_A_TO_Z;
+
+		// upper case
+		if (n < DELTA_A_TO_Z) {
+			return String.fromCharCode(START_UPPERCASE_ALPHABET_CODE + n);
+		}
+		n -= DELTA_A_TO_Z;
+
+		// numbers
+		if (n < 10) {
+			return `${n}`;
+		}
+
+		if (n === 10) return "_";
+		return "$";
+	}
+
+	/**
+	 * Returns converted identity.
+	 * @param {string | string[]} s string to convert to identity
+	 * @returns {string} converted identity
+	 */
+	static indent(s) {
+		if (Array.isArray(s)) {
+			return s.map(Template.indent).join("\n");
+		}
+		const str = s.trimEnd();
+		if (!str) return "";
+		const ind = str[0] === "\n" ? "" : "\t";
+		return ind + str.replace(/\n([^\n])/g, "\n\t$1");
+	}
+
+	/**
+	 * Returns new prefix string.
+	 * @param {string | string[]} s string to create prefix for
+	 * @param {string} prefix prefix to compose
+	 * @returns {string} returns new prefix string
+	 */
+	static prefix(s, prefix) {
+		const str = Template.asString(s).trim();
+		if (!str) return "";
+		const ind = str[0] === "\n" ? "" : prefix;
+		return ind + str.replace(/\n([^\n])/g, `\n${prefix}$1`);
+	}
+
+	/**
+	 * Returns a single string from array.
+	 * @param {string | string[]} str string or string collection
+	 * @returns {string} returns a single string from array
+	 */
+	static asString(str) {
+		if (Array.isArray(str)) {
+			return str.join("\n");
+		}
+		return str;
+	}
+
+	/**
+	 * Defines the with id type used by this module.
+	 * @typedef {object} WithId
+	 * @property {string | number} id
+	 */
+
+	/**
+	 * Gets modules array bounds.
+	 * @param {WithId[]} modules a collection of modules to get array bounds for
+	 * @returns {[number, number] | false} returns the upper and lower array bounds
+	 * or false if not every module has a number based id
+	 */
+	static getModulesArrayBounds(modules) {
+		let maxId = -Infinity;
+		let minId = Infinity;
+		for (const module of modules) {
+			const moduleId = module.id;
+			if (typeof moduleId !== "number") return false;
+			if (maxId < moduleId) maxId = moduleId;
+			if (minId > moduleId) minId = moduleId;
+		}
+		if (minId < 16 + String(minId).length) {
+			// add minId x ',' instead of 'Array(minId).concat(…)'
+			minId = 0;
+		}
+		// start with -1 because the first module needs no comma
+		let objectOverhead = -1;
+		for (const module of modules) {
+			// module id + colon + comma
+			objectOverhead += `${module.id}`.length + 2;
+		}
+		// number of commas, or when starting non-zero the length of Array(minId).concat()
+		const arrayOverhead = minId === 0 ? maxId : 16 + `${minId}`.length + maxId;
+		return arrayOverhead < objectOverhead ? [minId, maxId] : false;
+	}
+
+	/**
+	 * Renders chunk modules.
+	 * @param {ChunkRenderContext} renderContext render context
+	 * @param {Module[]} modules modules to render (should be ordered by identifier)
+	 * @param {(module: Module, renderInArray?: boolean) => Source | null} renderModule function to render a module
+	 * @param {string=} prefix applying prefix strings
+	 * @returns {Source | null} rendered chunk modules in a Source object or null if no modules
+	 */
+	static renderChunkModules(renderContext, modules, renderModule, prefix = "") {
+		const { chunkGraph } = renderContext;
+		const source = new ConcatSource();
+		if (modules.length === 0) {
+			return null;
+		}
+		/** @type {{ id: ModuleId, module: Module }[]} */
+		const modulesWithId = modules.map((m) => ({
+			id: /** @type {ModuleId} */ (chunkGraph.getModuleId(m)),
+			module: m
+		}));
+		const bounds = Template.getModulesArrayBounds(modulesWithId);
+		const renderInObject = bounds === false;
+
+		/** @type {{ id: ModuleId, source: Source | "false" }[]} */
+		const allModules = modulesWithId.map(({ id, module }) => ({
+			id,
+			source: renderModule(module, renderInObject) || "false"
+		}));
+
+		if (bounds) {
+			// Render a spare array
+			const minId = bounds[0];
+			const maxId = bounds[1];
+			if (minId !== 0) {
+				source.add(`Array(${minId}).concat(`);
+			}
+			source.add("[\n");
+			/** @type {Map<ModuleId, { id: ModuleId, source: Source | "false" }>} */
+			const modules = new Map();
+			for (const module of allModules) {
+				modules.set(module.id, module);
+			}
+			for (let idx = minId; idx <= maxId; idx++) {
+				const module = modules.get(idx);
+				if (idx !== minId) {
+					source.add(",\n");
+				}
+				source.add(`/* ${idx} */`);
+				if (module) {
+					source.add("\n");
+					source.add(module.source);
+				}
+			}
+			source.add(`\n${prefix}]`);
+			if (minId !== 0) {
+				source.add(")");
+			}
+		} else {
+			// Render an object
+			source.add("{\n");
+			for (let i = 0; i < allModules.length; i++) {
+				const module = allModules[i];
+				if (i !== 0) {
+					source.add(",\n");
+				}
+				source.add(
+					`\n/***/ ${JSON.stringify(module.id)}${renderContext.runtimeTemplate.supportsMethodShorthand() && module.source !== "false" ? "" : ":"}\n`
+				);
+				source.add(module.source);
+			}
+			source.add(`\n\n${prefix}}`);
+		}
+		return source;
+	}
+
+	/**
+	 * Renders runtime modules.
+	 * @param {RuntimeModule[]} runtimeModules array of runtime modules in order
+	 * @param {RenderContext & { codeGenerationResults?: CodeGenerationResults }} renderContext render context
+	 * @returns {Source} rendered runtime modules in a Source object
+	 */
+	static renderRuntimeModules(runtimeModules, renderContext) {
+		const source = new ConcatSource();
+		for (const module of runtimeModules) {
+			const codeGenerationResults = renderContext.codeGenerationResults;
+			/** @type {undefined | Source} */
+			let runtimeSource;
+			if (codeGenerationResults) {
+				runtimeSource = codeGenerationResults.getSource(
+					module,
+					renderContext.chunk.runtime,
+					WEBPACK_MODULE_TYPE_RUNTIME
+				);
+			} else {
+				const codeGenResult = module.codeGeneration({
+					chunkGraph: renderContext.chunkGraph,
+					dependencyTemplates: renderContext.dependencyTemplates,
+					moduleGraph: renderContext.moduleGraph,
+					runtimeTemplate: renderContext.runtimeTemplate,
+					runtime: renderContext.chunk.runtime,
+					runtimes: [renderContext.chunk.runtime],
+					codeGenerationResults
+				});
+				if (!codeGenResult) continue;
+				runtimeSource = codeGenResult.sources.get("runtime");
+			}
+			if (runtimeSource) {
+				source.add(`${Template.toNormalComment(module.identifier())}\n`);
+				if (!module.shouldIsolate()) {
+					source.add(runtimeSource);
+					source.add("\n\n");
+				} else if (renderContext.runtimeTemplate.supportsArrowFunction()) {
+					source.add("(() => {\n");
+					source.add(new PrefixSource("\t", runtimeSource));
+					source.add("\n})();\n\n");
+				} else {
+					source.add("!function() {\n");
+					source.add(new PrefixSource("\t", runtimeSource));
+					source.add("\n}();\n\n");
+				}
+			}
+		}
+		return source;
+	}
+
+	/**
+	 * Renders chunk runtime modules.
+	 * @param {RuntimeModule[]} runtimeModules array of runtime modules in order
+	 * @param {RenderContext} renderContext render context
+	 * @returns {Source} rendered chunk runtime modules in a Source object
+	 */
+	static renderChunkRuntimeModules(runtimeModules, renderContext) {
+		return new PrefixSource(
+			"/******/ ",
+			new ConcatSource(
+				`function(${RuntimeGlobals.require}) { // webpackRuntimeModules\n`,
+				this.renderRuntimeModules(runtimeModules, renderContext),
+				"}\n"
+			)
+		);
+	}
+}
+
+module.exports = Template;
+module.exports.NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS =
+	NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS;
+module.exports.NUMBER_OF_IDENTIFIER_START_CHARS =
+	NUMBER_OF_IDENTIFIER_START_CHARS;
Index: frontend/node_modules/webpack/lib/TemplatedPathPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/TemplatedPathPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/TemplatedPathPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,426 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Jason Anderson @diurnalist
+*/
+
+"use strict";
+
+const { basename, extname } = require("path");
+const util = require("util");
+const Chunk = require("./Chunk");
+const Module = require("./Module");
+const { parseResource } = require("./util/identifier");
+const memoize = require("./util/memoize");
+
+const getMimeTypes = memoize(() => require("./util/mimeTypes"));
+
+/** @typedef {import("./ChunkGraph")} ChunkGraph */
+/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compilation").PathData} PathData */
+/** @typedef {import("./Compilation").PathDataChunk} PathDataChunk */
+/** @typedef {import("./Compilation").PathDataModule} PathDataModule */
+/** @typedef {import("./Compiler")} Compiler */
+
+const REGEXP = /\[\\*([\w:]+)\\*\]/g;
+
+/** @type {PathData["prepareId"]} */
+const prepareId = (id) => {
+	if (typeof id !== "string") return id;
+
+	if (/^"\s\+*.*\+\s*"$/.test(id)) {
+		const match = /^"\s\+*\s*(.*)\s*\+\s*"$/.exec(id);
+
+		return `" + (${
+			/** @type {string[]} */ (match)[1]
+		} + "").replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_") + "`;
+	}
+
+	return id.replace(/(^[.-]|[^a-z0-9_-])+/gi, "_");
+};
+
+/**
+ * Defines the replacer function callback.
+ * @callback ReplacerFunction
+ * @param {string} match
+ * @param {string | undefined} arg
+ * @param {string} input
+ */
+
+/**
+ * Returns hash replacer function.
+ * @param {ReplacerFunction} replacer replacer
+ * @param {((arg0: number) => string) | undefined} handler handler
+ * @param {AssetInfo | undefined} assetInfo asset info
+ * @param {string} hashName hash name
+ * @returns {Replacer} hash replacer function
+ */
+const hashLength = (replacer, handler, assetInfo, hashName) => {
+	/** @type {Replacer} */
+	const fn = (match, arg, input) => {
+		/** @type {string} */
+		let result;
+		const length = arg && Number.parseInt(arg, 10);
+
+		if (length && handler) {
+			result = handler(length);
+		} else {
+			const hash = replacer(match, arg, input);
+
+			result = length ? hash.slice(0, length) : hash;
+		}
+		if (assetInfo) {
+			assetInfo.immutable = true;
+			if (Array.isArray(assetInfo[hashName])) {
+				assetInfo[hashName] = [...assetInfo[hashName], result];
+			} else if (assetInfo[hashName]) {
+				assetInfo[hashName] = [assetInfo[hashName], result];
+			} else {
+				assetInfo[hashName] = result;
+			}
+		}
+		return result;
+	};
+
+	return fn;
+};
+
+/** @typedef {(match: string, arg: string | undefined, input: string) => string} Replacer */
+
+/**
+ * Returns replacer.
+ * @param {string | number | null | undefined | (() => string | number | null | undefined)} value value
+ * @param {boolean=} allowEmpty allow empty
+ * @returns {Replacer} replacer
+ */
+const replacer = (value, allowEmpty) => {
+	/** @type {Replacer} */
+	const fn = (match, arg, input) => {
+		if (typeof value === "function") {
+			value = value();
+		}
+		if (value === null || value === undefined) {
+			if (!allowEmpty) {
+				throw new Error(
+					`Path variable ${match} not implemented in this context: ${input}`
+				);
+			}
+
+			return "";
+		}
+
+		return `${value}`;
+	};
+
+	return fn;
+};
+
+/** @type {Map<string, (...args: EXPECTED_ANY[]) => EXPECTED_ANY>} */
+const deprecationCache = new Map();
+const deprecatedFunction = (() => () => {})();
+/**
+ * Returns function with deprecation output.
+ * @template {(...args: EXPECTED_ANY[]) => EXPECTED_ANY} T
+ * @param {T} fn function
+ * @param {string} message message
+ * @param {string} code code
+ * @returns {T} function with deprecation output
+ */
+const deprecated = (fn, message, code) => {
+	let d = deprecationCache.get(message);
+	if (d === undefined) {
+		d = util.deprecate(deprecatedFunction, message, code);
+		deprecationCache.set(message, d);
+	}
+	return /** @type {T} */ (
+		(...args) => {
+			d();
+			return fn(...args);
+		}
+	);
+};
+
+/**
+ * Callback used to compute a path from contextual data. The type parameter
+ * narrows the `pathData` shape when the caller knows it operates in a chunk
+ * (`PathDataChunk`) or module (`PathDataModule`) context — defaults to the
+ * fully-optional `PathData` for backward compatibility.
+ * @template {PathData} [T=PathData]
+ * @typedef {(pathData: T, assetInfo?: AssetInfo) => string} TemplatePathFn
+ */
+
+/**
+ * Either a raw template string (e.g. `"[name].[contenthash].js"`) or a
+ * generic `TemplatePathFn`. Method signatures that need to thread a narrowed
+ * `PathData` shape spell the function side out as `TemplatePathFn<T>`
+ * directly — `TemplatePath` itself stays a plain alias so local JSDoc
+ * re-imports keep a single shared identity.
+ * @typedef {string | TemplatePathFn} TemplatePath
+ */
+
+/**
+ * Returns the interpolated path.
+ * @template {PathData} [T=PathData]
+ * @param {string | TemplatePathFn<T>} path the raw path
+ * @param {T} data context data
+ * @param {AssetInfo=} assetInfo extra info about the asset (will be written to)
+ * @returns {string} the interpolated path
+ */
+const interpolate = (path, data, assetInfo) => {
+	const chunkGraph = data.chunkGraph;
+
+	/** @type {Map<string, Replacer>} */
+	const replacements = new Map();
+
+	// Filename context
+	//
+	// Placeholders
+	//
+	// for /some/path/file.js?query#fragment:
+	// [file] - /some/path/file.js
+	// [query] - ?query
+	// [fragment] - #fragment
+	// [base] - file.js
+	// [path] - /some/path/
+	// [name] - file
+	// [ext] - .js
+	if (typeof data.filename === "string") {
+		// check that filename is data uri
+		const match = data.filename.match(/^data:([^;,]+)/);
+		if (match) {
+			const ext = getMimeTypes().extension(match[1]);
+			const emptyReplacer = replacer("", true);
+			// "XXXX" used for `updateHash`, so we don't need it here
+			const contentHash =
+				data.contentHash && !/X+/.test(data.contentHash)
+					? data.contentHash
+					: false;
+			const baseReplacer = contentHash ? replacer(contentHash) : emptyReplacer;
+
+			replacements.set("file", emptyReplacer);
+			replacements.set("query", emptyReplacer);
+			replacements.set("fragment", emptyReplacer);
+			replacements.set("path", emptyReplacer);
+			replacements.set("base", baseReplacer);
+			replacements.set("name", baseReplacer);
+			replacements.set("ext", replacer(ext ? `.${ext}` : "", true));
+			// Legacy
+			replacements.set(
+				"filebase",
+				deprecated(
+					baseReplacer,
+					"[filebase] is now [base]",
+					"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME"
+				)
+			);
+		} else {
+			const { path: file, query, fragment } = parseResource(data.filename);
+
+			const ext = extname(file);
+			const base = basename(file);
+			const name = base.slice(0, base.length - ext.length);
+			const path = file.slice(0, file.length - base.length);
+
+			replacements.set("file", replacer(file));
+			replacements.set("query", replacer(query, true));
+			replacements.set("fragment", replacer(fragment, true));
+			replacements.set("path", replacer(path, true));
+			replacements.set("base", replacer(base));
+			replacements.set("name", replacer(name));
+			replacements.set("ext", replacer(ext, true));
+			// Legacy
+			replacements.set(
+				"filebase",
+				deprecated(
+					replacer(base),
+					"[filebase] is now [base]",
+					"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME"
+				)
+			);
+		}
+	}
+
+	// Compilation context
+	//
+	// Placeholders
+	//
+	// [fullhash] - data.hash (3a4b5c6e7f)
+	//
+	// Legacy Placeholders
+	//
+	// [hash] - data.hash (3a4b5c6e7f)
+	if (data.hash) {
+		const hashReplacer = hashLength(
+			replacer(data.hash),
+			data.hashWithLength,
+			assetInfo,
+			"fullhash"
+		);
+
+		replacements.set("fullhash", hashReplacer);
+
+		// Legacy
+		replacements.set(
+			"hash",
+			deprecated(
+				hashReplacer,
+				"[hash] is now [fullhash] (also consider using [chunkhash] or [contenthash], see documentation for details)",
+				"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_HASH"
+			)
+		);
+	}
+
+	// Chunk Context
+	//
+	// Placeholders
+	//
+	// [id] - chunk.id (0.js)
+	// [name] - chunk.name (app.js)
+	// [chunkhash] - chunk.hash (7823t4t4.js)
+	// [contenthash] - chunk.contentHash[type] (3256u3zg.js)
+	if (data.chunk) {
+		const chunk = data.chunk;
+
+		const contentHashType = data.contentHashType;
+
+		const idReplacer = replacer(chunk.id);
+		const nameReplacer = replacer(chunk.name || chunk.id);
+		const chunkhashReplacer = hashLength(
+			replacer(chunk instanceof Chunk ? chunk.renderedHash : chunk.hash),
+			"hashWithLength" in chunk ? chunk.hashWithLength : undefined,
+			assetInfo,
+			"chunkhash"
+		);
+		const contenthashReplacer = hashLength(
+			replacer(
+				data.contentHash ||
+					(contentHashType &&
+						chunk.contentHash &&
+						chunk.contentHash[contentHashType])
+			),
+			data.contentHashWithLength ||
+				("contentHashWithLength" in chunk && chunk.contentHashWithLength
+					? chunk.contentHashWithLength[/** @type {string} */ (contentHashType)]
+					: undefined),
+			assetInfo,
+			"contenthash"
+		);
+
+		replacements.set("id", idReplacer);
+		replacements.set("name", nameReplacer);
+		replacements.set("chunkhash", chunkhashReplacer);
+		replacements.set("contenthash", contenthashReplacer);
+	}
+
+	// Module Context
+	//
+	// Placeholders
+	//
+	// [id] - module.id (2.png)
+	// [hash] - module.hash (6237543873.png)
+	//
+	// Legacy Placeholders
+	//
+	// [moduleid] - module.id (2.png)
+	// [modulehash] - module.hash (6237543873.png)
+	if (data.module) {
+		const module = data.module;
+
+		const idReplacer = replacer(() =>
+			(data.prepareId || prepareId)(
+				module instanceof Module
+					? /** @type {ModuleId} */
+						(/** @type {ChunkGraph} */ (chunkGraph).getModuleId(module))
+					: module.id
+			)
+		);
+		const moduleHashReplacer = hashLength(
+			replacer(() =>
+				module instanceof Module
+					? /** @type {ChunkGraph} */
+						(chunkGraph).getRenderedModuleHash(module, data.runtime)
+					: module.hash
+			),
+			"hashWithLength" in module ? module.hashWithLength : undefined,
+			assetInfo,
+			"modulehash"
+		);
+		const contentHashReplacer = hashLength(
+			replacer(/** @type {string} */ (data.contentHash)),
+			undefined,
+			assetInfo,
+			"contenthash"
+		);
+
+		replacements.set("id", idReplacer);
+		replacements.set("modulehash", moduleHashReplacer);
+		replacements.set("contenthash", contentHashReplacer);
+		replacements.set(
+			"hash",
+			data.contentHash ? contentHashReplacer : moduleHashReplacer
+		);
+		// Legacy
+		replacements.set(
+			"moduleid",
+			deprecated(
+				idReplacer,
+				"[moduleid] is now [id]",
+				"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_MODULE_ID"
+			)
+		);
+	}
+
+	// Other things
+	if (data.url) {
+		replacements.set("url", replacer(data.url));
+	}
+	if (typeof data.runtime === "string") {
+		replacements.set(
+			"runtime",
+			replacer(() =>
+				(data.prepareId || prepareId)(/** @type {string} */ (data.runtime))
+			)
+		);
+	} else {
+		replacements.set("runtime", replacer("_"));
+	}
+
+	if (typeof path === "function") {
+		path = path(data, assetInfo);
+	}
+
+	path = path.replace(REGEXP, (match, content) => {
+		if (content.length + 2 === match.length) {
+			const contentMatch = /^(\w+)(?::(\w+))?$/.exec(content);
+			if (!contentMatch) return match;
+			const [, kind, arg] = contentMatch;
+			const replacer = replacements.get(kind);
+			if (replacer !== undefined) {
+				return replacer(match, arg, /** @type {string} */ (path));
+			}
+		} else if (match.startsWith("[\\") && match.endsWith("\\]")) {
+			return `[${match.slice(2, -2)}]`;
+		}
+		return match;
+	});
+
+	return path;
+};
+
+const plugin = "TemplatedPathPlugin";
+
+class TemplatedPathPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(plugin, (compilation) => {
+			compilation.hooks.assetPath.tap(plugin, interpolate);
+		});
+	}
+}
+
+module.exports = TemplatedPathPlugin;
+module.exports.interpolate = interpolate;
Index: frontend/node_modules/webpack/lib/UseStrictPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/UseStrictPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/UseStrictPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,82 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const ConstDependency = require("./dependencies/ConstDependency");
+
+/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Module").BuildInfo} BuildInfo */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "UseStrictPlugin";
+
+class UseStrictPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {JavascriptParserOptions} parserOptions the javascript parser options
+				 */
+				const handler = (parser, parserOptions) => {
+					parser.hooks.program.tap(PLUGIN_NAME, (ast) => {
+						const firstNode = ast.body[0];
+						if (
+							firstNode &&
+							firstNode.type === "ExpressionStatement" &&
+							firstNode.expression.type === "Literal" &&
+							firstNode.expression.value === "use strict"
+						) {
+							// Remove "use strict" expression. It will be added later by the renderer again.
+							// This is necessary in order to not break the strict mode when webpack prepends code.
+							// @see https://github.com/webpack/webpack/issues/1970
+							const dep = new ConstDependency(
+								"",
+								/** @type {Range} */ (firstNode.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (firstNode.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).strict = true;
+						}
+						if (parserOptions.overrideStrict) {
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).strict =
+								parserOptions.overrideStrict === "strict";
+						}
+					});
+				};
+
+				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);
+			}
+		);
+	}
+}
+
+module.exports = UseStrictPlugin;
Index: frontend/node_modules/webpack/lib/WarnCaseSensitiveModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/WarnCaseSensitiveModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WarnCaseSensitiveModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,132 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./NormalModule")} NormalModule */
+
+const WebpackError = require("./errors/WebpackError");
+
+/**
+ * Sorts the conflicting modules by identifier to keep warning output stable.
+ * @param {Module[]} modules the modules to be sorted
+ * @returns {Module[]} sorted version of original modules
+ */
+const sortModules = (modules) =>
+	modules.sort((a, b) => {
+		const aIdent = a.identifier();
+		const bIdent = b.identifier();
+		/* istanbul ignore next */
+		if (aIdent < bIdent) return -1;
+		/* istanbul ignore next */
+		if (aIdent > bIdent) return 1;
+		/* istanbul ignore next */
+		return 0;
+	});
+
+/**
+ * Formats the conflicting modules and one representative incoming reason for
+ * each module into the warning body.
+ * @param {Module[]} modules each module from throw
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @returns {string} each message from provided modules
+ */
+const createModulesListMessage = (modules, moduleGraph) =>
+	modules
+		.map((m) => {
+			let message = `* ${m.identifier()}`;
+			const validReasons = [
+				...moduleGraph.getIncomingConnectionsByOriginModule(m).keys()
+			].filter(Boolean);
+
+			if (validReasons.length > 0) {
+				message += `\n    Used by ${validReasons.length} module(s), i. e.`;
+				message += `\n    ${
+					/** @type {Module[]} */ (validReasons)[0].identifier()
+				}`;
+			}
+			return message;
+		})
+		.join("\n");
+
+/**
+ * Warning emitted when webpack finds modules whose identifiers differ only by
+ * letter casing, which can behave inconsistently across filesystems.
+ */
+class CaseSensitiveModulesWarning extends WebpackError {
+	/**
+	 * Builds a warning message that lists the case-conflicting modules and
+	 * representative importers that caused them to be included.
+	 * @param {Iterable<Module>} modules modules that were detected
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 */
+	constructor(modules, moduleGraph) {
+		const sortedModules = sortModules([...modules]);
+		const modulesList = createModulesListMessage(sortedModules, moduleGraph);
+		super(`There are multiple modules with names that only differ in casing.
+This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
+Use equal casing. Compare these module identifiers:
+${modulesList}`);
+
+		/** @type {string} */
+		this.name = "CaseSensitiveModulesWarning";
+		this.module = sortedModules[0];
+	}
+}
+
+const PLUGIN_NAME = "WarnCaseSensitiveModulesPlugin";
+
+class WarnCaseSensitiveModulesPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.seal.tap(PLUGIN_NAME, () => {
+				/** @type {Map<string, Map<string, Module>>} */
+				const moduleWithoutCase = new Map();
+				for (const module of compilation.modules) {
+					const identifier = module.identifier();
+
+					// Ignore `data:` URLs, because it's not a real path
+					if (
+						/** @type {NormalModule} */
+						(module).resourceResolveData !== undefined &&
+						/** @type {NormalModule} */
+						(module).resourceResolveData.encodedContent !== undefined
+					) {
+						continue;
+					}
+
+					const lowerIdentifier = identifier.toLowerCase();
+					let map = moduleWithoutCase.get(lowerIdentifier);
+					if (map === undefined) {
+						map = new Map();
+						moduleWithoutCase.set(lowerIdentifier, map);
+					}
+					map.set(identifier, module);
+				}
+				for (const pair of moduleWithoutCase) {
+					const map = pair[1];
+					if (map.size > 1) {
+						compilation.warnings.push(
+							new CaseSensitiveModulesWarning(
+								map.values(),
+								compilation.moduleGraph
+							)
+						);
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = WarnCaseSensitiveModulesPlugin;
Index: frontend/node_modules/webpack/lib/WarnDeprecatedOptionPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/WarnDeprecatedOptionPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WarnDeprecatedOptionPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,60 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const WebpackError = require("./errors/WebpackError");
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "WarnDeprecatedOptionPlugin";
+
+class WarnDeprecatedOptionPlugin {
+	/**
+	 * Create an instance of the plugin
+	 * @param {string} option the target option
+	 * @param {string | number} value the deprecated option value
+	 * @param {string} suggestion the suggestion replacement
+	 */
+	constructor(option, value, suggestion) {
+		this.option = option;
+		this.value = value;
+		this.suggestion = suggestion;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.warnings.push(
+				new DeprecatedOptionWarning(this.option, this.value, this.suggestion)
+			);
+		});
+	}
+}
+
+class DeprecatedOptionWarning extends WebpackError {
+	/**
+	 * Create an instance deprecated option warning
+	 * @param {string} option the target option
+	 * @param {string | number} value the deprecated option value
+	 * @param {string} suggestion the suggestion replacement
+	 */
+	constructor(option, value, suggestion) {
+		super();
+
+		/** @type {string} */
+		this.name = "DeprecatedOptionWarning";
+		this.message =
+			"configuration\n" +
+			`The value '${value}' for option '${option}' is deprecated. ` +
+			`Use '${suggestion}' instead.`;
+	}
+}
+
+module.exports = WarnDeprecatedOptionPlugin;
Index: frontend/node_modules/webpack/lib/WarnNoModeSetPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/WarnNoModeSetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WarnNoModeSetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./errors/WebpackError");
+
+class NoModeWarning extends WebpackError {
+	constructor() {
+		super();
+
+		/** @type {string} */
+		this.name = "NoModeWarning";
+		this.message =
+			"configuration\n" +
+			"The 'mode' option has not been set, webpack will fallback to 'production' for this value.\n" +
+			"Set 'mode' option to 'development' or 'production' to enable defaults for each environment.\n" +
+			"You can also set it to 'none' to disable any default behavior. " +
+			"Learn more: https://webpack.js.org/configuration/mode/";
+	}
+}
+
+/** @typedef {import("./Compiler")} Compiler */
+
+const PLUGIN_NAME = "WarnNoModeSetPlugin";
+
+class WarnNoModeSetPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.warnings.push(new NoModeWarning());
+		});
+	}
+}
+
+module.exports = WarnNoModeSetPlugin;
Index: frontend/node_modules/webpack/lib/WatchIgnorePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/WatchIgnorePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WatchIgnorePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,160 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { groupBy } = require("./util/ArrayHelpers");
+
+/** @typedef {import("watchpack").TimeInfoEntries} TimeInfoEntries */
+/** @typedef {import("../declarations/plugins/WatchIgnorePlugin").WatchIgnorePluginOptions} WatchIgnorePluginOptions */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
+/** @typedef {import("./util/fs").WatchMethod} WatchMethod */
+/** @typedef {import("./util/fs").Watcher} Watcher */
+
+const IGNORE_TIME_ENTRY = "ignore";
+
+class IgnoringWatchFileSystem {
+	/**
+	 * Creates an instance of IgnoringWatchFileSystem.
+	 * @param {WatchFileSystem} wfs original file system
+	 * @param {WatchIgnorePluginOptions["paths"]} paths ignored paths
+	 */
+	constructor(wfs, paths) {
+		this.wfs = wfs;
+		this.paths = paths;
+	}
+
+	/** @type {WatchMethod} */
+	watch(files, dirs, missing, startTime, options, callback, callbackUndelayed) {
+		files = [...files];
+		dirs = [...dirs];
+		/**
+		 * Returns true, if path is ignored.
+		 * @param {string} path path to check
+		 * @returns {boolean} true, if path is ignored
+		 */
+		const ignored = (path) =>
+			this.paths.some((p) =>
+				p instanceof RegExp ? p.test(path) : path.indexOf(p) === 0
+			);
+
+		const [ignoredFiles, notIgnoredFiles] = groupBy(
+			/** @type {string[]} */
+			(files),
+			ignored
+		);
+		const [ignoredDirs, notIgnoredDirs] = groupBy(
+			/** @type {string[]} */
+			(dirs),
+			ignored
+		);
+
+		const watcher = this.wfs.watch(
+			notIgnoredFiles,
+			notIgnoredDirs,
+			missing,
+			startTime,
+			options,
+			(err, fileTimestamps, dirTimestamps, changedFiles, removedFiles) => {
+				if (err) return callback(err);
+				for (const path of ignoredFiles) {
+					/** @type {TimeInfoEntries} */
+					(fileTimestamps).set(path, IGNORE_TIME_ENTRY);
+				}
+
+				for (const path of ignoredDirs) {
+					/** @type {TimeInfoEntries} */
+					(dirTimestamps).set(path, IGNORE_TIME_ENTRY);
+				}
+
+				callback(
+					null,
+					fileTimestamps,
+					dirTimestamps,
+					changedFiles,
+					removedFiles
+				);
+			},
+			callbackUndelayed
+		);
+
+		return {
+			close: () => watcher.close(),
+			pause: () => watcher.pause(),
+			getContextTimeInfoEntries: () => {
+				const dirTimestamps = watcher.getContextTimeInfoEntries();
+				for (const path of ignoredDirs) {
+					dirTimestamps.set(path, IGNORE_TIME_ENTRY);
+				}
+				return dirTimestamps;
+			},
+			getFileTimeInfoEntries: () => {
+				const fileTimestamps = watcher.getFileTimeInfoEntries();
+				for (const path of ignoredFiles) {
+					fileTimestamps.set(path, IGNORE_TIME_ENTRY);
+				}
+				return fileTimestamps;
+			},
+			getInfo:
+				watcher.getInfo &&
+				(() => {
+					const info =
+						/** @type {NonNullable<Watcher["getInfo"]>} */
+						(watcher.getInfo)();
+					const { fileTimeInfoEntries, contextTimeInfoEntries } = info;
+					for (const path of ignoredFiles) {
+						fileTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
+					}
+					for (const path of ignoredDirs) {
+						contextTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
+					}
+					return info;
+				})
+		};
+	}
+}
+
+const PLUGIN_NAME = "WatchIgnorePlugin";
+
+class WatchIgnorePlugin {
+	/**
+	 * Creates an instance of WatchIgnorePlugin.
+	 * @param {WatchIgnorePluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {WatchIgnorePluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../schemas/plugins/WatchIgnorePlugin.json"),
+				this.options,
+				{
+					name: "Watch Ignore Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../schemas/plugins/WatchIgnorePlugin.check")(options)
+			);
+		});
+		compiler.hooks.afterEnvironment.tap(PLUGIN_NAME, () => {
+			compiler.watchFileSystem = new IgnoringWatchFileSystem(
+				/** @type {WatchFileSystem} */
+				(compiler.watchFileSystem),
+				this.options.paths
+			);
+		});
+	}
+}
+
+module.exports = WatchIgnorePlugin;
Index: frontend/node_modules/webpack/lib/Watching.js
===================================================================
--- frontend/node_modules/webpack/lib/Watching.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/Watching.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,544 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Stats = require("./Stats");
+
+/** @typedef {import("../declarations/WebpackOptions").WatchOptions} WatchOptions */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Compiler").ErrorCallback} ErrorCallback */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./util/fs").TimeInfoEntries} TimeInfoEntries */
+/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
+/** @typedef {import("./util/fs").Watcher} Watcher */
+
+/**
+ * Defines the callback type used by this module.
+ * @template T
+ * @template [R=void]
+ * @typedef {import("./webpack").Callback<T, R>} Callback
+ */
+
+/** @typedef {Set<string>} CollectedFiles */
+
+class Watching {
+	/**
+	 * Creates an instance of Watching.
+	 * @param {Compiler} compiler the compiler
+	 * @param {WatchOptions} watchOptions options
+	 * @param {Callback<Stats>} handler completion handler
+	 */
+	constructor(compiler, watchOptions, handler) {
+		/** @type {null | number} */
+		this.startTime = null;
+		this.invalid = false;
+		/** @type {Callback<Stats>} */
+		this.handler = handler;
+		/** @type {ErrorCallback[]} */
+		this.callbacks = [];
+		/** @type {ErrorCallback[] | undefined} */
+		this._closeCallbacks = undefined;
+		this.closed = false;
+		this.suspended = false;
+		this.blocked = false;
+		this._isBlocked = () => false;
+		this._onChange = () => {};
+		this._onInvalid = () => {};
+		if (typeof watchOptions === "number") {
+			/** @type {WatchOptions} */
+			this.watchOptions = {
+				aggregateTimeout: watchOptions
+			};
+		} else if (watchOptions && typeof watchOptions === "object") {
+			/** @type {WatchOptions} */
+			this.watchOptions = { ...watchOptions };
+		} else {
+			/** @type {WatchOptions} */
+			this.watchOptions = {};
+		}
+		if (typeof this.watchOptions.aggregateTimeout !== "number") {
+			this.watchOptions.aggregateTimeout = 20;
+		}
+		this.compiler = compiler;
+		this.running = false;
+		this._initial = true;
+		this._invalidReported = true;
+		this._needRecords = true;
+		/** @type {undefined | null | Watcher} */
+		this.watcher = undefined;
+		/** @type {undefined | null | Watcher} */
+		this.pausedWatcher = undefined;
+		/** @type {CollectedFiles | undefined} */
+		this._collectedChangedFiles = undefined;
+		/** @type {CollectedFiles | undefined} */
+		this._collectedRemovedFiles = undefined;
+		this._done = this._done.bind(this);
+		process.nextTick(() => {
+			if (this._initial) this._invalidate();
+		});
+	}
+
+	/**
+	 * Merge with collected.
+	 * @param {ReadonlySet<string> | undefined | null} changedFiles changed files
+	 * @param {ReadonlySet<string> | undefined | null} removedFiles removed files
+	 */
+	_mergeWithCollected(changedFiles, removedFiles) {
+		if (!changedFiles) return;
+		if (!this._collectedChangedFiles) {
+			this._collectedChangedFiles = new Set(changedFiles);
+			this._collectedRemovedFiles = new Set(removedFiles);
+		} else {
+			for (const file of changedFiles) {
+				this._collectedChangedFiles.add(file);
+				/** @type {CollectedFiles} */
+				(this._collectedRemovedFiles).delete(file);
+			}
+			for (const file of /** @type {ReadonlySet<string>} */ (removedFiles)) {
+				this._collectedChangedFiles.delete(file);
+				/** @type {CollectedFiles} */
+				(this._collectedRemovedFiles).add(file);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided file time info entries.
+	 * @param {TimeInfoEntries=} fileTimeInfoEntries info for files
+	 * @param {TimeInfoEntries=} contextTimeInfoEntries info for directories
+	 * @param {ReadonlySet<string>=} changedFiles changed files
+	 * @param {ReadonlySet<string>=} removedFiles removed files
+	 * @returns {void}
+	 */
+	_go(fileTimeInfoEntries, contextTimeInfoEntries, changedFiles, removedFiles) {
+		this._initial = false;
+		if (this.startTime === null) this.startTime = Date.now();
+		this.running = true;
+		if (this.watcher) {
+			this.pausedWatcher = this.watcher;
+			this.lastWatcherStartTime = Date.now();
+			this.watcher.pause();
+			this.watcher = null;
+		} else if (!this.lastWatcherStartTime) {
+			this.lastWatcherStartTime = Date.now();
+		}
+		this.compiler.fsStartTime = Date.now();
+		if (
+			changedFiles &&
+			removedFiles &&
+			fileTimeInfoEntries &&
+			contextTimeInfoEntries
+		) {
+			this._mergeWithCollected(changedFiles, removedFiles);
+			this.compiler.fileTimestamps = fileTimeInfoEntries;
+			this.compiler.contextTimestamps = contextTimeInfoEntries;
+		} else if (this.pausedWatcher) {
+			if (this.pausedWatcher.getInfo) {
+				const {
+					changes,
+					removals,
+					fileTimeInfoEntries,
+					contextTimeInfoEntries
+				} = this.pausedWatcher.getInfo();
+				this._mergeWithCollected(changes, removals);
+				this.compiler.fileTimestamps = fileTimeInfoEntries;
+				this.compiler.contextTimestamps = contextTimeInfoEntries;
+			} else {
+				this._mergeWithCollected(
+					this.pausedWatcher.getAggregatedChanges &&
+						this.pausedWatcher.getAggregatedChanges(),
+					this.pausedWatcher.getAggregatedRemovals &&
+						this.pausedWatcher.getAggregatedRemovals()
+				);
+				this.compiler.fileTimestamps =
+					this.pausedWatcher.getFileTimeInfoEntries();
+				this.compiler.contextTimestamps =
+					this.pausedWatcher.getContextTimeInfoEntries();
+			}
+		}
+		this.compiler.modifiedFiles = this._collectedChangedFiles;
+		this._collectedChangedFiles = undefined;
+		this.compiler.removedFiles = this._collectedRemovedFiles;
+		this._collectedRemovedFiles = undefined;
+
+		const run = () => {
+			if (this.compiler.idle) {
+				return this.compiler.cache.endIdle((err) => {
+					if (err) return this._done(err);
+					this.compiler.idle = false;
+					run();
+				});
+			}
+			if (this._needRecords) {
+				return this.compiler.readRecords((err) => {
+					if (err) return this._done(err);
+
+					this._needRecords = false;
+					run();
+				});
+			}
+			this.invalid = false;
+			this._invalidReported = false;
+			this.compiler.hooks.watchRun.callAsync(this.compiler, (err) => {
+				if (err) return this._done(err);
+				/**
+				 * Processes the provided err.
+				 * @param {Error | null} err error
+				 * @param {Compilation=} _compilation compilation
+				 * @returns {void}
+				 */
+				const onCompiled = (err, _compilation) => {
+					if (err) return this._done(err, _compilation);
+
+					const compilation = /** @type {Compilation} */ (_compilation);
+
+					if (this.compiler.hooks.shouldEmit.call(compilation) === false) {
+						return this._done(null, compilation);
+					}
+
+					process.nextTick(() => {
+						const logger = compilation.getLogger("webpack.Compiler");
+						logger.time("emitAssets");
+						this.compiler.emitAssets(compilation, (err) => {
+							logger.timeEnd("emitAssets");
+							if (err) return this._done(err, compilation);
+							if (this.invalid) return this._done(null, compilation);
+
+							logger.time("emitRecords");
+							this.compiler.emitRecords((err) => {
+								logger.timeEnd("emitRecords");
+								if (err) return this._done(err, compilation);
+
+								if (compilation.hooks.needAdditionalPass.call()) {
+									compilation.needAdditionalPass = true;
+
+									compilation.startTime = /** @type {number} */ (
+										this.startTime
+									);
+									compilation.endTime = Date.now();
+									logger.time("done hook");
+									const stats = new Stats(compilation);
+									this.compiler.hooks.done.callAsync(stats, (err) => {
+										logger.timeEnd("done hook");
+										if (err) return this._done(err, compilation);
+
+										this.compiler.hooks.additionalPass.callAsync((err) => {
+											if (err) return this._done(err, compilation);
+											this.compiler.compile(onCompiled);
+										});
+									});
+									return;
+								}
+								return this._done(null, compilation);
+							});
+						});
+					});
+				};
+				this.compiler.compile(onCompiled);
+			});
+		};
+
+		run();
+	}
+
+	/**
+	 * Returns the compilation stats.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {Stats} the compilation stats
+	 */
+	_getStats(compilation) {
+		const stats = new Stats(compilation);
+		return stats;
+	}
+
+	/**
+	 * Processes the provided err.
+	 * @param {(Error | null)=} err an optional error
+	 * @param {Compilation=} compilation the compilation
+	 * @returns {void}
+	 */
+	_done(err, compilation) {
+		this.running = false;
+
+		const logger =
+			/** @type {Logger} */
+			(compilation && compilation.getLogger("webpack.Watching"));
+
+		/** @type {Stats | undefined} */
+		let stats;
+
+		/**
+		 * Processes the provided err.
+		 * @param {Error} err error
+		 * @param {ErrorCallback[]=} cbs callbacks
+		 */
+		const handleError = (err, cbs) => {
+			this.compiler.hooks.failed.call(err);
+			this.compiler.cache.beginIdle();
+			this.compiler.idle = true;
+			this.handler(err, /** @type {Stats} */ (stats));
+			if (!cbs) {
+				cbs = this.callbacks;
+				this.callbacks = [];
+			}
+			for (const cb of cbs) cb(err);
+		};
+
+		if (
+			this.invalid &&
+			!this.suspended &&
+			!this.blocked &&
+			!(this._isBlocked() && (this.blocked = true))
+		) {
+			if (compilation) {
+				logger.time("storeBuildDependencies");
+				this.compiler.cache.storeBuildDependencies(
+					compilation.buildDependencies,
+					(err) => {
+						logger.timeEnd("storeBuildDependencies");
+						if (err) return handleError(err);
+						this._go();
+					}
+				);
+			} else {
+				this._go();
+			}
+			return;
+		}
+
+		if (compilation) {
+			compilation.startTime = /** @type {number} */ (this.startTime);
+			compilation.endTime = Date.now();
+			stats = new Stats(compilation);
+		}
+		this.startTime = null;
+		if (err) return handleError(err);
+
+		const cbs = this.callbacks;
+		this.callbacks = [];
+		logger.time("done hook");
+		this.compiler.hooks.done.callAsync(/** @type {Stats} */ (stats), (err) => {
+			logger.timeEnd("done hook");
+			if (err) return handleError(err, cbs);
+			this.handler(null, stats);
+			logger.time("storeBuildDependencies");
+			this.compiler.cache.storeBuildDependencies(
+				/** @type {Compilation} */
+				(compilation).buildDependencies,
+				(err) => {
+					logger.timeEnd("storeBuildDependencies");
+					if (err) return handleError(err, cbs);
+					logger.time("beginIdle");
+					this.compiler.cache.beginIdle();
+					this.compiler.idle = true;
+					logger.timeEnd("beginIdle");
+					process.nextTick(() => {
+						if (!this.closed) {
+							this.watch(
+								/** @type {Compilation} */
+								(compilation).fileDependencies,
+								/** @type {Compilation} */
+								(compilation).contextDependencies,
+								/** @type {Compilation} */
+								(compilation).missingDependencies
+							);
+						}
+					});
+					for (const cb of cbs) cb(null);
+					this.compiler.hooks.afterDone.call(/** @type {Stats} */ (stats));
+				}
+			);
+		});
+	}
+
+	/**
+	 * Processes the provided file.
+	 * @param {Iterable<string>} files watched files
+	 * @param {Iterable<string>} dirs watched directories
+	 * @param {Iterable<string>} missing watched existence entries
+	 * @returns {void}
+	 */
+	watch(files, dirs, missing) {
+		this.pausedWatcher = null;
+		this.watcher =
+			/** @type {WatchFileSystem} */
+			(this.compiler.watchFileSystem).watch(
+				files,
+				dirs,
+				missing,
+				/** @type {number} */ (this.lastWatcherStartTime),
+				this.watchOptions,
+				(
+					err,
+					fileTimeInfoEntries,
+					contextTimeInfoEntries,
+					changedFiles,
+					removedFiles
+				) => {
+					if (err) {
+						this.compiler.modifiedFiles = undefined;
+						this.compiler.removedFiles = undefined;
+						this.compiler.fileTimestamps = undefined;
+						this.compiler.contextTimestamps = undefined;
+						this.compiler.fsStartTime = undefined;
+						return this.handler(err);
+					}
+					this._invalidate(
+						fileTimeInfoEntries,
+						contextTimeInfoEntries,
+						changedFiles,
+						removedFiles
+					);
+					this._onChange();
+				},
+				(fileName, changeTime) => {
+					if (!this._invalidReported) {
+						this._invalidReported = true;
+						this.compiler.hooks.invalid.call(fileName, changeTime);
+					}
+					this._onInvalid();
+				}
+			);
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback=} callback signals when the build has completed again
+	 * @returns {void}
+	 */
+	invalidate(callback) {
+		if (callback) {
+			this.callbacks.push(callback);
+		}
+		if (!this._invalidReported) {
+			this._invalidReported = true;
+			this.compiler.hooks.invalid.call(null, Date.now());
+		}
+		this._onChange();
+		this._invalidate();
+	}
+
+	/**
+	 * Processes the provided file time info entries.
+	 * @param {TimeInfoEntries=} fileTimeInfoEntries info for files
+	 * @param {TimeInfoEntries=} contextTimeInfoEntries info for directories
+	 * @param {ReadonlySet<string>=} changedFiles changed files
+	 * @param {ReadonlySet<string>=} removedFiles removed files
+	 * @returns {void}
+	 */
+	_invalidate(
+		fileTimeInfoEntries,
+		contextTimeInfoEntries,
+		changedFiles,
+		removedFiles
+	) {
+		if (this.suspended || (this._isBlocked() && (this.blocked = true))) {
+			this._mergeWithCollected(changedFiles, removedFiles);
+			return;
+		}
+
+		if (this.running) {
+			this._mergeWithCollected(changedFiles, removedFiles);
+			this.invalid = true;
+		} else {
+			this._go(
+				fileTimeInfoEntries,
+				contextTimeInfoEntries,
+				changedFiles,
+				removedFiles
+			);
+		}
+	}
+
+	suspend() {
+		this.suspended = true;
+	}
+
+	resume() {
+		if (this.suspended) {
+			this.suspended = false;
+			this._invalidate();
+		}
+	}
+
+	/**
+	 * Processes the provided error callback.
+	 * @param {ErrorCallback} callback signals when the watcher is closed
+	 * @returns {void}
+	 */
+	close(callback) {
+		if (this._closeCallbacks) {
+			if (callback) {
+				this._closeCallbacks.push(callback);
+			}
+			return;
+		}
+		/**
+		 * Processes the provided err.
+		 * @param {Error | null} err error if any
+		 * @param {Compilation=} compilation compilation if any
+		 */
+		const finalCallback = (err, compilation) => {
+			this.running = false;
+			this.compiler.running = false;
+			this.compiler.watching = undefined;
+			this.compiler.watchMode = false;
+			this.compiler.modifiedFiles = undefined;
+			this.compiler.removedFiles = undefined;
+			this.compiler.fileTimestamps = undefined;
+			this.compiler.contextTimestamps = undefined;
+			this.compiler.fsStartTime = undefined;
+			/**
+			 * Processes the provided err.
+			 * @param {Error | null} err error if any
+			 */
+			const shutdown = (err) => {
+				this.compiler.hooks.watchClose.call();
+				const closeCallbacks =
+					/** @type {ErrorCallback[]} */
+					(this._closeCallbacks);
+				this._closeCallbacks = undefined;
+				for (const cb of closeCallbacks) cb(err);
+			};
+			if (compilation) {
+				const logger = compilation.getLogger("webpack.Watching");
+				logger.time("storeBuildDependencies");
+				this.compiler.cache.storeBuildDependencies(
+					compilation.buildDependencies,
+					(err2) => {
+						logger.timeEnd("storeBuildDependencies");
+						shutdown(err || err2);
+					}
+				);
+			} else {
+				shutdown(err);
+			}
+		};
+
+		this.closed = true;
+		if (this.watcher) {
+			this.watcher.close();
+			this.watcher = null;
+		}
+		if (this.pausedWatcher) {
+			this.pausedWatcher.close();
+			this.pausedWatcher = null;
+		}
+		this._closeCallbacks = [];
+		if (callback) {
+			this._closeCallbacks.push(callback);
+		}
+		if (this.running) {
+			this.invalid = true;
+			this._done = finalCallback;
+		} else {
+			finalCallback(null);
+		}
+	}
+}
+
+module.exports = Watching;
Index: frontend/node_modules/webpack/lib/WebpackError.js
===================================================================
--- frontend/node_modules/webpack/lib/WebpackError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WebpackError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,10 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Jarid Margolin @jaridmargolin
+*/
+
+"use strict";
+
+// TODO remove in webpack 6
+// Some old plugins use `require("webpack/lib/WebpackError")`, in webpack@6 developer should migrate to `compiler.webpack.WebpackError`
+module.exports = require("./errors/WebpackError");
Index: frontend/node_modules/webpack/lib/WebpackIsIncludedPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/WebpackIsIncludedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WebpackIsIncludedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,95 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("./ModuleTypeConstants");
+const WebpackIsIncludedDependency = require("./dependencies/WebpackIsIncludedDependency");
+const IgnoreErrorModuleFactory = require("./errors/IgnoreErrorModuleFactory");
+const {
+	toConstantDependency
+} = require("./javascript/JavascriptParserHelpers");
+
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "WebpackIsIncludedPlugin";
+
+class WebpackIsIncludedPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					WebpackIsIncludedDependency,
+					new IgnoreErrorModuleFactory(normalModuleFactory)
+				);
+				compilation.dependencyTemplates.set(
+					WebpackIsIncludedDependency,
+					new WebpackIsIncludedDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @returns {void}
+				 */
+				const handler = (parser) => {
+					parser.hooks.call
+						.for("__webpack_is_included__")
+						.tap(PLUGIN_NAME, (expr) => {
+							if (
+								expr.type !== "CallExpression" ||
+								expr.arguments.length !== 1 ||
+								expr.arguments[0].type === "SpreadElement"
+							) {
+								return;
+							}
+
+							const request = parser.evaluateExpression(expr.arguments[0]);
+
+							if (!request.isString()) return;
+
+							const dep = new WebpackIsIncludedDependency(
+								/** @type {string} */ (request.string),
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addDependency(dep);
+							return true;
+						});
+					parser.hooks.typeof
+						.for("__webpack_is_included__")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("function"))
+						);
+				};
+				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);
+			}
+		);
+	}
+}
+
+module.exports = WebpackIsIncludedPlugin;
Index: frontend/node_modules/webpack/lib/WebpackOptionsApply.js
===================================================================
--- frontend/node_modules/webpack/lib/WebpackOptionsApply.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WebpackOptionsApply.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,954 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const APIPlugin = require("./APIPlugin");
+
+const CompatibilityPlugin = require("./CompatibilityPlugin");
+
+const ConstPlugin = require("./ConstPlugin");
+
+const EntryOptionPlugin = require("./EntryOptionPlugin");
+
+const ExportsInfoApiPlugin = require("./ExportsInfoApiPlugin");
+const FlagDependencyExportsPlugin = require("./FlagDependencyExportsPlugin");
+
+const JavascriptMetaInfoPlugin = require("./JavascriptMetaInfoPlugin");
+
+const NodeStuffPlugin = require("./NodeStuffPlugin");
+const OptionsApply = require("./OptionsApply");
+
+const RecordIdsPlugin = require("./RecordIdsPlugin");
+
+const RuntimePlugin = require("./RuntimePlugin");
+
+const TemplatedPathPlugin = require("./TemplatedPathPlugin");
+
+const UseStrictPlugin = require("./UseStrictPlugin");
+
+const WarnCaseSensitiveModulesPlugin = require("./WarnCaseSensitiveModulesPlugin");
+
+const WebpackIsIncludedPlugin = require("./WebpackIsIncludedPlugin");
+
+const AssetModulesPlugin = require("./asset/AssetModulesPlugin");
+
+const InferAsyncModulesPlugin = require("./async-modules/InferAsyncModulesPlugin");
+
+const ResolverCachePlugin = require("./cache/ResolverCachePlugin");
+
+const CommonJsPlugin = require("./dependencies/CommonJsPlugin");
+
+const HarmonyModulesPlugin = require("./dependencies/HarmonyModulesPlugin");
+
+const ImportMetaContextPlugin = require("./dependencies/ImportMetaContextPlugin");
+const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
+
+const ImportPlugin = require("./dependencies/ImportPlugin");
+const LoaderPlugin = require("./dependencies/LoaderPlugin");
+
+const RequireContextPlugin = require("./dependencies/RequireContextPlugin");
+const RequireEnsurePlugin = require("./dependencies/RequireEnsurePlugin");
+const RequireIncludePlugin = require("./dependencies/RequireIncludePlugin");
+
+const SystemPlugin = require("./dependencies/SystemPlugin");
+
+const URLPlugin = require("./dependencies/URLPlugin");
+
+const WorkerPlugin = require("./dependencies/WorkerPlugin");
+
+const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
+const JavascriptParser = require("./javascript/JavascriptParser");
+
+const JsonModulesPlugin = require("./json/JsonModulesPlugin");
+
+const ChunkPrefetchPreloadPlugin = require("./prefetch/ChunkPrefetchPreloadPlugin");
+
+const DataUriPlugin = require("./schemes/DataUriPlugin");
+const FileUriPlugin = require("./schemes/FileUriPlugin");
+
+const DefaultStatsFactoryPlugin = require("./stats/DefaultStatsFactoryPlugin");
+const DefaultStatsPresetPlugin = require("./stats/DefaultStatsPresetPlugin");
+const DefaultStatsPrinterPlugin = require("./stats/DefaultStatsPrinterPlugin");
+
+const { cleverMerge } = require("./util/cleverMerge");
+
+/** @typedef {import("./webpack").WebpackPluginFunction} WebpackPluginFunction */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("./config/normalization").WebpackOptionsInterception} WebpackOptionsInterception */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
+
+const CLASS_NAME = "WebpackOptionsApply";
+
+class WebpackOptionsApply extends OptionsApply {
+	constructor() {
+		super();
+	}
+
+	/**
+	 * Returns options object.
+	 * @param {WebpackOptions} options options object
+	 * @param {Compiler} compiler compiler object
+	 * @param {WebpackOptionsInterception=} interception intercepted options
+	 * @returns {WebpackOptions} options object
+	 */
+	process(options, compiler, interception) {
+		compiler.outputPath = options.output.path;
+		compiler.recordsInputPath = options.recordsInputPath || null;
+		compiler.recordsOutputPath = options.recordsOutputPath || null;
+		compiler.name = options.name;
+
+		if (options.externals) {
+			// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+			const ExternalsPlugin = require("./ExternalsPlugin");
+
+			new ExternalsPlugin(options.externalsType, options.externals).apply(
+				compiler
+			);
+		}
+
+		if (options.externalsPresets.node) {
+			const NodeTargetPlugin = require("./node/NodeTargetPlugin");
+
+			// Some older versions of Node.js don't support all built-in modules via import, only via `require`,
+			// but it seems like there shouldn't be a warning here since these versions are rarely used in real applications
+			new NodeTargetPlugin(
+				options.output.module ? "module-import" : "node-commonjs"
+			).apply(compiler);
+
+			// Handle external CSS `@import` and `url()`
+			if (options.experiments.css) {
+				// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+				const ExternalsPlugin = require("./ExternalsPlugin");
+
+				new ExternalsPlugin(
+					"module",
+					({ request, dependencyType, contextInfo }, callback) => {
+						if (
+							/\.css(?:\?|$)/.test(contextInfo.issuer) &&
+							/^(?:\/\/|https?:\/\/|#)/.test(request)
+						) {
+							if (dependencyType === "url") {
+								return callback(null, `asset ${request}`);
+							} else if (
+								(dependencyType === "css-import" ||
+									dependencyType === "css-import-local-module" ||
+									dependencyType === "css-import-global-module") &&
+								options.experiments.css
+							) {
+								return callback(null, `css-import ${request}`);
+							}
+						}
+
+						callback();
+					}
+				).apply(compiler);
+			}
+		}
+		if (options.externalsPresets.webAsync || options.externalsPresets.web) {
+			const type = options.externalsPresets.webAsync ? "import" : "module";
+
+			// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+			const ExternalsPlugin = require("./ExternalsPlugin");
+
+			new ExternalsPlugin(type, ({ request, dependencyType }, callback) => {
+				if (/^(?:\/\/|https?:\/\/|#|std:|jsr:|npm:)/.test(request)) {
+					if (dependencyType === "url") {
+						return callback(null, `asset ${request}`);
+					} else if (
+						(dependencyType === "css-import" ||
+							dependencyType === "css-import-local-module" ||
+							dependencyType === "css-import-global-module") &&
+						options.experiments.css
+					) {
+						return callback(null, `css-import ${request}`);
+					} else if (/^(?:\/\/|https?:\/\/|std:|jsr:|npm:)/.test(request)) {
+						return callback(null, `${type} ${request}`);
+					}
+				}
+
+				callback();
+			}).apply(compiler);
+		}
+		if (options.externalsPresets.electron) {
+			if (options.externalsPresets.electronMain) {
+				// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+				const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
+
+				new ElectronTargetPlugin("main").apply(compiler);
+			}
+			if (options.externalsPresets.electronPreload) {
+				// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+				const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
+
+				new ElectronTargetPlugin("preload").apply(compiler);
+			}
+			if (options.externalsPresets.electronRenderer) {
+				// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+				const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
+
+				new ElectronTargetPlugin("renderer").apply(compiler);
+			}
+			if (
+				!options.externalsPresets.electronMain &&
+				!options.externalsPresets.electronPreload &&
+				!options.externalsPresets.electronRenderer
+			) {
+				// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+				const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
+
+				new ElectronTargetPlugin().apply(compiler);
+			}
+		}
+		if (options.externalsPresets.nwjs) {
+			// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+			const ExternalsPlugin = require("./ExternalsPlugin");
+
+			new ExternalsPlugin("node-commonjs", "nw.gui").apply(compiler);
+		}
+
+		new ChunkPrefetchPreloadPlugin().apply(compiler);
+
+		if (typeof options.output.chunkFormat === "string") {
+			switch (options.output.chunkFormat) {
+				case "array-push": {
+					const ArrayPushCallbackChunkFormatPlugin = require("./javascript/ArrayPushCallbackChunkFormatPlugin");
+
+					new ArrayPushCallbackChunkFormatPlugin().apply(compiler);
+					break;
+				}
+				case "commonjs": {
+					const CommonJsChunkFormatPlugin = require("./javascript/CommonJsChunkFormatPlugin");
+
+					new CommonJsChunkFormatPlugin().apply(compiler);
+					break;
+				}
+				case "module": {
+					const ModuleChunkFormatPlugin = require("./esm/ModuleChunkFormatPlugin");
+
+					new ModuleChunkFormatPlugin().apply(compiler);
+					break;
+				}
+				default:
+					throw new Error(
+						`Unsupported chunk format '${options.output.chunkFormat}'.`
+					);
+			}
+		}
+
+		const enabledChunkLoadingTypes =
+			/** @type {NonNullable<WebpackOptions["output"]["enabledChunkLoadingTypes"]>} */
+			(options.output.enabledChunkLoadingTypes);
+
+		if (enabledChunkLoadingTypes.length > 0) {
+			for (const type of enabledChunkLoadingTypes) {
+				const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin");
+
+				new EnableChunkLoadingPlugin(type).apply(compiler);
+			}
+		}
+
+		const enabledWasmLoadingTypes =
+			/** @type {NonNullable<WebpackOptions["output"]["enabledWasmLoadingTypes"]>} */
+			(options.output.enabledWasmLoadingTypes);
+
+		if (enabledWasmLoadingTypes.length > 0) {
+			for (const type of enabledWasmLoadingTypes) {
+				const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin");
+
+				new EnableWasmLoadingPlugin(type).apply(compiler);
+			}
+		}
+
+		const enabledLibraryTypes =
+			/** @type {NonNullable<WebpackOptions["output"]["enabledLibraryTypes"]>} */
+			(options.output.enabledLibraryTypes);
+
+		if (enabledLibraryTypes.length > 0) {
+			let once = true;
+			for (const type of enabledLibraryTypes) {
+				const EnableLibraryPlugin = require("./library/EnableLibraryPlugin");
+
+				new EnableLibraryPlugin(type, {
+					// eslint-disable-next-line no-loop-func
+					additionalApply: () => {
+						if (!once) return;
+						once = false;
+						// We rely on `exportInfo` to generate the `export statement` in certain library bundles.
+						// Therefore, we ignore the disabling of `optimization.providedExport` and continue to apply `FlagDependencyExportsPlugin`.
+						if (
+							["module", "commonjs-static", "modern-module"].includes(type) &&
+							!options.optimization.providedExports
+						) {
+							new FlagDependencyExportsPlugin().apply(compiler);
+						}
+					}
+				}).apply(compiler);
+			}
+		}
+
+		if (options.output.pathinfo) {
+			const ModuleInfoHeaderPlugin = require("./ModuleInfoHeaderPlugin");
+
+			new ModuleInfoHeaderPlugin(options.output.pathinfo !== true).apply(
+				compiler
+			);
+		}
+
+		if (options.output.clean) {
+			const CleanPlugin = require("./CleanPlugin");
+
+			new CleanPlugin(
+				options.output.clean === true ? {} : options.output.clean
+			).apply(compiler);
+		}
+
+		if (options.dotenv) {
+			const DotenvPlugin = require("./DotenvPlugin");
+
+			new DotenvPlugin(
+				typeof options.dotenv === "boolean" ? {} : options.dotenv
+			).apply(compiler);
+		}
+
+		let devtool =
+			interception === undefined ? options.devtool : interception.devtool;
+		devtool = Array.isArray(devtool)
+			? devtool
+			: typeof devtool === "string"
+				? [{ type: "all", use: devtool }]
+				: [];
+
+		for (const item of devtool) {
+			const { type, use } = item;
+
+			if (use) {
+				if (use.includes("source-map")) {
+					const hidden = use.includes("hidden");
+					const inline = use.includes("inline");
+					const evalWrapped = use.includes("eval");
+					const cheap = use.includes("cheap");
+					const moduleMaps = use.includes("module");
+					const noSources = use.includes("nosources");
+					const debugIds = use.includes("debugids");
+					const Plugin = evalWrapped
+						? require("./EvalSourceMapDevToolPlugin")
+						: require("./SourceMapDevToolPlugin");
+					const assetExt =
+						type === "javascript"
+							? /\.((c|m)?js)($|\?)/i
+							: type === "css"
+								? /\.(css)($|\?)/i
+								: /\.((c|m)?js|css)($|\?)/i;
+
+					new Plugin({
+						test: evalWrapped ? undefined : assetExt,
+						filename: inline ? null : options.output.sourceMapFilename,
+						moduleFilenameTemplate:
+							options.output.devtoolModuleFilenameTemplate,
+						fallbackModuleFilenameTemplate:
+							options.output.devtoolFallbackModuleFilenameTemplate,
+						append: hidden ? false : undefined,
+						module: moduleMaps ? true : !cheap,
+						columns: !cheap,
+						noSources,
+						namespace: options.output.devtoolNamespace,
+						debugIds
+					}).apply(compiler);
+				} else if (use.includes("eval")) {
+					const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
+
+					new EvalDevToolModulePlugin({
+						moduleFilenameTemplate:
+							options.output.devtoolModuleFilenameTemplate,
+						namespace: options.output.devtoolNamespace
+					}).apply(compiler);
+				}
+			}
+		}
+
+		new JavascriptModulesPlugin().apply(compiler);
+		new JsonModulesPlugin().apply(compiler);
+		new AssetModulesPlugin({
+			sideEffectFree: options.experiments.futureDefaults
+		}).apply(compiler);
+
+		if (!options.experiments.outputModule) {
+			if (options.output.module) {
+				throw new Error(
+					"'output.module: true' is only allowed when 'experiments.outputModule' is enabled"
+				);
+			}
+			if (options.output.enabledLibraryTypes.includes("module")) {
+				throw new Error(
+					"library type \"module\" is only allowed when 'experiments.outputModule' is enabled"
+				);
+			}
+			if (options.output.enabledLibraryTypes.includes("modern-module")) {
+				throw new Error(
+					"library type \"modern-module\" is only allowed when 'experiments.outputModule' is enabled"
+				);
+			}
+			if (
+				options.externalsType === "module" ||
+				options.externalsType === "module-import"
+			) {
+				throw new Error(
+					"'externalsType: \"module\"' is only allowed when 'experiments.outputModule' is enabled"
+				);
+			}
+		}
+
+		if (options.experiments.syncWebAssembly) {
+			const WebAssemblyModulesPlugin = require("./wasm-sync/WebAssemblyModulesPlugin");
+
+			new WebAssemblyModulesPlugin({
+				mangleImports: options.optimization.mangleWasmImports
+			}).apply(compiler);
+		}
+
+		if (options.experiments.asyncWebAssembly) {
+			const AsyncWebAssemblyModulesPlugin = require("./wasm-async/AsyncWebAssemblyModulesPlugin");
+
+			new AsyncWebAssemblyModulesPlugin({
+				mangleImports: options.optimization.mangleWasmImports
+			}).apply(compiler);
+		}
+
+		if (options.experiments.css) {
+			const CssModulesPlugin = require("./css/CssModulesPlugin");
+
+			new CssModulesPlugin().apply(compiler);
+		}
+
+		if (options.experiments.html) {
+			const HtmlModulesPlugin = require("./html/HtmlModulesPlugin");
+
+			new HtmlModulesPlugin().apply(compiler);
+		}
+
+		if (options.experiments.typescript) {
+			const TypeScriptPlugin = require("./typescript/TypeScriptPlugin");
+
+			new TypeScriptPlugin().apply(compiler);
+		}
+
+		if (options.experiments.lazyCompilation) {
+			const LazyCompilationPlugin = require("./hmr/LazyCompilationPlugin");
+
+			const lazyOptions =
+				typeof options.experiments.lazyCompilation === "object"
+					? options.experiments.lazyCompilation
+					: {};
+			const isUniversalTarget =
+				options.output.module &&
+				compiler.platform.node === null &&
+				compiler.platform.web === null;
+
+			if (isUniversalTarget) {
+				const emitter = require.resolve("../hot/emitter-event-target.js");
+
+				const NormalModuleReplacementPlugin = require("./NormalModuleReplacementPlugin");
+
+				// Override emitter that using `EventEmitter` to `EventTarget`
+				// TODO webpack 6 - migrate to `EventTarget` by default
+				new NormalModuleReplacementPlugin(/emitter(\.js)?$/, (result) => {
+					if (
+						/webpack[/\\]hot|webpack-dev-server[/\\]client|webpack-hot-middleware[/\\]client/.test(
+							result.context
+						)
+					) {
+						result.request = emitter;
+					}
+
+					return result;
+				}).apply(compiler);
+			}
+
+			const backend = require.resolve(
+				isUniversalTarget
+					? "../hot/lazy-compilation-universal.js"
+					: `../hot/lazy-compilation-${
+							options.externalsPresets.node ? "node" : "web"
+						}.js`
+			);
+
+			new LazyCompilationPlugin({
+				backend:
+					typeof lazyOptions.backend === "function"
+						? lazyOptions.backend
+						: require("./hmr/lazyCompilationBackend")({
+								...lazyOptions.backend,
+								client:
+									(lazyOptions.backend && lazyOptions.backend.client) || backend
+							}),
+				entries: !lazyOptions || lazyOptions.entries !== false,
+				imports: !lazyOptions || lazyOptions.imports !== false,
+				test: (lazyOptions && lazyOptions.test) || undefined
+			}).apply(compiler);
+		}
+
+		if (options.experiments.buildHttp) {
+			const HttpUriPlugin = require("./schemes/HttpUriPlugin");
+
+			const httpOptions = options.experiments.buildHttp;
+			new HttpUriPlugin(httpOptions).apply(compiler);
+		}
+
+		if (
+			!(
+				/** @type {typeof JavascriptParser & { __importPhasesExtended?: true }} */
+				(JavascriptParser).__importPhasesExtended
+			) &&
+			(options.experiments.deferImport || options.experiments.sourceImport)
+		) {
+			const importPhases = require("acorn-import-phases");
+
+			JavascriptParser.extend(importPhases({ source: true, defer: true }));
+			/** @type {typeof JavascriptParser & { __importPhasesExtended?: true }} */
+			(JavascriptParser).__importPhasesExtended = true;
+		}
+
+		new EntryOptionPlugin().apply(compiler);
+		compiler.hooks.entryOption.call(options.context, options.entry);
+
+		new RuntimePlugin().apply(compiler);
+
+		new InferAsyncModulesPlugin().apply(compiler);
+
+		new DataUriPlugin().apply(compiler);
+		new FileUriPlugin().apply(compiler);
+
+		new CompatibilityPlugin().apply(compiler);
+		new HarmonyModulesPlugin({
+			deferImport: options.experiments.deferImport
+		}).apply(compiler);
+		if (options.amd !== false) {
+			const AMDPlugin = require("./dependencies/AMDPlugin");
+			const RequireJsStuffPlugin = require("./dependencies/RequireJsStuffPlugin");
+
+			new AMDPlugin(options.amd || {}).apply(compiler);
+			new RequireJsStuffPlugin().apply(compiler);
+		}
+		new CommonJsPlugin().apply(compiler);
+		new LoaderPlugin().apply(compiler);
+		new NodeStuffPlugin({
+			global: options.node ? options.node.global : false,
+			__dirname: options.node ? options.node.__dirname : false,
+			__filename: options.node ? options.node.__filename : false
+		}).apply(compiler);
+		new APIPlugin().apply(compiler);
+		new ExportsInfoApiPlugin().apply(compiler);
+		new WebpackIsIncludedPlugin().apply(compiler);
+		new ConstPlugin().apply(compiler);
+		new UseStrictPlugin().apply(compiler);
+		new RequireIncludePlugin().apply(compiler);
+		new RequireEnsurePlugin().apply(compiler);
+		new RequireContextPlugin().apply(compiler);
+		new ImportPlugin().apply(compiler);
+		new ImportMetaContextPlugin().apply(compiler);
+		new SystemPlugin().apply(compiler);
+		new ImportMetaPlugin().apply(compiler);
+		new URLPlugin().apply(compiler);
+		new WorkerPlugin(
+			options.output.workerChunkLoading,
+			options.output.workerWasmLoading,
+			options.output.module,
+			options.output.workerPublicPath
+		).apply(compiler);
+
+		new DefaultStatsFactoryPlugin().apply(compiler);
+		new DefaultStatsPresetPlugin().apply(compiler);
+		new DefaultStatsPrinterPlugin().apply(compiler);
+
+		new JavascriptMetaInfoPlugin().apply(compiler);
+
+		if (typeof options.mode !== "string") {
+			const WarnNoModeSetPlugin = require("./WarnNoModeSetPlugin");
+
+			new WarnNoModeSetPlugin().apply(compiler);
+		}
+
+		const EnsureChunkConditionsPlugin = require("./optimize/EnsureChunkConditionsPlugin");
+
+		new EnsureChunkConditionsPlugin().apply(compiler);
+		if (options.optimization.removeAvailableModules) {
+			const RemoveParentModulesPlugin = require("./optimize/RemoveParentModulesPlugin");
+
+			new RemoveParentModulesPlugin().apply(compiler);
+		}
+		if (options.optimization.removeEmptyChunks) {
+			const RemoveEmptyChunksPlugin = require("./optimize/RemoveEmptyChunksPlugin");
+
+			new RemoveEmptyChunksPlugin().apply(compiler);
+		}
+		if (options.optimization.mergeDuplicateChunks) {
+			const MergeDuplicateChunksPlugin = require("./optimize/MergeDuplicateChunksPlugin");
+
+			new MergeDuplicateChunksPlugin().apply(compiler);
+		}
+		if (options.optimization.flagIncludedChunks) {
+			const FlagIncludedChunksPlugin = require("./optimize/FlagIncludedChunksPlugin");
+
+			new FlagIncludedChunksPlugin().apply(compiler);
+		}
+		if (options.optimization.sideEffects) {
+			const SideEffectsFlagPlugin = require("./optimize/SideEffectsFlagPlugin");
+
+			new SideEffectsFlagPlugin(
+				options.optimization.sideEffects === true
+			).apply(compiler);
+		}
+		if (options.optimization.providedExports) {
+			new FlagDependencyExportsPlugin().apply(compiler);
+		}
+		if (options.optimization.usedExports) {
+			const FlagDependencyUsagePlugin = require("./FlagDependencyUsagePlugin");
+
+			new FlagDependencyUsagePlugin(
+				options.optimization.usedExports === "global"
+			).apply(compiler);
+		}
+		if (options.optimization.innerGraph) {
+			const InnerGraphPlugin = require("./optimize/InnerGraphPlugin");
+
+			new InnerGraphPlugin().apply(compiler);
+		}
+		if (options.optimization.mangleExports) {
+			const MangleExportsPlugin = require("./optimize/MangleExportsPlugin");
+
+			new MangleExportsPlugin(
+				options.optimization.mangleExports !== "size"
+			).apply(compiler);
+		}
+		if (options.optimization.concatenateModules) {
+			const ModuleConcatenationPlugin = require("./optimize/ModuleConcatenationPlugin");
+
+			new ModuleConcatenationPlugin().apply(compiler);
+		}
+		if (options.optimization.splitChunks) {
+			const SplitChunksPlugin = require("./optimize/SplitChunksPlugin");
+
+			new SplitChunksPlugin(options.optimization.splitChunks).apply(compiler);
+		}
+		if (options.optimization.runtimeChunk) {
+			const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin");
+
+			new RuntimeChunkPlugin(options.optimization.runtimeChunk).apply(compiler);
+		}
+		if (!options.optimization.emitOnErrors) {
+			const NoEmitOnErrorsPlugin = require("./NoEmitOnErrorsPlugin");
+
+			new NoEmitOnErrorsPlugin().apply(compiler);
+		}
+		if (options.optimization.realContentHash) {
+			const RealContentHashPlugin = require("./optimize/RealContentHashPlugin");
+
+			new RealContentHashPlugin({
+				hashFunction:
+					/** @type {NonNullable<WebpackOptions["output"]["hashFunction"]>} */
+					(options.output.hashFunction),
+				hashDigest:
+					/** @type {NonNullable<WebpackOptions["output"]["hashDigest"]>} */
+					(options.output.hashDigest)
+			}).apply(compiler);
+		}
+		if (options.optimization.checkWasmTypes) {
+			const WasmFinalizeExportsPlugin = require("./wasm-sync/WasmFinalizeExportsPlugin");
+
+			new WasmFinalizeExportsPlugin().apply(compiler);
+		}
+		const moduleIds = options.optimization.moduleIds;
+		if (moduleIds) {
+			switch (moduleIds) {
+				case "natural": {
+					const NaturalModuleIdsPlugin = require("./ids/NaturalModuleIdsPlugin");
+
+					new NaturalModuleIdsPlugin().apply(compiler);
+					break;
+				}
+				case "named": {
+					const NamedModuleIdsPlugin = require("./ids/NamedModuleIdsPlugin");
+
+					new NamedModuleIdsPlugin().apply(compiler);
+					break;
+				}
+				case "hashed": {
+					const WarnDeprecatedOptionPlugin = require("./WarnDeprecatedOptionPlugin");
+					const HashedModuleIdsPlugin = require("./ids/HashedModuleIdsPlugin");
+
+					new WarnDeprecatedOptionPlugin(
+						"optimization.moduleIds",
+						"hashed",
+						"deterministic"
+					).apply(compiler);
+					new HashedModuleIdsPlugin({
+						hashFunction: options.output.hashFunction
+					}).apply(compiler);
+					break;
+				}
+				case "deterministic": {
+					const DeterministicModuleIdsPlugin = require("./ids/DeterministicModuleIdsPlugin");
+
+					new DeterministicModuleIdsPlugin().apply(compiler);
+					break;
+				}
+				case "size": {
+					const OccurrenceModuleIdsPlugin = require("./ids/OccurrenceModuleIdsPlugin");
+
+					new OccurrenceModuleIdsPlugin({
+						prioritiseInitial: true
+					}).apply(compiler);
+					break;
+				}
+				default:
+					throw new Error(
+						`webpack bug: moduleIds: ${moduleIds} is not implemented`
+					);
+			}
+		}
+		const chunkIds = options.optimization.chunkIds;
+		if (chunkIds) {
+			switch (chunkIds) {
+				case "natural": {
+					const NaturalChunkIdsPlugin = require("./ids/NaturalChunkIdsPlugin");
+
+					new NaturalChunkIdsPlugin().apply(compiler);
+					break;
+				}
+				case "named": {
+					const NamedChunkIdsPlugin = require("./ids/NamedChunkIdsPlugin");
+
+					new NamedChunkIdsPlugin().apply(compiler);
+					break;
+				}
+				case "deterministic": {
+					const DeterministicChunkIdsPlugin = require("./ids/DeterministicChunkIdsPlugin");
+
+					new DeterministicChunkIdsPlugin().apply(compiler);
+					break;
+				}
+				case "size": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const OccurrenceChunkIdsPlugin = require("./ids/OccurrenceChunkIdsPlugin");
+
+					new OccurrenceChunkIdsPlugin({
+						prioritiseInitial: true
+					}).apply(compiler);
+					break;
+				}
+				case "total-size": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const OccurrenceChunkIdsPlugin = require("./ids/OccurrenceChunkIdsPlugin");
+
+					new OccurrenceChunkIdsPlugin({
+						prioritiseInitial: false
+					}).apply(compiler);
+					break;
+				}
+				default:
+					throw new Error(
+						`webpack bug: chunkIds: ${chunkIds} is not implemented`
+					);
+			}
+		}
+		if (options.optimization.nodeEnv) {
+			const DefinePlugin = require("./DefinePlugin");
+
+			const defValue = JSON.stringify(options.optimization.nodeEnv);
+
+			new DefinePlugin({
+				"process.env.NODE_ENV": defValue,
+				"import.meta.env.NODE_ENV": defValue
+			}).apply(compiler);
+		}
+		if (options.optimization.minimize) {
+			for (const minimizer of options.optimization.minimizer) {
+				if (typeof minimizer === "function") {
+					/** @type {WebpackPluginFunction} */
+					(minimizer).call(compiler, compiler);
+				} else if (minimizer !== "..." && minimizer) {
+					minimizer.apply(compiler);
+				}
+			}
+		}
+
+		if (options.performance) {
+			const SizeLimitsPlugin = require("./performance/SizeLimitsPlugin");
+
+			new SizeLimitsPlugin(options.performance).apply(compiler);
+		}
+
+		new TemplatedPathPlugin().apply(compiler);
+
+		new RecordIdsPlugin({
+			portableIds: options.optimization.portableRecords
+		}).apply(compiler);
+
+		new WarnCaseSensitiveModulesPlugin().apply(compiler);
+
+		const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin");
+
+		new AddManagedPathsPlugin(
+			/** @type {NonNullable<WebpackOptions["snapshot"]["managedPaths"]>} */
+			(options.snapshot.managedPaths),
+			/** @type {NonNullable<WebpackOptions["snapshot"]["managedPaths"]>} */
+			(options.snapshot.immutablePaths),
+			/** @type {NonNullable<WebpackOptions["snapshot"]["managedPaths"]>} */
+			(options.snapshot.unmanagedPaths)
+		).apply(compiler);
+
+		if (options.cache && typeof options.cache === "object") {
+			const cacheOptions = options.cache;
+			switch (cacheOptions.type) {
+				case "memory": {
+					if (Number.isFinite(cacheOptions.maxGenerations)) {
+						// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+						const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin");
+
+						new MemoryWithGcCachePlugin({
+							maxGenerations:
+								/** @type {number} */
+								(cacheOptions.maxGenerations)
+						}).apply(compiler);
+					} else {
+						// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+						const MemoryCachePlugin = require("./cache/MemoryCachePlugin");
+
+						new MemoryCachePlugin().apply(compiler);
+					}
+					if (cacheOptions.cacheUnaffected) {
+						if (!options.experiments.cacheUnaffected) {
+							throw new Error(
+								"'cache.cacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
+							);
+						}
+						compiler.moduleMemCaches = new Map();
+					}
+					break;
+				}
+				case "filesystem": {
+					const AddBuildDependenciesPlugin = require("./cache/AddBuildDependenciesPlugin");
+
+					for (const key in cacheOptions.buildDependencies) {
+						const list = cacheOptions.buildDependencies[key];
+						new AddBuildDependenciesPlugin(list).apply(compiler);
+					}
+					if (!Number.isFinite(cacheOptions.maxMemoryGenerations)) {
+						// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+						const MemoryCachePlugin = require("./cache/MemoryCachePlugin");
+
+						new MemoryCachePlugin().apply(compiler);
+					} else if (cacheOptions.maxMemoryGenerations !== 0) {
+						// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+						const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin");
+
+						new MemoryWithGcCachePlugin({
+							maxGenerations:
+								/** @type {number} */
+								(cacheOptions.maxMemoryGenerations)
+						}).apply(compiler);
+					}
+					if (cacheOptions.memoryCacheUnaffected) {
+						if (!options.experiments.cacheUnaffected) {
+							throw new Error(
+								"'cache.memoryCacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
+							);
+						}
+						compiler.moduleMemCaches = new Map();
+					}
+					switch (cacheOptions.store) {
+						case "pack": {
+							const IdleFileCachePlugin = require("./cache/IdleFileCachePlugin");
+							const PackFileCacheStrategy = require("./cache/PackFileCacheStrategy");
+
+							new IdleFileCachePlugin(
+								new PackFileCacheStrategy({
+									compiler,
+									fs:
+										/** @type {IntermediateFileSystem} */
+										(compiler.intermediateFileSystem),
+									context: options.context,
+									cacheLocation:
+										/** @type {string} */
+										(cacheOptions.cacheLocation),
+									version: /** @type {string} */ (cacheOptions.version),
+									logger: compiler.getInfrastructureLogger(
+										"webpack.cache.PackFileCacheStrategy"
+									),
+									snapshot: options.snapshot,
+									maxAge: /** @type {number} */ (cacheOptions.maxAge),
+									profile: cacheOptions.profile,
+									allowCollectingMemory: cacheOptions.allowCollectingMemory,
+									compression: cacheOptions.compression,
+									readonly: cacheOptions.readonly
+								}),
+								/** @type {number} */
+								(cacheOptions.idleTimeout),
+								/** @type {number} */
+								(cacheOptions.idleTimeoutForInitialStore),
+								/** @type {number} */
+								(cacheOptions.idleTimeoutAfterLargeChanges)
+							).apply(compiler);
+							break;
+						}
+						default:
+							throw new Error("Unhandled value for cache.store");
+					}
+					break;
+				}
+				default:
+					// @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339)
+					throw new Error(`Unknown cache type ${cacheOptions.type}`);
+			}
+		}
+		new ResolverCachePlugin().apply(compiler);
+
+		if (options.ignoreWarnings && options.ignoreWarnings.length > 0) {
+			const IgnoreWarningsPlugin = require("./IgnoreWarningsPlugin");
+
+			new IgnoreWarningsPlugin(options.ignoreWarnings).apply(compiler);
+		}
+
+		compiler.hooks.afterPlugins.call(compiler);
+		if (!compiler.inputFileSystem) {
+			throw new Error("No input filesystem provided");
+		}
+		compiler.resolverFactory.hooks.resolveOptions
+			.for("normal")
+			.tap(CLASS_NAME, (resolveOptions) => {
+				resolveOptions = cleverMerge(options.resolve, resolveOptions);
+				resolveOptions.fileSystem =
+					/** @type {InputFileSystem} */
+					(compiler.inputFileSystem);
+				return resolveOptions;
+			});
+		compiler.resolverFactory.hooks.resolveOptions
+			.for("context")
+			.tap(CLASS_NAME, (resolveOptions) => {
+				resolveOptions = cleverMerge(options.resolve, resolveOptions);
+				resolveOptions.fileSystem =
+					/** @type {InputFileSystem} */
+					(compiler.inputFileSystem);
+				resolveOptions.resolveToContext = true;
+				return resolveOptions;
+			});
+		compiler.resolverFactory.hooks.resolveOptions
+			.for("loader")
+			.tap(CLASS_NAME, (resolveOptions) => {
+				resolveOptions = cleverMerge(options.resolveLoader, resolveOptions);
+				resolveOptions.fileSystem =
+					/** @type {InputFileSystem} */
+					(compiler.inputFileSystem);
+				return resolveOptions;
+			});
+		compiler.hooks.afterResolvers.call(compiler);
+		return options;
+	}
+}
+
+module.exports = WebpackOptionsApply;
Index: frontend/node_modules/webpack/lib/WebpackOptionsDefaulter.js
===================================================================
--- frontend/node_modules/webpack/lib/WebpackOptionsDefaulter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/WebpackOptionsDefaulter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,27 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { applyWebpackOptionsDefaults } = require("./config/defaults");
+const { getNormalizedWebpackOptions } = require("./config/normalization");
+
+/** @typedef {import("./config/normalization").WebpackOptions} WebpackOptions */
+/** @typedef {import("./config/normalization").WebpackOptionsNormalized} WebpackOptionsNormalized */
+
+class WebpackOptionsDefaulter {
+	/**
+	 * Returns normalized webpack options.
+	 * @param {WebpackOptions} options webpack options
+	 * @returns {WebpackOptionsNormalized} normalized webpack options
+	 */
+	process(options) {
+		const normalizedOptions = getNormalizedWebpackOptions(options);
+		applyWebpackOptionsDefaults(normalizedOptions);
+		return normalizedOptions;
+	}
+}
+
+module.exports = WebpackOptionsDefaulter;
Index: frontend/node_modules/webpack/lib/asset/AssetBytesGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetBytesGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetBytesGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,182 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const ConcatenationScope = require("../ConcatenationScope");
+const Generator = require("../Generator");
+const {
+	ASSET_URL_TYPE,
+	ASSET_URL_TYPES,
+	CSS_TYPE,
+	HTML_TYPE,
+	JAVASCRIPT_AND_ASSET_URL_TYPES,
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES,
+	NO_TYPES
+} = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+class AssetSourceGenerator extends Generator {
+	/**
+	 * Creates an instance of AssetSourceGenerator.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 */
+	constructor(moduleGraph) {
+		super();
+
+		this._moduleGraph = moduleGraph;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(
+		module,
+		{ type, concatenationScope, getData, runtimeTemplate, runtimeRequirements }
+	) {
+		const originalSource = module.originalSource();
+		const data = getData ? getData() : undefined;
+
+		switch (type) {
+			case JAVASCRIPT_TYPE: {
+				if (!originalSource) {
+					return new RawSource("");
+				}
+
+				const encodedSource = originalSource.buffer().toString("base64");
+
+				runtimeRequirements.add(RuntimeGlobals.requireScope);
+				runtimeRequirements.add(RuntimeGlobals.toBinary);
+
+				/** @type {string} */
+				let sourceContent;
+				if (concatenationScope) {
+					concatenationScope.registerNamespaceExport(
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					);
+					sourceContent = `${runtimeTemplate.renderConst()} ${
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					} = ${RuntimeGlobals.toBinary}(${JSON.stringify(encodedSource)});`;
+				} else {
+					runtimeRequirements.add(RuntimeGlobals.module);
+					sourceContent = `${module.moduleArgument}.exports = ${RuntimeGlobals.toBinary}(${JSON.stringify(
+						encodedSource
+					)});`;
+				}
+				return new RawSource(sourceContent);
+			}
+			case ASSET_URL_TYPE: {
+				if (!originalSource) {
+					return null;
+				}
+
+				const encodedSource = originalSource.buffer().toString("base64");
+
+				if (data) {
+					data.set("url", {
+						[type]: `data:application/octet-stream;base64,${encodedSource}`
+					});
+				}
+				return null;
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		switch (generateContext.type) {
+			case JAVASCRIPT_TYPE: {
+				return new RawSource(
+					`throw new Error(${JSON.stringify(error.message)});`
+				);
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		return undefined;
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		/** @type {Set<string>} */
+		const sourceTypes = new Set();
+		const connections = this._moduleGraph.getIncomingConnections(module);
+
+		for (const connection of connections) {
+			if (!connection.originModule) {
+				continue;
+			}
+
+			sourceTypes.add(connection.originModule.type.split("/")[0]);
+		}
+
+		if (sourceTypes.size > 0) {
+			if (
+				sourceTypes.has(JAVASCRIPT_TYPE) &&
+				(sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE))
+			) {
+				return JAVASCRIPT_AND_ASSET_URL_TYPES;
+			} else if (sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE)) {
+				return ASSET_URL_TYPES;
+			}
+			return JAVASCRIPT_TYPES;
+		}
+
+		return NO_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const originalSource = module.originalSource();
+
+		if (!originalSource) {
+			return 0;
+		}
+
+		// Example: m.exports="abcd"
+		return originalSource.size() + 12;
+	}
+}
+
+module.exports = AssetSourceGenerator;
Index: frontend/node_modules/webpack/lib/asset/AssetBytesParser.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetBytesParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetBytesParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const Parser = require("../Parser");
+
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+class AssetBytesParser extends Parser {
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (typeof source === "object" && !Buffer.isBuffer(source)) {
+			throw new Error("AssetBytesParser doesn't accept preparsed AST");
+		}
+		const { module } = state;
+		/** @type {BuildInfo} */
+		(module.buildInfo).strict = true;
+		/** @type {BuildMeta} */
+		(module.buildMeta).exportsType = "default";
+		/** @type {BuildMeta} */
+		(state.module.buildMeta).defaultObject = false;
+
+		return state;
+	}
+}
+
+module.exports = AssetBytesParser;
Index: frontend/node_modules/webpack/lib/asset/AssetGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,848 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const path = require("path");
+const { RawSource } = require("webpack-sources");
+const ConcatenationScope = require("../ConcatenationScope");
+const Generator = require("../Generator");
+const {
+	ASSET_AND_ASSET_URL_TYPES,
+	ASSET_AND_JAVASCRIPT_AND_ASSET_URL_TYPES,
+	ASSET_AND_JAVASCRIPT_TYPES,
+	ASSET_TYPES,
+	ASSET_URL_TYPE,
+	ASSET_URL_TYPES,
+	CSS_TYPE,
+	HTML_TYPE,
+	JAVASCRIPT_AND_ASSET_URL_TYPES,
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES,
+	NO_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { ASSET_MODULE_TYPE } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const CssUrlDependency = require("../dependencies/CssUrlDependency");
+const createHash = require("../util/createHash");
+const { makePathsRelative } = require("../util/identifier");
+const memoize = require("../util/memoize");
+const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
+const { updateHashFromSource } = require("../util/source");
+
+const getMimeTypes = memoize(() => require("../util/mimeTypes"));
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorDataUrlOptions} AssetGeneratorDataUrlOptions */
+/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
+/** @typedef {import("../../declarations/WebpackOptions").AssetModuleFilename} AssetModuleFilename */
+/** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */
+/** @typedef {import("../../declarations/WebpackOptions").AssetResourceGeneratorOptions} AssetResourceGeneratorOptions */
+/** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").NameForCondition} NameForCondition */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {(source: string | Buffer, context: { filename: string, module: Module }) => string} DataUrlFunction */
+
+/**
+ * Merges maybe arrays.
+ * @template T
+ * @template U
+ * @param {null | string | T[] | Set<T> | undefined} a a
+ * @param {null | string | U[] | Set<U> | undefined} b b
+ * @returns {T[] & U[]} array
+ */
+const mergeMaybeArrays = (a, b) => {
+	/** @type {Set<T | U | null | undefined | string | Set<T> | Set<U>>} */
+	const set = new Set();
+	if (Array.isArray(a)) for (const item of a) set.add(item);
+	else set.add(a);
+	if (Array.isArray(b)) for (const item of b) set.add(item);
+	else set.add(b);
+	return /** @type {T[] & U[]} */ ([.../** @type {Set<T | U>} */ (set)]);
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @param {AssetInfo} a a
+ * @param {AssetInfo} b b
+ * @returns {AssetInfo} object
+ */
+const mergeAssetInfo = (a, b) => {
+	/** @type {AssetInfo} */
+	const result = { ...a, ...b };
+	for (const key of Object.keys(a)) {
+		if (key in b) {
+			if (a[key] === b[key]) continue;
+			switch (key) {
+				case "fullhash":
+				case "chunkhash":
+				case "modulehash":
+				case "contenthash":
+					result[key] = mergeMaybeArrays(a[key], b[key]);
+					break;
+				case "immutable":
+				case "development":
+				case "hotModuleReplacement":
+				case "javascriptModule":
+					result[key] = a[key] || b[key];
+					break;
+				case "related":
+					result[key] = mergeRelatedInfo(
+						/** @type {NonNullable<AssetInfo["related"]>} */
+						(a[key]),
+						/** @type {NonNullable<AssetInfo["related"]>} */
+						(b[key])
+					);
+					break;
+				default:
+					throw new Error(`Can't handle conflicting asset info for ${key}`);
+			}
+		}
+	}
+	return result;
+};
+
+/**
+ * Merges related info.
+ * @param {NonNullable<AssetInfo["related"]>} a a
+ * @param {NonNullable<AssetInfo["related"]>} b b
+ * @returns {NonNullable<AssetInfo["related"]>} object
+ */
+const mergeRelatedInfo = (a, b) => {
+	const result = { ...a, ...b };
+	for (const key of Object.keys(a)) {
+		if (key in b) {
+			if (a[key] === b[key]) continue;
+			result[key] = mergeMaybeArrays(a[key], b[key]);
+		}
+	}
+	return result;
+};
+
+/**
+ * Encodes the provided encoding.
+ * @param {"base64" | false} encoding encoding
+ * @param {Source} source source
+ * @returns {string} encoded data
+ */
+const encodeDataUri = (encoding, source) => {
+	/** @type {string | undefined} */
+	let encodedContent;
+
+	switch (encoding) {
+		case "base64": {
+			encodedContent = source.buffer().toString("base64");
+			break;
+		}
+		case false: {
+			const content = source.source();
+
+			if (typeof content !== "string") {
+				encodedContent = content.toString("utf8");
+			}
+
+			encodedContent = encodeURIComponent(
+				/** @type {string} */
+				(encodedContent)
+			).replace(
+				/[!'()*]/g,
+				(character) =>
+					`%${/** @type {number} */ (character.codePointAt(0)).toString(16)}`
+			);
+			break;
+		}
+		default:
+			throw new Error(`Unsupported encoding '${encoding}'`);
+	}
+
+	return encodedContent;
+};
+
+/**
+ * Decodes data uri content.
+ * @param {"base64" | false} encoding encoding
+ * @param {string} content content
+ * @returns {Buffer} decoded content
+ */
+const decodeDataUriContent = (encoding, content) => {
+	const isBase64 = encoding === "base64";
+
+	if (isBase64) {
+		return Buffer.from(content, "base64");
+	}
+
+	// If we can't decode return the original body
+	try {
+		return Buffer.from(decodeURIComponent(content), "ascii");
+	} catch (_) {
+		return Buffer.from(content, "ascii");
+	}
+};
+
+const DEFAULT_ENCODING = "base64";
+
+class AssetGenerator extends Generator {
+	/**
+	 * Creates an instance of AssetGenerator.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url
+	 * @param {AssetModuleFilename=} filename override for output.assetModuleFilename
+	 * @param {RawPublicPath=} publicPath override for output.assetModulePublicPath
+	 * @param {AssetModuleOutputPath=} outputPath the output path for the emitted file which is not included in the runtime import
+	 * @param {boolean=} emit generate output asset
+	 */
+	constructor(
+		moduleGraph,
+		dataUrlOptions,
+		filename,
+		publicPath,
+		outputPath,
+		emit
+	) {
+		super();
+		/** @type {AssetGeneratorOptions["dataUrl"] | undefined} */
+		this.dataUrlOptions = dataUrlOptions;
+		/** @type {AssetModuleFilename | undefined} */
+		this.filename = filename;
+		/** @type {RawPublicPath | undefined} */
+		this.publicPath = publicPath;
+		/** @type {AssetModuleOutputPath | undefined} */
+		this.outputPath = outputPath;
+		/** @type {boolean | undefined} */
+		this.emit = emit;
+		/** @type {ModuleGraph} */
+		this._moduleGraph = moduleGraph;
+	}
+
+	/**
+	 * Gets source file name.
+	 * @param {NormalModule} module module
+	 * @param {RuntimeTemplate} runtimeTemplate runtime template
+	 * @returns {string} source file name
+	 */
+	static getSourceFileName(module, runtimeTemplate) {
+		return makePathsRelative(
+			runtimeTemplate.compilation.compiler.context,
+			/** @type {string} */
+			(module.getResource()),
+			runtimeTemplate.compilation.compiler.root
+		).replace(/^\.\//, "");
+	}
+
+	/**
+	 * Gets full content hash.
+	 * @param {NormalModule} module module
+	 * @param {RuntimeTemplate} runtimeTemplate runtime template
+	 * @returns {[string, string]} return full hash and non-numeric full hash
+	 */
+	static getFullContentHash(module, runtimeTemplate) {
+		const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
+
+		if (runtimeTemplate.outputOptions.hashSalt) {
+			hash.update(runtimeTemplate.outputOptions.hashSalt);
+		}
+
+		const source = module.originalSource();
+
+		if (source) {
+			updateHashFromSource(hash, source);
+		}
+
+		if (module.error) {
+			hash.update(module.error.toString());
+		}
+
+		const fullContentHash = hash.digest(
+			runtimeTemplate.outputOptions.hashDigest
+		);
+
+		const contentHash = nonNumericOnlyHash(
+			fullContentHash,
+			runtimeTemplate.outputOptions.hashDigestLength
+		);
+
+		return [fullContentHash, contentHash];
+	}
+
+	/**
+	 * Gets filename with info.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {Pick<AssetResourceGeneratorOptions, "filename" | "outputPath">} generatorOptions generator options
+	 * @param {{ runtime: RuntimeSpec, runtimeTemplate: RuntimeTemplate, chunkGraph: ChunkGraph }} generateContext context for generate
+	 * @param {string} contentHash the content hash
+	 * @returns {{ filename: string, originalFilename: string, assetInfo: AssetInfo }} info
+	 */
+	static getFilenameWithInfo(
+		module,
+		generatorOptions,
+		{ runtime, runtimeTemplate, chunkGraph },
+		contentHash
+	) {
+		const assetModuleFilename =
+			generatorOptions.filename ||
+			runtimeTemplate.outputOptions.assetModuleFilename;
+
+		const sourceFilename = AssetGenerator.getSourceFileName(
+			module,
+			runtimeTemplate
+		);
+		let { path: filename, info: assetInfo } =
+			runtimeTemplate.compilation.getAssetPathWithInfo(assetModuleFilename, {
+				module,
+				runtime,
+				filename: sourceFilename,
+				chunkGraph,
+				contentHash
+			});
+
+		const originalFilename = filename;
+
+		if (generatorOptions.outputPath) {
+			const { path: outputPath, info } =
+				runtimeTemplate.compilation.getAssetPathWithInfo(
+					generatorOptions.outputPath,
+					{
+						module,
+						runtime,
+						filename: sourceFilename,
+						chunkGraph,
+						contentHash
+					}
+				);
+			filename = path.posix.join(outputPath, filename);
+			assetInfo = mergeAssetInfo(assetInfo, info);
+		}
+
+		return { originalFilename, filename, assetInfo };
+	}
+
+	/**
+	 * Gets asset path with info.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {Pick<AssetResourceGeneratorOptions, "publicPath">} generatorOptions generator options
+	 * @param {GenerateContext} generateContext context for generate
+	 * @param {string} filename the filename
+	 * @param {AssetInfo} assetInfo the asset info
+	 * @param {string} contentHash the content hash
+	 * @returns {{ assetPath: string, assetInfo: AssetInfo }} asset path and info
+	 */
+	static getAssetPathWithInfo(
+		module,
+		generatorOptions,
+		{ runtime, runtimeTemplate, type, chunkGraph, runtimeRequirements },
+		filename,
+		assetInfo,
+		contentHash
+	) {
+		const sourceFilename = AssetGenerator.getSourceFileName(
+			module,
+			runtimeTemplate
+		);
+
+		/** @type {undefined | string} */
+		let assetPath;
+
+		if (generatorOptions.publicPath !== undefined && type === JAVASCRIPT_TYPE) {
+			const { path, info } = runtimeTemplate.compilation.getAssetPathWithInfo(
+				generatorOptions.publicPath,
+				{
+					module,
+					runtime,
+					filename: sourceFilename,
+					chunkGraph,
+					contentHash
+				}
+			);
+			assetInfo = mergeAssetInfo(assetInfo, info);
+			assetPath = JSON.stringify(path + filename);
+		} else if (
+			generatorOptions.publicPath !== undefined &&
+			type === ASSET_URL_TYPE
+		) {
+			const { path, info } = runtimeTemplate.compilation.getAssetPathWithInfo(
+				generatorOptions.publicPath,
+				{
+					module,
+					runtime,
+					filename: sourceFilename,
+					chunkGraph,
+					contentHash
+				}
+			);
+			assetInfo = mergeAssetInfo(assetInfo, info);
+			assetPath = path + filename;
+		} else if (type === JAVASCRIPT_TYPE) {
+			// add __webpack_require__.p
+			runtimeRequirements.add(RuntimeGlobals.publicPath);
+			assetPath = runtimeTemplate.concatenation(
+				{ expr: RuntimeGlobals.publicPath },
+				filename
+			);
+		} else if (type === ASSET_URL_TYPE) {
+			const compilation = runtimeTemplate.compilation;
+			const path =
+				compilation.outputOptions.publicPath === "auto"
+					? CssUrlDependency.PUBLIC_PATH_AUTO
+					: compilation.getAssetPath(compilation.outputOptions.publicPath, {
+							hash:
+								compilation.hash ||
+								`${CssUrlDependency.PUBLIC_PATH_FULL_HASH}0__`,
+							hashWithLength: (length) =>
+								compilation.hash
+									? compilation.hash.slice(0, length)
+									: `${CssUrlDependency.PUBLIC_PATH_FULL_HASH}${length}__`
+						});
+
+			assetPath = path + filename;
+		}
+
+		return {
+			assetPath: /** @type {string} */ (assetPath),
+			assetInfo: { sourceFilename, ...assetInfo }
+		};
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		return undefined;
+	}
+
+	/**
+	 * Returns mime type.
+	 * @param {NormalModule} module module
+	 * @returns {string} mime type
+	 */
+	getMimeType(module) {
+		if (typeof this.dataUrlOptions === "function") {
+			throw new Error(
+				"This method must not be called when dataUrlOptions is a function"
+			);
+		}
+
+		/** @type {string | undefined} */
+		let mimeType =
+			/** @type {AssetGeneratorDataUrlOptions} */
+			(this.dataUrlOptions).mimetype;
+		if (mimeType === undefined) {
+			const ext = path.extname(
+				/** @type {NameForCondition} */
+				(module.nameForCondition())
+			);
+			if (
+				module.resourceResolveData &&
+				module.resourceResolveData.mimetype !== undefined
+			) {
+				mimeType =
+					module.resourceResolveData.mimetype +
+					module.resourceResolveData.parameters;
+			} else if (ext) {
+				mimeType = getMimeTypes().lookup(ext);
+
+				if (typeof mimeType !== "string") {
+					throw new Error(
+						"DataUrl can't be generated automatically, " +
+							`because there is no mimetype for "${ext}" in mimetype database. ` +
+							'Either pass a mimetype via "generator.mimetype" or ' +
+							'use type: "asset/resource" to create a resource file instead of a DataUrl'
+					);
+				}
+			}
+		}
+
+		if (typeof mimeType !== "string") {
+			throw new Error(
+				"DataUrl can't be generated automatically. " +
+					'Either pass a mimetype via "generator.mimetype" or ' +
+					'use type: "asset/resource" to create a resource file instead of a DataUrl'
+			);
+		}
+
+		return /** @type {string} */ (mimeType);
+	}
+
+	/**
+	 * Generates data uri.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @returns {string} DataURI
+	 */
+	generateDataUri(module) {
+		const source = /** @type {Source} */ (module.originalSource());
+
+		/** @type {string} */
+		let encodedSource;
+
+		if (typeof this.dataUrlOptions === "function") {
+			encodedSource = this.dataUrlOptions.call(null, source.source(), {
+				filename: /** @type {string} */ (module.getResource()),
+				module
+			});
+		} else {
+			let encoding =
+				/** @type {AssetGeneratorDataUrlOptions} */
+				(this.dataUrlOptions).encoding;
+			if (
+				encoding === undefined &&
+				module.resourceResolveData &&
+				module.resourceResolveData.encoding !== undefined
+			) {
+				encoding = module.resourceResolveData.encoding;
+			}
+			if (encoding === undefined) {
+				encoding = DEFAULT_ENCODING;
+			}
+			const mimeType = this.getMimeType(module);
+
+			/** @type {string} */
+			let encodedContent;
+
+			if (
+				module.resourceResolveData &&
+				module.resourceResolveData.encoding === encoding &&
+				decodeDataUriContent(
+					module.resourceResolveData.encoding,
+					/** @type {string} */ (module.resourceResolveData.encodedContent)
+				).equals(source.buffer())
+			) {
+				encodedContent =
+					/** @type {string} */
+					(module.resourceResolveData.encodedContent);
+			} else {
+				encodedContent = encodeDataUri(
+					/** @type {"base64" | false} */ (encoding),
+					source
+				);
+			}
+
+			encodedSource = `data:${mimeType}${
+				encoding ? `;${encoding}` : ""
+			},${encodedContent}`;
+		}
+
+		return encodedSource;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const {
+			type,
+			getData,
+			runtimeTemplate,
+			runtimeRequirements,
+			concatenationScope
+		} = generateContext;
+
+		/** @type {string} */
+		let content;
+
+		const needContent = type === JAVASCRIPT_TYPE || type === ASSET_URL_TYPE;
+		const data = getData ? getData() : undefined;
+
+		if (
+			/** @type {BuildInfo} */
+			(module.buildInfo).dataUrl &&
+			needContent
+		) {
+			const encodedSource = this.generateDataUri(module);
+			content =
+				type === JAVASCRIPT_TYPE
+					? JSON.stringify(encodedSource)
+					: encodedSource;
+
+			if (data) {
+				data.set("url", { ...data.get("url"), [type]: content });
+			}
+		} else {
+			const [fullContentHash, contentHash] = AssetGenerator.getFullContentHash(
+				module,
+				runtimeTemplate
+			);
+
+			if (data) {
+				data.set("fullContentHash", fullContentHash);
+				data.set("contentHash", contentHash);
+			}
+
+			/** @type {BuildInfo} */
+			(module.buildInfo).fullContentHash = fullContentHash;
+
+			const { originalFilename, filename, assetInfo } =
+				AssetGenerator.getFilenameWithInfo(
+					module,
+					{ filename: this.filename, outputPath: this.outputPath },
+					generateContext,
+					contentHash
+				);
+
+			if (data) {
+				data.set("filename", filename);
+			}
+
+			let { assetPath, assetInfo: newAssetInfo } =
+				AssetGenerator.getAssetPathWithInfo(
+					module,
+					{ publicPath: this.publicPath },
+					generateContext,
+					originalFilename,
+					assetInfo,
+					contentHash
+				);
+
+			if (data && (type === JAVASCRIPT_TYPE || type === ASSET_URL_TYPE)) {
+				data.set("url", { ...data.get("url"), [type]: assetPath });
+			}
+
+			if (data) {
+				const oldAssetInfo = data.get("assetInfo");
+
+				if (oldAssetInfo) {
+					newAssetInfo = mergeAssetInfo(oldAssetInfo, newAssetInfo);
+				}
+			}
+
+			if (data) {
+				data.set("assetInfo", newAssetInfo);
+			}
+
+			// Due to code generation caching module.buildInfo.XXX can't used to store such information
+			// It need to be stored in the code generation results instead, where it's cached too
+			// TODO webpack 6 For back-compat reasons we also store in on module.buildInfo
+			/** @type {BuildInfo} */
+			(module.buildInfo).filename = filename;
+
+			/** @type {BuildInfo} */
+			(module.buildInfo).assetInfo = newAssetInfo;
+
+			content = assetPath;
+		}
+
+		if (type === JAVASCRIPT_TYPE) {
+			if (concatenationScope) {
+				concatenationScope.registerNamespaceExport(
+					ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+				);
+
+				return new RawSource(
+					`${runtimeTemplate.renderConst()} ${
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					} = ${content};`
+				);
+			}
+
+			runtimeRequirements.add(RuntimeGlobals.module);
+
+			return new RawSource(`${module.moduleArgument}.exports = ${content};`);
+		} else if (type === ASSET_URL_TYPE) {
+			return null;
+		}
+
+		return /** @type {Source} */ (module.originalSource());
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		switch (generateContext.type) {
+			case "asset": {
+				return new RawSource(error.message);
+			}
+			case JAVASCRIPT_TYPE: {
+				return new RawSource(
+					`throw new Error(${JSON.stringify(error.message)});`
+				);
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		/** @type {Set<string>} */
+		const sourceTypes = new Set();
+		const connections = this._moduleGraph.getIncomingConnections(module);
+
+		for (const connection of connections) {
+			if (!connection.originModule) {
+				continue;
+			}
+
+			sourceTypes.add(connection.originModule.type.split("/")[0]);
+		}
+
+		if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) {
+			if (sourceTypes.size > 0) {
+				if (
+					sourceTypes.has(JAVASCRIPT_TYPE) &&
+					(sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE))
+				) {
+					return JAVASCRIPT_AND_ASSET_URL_TYPES;
+				} else if (sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE)) {
+					return ASSET_URL_TYPES;
+				}
+				return JAVASCRIPT_TYPES;
+			}
+
+			return NO_TYPES;
+		}
+
+		if (sourceTypes.size > 0) {
+			if (
+				sourceTypes.has(JAVASCRIPT_TYPE) &&
+				(sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE))
+			) {
+				return ASSET_AND_JAVASCRIPT_AND_ASSET_URL_TYPES;
+			} else if (sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE)) {
+				return ASSET_AND_ASSET_URL_TYPES;
+			}
+			return ASSET_AND_JAVASCRIPT_TYPES;
+		}
+
+		return ASSET_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		switch (type) {
+			case ASSET_MODULE_TYPE: {
+				const originalSource = module.originalSource();
+
+				if (!originalSource) {
+					return 0;
+				}
+
+				return originalSource.size();
+			}
+			default:
+				if (module.buildInfo && module.buildInfo.dataUrl) {
+					const originalSource = module.originalSource();
+
+					if (!originalSource) {
+						return 0;
+					}
+
+					// roughly for data url
+					// Example: m.exports="data:image/png;base64,ag82/f+2=="
+					// 4/3 = base64 encoding
+					// 34 = ~ data url header + footer + rounding
+					return originalSource.size() * 1.34 + 36;
+				}
+				// it's only estimated so this number is probably fine
+				// Example: m.exports=r.p+"0123456789012345678901.ext"
+				return 42;
+		}
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash that will be modified
+	 * @param {UpdateHashContext} updateHashContext context for updating hash
+	 */
+	updateHash(hash, updateHashContext) {
+		const { module } = updateHashContext;
+
+		if (
+			/** @type {BuildInfo} */
+			(module.buildInfo).dataUrl
+		) {
+			hash.update("data-url");
+			// this.dataUrlOptions as function should be pure and only depend on input source and filename
+			// therefore it doesn't need to be hashed
+			if (typeof this.dataUrlOptions === "function") {
+				const ident = /** @type {{ ident?: string }} */ (this.dataUrlOptions)
+					.ident;
+				if (ident) hash.update(ident);
+			} else {
+				const dataUrlOptions =
+					/** @type {AssetGeneratorDataUrlOptions} */
+					(this.dataUrlOptions);
+				if (
+					dataUrlOptions.encoding &&
+					dataUrlOptions.encoding !== DEFAULT_ENCODING
+				) {
+					hash.update(dataUrlOptions.encoding);
+				}
+				if (dataUrlOptions.mimetype) hash.update(dataUrlOptions.mimetype);
+				// computed mimetype depends only on module filename which is already part of the hash
+			}
+		} else {
+			hash.update("resource");
+
+			const { module, chunkGraph, runtime } = updateHashContext;
+			const runtimeTemplate =
+				/** @type {NonNullable<UpdateHashContext["runtimeTemplate"]>} */
+				(updateHashContext.runtimeTemplate);
+
+			const pathData = {
+				module,
+				runtime,
+				filename: AssetGenerator.getSourceFileName(module, runtimeTemplate),
+				chunkGraph,
+				contentHash: runtimeTemplate.contentHashReplacement
+			};
+
+			if (typeof this.publicPath === "function") {
+				hash.update("path");
+				const assetInfo = {};
+				hash.update(this.publicPath(pathData, assetInfo));
+				hash.update(JSON.stringify(assetInfo));
+			} else if (this.publicPath) {
+				hash.update("path");
+				hash.update(this.publicPath);
+			} else {
+				hash.update("no-path");
+			}
+
+			const assetModuleFilename =
+				this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
+			const { path: filename, info } =
+				runtimeTemplate.compilation.getAssetPathWithInfo(
+					assetModuleFilename,
+					pathData
+				);
+			hash.update(filename);
+			hash.update(JSON.stringify(info));
+		}
+	}
+}
+
+module.exports = AssetGenerator;
Index: frontend/node_modules/webpack/lib/asset/AssetModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,380 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Yuta Hiroto @hiroppy
+*/
+
+"use strict";
+
+const {
+	ASSET_MODULE_TYPE,
+	ASSET_MODULE_TYPE_BYTES,
+	ASSET_MODULE_TYPE_INLINE,
+	ASSET_MODULE_TYPE_RESOURCE,
+	ASSET_MODULE_TYPE_SOURCE
+} = require("../ModuleTypeConstants");
+const { compareModulesByFullName } = require("../util/comparators");
+const memoize = require("../util/memoize");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("schema-utils").Schema} Schema */
+/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorDataUrl} AssetGeneratorDataUrl */
+/** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */
+/** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */
+/** @typedef {import("../../declarations/WebpackOptions").AssetModuleFilename} AssetModuleFilename */
+/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+/**
+ * Returns definition.
+ * @param {string} name name of definitions
+ * @returns {Schema} definition
+ */
+const getSchema = (name) => {
+	const { definitions } =
+		/** @type {EXPECTED_ANY} */
+		(require("../../schemas/WebpackOptions.json"));
+
+	return {
+		definitions,
+		oneOf: [{ $ref: `#/definitions/${name}` }]
+	};
+};
+
+const generatorValidationOptions = {
+	name: "Asset Modules Plugin",
+	baseDataPath: "generator"
+};
+
+const getAssetGenerator = memoize(() => require("./AssetGenerator"));
+const getAssetParser = memoize(() => require("./AssetParser"));
+const getAssetSourceParser = memoize(() => require("./AssetSourceParser"));
+const getAssetBytesParser = memoize(() => require("./AssetBytesParser"));
+const getAssetSourceGenerator = memoize(() =>
+	require("./AssetSourceGenerator")
+);
+const getAssetBytesGenerator = memoize(() => require("./AssetBytesGenerator"));
+const getNormalModule = memoize(() => require("../NormalModule"));
+
+const type = ASSET_MODULE_TYPE;
+const PLUGIN_NAME = "AssetModulesPlugin";
+
+/**
+ * Represents the asset modules plugin runtime component.
+ * @typedef {object} AssetModulesPluginOptions
+ * @property {boolean=} sideEffectFree
+ */
+
+class AssetModulesPlugin {
+	/**
+	 * Creates an instance of AssetModulesPlugin.
+	 * @param {AssetModulesPluginOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const NormalModule = getNormalModule();
+				for (const type of [
+					ASSET_MODULE_TYPE,
+					ASSET_MODULE_TYPE_BYTES,
+					ASSET_MODULE_TYPE_INLINE,
+					ASSET_MODULE_TYPE_RESOURCE,
+					ASSET_MODULE_TYPE_SOURCE
+				]) {
+					normalModuleFactory.hooks.createModuleClass
+						.for(type)
+						.tap(PLUGIN_NAME, (createData, _resolveData) => {
+							// TODO create the module via new AssetModule with its own properties
+							const module = new NormalModule(createData);
+							if (this.options.sideEffectFree) {
+								module.factoryMeta = { sideEffectFree: true };
+							}
+
+							return module;
+						});
+				}
+
+				normalModuleFactory.hooks.createParser
+					.for(ASSET_MODULE_TYPE)
+					.tap(PLUGIN_NAME, (parserOptions) => {
+						compiler.validate(
+							() => getSchema("AssetParserOptions"),
+							parserOptions,
+							{
+								name: "Asset Modules Plugin",
+								baseDataPath: "parser"
+							},
+							(options) =>
+								require("../../schemas/plugins/asset/AssetParserOptions.check")(
+									options
+								)
+						);
+
+						let dataUrlCondition = parserOptions.dataUrlCondition;
+						if (!dataUrlCondition || typeof dataUrlCondition === "object") {
+							dataUrlCondition = {
+								maxSize: 8096,
+								...dataUrlCondition
+							};
+						}
+
+						const AssetParser = getAssetParser();
+
+						return new AssetParser(dataUrlCondition);
+					});
+				normalModuleFactory.hooks.createParser
+					.for(ASSET_MODULE_TYPE_INLINE)
+					.tap(PLUGIN_NAME, (_parserOptions) => {
+						const AssetParser = getAssetParser();
+
+						return new AssetParser(true);
+					});
+				normalModuleFactory.hooks.createParser
+					.for(ASSET_MODULE_TYPE_RESOURCE)
+					.tap(PLUGIN_NAME, (_parserOptions) => {
+						const AssetParser = getAssetParser();
+
+						return new AssetParser(false);
+					});
+				normalModuleFactory.hooks.createParser
+					.for(ASSET_MODULE_TYPE_SOURCE)
+					.tap(PLUGIN_NAME, (_parserOptions) => {
+						const AssetSourceParser = getAssetSourceParser();
+
+						return new AssetSourceParser();
+					});
+				normalModuleFactory.hooks.createParser
+					.for(ASSET_MODULE_TYPE_BYTES)
+					.tap(PLUGIN_NAME, (_parserOptions) => {
+						const AssetBytesParser = getAssetBytesParser();
+
+						return new AssetBytesParser();
+					});
+
+				for (const type of [
+					ASSET_MODULE_TYPE,
+					ASSET_MODULE_TYPE_INLINE,
+					ASSET_MODULE_TYPE_RESOURCE
+				]) {
+					normalModuleFactory.hooks.createGenerator
+						.for(type)
+						.tap(PLUGIN_NAME, (generatorOptions) => {
+							switch (type) {
+								case ASSET_MODULE_TYPE: {
+									compiler.validate(
+										() => getSchema("AssetGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/asset/AssetGeneratorOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+								case ASSET_MODULE_TYPE_RESOURCE: {
+									compiler.validate(
+										() => getSchema("AssetResourceGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/asset/AssetResourceGeneratorOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+								case ASSET_MODULE_TYPE_INLINE: {
+									compiler.validate(
+										() => getSchema("AssetInlineGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/asset/AssetInlineGeneratorOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+							}
+
+							/** @type {undefined | AssetGeneratorDataUrl} */
+							let dataUrl;
+							if (type !== ASSET_MODULE_TYPE_RESOURCE) {
+								dataUrl = generatorOptions.dataUrl;
+								if (!dataUrl || typeof dataUrl === "object") {
+									dataUrl = {
+										encoding: undefined,
+										mimetype: undefined,
+										...dataUrl
+									};
+								}
+							}
+
+							/** @type {undefined | AssetModuleFilename} */
+							let filename;
+							/** @type {undefined | RawPublicPath} */
+							let publicPath;
+							/** @type {undefined | AssetModuleOutputPath} */
+							let outputPath;
+							if (type !== ASSET_MODULE_TYPE_INLINE) {
+								filename = generatorOptions.filename;
+								publicPath = generatorOptions.publicPath;
+								outputPath = generatorOptions.outputPath;
+							}
+
+							const AssetGenerator = getAssetGenerator();
+
+							return new AssetGenerator(
+								compilation.moduleGraph,
+								dataUrl,
+								filename,
+								publicPath,
+								outputPath,
+								generatorOptions.emit !== false
+							);
+						});
+				}
+				normalModuleFactory.hooks.createGenerator
+					.for(ASSET_MODULE_TYPE_SOURCE)
+					.tap(PLUGIN_NAME, () => {
+						const AssetSourceGenerator = getAssetSourceGenerator();
+
+						return new AssetSourceGenerator(compilation.moduleGraph);
+					});
+
+				normalModuleFactory.hooks.createGenerator
+					.for(ASSET_MODULE_TYPE_BYTES)
+					.tap(PLUGIN_NAME, () => {
+						const AssetBytesGenerator = getAssetBytesGenerator();
+
+						return new AssetBytesGenerator(compilation.moduleGraph);
+					});
+
+				compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
+					const { chunkGraph } = compilation;
+					const { chunk, codeGenerationResults, runtimeTemplate } = options;
+
+					const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
+						chunk,
+						ASSET_MODULE_TYPE,
+						compareModulesByFullName(compilation.compiler)
+					);
+					if (modules) {
+						for (const module of modules) {
+							try {
+								const codeGenResult = codeGenerationResults.get(
+									module,
+									chunk.runtime
+								);
+								const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
+								const data =
+									/** @type {NonNullable<CodeGenerationResult["data"]>} */
+									(codeGenResult.data);
+								const errored = module.getNumberOfErrors() > 0;
+
+								/** @type {string} */
+								let entryFilename;
+								/** @type {AssetInfo} */
+								let entryInfo;
+								/** @type {string} */
+								let entryHash;
+
+								if (errored) {
+									const erroredModule = /** @type {NormalModule} */ (module);
+									const AssetGenerator = getAssetGenerator();
+									const [fullContentHash, contentHash] =
+										AssetGenerator.getFullContentHash(
+											erroredModule,
+											runtimeTemplate
+										);
+									const { filename, assetInfo } =
+										AssetGenerator.getFilenameWithInfo(
+											erroredModule,
+											{
+												filename:
+													erroredModule.generatorOptions &&
+													erroredModule.generatorOptions.filename,
+												outputPath:
+													erroredModule.generatorOptions &&
+													erroredModule.generatorOptions.outputPath
+											},
+											{
+												runtime: chunk.runtime,
+												runtimeTemplate,
+												chunkGraph
+											},
+											contentHash
+										);
+									entryFilename = filename;
+									entryInfo = assetInfo;
+									entryHash = fullContentHash;
+								} else {
+									entryFilename =
+										/** @type {string} */
+										(buildInfo.filename || data.get("filename"));
+									entryInfo =
+										/** @type {AssetInfo} */
+										(buildInfo.assetInfo || data.get("assetInfo"));
+									entryHash =
+										/** @type {string} */
+										(buildInfo.fullContentHash || data.get("fullContentHash"));
+								}
+
+								result.push({
+									render: () =>
+										/** @type {Source} */ (codeGenResult.sources.get(type)),
+									filename: entryFilename,
+									info: entryInfo,
+									auxiliary: true,
+									identifier: `assetModule${chunkGraph.getModuleId(module)}`,
+									hash: entryHash
+								});
+							} catch (err) {
+								/** @type {Error} */ (err).message +=
+									`\nduring rendering of asset ${module.identifier()}`;
+								throw err;
+							}
+						}
+					}
+
+					return result;
+				});
+
+				compilation.hooks.prepareModuleExecution.tap(
+					PLUGIN_NAME,
+					(options, context) => {
+						const { codeGenerationResult } = options;
+						const source = codeGenerationResult.sources.get(ASSET_MODULE_TYPE);
+						if (source === undefined) return;
+						const data =
+							/** @type {NonNullable<CodeGenerationResult["data"]>} */
+							(codeGenerationResult.data);
+						context.assets.set(
+							/** @type {string} */
+							(data.get("filename")),
+							{
+								source,
+								info: data.get("assetInfo")
+							}
+						);
+					}
+				);
+			}
+		);
+	}
+}
+
+module.exports = AssetModulesPlugin;
Index: frontend/node_modules/webpack/lib/asset/AssetParser.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Yuta Hiroto @hiroppy
+*/
+
+"use strict";
+
+const Parser = require("../Parser");
+
+/** @typedef {import("../../declarations/WebpackOptions").AssetParserDataUrlOptions} AssetParserDataUrlOptions */
+/** @typedef {import("../../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+/** @typedef {((source: string | Buffer, context: { filename: string, module: Module }) => boolean)} AssetParserDataUrlFunction */
+
+class AssetParser extends Parser {
+	/**
+	 * Creates an instance of AssetParser.
+	 * @param {AssetParserOptions["dataUrlCondition"] | boolean} dataUrlCondition condition for inlining as DataUrl
+	 */
+	constructor(dataUrlCondition) {
+		super();
+		/** @type {AssetParserOptions["dataUrlCondition"] | boolean} */
+		this.dataUrlCondition = dataUrlCondition;
+	}
+
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (typeof source === "object" && !Buffer.isBuffer(source)) {
+			throw new Error("AssetParser doesn't accept preparsed AST");
+		}
+
+		const buildInfo =
+			/** @type {BuildInfo} */
+			(state.module.buildInfo);
+		buildInfo.strict = true;
+		const buildMeta =
+			/** @type {BuildMeta} */
+			(state.module.buildMeta);
+		buildMeta.exportsType = "default";
+		buildMeta.defaultObject = false;
+
+		if (typeof this.dataUrlCondition === "function") {
+			buildInfo.dataUrl = this.dataUrlCondition(source, {
+				filename: /** @type {string} */ (state.module.getResource()),
+				module: state.module
+			});
+		} else if (typeof this.dataUrlCondition === "boolean") {
+			buildInfo.dataUrl = this.dataUrlCondition;
+		} else if (
+			this.dataUrlCondition &&
+			typeof this.dataUrlCondition === "object"
+		) {
+			buildInfo.dataUrl =
+				Buffer.byteLength(source) <=
+				/** @type {NonNullable<AssetParserDataUrlOptions["maxSize"]>} */
+				(this.dataUrlCondition.maxSize);
+		} else {
+			throw new Error("Unexpected dataUrlCondition type");
+		}
+
+		return state;
+	}
+}
+
+module.exports = AssetParser;
Index: frontend/node_modules/webpack/lib/asset/AssetSourceGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetSourceGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetSourceGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,181 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const ConcatenationScope = require("../ConcatenationScope");
+const Generator = require("../Generator");
+const {
+	ASSET_URL_TYPE,
+	ASSET_URL_TYPES,
+	CSS_TYPE,
+	HTML_TYPE,
+	JAVASCRIPT_AND_ASSET_URL_TYPES,
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES,
+	NO_TYPES
+} = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+class AssetSourceGenerator extends Generator {
+	/**
+	 * Creates an instance of AssetSourceGenerator.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 */
+	constructor(moduleGraph) {
+		super();
+
+		this._moduleGraph = moduleGraph;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(
+		module,
+		{ type, concatenationScope, getData, runtimeTemplate, runtimeRequirements }
+	) {
+		const originalSource = module.originalSource();
+		const data = getData ? getData() : undefined;
+
+		switch (type) {
+			case JAVASCRIPT_TYPE: {
+				if (!originalSource) {
+					return new RawSource("");
+				}
+
+				const content = originalSource.source();
+				const encodedSource =
+					typeof content === "string" ? content : content.toString("utf8");
+
+				/** @type {string} */
+				let sourceContent;
+				if (concatenationScope) {
+					concatenationScope.registerNamespaceExport(
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					);
+					sourceContent = `${runtimeTemplate.renderConst()} ${
+						ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+					} = ${JSON.stringify(encodedSource)};`;
+				} else {
+					runtimeRequirements.add(RuntimeGlobals.module);
+					sourceContent = `${module.moduleArgument}.exports = ${JSON.stringify(
+						encodedSource
+					)};`;
+				}
+				return new RawSource(sourceContent);
+			}
+			case ASSET_URL_TYPE: {
+				if (!originalSource) {
+					return null;
+				}
+
+				const content = originalSource.source();
+				const encodedSource =
+					typeof content === "string" ? content : content.toString("utf8");
+
+				if (data) {
+					data.set("url", { [type]: encodedSource });
+				}
+				return null;
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		switch (generateContext.type) {
+			case JAVASCRIPT_TYPE: {
+				return new RawSource(
+					`throw new Error(${JSON.stringify(error.message)});`
+				);
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		return undefined;
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		/** @type {Set<string>} */
+		const sourceTypes = new Set();
+		const connections = this._moduleGraph.getIncomingConnections(module);
+
+		for (const connection of connections) {
+			if (!connection.originModule) {
+				continue;
+			}
+
+			sourceTypes.add(connection.originModule.type.split("/")[0]);
+		}
+
+		if (sourceTypes.size > 0) {
+			if (
+				sourceTypes.has(JAVASCRIPT_TYPE) &&
+				(sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE))
+			) {
+				return JAVASCRIPT_AND_ASSET_URL_TYPES;
+			} else if (sourceTypes.has(CSS_TYPE) || sourceTypes.has(HTML_TYPE)) {
+				return ASSET_URL_TYPES;
+			}
+			return JAVASCRIPT_TYPES;
+		}
+
+		return NO_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const originalSource = module.originalSource();
+
+		if (!originalSource) {
+			return 0;
+		}
+
+		// Example: m.exports="abcd"
+		return originalSource.size() + 12;
+	}
+}
+
+module.exports = AssetSourceGenerator;
Index: frontend/node_modules/webpack/lib/asset/AssetSourceParser.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/AssetSourceParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/AssetSourceParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Yuta Hiroto @hiroppy
+*/
+
+"use strict";
+
+const Parser = require("../Parser");
+
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+class AssetSourceParser extends Parser {
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (typeof source === "object" && !Buffer.isBuffer(source)) {
+			throw new Error("AssetSourceParser doesn't accept preparsed AST");
+		}
+		const { module } = state;
+		/** @type {BuildInfo} */
+		(module.buildInfo).strict = true;
+		/** @type {BuildMeta} */
+		(module.buildMeta).exportsType = "default";
+		/** @type {BuildMeta} */
+		(state.module.buildMeta).defaultObject = false;
+
+		return state;
+	}
+}
+
+module.exports = AssetSourceParser;
Index: frontend/node_modules/webpack/lib/asset/RawDataUrlModule.js
===================================================================
--- frontend/node_modules/webpack/lib/asset/RawDataUrlModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/asset/RawDataUrlModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,190 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Module = require("../Module");
+const {
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { ASSET_MODULE_TYPE_RAW_DATA_URL } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+class RawDataUrlModule extends Module {
+	/**
+	 * Creates an instance of RawDataUrlModule.
+	 * @param {string} url raw url
+	 * @param {string} identifier unique identifier
+	 * @param {string=} readableIdentifier readable identifier
+	 */
+	constructor(url, identifier, readableIdentifier) {
+		super(ASSET_MODULE_TYPE_RAW_DATA_URL, null);
+		/** @type {string} */
+		this.url = url;
+		/** @type {Buffer | undefined} */
+		this.urlBuffer = url ? Buffer.from(url) : undefined;
+		/** @type {string} */
+		this.identifierStr = identifier;
+		/** @type {string} */
+		this.readableIdentifierStr = readableIdentifier || this.identifierStr;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this.identifierStr;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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) {
+		if (this.url === undefined) {
+			this.url = /** @type {Buffer} */ (this.urlBuffer).toString();
+		}
+		return Math.max(1, this.url.length);
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return /** @type {string} */ (
+			requestShortener.shorten(this.readableIdentifierStr)
+		);
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, !this.buildMeta);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {
+			cacheable: true
+		};
+		callback();
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration(context) {
+		if (this.url === undefined) {
+			this.url = /** @type {Buffer} */ (this.urlBuffer).toString();
+		}
+		/** @type {Sources} */
+		const sources = new Map();
+		sources.set(
+			JAVASCRIPT_TYPE,
+			new RawSource(`module.exports = ${JSON.stringify(this.url)};`)
+		);
+		/** @type {CodeGenerationResultData} */
+		const data = new Map();
+		data.set("url", {
+			javascript: this.url
+		});
+		/** @type {RuntimeRequirements} */
+		const runtimeRequirements = new Set();
+		runtimeRequirements.add(RuntimeGlobals.module);
+		return { sources, runtimeRequirements, data };
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		hash.update(/** @type {Buffer} */ (this.urlBuffer));
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.urlBuffer);
+		write(this.identifierStr);
+		write(this.readableIdentifierStr);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.urlBuffer = read();
+		this.identifierStr = read();
+		this.readableIdentifierStr = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(RawDataUrlModule, "webpack/lib/asset/RawDataUrlModule");
+
+module.exports = RawDataUrlModule;
Index: frontend/node_modules/webpack/lib/async-modules/AsyncModuleHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/async-modules/AsyncModuleHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/async-modules/AsyncModuleHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,53 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Haijie Xie @hai-x
+*/
+
+"use strict";
+
+const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
+
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../Module")} Module */
+
+/** @typedef {Set<Module>} Modules */
+
+/**
+ * Gets outgoing async modules.
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {Module} module module
+ * @returns {Modules} set of modules
+ */
+const getOutgoingAsyncModules = (moduleGraph, module) => {
+	/** @type {Modules} */
+	const set = new Set();
+	/** @type {Modules} */
+	const seen = new Set();
+	(function g(module) {
+		if (!moduleGraph.isAsync(module) || seen.has(module)) return;
+		seen.add(module);
+		if (module.buildMeta && module.buildMeta.async) {
+			set.add(module);
+		} else {
+			const outgoingConnectionMap =
+				moduleGraph.getOutgoingConnectionsByModule(module);
+			if (outgoingConnectionMap) {
+				for (const [module, connections] of outgoingConnectionMap) {
+					if (
+						connections.some(
+							(c) =>
+								c.dependency instanceof HarmonyImportDependency &&
+								c.isTargetActive(undefined)
+						) &&
+						module
+					) {
+						g(module);
+					}
+				}
+			}
+		}
+	})(module);
+	return set;
+};
+
+module.exports.getOutgoingAsyncModules = getOutgoingAsyncModules;
Index: frontend/node_modules/webpack/lib/async-modules/AwaitDependenciesInitFragment.js
===================================================================
--- frontend/node_modules/webpack/lib/async-modules/AwaitDependenciesInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/async-modules/AwaitDependenciesInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,94 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+
+/** @typedef {Map<string, string>} Dependencies */
+
+/**
+ * Represents AwaitDependenciesInitFragment.
+ * @extends {InitFragment<GenerateContext>}
+ */
+class AwaitDependenciesInitFragment extends InitFragment {
+	/**
+	 * Creates an instance of AwaitDependenciesInitFragment.
+	 * @param {Dependencies} dependencies maps an import var to an async module that needs to be awaited
+	 */
+	constructor(dependencies) {
+		super(
+			undefined,
+			InitFragment.STAGE_ASYNC_DEPENDENCIES,
+			0,
+			"await-dependencies"
+		);
+		/** @type {Dependencies} */
+		this.dependencies = dependencies;
+	}
+
+	/**
+	 * Merges another await-dependencies fragment into this fragment.
+	 * @param {AwaitDependenciesInitFragment} other other AwaitDependenciesInitFragment
+	 * @returns {AwaitDependenciesInitFragment} AwaitDependenciesInitFragment
+	 */
+	merge(other) {
+		const dependencies = new Map(other.dependencies);
+		for (const [key, value] of this.dependencies) {
+			dependencies.set(key, value);
+		}
+		return new AwaitDependenciesInitFragment(dependencies);
+	}
+
+	/**
+	 * Returns the source code that will be included as initialization code.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included as initialization code
+	 */
+	getContent({ runtimeRequirements, runtimeTemplate }) {
+		runtimeRequirements.add(RuntimeGlobals.module);
+		if (this.dependencies.size === 0) {
+			return "";
+		}
+
+		const importVars = [...this.dependencies.keys()];
+		const asyncModuleValues = [...this.dependencies.values()].join(", ");
+
+		const templateInput = [
+			`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${asyncModuleValues}]);`
+		];
+
+		if (
+			this.dependencies.size === 1 ||
+			!runtimeTemplate.supportsDestructuring()
+		) {
+			templateInput.push(
+				"var __webpack_async_dependencies_result__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);"
+			);
+			for (const [index, importVar] of importVars.entries()) {
+				templateInput.push(
+					`${importVar} = __webpack_async_dependencies_result__[${index}];`
+				);
+			}
+		} else {
+			const importVarsStr = importVars.join(", ");
+
+			templateInput.push(
+				`([${importVarsStr}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);`
+			);
+		}
+
+		templateInput.push("");
+
+		return Template.asString(templateInput);
+	}
+}
+
+module.exports = AwaitDependenciesInitFragment;
Index: frontend/node_modules/webpack/lib/async-modules/InferAsyncModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/async-modules/InferAsyncModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/async-modules/InferAsyncModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,54 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+const PLUGIN_NAME = "InferAsyncModulesPlugin";
+
+class InferAsyncModulesPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const { moduleGraph } = compilation;
+			compilation.hooks.finishModules.tap(PLUGIN_NAME, (modules) => {
+				/** @type {Set<Module>} */
+				const queue = new Set();
+				for (const module of modules) {
+					if (module.buildMeta && module.buildMeta.async) {
+						queue.add(module);
+					}
+				}
+				for (const module of queue) {
+					moduleGraph.setAsync(module);
+					for (const [
+						originModule,
+						connections
+					] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
+						if (
+							connections.some(
+								(c) =>
+									c.dependency instanceof HarmonyImportDependency &&
+									c.isTargetActive(undefined)
+							)
+						) {
+							queue.add(/** @type {Module} */ (originModule));
+						}
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = InferAsyncModulesPlugin;
Index: frontend/node_modules/webpack/lib/buildChunkGraph.js
===================================================================
--- frontend/node_modules/webpack/lib/buildChunkGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/buildChunkGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1405 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleGraphConnection = require("./ModuleGraphConnection");
+const AsyncDependencyToInitialChunkError = require("./errors/AsyncDependencyToInitialChunkError");
+const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
+
+/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("./Chunk")} Chunk */
+/** @typedef {import("./ChunkGroup")} ChunkGroup */
+/** @typedef {import("./Compilation")} Compilation */
+/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("./Entrypoint")} Entrypoint */
+/** @typedef {import("./Module")} Module */
+/** @typedef {import("./ModuleGraph")} ModuleGraph */
+/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Defines the queue item type used by this module.
+ * @typedef {object} QueueItem
+ * @property {number} action
+ * @property {DependenciesBlock} block
+ * @property {Module} module
+ * @property {Chunk} chunk
+ * @property {ChunkGroup} chunkGroup
+ * @property {ChunkGroupInfo} chunkGroupInfo
+ */
+
+/**
+ * Defines the chunk group info type used by this module.
+ * @typedef {object} ChunkGroupInfo
+ * @property {ChunkGroup} chunkGroup the chunk group
+ * @property {RuntimeSpec} runtime the runtimes
+ * @property {boolean} initialized is this chunk group initialized
+ * @property {bigint | undefined} minAvailableModules current minimal set of modules available at this point
+ * @property {bigint[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
+ * @property {Set<Module>=} skippedItems modules that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking)
+ * @property {Set<[Module, ModuleGraphConnection[]]>=} skippedModuleConnections referenced modules that where skipped because they were not active in this runtime
+ * @property {bigint | undefined} resultingAvailableModules set of modules available including modules from this chunk group
+ * @property {Set<ChunkGroupInfo> | undefined} children set of children chunk groups, that will be revisited when availableModules shrink
+ * @property {Set<ChunkGroupInfo> | undefined} availableSources set of chunk groups that are the source for minAvailableModules
+ * @property {Set<ChunkGroupInfo> | undefined} availableChildren set of chunk groups which depend on the this chunk group as availableSource
+ * @property {number} preOrderIndex next pre order index
+ * @property {number} postOrderIndex next post order index
+ * @property {boolean} chunkLoading has a chunk loading mechanism
+ * @property {boolean} asyncChunks create async chunks
+ * @property {Module | null} depModule the module that is the dependency of the block
+ * @property {boolean} circular Whether to deduplicate to avoid circular references
+ */
+
+/**
+ * Defines the block chunk group connection type used by this module.
+ * @typedef {object} BlockChunkGroupConnection
+ * @property {ChunkGroupInfo} originChunkGroupInfo origin chunk group
+ * @property {ChunkGroup} chunkGroup referenced chunk group
+ */
+
+/** @typedef {(Module | ConnectionState | ModuleGraphConnection)[]} BlockModulesInTuples */
+/** @typedef {(Module | ConnectionState | ModuleGraphConnection[])[]} BlockModulesInFlattenTuples */
+/** @typedef {Map<DependenciesBlock, BlockModulesInFlattenTuples>} BlockModulesMap */
+/** @typedef {Map<Chunk, bigint>} MaskByChunk */
+/** @typedef {Set<DependenciesBlock>} BlocksWithNestedBlocks */
+/** @typedef {Map<AsyncDependenciesBlock, BlockChunkGroupConnection[]>} BlockConnections */
+/** @typedef {Map<ChunkGroup, ChunkGroupInfo>} ChunkGroupInfoMap */
+/** @typedef {Set<ChunkGroup>} AllCreatedChunkGroups */
+/** @typedef {Map<Entrypoint, Module[]>} InputEntrypointsAndModules */
+
+const ZERO_BIGINT = BigInt(0);
+const ONE_BIGINT = BigInt(1);
+
+/**
+ * Checks whether this object is ordinal set in mask.
+ * @param {bigint} mask The mask to test
+ * @param {number} ordinal The ordinal of the bit to test
+ * @returns {boolean} If the ordinal-th bit is set in the mask
+ */
+const isOrdinalSetInMask = (mask, ordinal) =>
+	BigInt.asUintN(1, mask >> BigInt(ordinal)) !== ZERO_BIGINT;
+
+/**
+ * Gets active state of connections.
+ * @param {ModuleGraphConnection[]} connections list of connections
+ * @param {RuntimeSpec} runtime for which runtime
+ * @returns {ConnectionState} connection state
+ */
+const getActiveStateOfConnections = (connections, runtime) => {
+	let merged = connections[0].getActiveState(runtime);
+	if (merged === true) return true;
+	for (let i = 1; i < connections.length; i++) {
+		const c = connections[i];
+		merged = ModuleGraphConnection.addConnectionStates(
+			merged,
+			c.getActiveState(runtime)
+		);
+		if (merged === true) return true;
+	}
+	return merged;
+};
+
+/**
+ * Extract block modules.
+ * @param {Module} module module
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {RuntimeSpec} runtime runtime
+ * @param {BlockModulesMap} blockModulesMap block modules map
+ */
+const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
+	/** @type {DependenciesBlock | undefined} */
+	let blockCache;
+	/** @type {BlockModulesInTuples | undefined} */
+	let modules;
+
+	/** @type {BlockModulesInTuples[]} */
+	const arrays = [];
+
+	/** @type {DependenciesBlock[]} */
+	const queue = [module];
+	while (queue.length > 0) {
+		const block = /** @type {DependenciesBlock} */ (queue.pop());
+		/** @type {Module[]} */
+		const arr = [];
+		arrays.push(arr);
+		blockModulesMap.set(block, arr);
+		for (const b of block.blocks) {
+			queue.push(b);
+		}
+	}
+
+	for (const connection of moduleGraph.getOutgoingConnections(module)) {
+		const d = connection.dependency;
+		// We skip connections without dependency
+		if (!d) continue;
+		const m = connection.module;
+		// We skip connections without Module pointer
+		if (!m) continue;
+		// We skip weak connections
+		if (connection.weak) continue;
+
+		const block = moduleGraph.getParentBlock(d);
+		let index = moduleGraph.getParentBlockIndex(d);
+
+		// deprecated fallback
+		if (index < 0) {
+			index = /** @type {DependenciesBlock} */ (block).dependencies.indexOf(d);
+		}
+
+		if (blockCache !== block) {
+			modules =
+				/** @type {BlockModulesInTuples} */
+				(
+					blockModulesMap.get(
+						(blockCache = /** @type {DependenciesBlock} */ (block))
+					)
+				);
+		}
+
+		const i = index * 3;
+		/** @type {BlockModulesInTuples} */
+		(modules)[i] = m;
+		/** @type {BlockModulesInTuples} */
+		(modules)[i + 1] = connection.getActiveState(runtime);
+		/** @type {BlockModulesInTuples} */
+		(modules)[i + 2] = connection;
+	}
+
+	for (const modules of arrays) {
+		if (modules.length === 0) continue;
+		/** @type {undefined | Map<Module | ModuleGraphConnection | ConnectionState, number>} */
+		let indexMap;
+		let length = 0;
+		outer: for (let j = 0; j < modules.length; j += 3) {
+			const m = modules[j];
+			if (m === undefined) continue;
+			const state = /** @type {ConnectionState} */ (modules[j + 1]);
+			const connection = /** @type {ModuleGraphConnection} */ (modules[j + 2]);
+			if (indexMap === undefined) {
+				let i = 0;
+				for (; i < length; i += 3) {
+					if (modules[i] === m) {
+						const merged = /** @type {ConnectionState} */ (modules[i + 1]);
+						/** @type {ModuleGraphConnection[]} */
+						(/** @type {unknown} */ (modules[i + 2])).push(connection);
+						if (merged === true) continue outer;
+						modules[i + 1] = ModuleGraphConnection.addConnectionStates(
+							merged,
+							state
+						);
+						continue outer;
+					}
+				}
+				modules[length] = m;
+				length++;
+				modules[length] = state;
+				length++;
+				/** @type {ModuleGraphConnection[]} */
+				(/** @type {unknown} */ (modules[length])) = [connection];
+				length++;
+				if (length > 30) {
+					// To avoid worse case performance, we will use an index map for
+					// linear cost access, which allows to maintain O(n) complexity
+					// while keeping allocations down to a minimum
+					indexMap = new Map();
+					for (let i = 0; i < length; i += 3) {
+						indexMap.set(modules[i], i + 1);
+					}
+				}
+			} else {
+				const idx = indexMap.get(m);
+				if (idx !== undefined) {
+					const merged = /** @type {ConnectionState} */ (modules[idx]);
+					/** @type {ModuleGraphConnection[]} */
+					(/** @type {unknown} */ (modules[idx + 1])).push(connection);
+					if (merged === true) continue;
+					modules[idx] = ModuleGraphConnection.addConnectionStates(
+						merged,
+						state
+					);
+				} else {
+					modules[length] = m;
+					length++;
+					modules[length] = state;
+					indexMap.set(m, length);
+					length++;
+					/** @type {ModuleGraphConnection[]} */
+					(
+						/** @type {unknown} */
+						(modules[length])
+					) = [connection];
+					length++;
+				}
+			}
+		}
+		modules.length = length;
+	}
+};
+
+/**
+ * Processes the provided logger.
+ * @param {Logger} logger a logger
+ * @param {Compilation} compilation the compilation
+ * @param {InputEntrypointsAndModules} inputEntrypointsAndModules chunk groups which are processed with the modules
+ * @param {ChunkGroupInfoMap} chunkGroupInfoMap mapping from chunk group to available modules
+ * @param {BlockConnections} blockConnections connection for blocks
+ * @param {BlocksWithNestedBlocks} blocksWithNestedBlocks flag for blocks that have nested blocks
+ * @param {AllCreatedChunkGroups} allCreatedChunkGroups filled with all chunk groups that are created here
+ * @param {MaskByChunk} maskByChunk module content mask by chunk
+ */
+const visitModules = (
+	logger,
+	compilation,
+	inputEntrypointsAndModules,
+	chunkGroupInfoMap,
+	blockConnections,
+	blocksWithNestedBlocks,
+	allCreatedChunkGroups,
+	maskByChunk
+) => {
+	const { moduleGraph, chunkGraph, moduleMemCaches } = compilation;
+
+	/** @type {Map<RuntimeSpec, BlockModulesMap>} */
+	const blockModulesRuntimeMap = new Map();
+
+	/** @type {BlockModulesMap | undefined} */
+	let blockModulesMap;
+
+	/** @type {Map<Module, number>} */
+	const ordinalByModule = new Map();
+
+	/**
+	 * Gets module ordinal.
+	 * @param {Module} module The module to look up
+	 * @returns {number} The ordinal of the module in masks
+	 */
+	const getModuleOrdinal = (module) => {
+		let ordinal = ordinalByModule.get(module);
+		if (ordinal === undefined) {
+			ordinal = ordinalByModule.size;
+			ordinalByModule.set(module, ordinal);
+		}
+		return ordinal;
+	};
+
+	for (const chunk of compilation.chunks) {
+		let mask = ZERO_BIGINT;
+		for (const m of chunkGraph.getChunkModulesIterable(chunk)) {
+			mask |= ONE_BIGINT << BigInt(getModuleOrdinal(m));
+		}
+		maskByChunk.set(chunk, mask);
+	}
+
+	/**
+	 * Gets block modules.
+	 * @param {DependenciesBlock} block block
+	 * @param {RuntimeSpec} runtime runtime
+	 * @returns {BlockModulesInFlattenTuples | undefined} block modules in flatten tuples
+	 */
+	const getBlockModules = (block, runtime) => {
+		blockModulesMap = blockModulesRuntimeMap.get(runtime);
+		if (blockModulesMap === undefined) {
+			/** @type {BlockModulesMap} */
+			blockModulesMap = new Map();
+			blockModulesRuntimeMap.set(runtime, blockModulesMap);
+		}
+		let blockModules = blockModulesMap.get(block);
+		if (blockModules !== undefined) return blockModules;
+		const module = /** @type {Module} */ (block.getRootBlock());
+		const memCache = moduleMemCaches && moduleMemCaches.get(module);
+		if (memCache !== undefined) {
+			/** @type {BlockModulesMap} */
+			const map = memCache.provide(
+				"bundleChunkGraph.blockModules",
+				runtime,
+				() => {
+					logger.time("visitModules: prepare");
+					const map = new Map();
+					extractBlockModules(module, moduleGraph, runtime, map);
+					logger.timeAggregate("visitModules: prepare");
+					return map;
+				}
+			);
+			for (const [block, blockModules] of map) {
+				blockModulesMap.set(block, blockModules);
+			}
+			return map.get(block);
+		}
+		logger.time("visitModules: prepare");
+		extractBlockModules(module, moduleGraph, runtime, blockModulesMap);
+		blockModules =
+			/** @type {BlockModulesInFlattenTuples} */
+			(blockModulesMap.get(block));
+		logger.timeAggregate("visitModules: prepare");
+		return blockModules;
+	};
+
+	let statProcessedQueueItems = 0;
+	let statProcessedBlocks = 0;
+	let statConnectedChunkGroups = 0;
+	let statProcessedChunkGroupsForMerging = 0;
+	let statMergedAvailableModuleSets = 0;
+	const statForkedAvailableModules = 0;
+	const statForkedAvailableModulesCount = 0;
+	const statForkedAvailableModulesCountPlus = 0;
+	const statForkedMergedModulesCount = 0;
+	const statForkedMergedModulesCountPlus = 0;
+	const statForkedResultModulesCount = 0;
+	let statChunkGroupInfoUpdated = 0;
+	let statChildChunkGroupsReconnected = 0;
+
+	let nextChunkGroupIndex = 0;
+	let nextFreeModulePreOrderIndex = 0;
+	let nextFreeModulePostOrderIndex = 0;
+
+	/** @type {Map<DependenciesBlock, ChunkGroupInfo>} */
+	const blockChunkGroups = new Map();
+
+	/** @type {Map<ChunkGroupInfo, Set<DependenciesBlock>>} */
+	const blocksByChunkGroups = new Map();
+
+	/** @typedef {Map<string, ChunkGroupInfo>} NamedChunkGroup */
+
+	/** @type {NamedChunkGroup} */
+	const namedChunkGroups = new Map();
+
+	/** @type {NamedChunkGroup} */
+	const namedAsyncEntrypoints = new Map();
+
+	/** @type {Map<Module, ChunkGroupInfo>} */
+	const depModuleAsyncEntrypoints = new Map();
+
+	/** @type {Set<ChunkGroupInfo>} */
+	const outdatedOrderIndexChunkGroups = new Set();
+
+	const ADD_AND_ENTER_ENTRY_MODULE = 0;
+	const ADD_AND_ENTER_MODULE = 1;
+	const ENTER_MODULE = 2;
+	const PROCESS_BLOCK = 3;
+	const PROCESS_ENTRY_BLOCK = 4;
+	const LEAVE_MODULE = 5;
+
+	/** @type {QueueItem[]} */
+	let queue = [];
+
+	/** @typedef {Set<[ChunkGroupInfo, QueueItem | null]>} ConnectList */
+	/** @type {Map<ChunkGroupInfo, ConnectList>} */
+	const queueConnect = new Map();
+	/** @type {Set<ChunkGroupInfo>} */
+	const chunkGroupsForCombining = new Set();
+
+	// Fill queue with entrypoint modules
+	// Create ChunkGroupInfo for entrypoints
+	for (const [chunkGroup, modules] of inputEntrypointsAndModules) {
+		const runtime = getEntryRuntime(
+			compilation,
+			/** @type {string} */ (chunkGroup.name),
+			chunkGroup.options
+		);
+		/** @type {ChunkGroupInfo} */
+		const chunkGroupInfo = {
+			depModule: null,
+			circular: false,
+			initialized: false,
+			chunkGroup,
+			runtime,
+			minAvailableModules: undefined,
+			availableModulesToBeMerged: [],
+			skippedItems: undefined,
+			resultingAvailableModules: undefined,
+			children: undefined,
+			availableSources: undefined,
+			availableChildren: undefined,
+			preOrderIndex: 0,
+			postOrderIndex: 0,
+			chunkLoading:
+				chunkGroup.options.chunkLoading !== undefined
+					? chunkGroup.options.chunkLoading !== false
+					: compilation.outputOptions.chunkLoading !== false,
+			asyncChunks:
+				chunkGroup.options.asyncChunks !== undefined
+					? chunkGroup.options.asyncChunks
+					: compilation.outputOptions.asyncChunks !== false
+		};
+		chunkGroup.index = nextChunkGroupIndex++;
+		if (chunkGroup.getNumberOfParents() > 0) {
+			// minAvailableModules for child entrypoints are unknown yet, set to undefined.
+			// This means no module is added until other sets are merged into
+			// this minAvailableModules (by the parent entrypoints)
+			const skippedItems = new Set(modules);
+			chunkGroupInfo.skippedItems = skippedItems;
+			chunkGroupsForCombining.add(chunkGroupInfo);
+		} else {
+			// The application may start here: We start with an empty list of available modules
+			chunkGroupInfo.minAvailableModules = ZERO_BIGINT;
+			const chunk = chunkGroup.getEntrypointChunk();
+			for (const module of modules) {
+				queue.push({
+					action: ADD_AND_ENTER_MODULE,
+					block: module,
+					module,
+					chunk,
+					chunkGroup,
+					chunkGroupInfo
+				});
+			}
+		}
+		chunkGroupInfoMap.set(chunkGroup, chunkGroupInfo);
+		if (chunkGroup.name) {
+			namedChunkGroups.set(chunkGroup.name, chunkGroupInfo);
+		}
+	}
+	// Fill availableSources with parent-child dependencies between entrypoints
+	for (const chunkGroupInfo of chunkGroupsForCombining) {
+		const { chunkGroup } = chunkGroupInfo;
+		chunkGroupInfo.availableSources = new Set();
+		for (const parent of chunkGroup.parentsIterable) {
+			const parentChunkGroupInfo =
+				/** @type {ChunkGroupInfo} */
+				(chunkGroupInfoMap.get(parent));
+			chunkGroupInfo.availableSources.add(parentChunkGroupInfo);
+			if (parentChunkGroupInfo.availableChildren === undefined) {
+				parentChunkGroupInfo.availableChildren = new Set();
+			}
+			parentChunkGroupInfo.availableChildren.add(chunkGroupInfo);
+		}
+	}
+	// pop() is used to read from the queue
+	// so it need to be reversed to be iterated in
+	// correct order
+	queue.reverse();
+
+	/** @type {Set<ChunkGroupInfo>} */
+	const outdatedChunkGroupInfo = new Set();
+	/** @type {Set<[ChunkGroupInfo, QueueItem | null]>} */
+	const chunkGroupsForMerging = new Set();
+	/** @type {QueueItem[]} */
+	let queueDelayed = [];
+
+	/** @type {[Module, ModuleGraphConnection[]][]} */
+	const skipConnectionBuffer = [];
+	/** @type {Module[]} */
+	const skipBuffer = [];
+	/** @type {QueueItem[]} */
+	const queueBuffer = [];
+
+	/** @type {Module} */
+	let module;
+	/** @type {Chunk} */
+	let chunk;
+	/** @type {ChunkGroup} */
+	let chunkGroup;
+	/** @type {DependenciesBlock} */
+	let block;
+	/** @type {ChunkGroupInfo} */
+	let chunkGroupInfo;
+
+	// For each async Block in graph
+	/**
+	 * Processes the provided b.
+	 * @param {AsyncDependenciesBlock} b iterating over each Async DepBlock
+	 * @returns {void}
+	 */
+	const iteratorBlock = (b) => {
+		// 1. We create a chunk group with single chunk in it for this Block
+		// but only once (blockChunkGroups map)
+		/** @type {ChunkGroupInfo | undefined} */
+		let cgi = blockChunkGroups.get(b);
+		/** @type {ChunkGroup | undefined} */
+		let c;
+		/** @type {Entrypoint | undefined} */
+		let entrypoint;
+		/** @type {Module | null} */
+		const depModule = moduleGraph.getModule(b.dependencies[0]);
+		const entryOptions = b.groupOptions && b.groupOptions.entryOptions;
+		if (cgi === undefined) {
+			const chunkName = (b.groupOptions && b.groupOptions.name) || b.chunkName;
+			if (entryOptions) {
+				cgi = namedAsyncEntrypoints.get(/** @type {string} */ (chunkName));
+				if (!cgi && !b.circular && depModule) {
+					cgi = depModuleAsyncEntrypoints.get(depModule);
+				}
+				if (!cgi) {
+					entrypoint = compilation.addAsyncEntrypoint(
+						entryOptions,
+						module,
+						/** @type {DependencyLocation} */ (b.loc),
+						/** @type {string} */ (b.request)
+					);
+					maskByChunk.set(entrypoint.chunks[0], ZERO_BIGINT);
+					entrypoint.index = nextChunkGroupIndex++;
+					cgi = {
+						depModule,
+						circular: b.circular,
+						chunkGroup: entrypoint,
+						initialized: false,
+						runtime:
+							entrypoint.options.runtime ||
+							/** @type {string | undefined} */ (entrypoint.name),
+						minAvailableModules: ZERO_BIGINT,
+						availableModulesToBeMerged: [],
+						skippedItems: undefined,
+						resultingAvailableModules: undefined,
+						children: undefined,
+						availableSources: undefined,
+						availableChildren: undefined,
+						preOrderIndex: 0,
+						postOrderIndex: 0,
+						chunkLoading:
+							entryOptions.chunkLoading !== undefined
+								? entryOptions.chunkLoading !== false
+								: chunkGroupInfo.chunkLoading,
+						asyncChunks:
+							entryOptions.asyncChunks !== undefined
+								? entryOptions.asyncChunks
+								: chunkGroupInfo.asyncChunks
+					};
+					chunkGroupInfoMap.set(
+						entrypoint,
+						/** @type {ChunkGroupInfo} */
+						(cgi)
+					);
+
+					chunkGraph.connectBlockAndChunkGroup(b, entrypoint);
+					if (chunkName) {
+						namedAsyncEntrypoints.set(
+							chunkName,
+							/** @type {ChunkGroupInfo} */
+							(cgi)
+						);
+					}
+					if (!b.circular && depModule) {
+						depModuleAsyncEntrypoints.set(
+							depModule,
+							/** @type {ChunkGroupInfo} */ (cgi)
+						);
+					}
+				} else {
+					entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
+					// TODO merge entryOptions
+					entrypoint.addOrigin(
+						module,
+						/** @type {DependencyLocation} */ (b.loc),
+						/** @type {string} */ (b.request)
+					);
+					chunkGraph.connectBlockAndChunkGroup(b, entrypoint);
+				}
+
+				// 2. We enqueue the DependenciesBlock for traversal
+				queueDelayed.push({
+					action: PROCESS_ENTRY_BLOCK,
+					block: b,
+					module,
+					chunk: entrypoint.chunks[0],
+					chunkGroup: entrypoint,
+					chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
+				});
+			} else if (!chunkGroupInfo.asyncChunks || !chunkGroupInfo.chunkLoading) {
+				// Just queue the block into the current chunk group
+				queue.push({
+					action: PROCESS_BLOCK,
+					block: b,
+					module,
+					chunk,
+					chunkGroup,
+					chunkGroupInfo
+				});
+			} else {
+				cgi = chunkName ? namedChunkGroups.get(chunkName) : undefined;
+				if (!cgi) {
+					c = compilation.addChunkInGroup(
+						b.groupOptions || b.chunkName,
+						module,
+						/** @type {DependencyLocation} */ (b.loc),
+						/** @type {string} */ (b.request)
+					);
+					maskByChunk.set(c.chunks[0], ZERO_BIGINT);
+					c.index = nextChunkGroupIndex++;
+					cgi = {
+						depModule,
+						circular: b.circular,
+						initialized: false,
+						chunkGroup: c,
+						runtime: chunkGroupInfo.runtime,
+						minAvailableModules: undefined,
+						availableModulesToBeMerged: [],
+						skippedItems: undefined,
+						resultingAvailableModules: undefined,
+						children: undefined,
+						availableSources: undefined,
+						availableChildren: undefined,
+						preOrderIndex: 0,
+						postOrderIndex: 0,
+						chunkLoading: chunkGroupInfo.chunkLoading,
+						asyncChunks: chunkGroupInfo.asyncChunks
+					};
+					allCreatedChunkGroups.add(c);
+					chunkGroupInfoMap.set(c, cgi);
+					if (chunkName) {
+						namedChunkGroups.set(chunkName, cgi);
+					}
+				} else {
+					c = cgi.chunkGroup;
+					if (c.isInitial()) {
+						compilation.errors.push(
+							new AsyncDependencyToInitialChunkError(
+								/** @type {string} */ (chunkName),
+								module,
+								/** @type {DependencyLocation} */ (b.loc)
+							)
+						);
+						c = chunkGroup;
+					} else {
+						c.addOptions(b.groupOptions);
+					}
+					c.addOrigin(
+						module,
+						/** @type {DependencyLocation} */ (b.loc),
+						/** @type {string} */ (b.request)
+					);
+				}
+				blockConnections.set(b, []);
+			}
+			blockChunkGroups.set(b, /** @type {ChunkGroupInfo} */ (cgi));
+		} else if (entryOptions) {
+			entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
+		} else {
+			c = cgi.chunkGroup;
+		}
+
+		if (c !== undefined) {
+			// 2. We store the connection for the block
+			// to connect it later if needed
+			/** @type {BlockChunkGroupConnection[]} */
+			(blockConnections.get(b)).push({
+				originChunkGroupInfo: chunkGroupInfo,
+				chunkGroup: c
+			});
+
+			// 3. We enqueue the chunk group info creation/updating
+			let connectList = queueConnect.get(chunkGroupInfo);
+			if (connectList === undefined) {
+				/** @type {ConnectList} */
+				connectList = new Set();
+				queueConnect.set(chunkGroupInfo, connectList);
+			}
+			connectList.add([
+				/** @type {ChunkGroupInfo} */ (cgi),
+				{
+					action: PROCESS_BLOCK,
+					block: b,
+					module,
+					chunk: c.chunks[0],
+					chunkGroup: c,
+					chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
+				}
+			]);
+		} else if (
+			entrypoint !== undefined &&
+			(chunkGroupInfo.circular || chunkGroupInfo.depModule !== depModule)
+		) {
+			chunkGroupInfo.chunkGroup.addAsyncEntrypoint(entrypoint);
+		}
+	};
+
+	/**
+	 * Processes the provided block.
+	 * @param {DependenciesBlock} block the block
+	 * @returns {void}
+	 */
+	const processBlock = (block) => {
+		statProcessedBlocks++;
+		// get prepared block info
+		const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
+
+		if (blockModules !== undefined) {
+			const minAvailableModules =
+				/** @type {bigint} */
+				(chunkGroupInfo.minAvailableModules);
+			// Buffer items because order need to be reversed to get indices correct
+			// Traverse all referenced modules
+			for (let i = 0, len = blockModules.length; i < len; i += 3) {
+				const refModule = /** @type {Module} */ (blockModules[i]);
+				// For single comparisons this might be cheaper
+				const isModuleInChunk = chunkGraph.isModuleInChunk(refModule, chunk);
+
+				if (isModuleInChunk) {
+					// skip early if already connected
+					continue;
+				}
+
+				const refOrdinal = /** @type {number} */ getModuleOrdinal(refModule);
+				const activeState = /** @type {ConnectionState} */ (
+					blockModules[i + 1]
+				);
+				if (activeState !== true) {
+					const connections = /** @type {ModuleGraphConnection[]} */ (
+						blockModules[i + 2]
+					);
+					skipConnectionBuffer.push([refModule, connections]);
+					// We skip inactive connections
+					if (activeState === false) continue;
+				} else if (isOrdinalSetInMask(minAvailableModules, refOrdinal)) {
+					// already in parent chunks, skip it for now
+					skipBuffer.push(refModule);
+					continue;
+				}
+				// enqueue, then add and enter to be in the correct order
+				// this is relevant with circular dependencies
+				queueBuffer.push({
+					action: activeState === true ? ADD_AND_ENTER_MODULE : PROCESS_BLOCK,
+					block: refModule,
+					module: refModule,
+					chunk,
+					chunkGroup,
+					chunkGroupInfo
+				});
+			}
+			// Add buffered items in reverse order
+			if (skipConnectionBuffer.length > 0) {
+				let { skippedModuleConnections } = chunkGroupInfo;
+				if (skippedModuleConnections === undefined) {
+					chunkGroupInfo.skippedModuleConnections = skippedModuleConnections =
+						new Set();
+				}
+				for (let i = skipConnectionBuffer.length - 1; i >= 0; i--) {
+					skippedModuleConnections.add(skipConnectionBuffer[i]);
+				}
+				skipConnectionBuffer.length = 0;
+			}
+			if (skipBuffer.length > 0) {
+				let { skippedItems } = chunkGroupInfo;
+				if (skippedItems === undefined) {
+					chunkGroupInfo.skippedItems = skippedItems = new Set();
+				}
+				for (let i = skipBuffer.length - 1; i >= 0; i--) {
+					skippedItems.add(skipBuffer[i]);
+				}
+				skipBuffer.length = 0;
+			}
+			if (queueBuffer.length > 0) {
+				for (let i = queueBuffer.length - 1; i >= 0; i--) {
+					queue.push(queueBuffer[i]);
+				}
+				queueBuffer.length = 0;
+			}
+		}
+
+		// Traverse all Blocks
+		for (const b of block.blocks) {
+			iteratorBlock(b);
+		}
+
+		if (block.blocks.length > 0 && module !== block) {
+			blocksWithNestedBlocks.add(block);
+		}
+	};
+
+	/**
+	 * Process entry block.
+	 * @param {DependenciesBlock} block the block
+	 * @returns {void}
+	 */
+	const processEntryBlock = (block) => {
+		statProcessedBlocks++;
+		// get prepared block info
+		const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
+
+		if (blockModules !== undefined) {
+			// Traverse all referenced modules in reverse order
+			for (let i = blockModules.length - 3; i >= 0; i -= 3) {
+				const refModule = /** @type {Module} */ (blockModules[i]);
+				const activeState = /** @type {ConnectionState} */ (
+					blockModules[i + 1]
+				);
+				// enqueue, then add and enter to be in the correct order
+				// this is relevant with circular dependencies
+				queue.push({
+					action:
+						activeState === true ? ADD_AND_ENTER_ENTRY_MODULE : PROCESS_BLOCK,
+					block: refModule,
+					module: refModule,
+					chunk,
+					chunkGroup,
+					chunkGroupInfo
+				});
+			}
+		}
+
+		// Traverse all Blocks
+		for (const b of block.blocks) {
+			iteratorBlock(b);
+		}
+
+		if (block.blocks.length > 0 && module !== block) {
+			blocksWithNestedBlocks.add(block);
+		}
+	};
+
+	const processQueue = () => {
+		while (queue.length) {
+			statProcessedQueueItems++;
+			const queueItem = /** @type {QueueItem} */ (queue.pop());
+			module = queueItem.module;
+			block = queueItem.block;
+			chunk = queueItem.chunk;
+			chunkGroup = queueItem.chunkGroup;
+			chunkGroupInfo = queueItem.chunkGroupInfo;
+
+			switch (queueItem.action) {
+				case ADD_AND_ENTER_ENTRY_MODULE:
+					chunkGraph.connectChunkAndEntryModule(
+						chunk,
+						module,
+						/** @type {Entrypoint} */ (chunkGroup)
+					);
+				// fallthrough
+				case ADD_AND_ENTER_MODULE: {
+					const isModuleInChunk = chunkGraph.isModuleInChunk(module, chunk);
+
+					if (isModuleInChunk) {
+						// already connected, skip it
+						break;
+					}
+					// We connect Module and Chunk
+					chunkGraph.connectChunkAndModule(chunk, module);
+					const moduleOrdinal = getModuleOrdinal(module);
+					let chunkMask = /** @type {bigint} */ (maskByChunk.get(chunk));
+					chunkMask |= ONE_BIGINT << BigInt(moduleOrdinal);
+					maskByChunk.set(chunk, chunkMask);
+				}
+				// fallthrough
+				case ENTER_MODULE: {
+					const index = chunkGroup.getModulePreOrderIndex(module);
+					if (index === undefined) {
+						chunkGroup.setModulePreOrderIndex(
+							module,
+							chunkGroupInfo.preOrderIndex++
+						);
+					}
+
+					if (
+						moduleGraph.setPreOrderIndexIfUnset(
+							module,
+							nextFreeModulePreOrderIndex
+						)
+					) {
+						nextFreeModulePreOrderIndex++;
+					}
+
+					// reuse queueItem
+					queueItem.action = LEAVE_MODULE;
+					queue.push(queueItem);
+				}
+				// fallthrough
+				case PROCESS_BLOCK: {
+					processBlock(block);
+					break;
+				}
+				case PROCESS_ENTRY_BLOCK: {
+					processEntryBlock(block);
+					break;
+				}
+				case LEAVE_MODULE: {
+					const index = chunkGroup.getModulePostOrderIndex(module);
+					if (index === undefined) {
+						chunkGroup.setModulePostOrderIndex(
+							module,
+							chunkGroupInfo.postOrderIndex++
+						);
+					}
+
+					if (
+						moduleGraph.setPostOrderIndexIfUnset(
+							module,
+							nextFreeModulePostOrderIndex
+						)
+					) {
+						nextFreeModulePostOrderIndex++;
+					}
+					break;
+				}
+			}
+		}
+	};
+
+	/**
+	 * Calculate resulting available modules.
+	 * @param {ChunkGroupInfo} chunkGroupInfo The info object for the chunk group
+	 * @returns {bigint} The mask of available modules after the chunk group
+	 */
+	const calculateResultingAvailableModules = (chunkGroupInfo) => {
+		if (chunkGroupInfo.resultingAvailableModules !== undefined) {
+			return chunkGroupInfo.resultingAvailableModules;
+		}
+
+		let resultingAvailableModules = /** @type {bigint} */ (
+			chunkGroupInfo.minAvailableModules
+		);
+
+		// add the modules from the chunk group to the set
+		for (const chunk of chunkGroupInfo.chunkGroup.chunks) {
+			const mask = /** @type {bigint} */ (maskByChunk.get(chunk));
+			resultingAvailableModules |= mask;
+		}
+
+		return (chunkGroupInfo.resultingAvailableModules =
+			resultingAvailableModules);
+	};
+
+	const processConnectQueue = () => {
+		// Figure out new parents for chunk groups
+		// to get new available modules for these children
+		for (const [chunkGroupInfo, targets] of queueConnect) {
+			// 1. Add new targets to the list of children
+			if (chunkGroupInfo.children === undefined) {
+				chunkGroupInfo.children = new Set();
+			}
+			for (const [target] of targets) {
+				chunkGroupInfo.children.add(target);
+			}
+
+			// 2. Calculate resulting available modules
+			const resultingAvailableModules =
+				calculateResultingAvailableModules(chunkGroupInfo);
+
+			const runtime = chunkGroupInfo.runtime;
+
+			// 3. Update chunk group info
+			for (const [target, processBlock] of targets) {
+				target.availableModulesToBeMerged.push(resultingAvailableModules);
+				chunkGroupsForMerging.add([target, processBlock]);
+				const oldRuntime = target.runtime;
+				const newRuntime = mergeRuntime(oldRuntime, runtime);
+				if (oldRuntime !== newRuntime) {
+					target.runtime = newRuntime;
+					outdatedChunkGroupInfo.add(target);
+				}
+			}
+
+			statConnectedChunkGroups += targets.size;
+		}
+		queueConnect.clear();
+	};
+
+	const processChunkGroupsForMerging = () => {
+		statProcessedChunkGroupsForMerging += chunkGroupsForMerging.size;
+
+		// Execute the merge
+		for (const [info, processBlock] of chunkGroupsForMerging) {
+			const availableModulesToBeMerged = info.availableModulesToBeMerged;
+			const cachedMinAvailableModules = info.minAvailableModules;
+			let minAvailableModules = cachedMinAvailableModules;
+
+			statMergedAvailableModuleSets += availableModulesToBeMerged.length;
+
+			for (const availableModules of availableModulesToBeMerged) {
+				if (minAvailableModules === undefined) {
+					minAvailableModules = availableModules;
+				} else {
+					minAvailableModules &= availableModules;
+				}
+			}
+
+			const changed = minAvailableModules !== cachedMinAvailableModules;
+
+			availableModulesToBeMerged.length = 0;
+			if (changed) {
+				info.minAvailableModules = minAvailableModules;
+				info.resultingAvailableModules = undefined;
+				outdatedChunkGroupInfo.add(info);
+			}
+
+			if (processBlock) {
+				let blocks = blocksByChunkGroups.get(info);
+				if (!blocks) {
+					blocksByChunkGroups.set(info, (blocks = new Set()));
+				}
+
+				// Whether to walk block depends on minAvailableModules and input block.
+				// We can treat creating chunk group as a function with 2 input, entry block and minAvailableModules
+				// If input is the same, we can skip re-walk
+				let needWalkBlock = !info.initialized || changed;
+				if (!blocks.has(processBlock.block)) {
+					needWalkBlock = true;
+					blocks.add(processBlock.block);
+				}
+
+				if (needWalkBlock) {
+					info.initialized = true;
+					queueDelayed.push(processBlock);
+				}
+			}
+		}
+		chunkGroupsForMerging.clear();
+	};
+
+	const processChunkGroupsForCombining = () => {
+		for (const info of chunkGroupsForCombining) {
+			for (const source of /** @type {Set<ChunkGroupInfo>} */ (
+				info.availableSources
+			)) {
+				if (source.minAvailableModules === undefined) {
+					chunkGroupsForCombining.delete(info);
+					break;
+				}
+			}
+		}
+
+		for (const info of chunkGroupsForCombining) {
+			let availableModules = ZERO_BIGINT;
+			// combine minAvailableModules from all resultingAvailableModules
+			for (const source of /** @type {Set<ChunkGroupInfo>} */ (
+				info.availableSources
+			)) {
+				const resultingAvailableModules =
+					calculateResultingAvailableModules(source);
+				availableModules |= resultingAvailableModules;
+			}
+			info.minAvailableModules = availableModules;
+			info.resultingAvailableModules = undefined;
+			outdatedChunkGroupInfo.add(info);
+		}
+		chunkGroupsForCombining.clear();
+	};
+
+	const processOutdatedChunkGroupInfo = () => {
+		statChunkGroupInfoUpdated += outdatedChunkGroupInfo.size;
+		// Revisit skipped elements
+		for (const info of outdatedChunkGroupInfo) {
+			// 1. Reconsider skipped items
+			if (info.skippedItems !== undefined) {
+				const minAvailableModules =
+					/** @type {bigint} */
+					(info.minAvailableModules);
+				for (const module of info.skippedItems) {
+					const ordinal = getModuleOrdinal(module);
+					if (!isOrdinalSetInMask(minAvailableModules, ordinal)) {
+						queue.push({
+							action: ADD_AND_ENTER_MODULE,
+							block: module,
+							module,
+							chunk: info.chunkGroup.chunks[0],
+							chunkGroup: info.chunkGroup,
+							chunkGroupInfo: info
+						});
+						info.skippedItems.delete(module);
+					}
+				}
+			}
+
+			// 2. Reconsider skipped connections
+			if (info.skippedModuleConnections !== undefined) {
+				const minAvailableModules =
+					/** @type {bigint} */
+					(info.minAvailableModules);
+				for (const entry of info.skippedModuleConnections) {
+					const [module, connections] = entry;
+					const activeState = getActiveStateOfConnections(
+						connections,
+						info.runtime
+					);
+					if (activeState === false) continue;
+					if (activeState === true) {
+						const ordinal = getModuleOrdinal(module);
+						info.skippedModuleConnections.delete(entry);
+						if (isOrdinalSetInMask(minAvailableModules, ordinal)) {
+							/** @type {NonNullable<ChunkGroupInfo["skippedItems"]>} */
+							(info.skippedItems).add(module);
+							continue;
+						}
+					}
+					queue.push({
+						action: activeState === true ? ADD_AND_ENTER_MODULE : PROCESS_BLOCK,
+						block: module,
+						module,
+						chunk: info.chunkGroup.chunks[0],
+						chunkGroup: info.chunkGroup,
+						chunkGroupInfo: info
+					});
+				}
+			}
+
+			// 2. Reconsider children chunk groups
+			if (info.children !== undefined) {
+				statChildChunkGroupsReconnected += info.children.size;
+				for (const cgi of info.children) {
+					let connectList = queueConnect.get(info);
+					if (connectList === undefined) {
+						/** @type {ConnectList} */
+						connectList = new Set();
+						queueConnect.set(info, connectList);
+					}
+					connectList.add([cgi, null]);
+				}
+			}
+
+			// 3. Reconsider chunk groups for combining
+			if (info.availableChildren !== undefined) {
+				for (const cgi of info.availableChildren) {
+					chunkGroupsForCombining.add(cgi);
+				}
+			}
+			outdatedOrderIndexChunkGroups.add(info);
+		}
+		outdatedChunkGroupInfo.clear();
+	};
+
+	// Iterative traversal of the Module graph
+	// Recursive would be simpler to write but could result in Stack Overflows
+	while (queue.length || queueConnect.size) {
+		logger.time("visitModules: visiting");
+		processQueue();
+		logger.timeAggregateEnd("visitModules: prepare");
+		logger.timeEnd("visitModules: visiting");
+
+		if (chunkGroupsForCombining.size > 0) {
+			logger.time("visitModules: combine available modules");
+			processChunkGroupsForCombining();
+			logger.timeEnd("visitModules: combine available modules");
+		}
+
+		if (queueConnect.size > 0) {
+			logger.time("visitModules: calculating available modules");
+			processConnectQueue();
+			logger.timeEnd("visitModules: calculating available modules");
+
+			if (chunkGroupsForMerging.size > 0) {
+				logger.time("visitModules: merging available modules");
+				processChunkGroupsForMerging();
+				logger.timeEnd("visitModules: merging available modules");
+			}
+		}
+
+		if (outdatedChunkGroupInfo.size > 0) {
+			logger.time("visitModules: check modules for revisit");
+			processOutdatedChunkGroupInfo();
+			logger.timeEnd("visitModules: check modules for revisit");
+		}
+
+		// Run queueDelayed when all items of the queue are processed
+		// This is important to get the global indexing correct
+		// Async blocks should be processed after all sync blocks are processed
+		if (queue.length === 0) {
+			const tempQueue = queue;
+			queue = queueDelayed.reverse();
+			queueDelayed = tempQueue;
+		}
+	}
+
+	for (const info of outdatedOrderIndexChunkGroups) {
+		const { chunkGroup, runtime } = info;
+
+		const blocks = blocksByChunkGroups.get(info);
+
+		if (!blocks) {
+			continue;
+		}
+
+		for (const block of blocks) {
+			let preOrderIndex = 0;
+			let postOrderIndex = 0;
+			/**
+			 * Processes the provided current.
+			 * @param {DependenciesBlock} current current
+			 * @param {BlocksWithNestedBlocks} visited visited dependencies blocks
+			 */
+			const process = (current, visited) => {
+				const blockModules =
+					/** @type {BlockModulesInFlattenTuples} */
+					(getBlockModules(current, runtime));
+				for (let i = 0, len = blockModules.length; i < len; i += 3) {
+					const activeState = /** @type {ConnectionState} */ (
+						blockModules[i + 1]
+					);
+					if (activeState === false) {
+						continue;
+					}
+					const refModule = /** @type {Module} */ (blockModules[i]);
+					if (visited.has(refModule)) {
+						continue;
+					}
+
+					visited.add(refModule);
+
+					if (refModule) {
+						chunkGroup.setModulePreOrderIndex(refModule, preOrderIndex++);
+						process(refModule, visited);
+						chunkGroup.setModulePostOrderIndex(refModule, postOrderIndex++);
+					}
+				}
+			};
+			process(block, new Set());
+		}
+	}
+	outdatedOrderIndexChunkGroups.clear();
+	ordinalByModule.clear();
+
+	logger.log(
+		`${statProcessedQueueItems} queue items processed (${statProcessedBlocks} blocks)`
+	);
+	logger.log(`${statConnectedChunkGroups} chunk groups connected`);
+	logger.log(
+		`${statProcessedChunkGroupsForMerging} chunk groups processed for merging (${statMergedAvailableModuleSets} module sets, ${statForkedAvailableModules} forked, ${statForkedAvailableModulesCount} + ${statForkedAvailableModulesCountPlus} modules forked, ${statForkedMergedModulesCount} + ${statForkedMergedModulesCountPlus} modules merged into fork, ${statForkedResultModulesCount} resulting modules)`
+	);
+	logger.log(
+		`${statChunkGroupInfoUpdated} chunk group info updated (${statChildChunkGroupsReconnected} already connected chunk groups reconnected)`
+	);
+};
+
+/**
+ * Connects chunk groups.
+ * @param {Compilation} compilation the compilation
+ * @param {BlocksWithNestedBlocks} blocksWithNestedBlocks flag for blocks that have nested blocks
+ * @param {BlockConnections} blockConnections connection for blocks
+ * @param {MaskByChunk} maskByChunk mapping from chunk to module mask
+ */
+const connectChunkGroups = (
+	compilation,
+	blocksWithNestedBlocks,
+	blockConnections,
+	maskByChunk
+) => {
+	const { chunkGraph } = compilation;
+
+	/**
+	 * Helper function to check if all modules of a chunk are available
+	 * @param {ChunkGroup} chunkGroup the chunkGroup to scan
+	 * @param {bigint} availableModules the comparator set
+	 * @returns {boolean} return true if all modules of a chunk are available
+	 */
+	const areModulesAvailable = (chunkGroup, availableModules) => {
+		for (const chunk of chunkGroup.chunks) {
+			const chunkMask = /** @type {bigint} */ (maskByChunk.get(chunk));
+			if ((chunkMask & availableModules) !== chunkMask) return false;
+		}
+		return true;
+	};
+
+	// For each edge in the basic chunk graph
+	for (const [block, connections] of blockConnections) {
+		// 1. Check if connection is needed
+		// When none of the dependencies need to be connected
+		// we can skip all of them
+		// It's not possible to filter each item so it doesn't create inconsistent
+		// connections and modules can only create one version
+		// TODO maybe decide this per runtime
+		if (
+			// TODO is this needed?
+			!blocksWithNestedBlocks.has(block) &&
+			connections.every(({ chunkGroup, originChunkGroupInfo }) =>
+				areModulesAvailable(
+					chunkGroup,
+					/** @type {bigint} */ (originChunkGroupInfo.resultingAvailableModules)
+				)
+			)
+		) {
+			continue;
+		}
+
+		// 2. Foreach edge
+		for (let i = 0; i < connections.length; i++) {
+			const { chunkGroup, originChunkGroupInfo } = connections[i];
+
+			// 3. Connect block with chunk
+			chunkGraph.connectBlockAndChunkGroup(block, chunkGroup);
+
+			// 4. Connect chunk with parent
+			if (originChunkGroupInfo.chunkGroup.addChild(chunkGroup)) {
+				chunkGroup.addParent(originChunkGroupInfo.chunkGroup);
+			}
+		}
+	}
+};
+
+/**
+ * Remove all unconnected chunk groups
+ * @param {Compilation} compilation the compilation
+ * @param {Iterable<ChunkGroup>} allCreatedChunkGroups all chunk groups that where created before
+ */
+const cleanupUnconnectedGroups = (compilation, allCreatedChunkGroups) => {
+	const { chunkGraph } = compilation;
+
+	for (const chunkGroup of allCreatedChunkGroups) {
+		if (chunkGroup.getNumberOfParents() === 0) {
+			for (const chunk of chunkGroup.chunks) {
+				compilation.chunks.delete(chunk);
+				chunkGraph.disconnectChunk(chunk);
+			}
+			chunkGraph.disconnectChunkGroup(chunkGroup);
+			chunkGroup.remove();
+		}
+	}
+};
+
+/**
+ * This method creates the Chunk graph from the Module graph
+ * @param {Compilation} compilation the compilation
+ * @param {InputEntrypointsAndModules} inputEntrypointsAndModules chunk groups which are processed with the modules
+ * @returns {void}
+ */
+const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
+	const logger = compilation.getLogger("webpack.buildChunkGraph");
+
+	// SHARED STATE
+
+	/** @type {BlockConnections} */
+	const blockConnections = new Map();
+
+	/** @type {AllCreatedChunkGroups} */
+	const allCreatedChunkGroups = new Set();
+
+	/** @type {ChunkGroupInfoMap} */
+	const chunkGroupInfoMap = new Map();
+
+	/** @type {BlocksWithNestedBlocks} */
+	const blocksWithNestedBlocks = new Set();
+
+	/** @type {MaskByChunk} */
+	const maskByChunk = new Map();
+
+	// PART ONE
+
+	logger.time("visitModules");
+	visitModules(
+		logger,
+		compilation,
+		inputEntrypointsAndModules,
+		chunkGroupInfoMap,
+		blockConnections,
+		blocksWithNestedBlocks,
+		allCreatedChunkGroups,
+		maskByChunk
+	);
+	logger.timeEnd("visitModules");
+
+	// PART TWO
+
+	logger.time("connectChunkGroups");
+	connectChunkGroups(
+		compilation,
+		blocksWithNestedBlocks,
+		blockConnections,
+		maskByChunk
+	);
+	logger.timeEnd("connectChunkGroups");
+
+	for (const [chunkGroup, chunkGroupInfo] of chunkGroupInfoMap) {
+		for (const chunk of chunkGroup.chunks) {
+			chunk.runtime = mergeRuntime(chunk.runtime, chunkGroupInfo.runtime);
+		}
+	}
+
+	// Cleanup work
+
+	logger.time("cleanup");
+	cleanupUnconnectedGroups(compilation, allCreatedChunkGroups);
+	logger.timeEnd("cleanup");
+};
+
+module.exports = buildChunkGraph;
Index: frontend/node_modules/webpack/lib/cache/AddBuildDependenciesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/AddBuildDependenciesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/AddBuildDependenciesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,33 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "AddBuildDependenciesPlugin";
+
+class AddBuildDependenciesPlugin {
+	/**
+	 * Creates an instance of AddBuildDependenciesPlugin.
+	 * @param {Iterable<string>} buildDependencies list of build dependencies
+	 */
+	constructor(buildDependencies) {
+		this.buildDependencies = new Set(buildDependencies);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.buildDependencies.addAll(this.buildDependencies);
+		});
+	}
+}
+
+module.exports = AddBuildDependenciesPlugin;
Index: frontend/node_modules/webpack/lib/cache/AddManagedPathsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/AddManagedPathsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/AddManagedPathsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Compiler")} Compiler */
+
+class AddManagedPathsPlugin {
+	/**
+	 * Creates an instance of AddManagedPathsPlugin.
+	 * @param {Iterable<string | RegExp>} managedPaths list of managed paths
+	 * @param {Iterable<string | RegExp>} immutablePaths list of immutable paths
+	 * @param {Iterable<string | RegExp>} unmanagedPaths list of unmanaged paths
+	 */
+	constructor(managedPaths, immutablePaths, unmanagedPaths) {
+		this.managedPaths = new Set(managedPaths);
+		this.immutablePaths = new Set(immutablePaths);
+		this.unmanagedPaths = new Set(unmanagedPaths);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		for (const managedPath of this.managedPaths) {
+			compiler.managedPaths.add(managedPath);
+		}
+		for (const immutablePath of this.immutablePaths) {
+			compiler.immutablePaths.add(immutablePath);
+		}
+		for (const unmanagedPath of this.unmanagedPaths) {
+			compiler.unmanagedPaths.add(unmanagedPath);
+		}
+	}
+}
+
+module.exports = AddManagedPathsPlugin;
Index: frontend/node_modules/webpack/lib/cache/IdleFileCachePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/IdleFileCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/IdleFileCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,243 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Cache = require("../Cache");
+const ProgressPlugin = require("../ProgressPlugin");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./PackFileCacheStrategy")} PackFileCacheStrategy */
+
+const BUILD_DEPENDENCIES_KEY = Symbol("build dependencies key");
+const PLUGIN_NAME = "IdleFileCachePlugin";
+
+class IdleFileCachePlugin {
+	/**
+	 * Creates an instance of IdleFileCachePlugin.
+	 * @param {PackFileCacheStrategy} strategy cache strategy
+	 * @param {number} idleTimeout timeout
+	 * @param {number} idleTimeoutForInitialStore initial timeout
+	 * @param {number} idleTimeoutAfterLargeChanges timeout after changes
+	 */
+	constructor(
+		strategy,
+		idleTimeout,
+		idleTimeoutForInitialStore,
+		idleTimeoutAfterLargeChanges
+	) {
+		this.strategy = strategy;
+		this.idleTimeout = idleTimeout;
+		this.idleTimeoutForInitialStore = idleTimeoutForInitialStore;
+		this.idleTimeoutAfterLargeChanges = idleTimeoutAfterLargeChanges;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const strategy = this.strategy;
+		const idleTimeout = this.idleTimeout;
+		const idleTimeoutForInitialStore = Math.min(
+			idleTimeout,
+			this.idleTimeoutForInitialStore
+		);
+		const idleTimeoutAfterLargeChanges = this.idleTimeoutAfterLargeChanges;
+		const resolvedPromise = Promise.resolve();
+
+		let timeSpendInBuild = 0;
+		let timeSpendInStore = 0;
+		let avgTimeSpendInStore = 0;
+
+		/** @type {Map<string | typeof BUILD_DEPENDENCIES_KEY, () => Promise<void | void[]>>} */
+		const pendingIdleTasks = new Map();
+
+		compiler.cache.hooks.store.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
+			(identifier, etag, data) => {
+				pendingIdleTasks.set(identifier, () =>
+					strategy.store(identifier, etag, data)
+				);
+			}
+		);
+
+		compiler.cache.hooks.get.tapPromise(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
+			(identifier, etag, gotHandlers) => {
+				const restore = () =>
+					strategy.restore(identifier, etag).then((cacheEntry) => {
+						if (cacheEntry === undefined) {
+							gotHandlers.push((result, callback) => {
+								if (result !== undefined) {
+									pendingIdleTasks.set(identifier, () =>
+										strategy.store(identifier, etag, result)
+									);
+								}
+								callback();
+							});
+						} else {
+							return cacheEntry;
+						}
+					});
+				const pendingTask = pendingIdleTasks.get(identifier);
+				if (pendingTask !== undefined) {
+					pendingIdleTasks.delete(identifier);
+					return pendingTask().then(restore);
+				}
+				return restore();
+			}
+		);
+
+		compiler.cache.hooks.storeBuildDependencies.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
+			(dependencies) => {
+				pendingIdleTasks.set(BUILD_DEPENDENCIES_KEY, () =>
+					Promise.resolve().then(() =>
+						strategy.storeBuildDependencies(dependencies)
+					)
+				);
+			}
+		);
+
+		compiler.cache.hooks.shutdown.tapPromise(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
+			() => {
+				if (idleTimer) {
+					clearTimeout(idleTimer);
+					idleTimer = undefined;
+				}
+				isIdle = false;
+				const reportProgress = ProgressPlugin.getReporter(compiler);
+				const jobs = [...pendingIdleTasks.values()];
+				if (reportProgress) reportProgress(0, "process pending cache items");
+				const promises = jobs.map((fn) => fn());
+				pendingIdleTasks.clear();
+				promises.push(currentIdlePromise);
+				const promise = Promise.all(promises);
+				currentIdlePromise = promise.then(() => strategy.afterAllStored());
+				if (reportProgress) {
+					currentIdlePromise = currentIdlePromise.then(() => {
+						reportProgress(1, "stored");
+					});
+				}
+				return currentIdlePromise.then(() => {
+					// Reset strategy
+					if (strategy.clear) strategy.clear();
+				});
+			}
+		);
+
+		/** @type {Promise<void | void[]>} */
+		let currentIdlePromise = resolvedPromise;
+		let isIdle = false;
+		let isInitialStore = true;
+		const processIdleTasks = () => {
+			if (isIdle) {
+				const startTime = Date.now();
+				if (pendingIdleTasks.size > 0) {
+					const promises = [currentIdlePromise];
+					const maxTime = startTime + 100;
+					let maxCount = 100;
+					for (const [filename, factory] of pendingIdleTasks) {
+						pendingIdleTasks.delete(filename);
+						promises.push(factory());
+						if (maxCount-- <= 0 || Date.now() > maxTime) break;
+					}
+					currentIdlePromise = Promise.all(
+						/** @type {Promise<void>[]} */
+						(promises)
+					);
+					currentIdlePromise.then(() => {
+						timeSpendInStore += Date.now() - startTime;
+						// Allow to exit the process between
+						idleTimer = setTimeout(processIdleTasks, 0);
+						idleTimer.unref();
+					});
+					return;
+				}
+				currentIdlePromise = currentIdlePromise
+					.then(async () => {
+						await strategy.afterAllStored();
+						timeSpendInStore += Date.now() - startTime;
+						avgTimeSpendInStore =
+							Math.max(avgTimeSpendInStore, timeSpendInStore) * 0.9 +
+							timeSpendInStore * 0.1;
+						timeSpendInStore = 0;
+						timeSpendInBuild = 0;
+					})
+					.catch((err) => {
+						const logger = compiler.getInfrastructureLogger(PLUGIN_NAME);
+						logger.warn(`Background tasks during idle failed: ${err.message}`);
+						logger.debug(err.stack);
+					});
+				isInitialStore = false;
+			}
+		};
+		/** @type {ReturnType<typeof setTimeout> | undefined} */
+		let idleTimer;
+		compiler.cache.hooks.beginIdle.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
+			() => {
+				const isLargeChange = timeSpendInBuild > avgTimeSpendInStore * 2;
+				if (isInitialStore && idleTimeoutForInitialStore < idleTimeout) {
+					compiler
+						.getInfrastructureLogger(PLUGIN_NAME)
+						.log(
+							`Initial cache was generated and cache will be persisted in ${
+								idleTimeoutForInitialStore / 1000
+							}s.`
+						);
+				} else if (
+					isLargeChange &&
+					idleTimeoutAfterLargeChanges < idleTimeout
+				) {
+					compiler
+						.getInfrastructureLogger(PLUGIN_NAME)
+						.log(
+							`Spend ${Math.round(timeSpendInBuild) / 1000}s in build and ${
+								Math.round(avgTimeSpendInStore) / 1000
+							}s in average in cache store. This is considered as large change and cache will be persisted in ${
+								idleTimeoutAfterLargeChanges / 1000
+							}s.`
+						);
+				}
+				idleTimer = setTimeout(
+					() => {
+						idleTimer = undefined;
+						isIdle = true;
+						resolvedPromise.then(processIdleTasks);
+					},
+					Math.min(
+						isInitialStore ? idleTimeoutForInitialStore : Infinity,
+						isLargeChange ? idleTimeoutAfterLargeChanges : Infinity,
+						idleTimeout
+					)
+				);
+				idleTimer.unref();
+			}
+		);
+		compiler.cache.hooks.endIdle.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
+			() => {
+				if (idleTimer) {
+					clearTimeout(idleTimer);
+					idleTimer = undefined;
+				}
+				isIdle = false;
+			}
+		);
+		compiler.hooks.done.tap(PLUGIN_NAME, (stats) => {
+			// 10% build overhead is ignored, as it's not cacheable
+			timeSpendInBuild *= 0.9;
+			timeSpendInBuild +=
+				/** @type {number} */ (stats.endTime) -
+				/** @type {number} */ (stats.startTime);
+		});
+	}
+}
+
+module.exports = IdleFileCachePlugin;
Index: frontend/node_modules/webpack/lib/cache/MemoryCachePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/MemoryCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/MemoryCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,57 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Cache = require("../Cache");
+
+/** @typedef {import("../Cache").Data} Data */
+/** @typedef {import("../Cache").Etag} Etag */
+/** @typedef {import("../Compiler")} Compiler */
+
+class MemoryCachePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		/** @type {Map<string, { etag: Etag | null, data: Data } | null>} */
+		const cache = new Map();
+		compiler.cache.hooks.store.tap(
+			{ name: "MemoryCachePlugin", stage: Cache.STAGE_MEMORY },
+			(identifier, etag, data) => {
+				cache.set(identifier, { etag, data });
+			}
+		);
+		compiler.cache.hooks.get.tap(
+			{ name: "MemoryCachePlugin", stage: Cache.STAGE_MEMORY },
+			(identifier, etag, gotHandlers) => {
+				const cacheEntry = cache.get(identifier);
+				if (cacheEntry === null) {
+					return null;
+				} else if (cacheEntry !== undefined) {
+					return cacheEntry.etag === etag ? cacheEntry.data : null;
+				}
+				gotHandlers.push((result, callback) => {
+					if (result === undefined) {
+						cache.set(identifier, null);
+					} else {
+						cache.set(identifier, { etag, data: result });
+					}
+					return callback();
+				});
+			}
+		);
+		compiler.cache.hooks.shutdown.tap(
+			{ name: "MemoryCachePlugin", stage: Cache.STAGE_MEMORY },
+			() => {
+				cache.clear();
+			}
+		);
+	}
+}
+
+module.exports = MemoryCachePlugin;
Index: frontend/node_modules/webpack/lib/cache/MemoryWithGcCachePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/MemoryWithGcCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/MemoryWithGcCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,144 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Cache = require("../Cache");
+
+/** @typedef {import("../Cache").Data} Data */
+/** @typedef {import("../Cache").Etag} Etag */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the memory with gc cache plugin options type used by this module.
+ * @typedef {object} MemoryWithGcCachePluginOptions
+ * @property {number} maxGenerations max generations
+ */
+
+const PLUGIN_NAME = "MemoryWithGcCachePlugin";
+
+class MemoryWithGcCachePlugin {
+	/**
+	 * Creates an instance of MemoryWithGcCachePlugin.
+	 * @param {MemoryWithGcCachePluginOptions} options options
+	 */
+	constructor({ maxGenerations }) {
+		this._maxGenerations = maxGenerations;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const maxGenerations = this._maxGenerations;
+		/** @type {Map<string, { etag: Etag | null, data: Data } | undefined | null>} */
+		const cache = new Map();
+		/** @type {Map<string, { entry: { etag: Etag | null, data: Data } | null, until: number }>} */
+		const oldCache = new Map();
+		let generation = 0;
+		let cachePosition = 0;
+		const logger = compiler.getInfrastructureLogger(PLUGIN_NAME);
+		compiler.hooks.afterDone.tap(PLUGIN_NAME, () => {
+			generation++;
+			let clearedEntries = 0;
+			/** @type {undefined | string} */
+			let lastClearedIdentifier;
+			// Avoid coverage problems due indirect changes
+			/* istanbul ignore next */
+			for (const [identifier, entry] of oldCache) {
+				if (entry.until > generation) break;
+
+				oldCache.delete(identifier);
+				if (cache.get(identifier) === undefined) {
+					cache.delete(identifier);
+					clearedEntries++;
+					lastClearedIdentifier = identifier;
+				}
+			}
+			if (clearedEntries > 0 || oldCache.size > 0) {
+				logger.log(
+					`${cache.size - oldCache.size} active entries, ${
+						oldCache.size
+					} recently unused cached entries${
+						clearedEntries > 0
+							? `, ${clearedEntries} old unused cache entries removed e. g. ${lastClearedIdentifier}`
+							: ""
+					}`
+				);
+			}
+			let i = (cache.size / maxGenerations) | 0;
+			let j = cachePosition >= cache.size ? 0 : cachePosition;
+			cachePosition = j + i;
+			for (const [identifier, entry] of cache) {
+				if (j !== 0) {
+					j--;
+					continue;
+				}
+				if (entry !== undefined) {
+					// We don't delete the cache entry, but set it to undefined instead
+					// This reserves the location in the data table and avoids rehashing
+					// when constantly adding and removing entries.
+					// It will be deleted when removed from oldCache.
+					cache.set(identifier, undefined);
+					oldCache.delete(identifier);
+					oldCache.set(identifier, {
+						entry,
+						until: generation + maxGenerations
+					});
+					if (i-- === 0) break;
+				}
+			}
+		});
+		compiler.cache.hooks.store.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_MEMORY },
+			(identifier, etag, data) => {
+				cache.set(identifier, { etag, data });
+			}
+		);
+		compiler.cache.hooks.get.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_MEMORY },
+			(identifier, etag, gotHandlers) => {
+				const cacheEntry = cache.get(identifier);
+				if (cacheEntry === null) {
+					return null;
+				} else if (cacheEntry !== undefined) {
+					return cacheEntry.etag === etag ? cacheEntry.data : null;
+				}
+				const oldCacheEntry = oldCache.get(identifier);
+				if (oldCacheEntry !== undefined) {
+					const cacheEntry = oldCacheEntry.entry;
+					if (cacheEntry === null) {
+						oldCache.delete(identifier);
+						cache.set(identifier, cacheEntry);
+						return null;
+					}
+					if (cacheEntry.etag !== etag) return null;
+					oldCache.delete(identifier);
+					cache.set(identifier, cacheEntry);
+					return cacheEntry.data;
+				}
+				gotHandlers.push((result, callback) => {
+					if (result === undefined) {
+						cache.set(identifier, null);
+					} else {
+						cache.set(identifier, { etag, data: result });
+					}
+					return callback();
+				});
+			}
+		);
+		compiler.cache.hooks.shutdown.tap(
+			{ name: PLUGIN_NAME, stage: Cache.STAGE_MEMORY },
+			() => {
+				cache.clear();
+				oldCache.clear();
+			}
+		);
+	}
+}
+
+module.exports = MemoryWithGcCachePlugin;
Index: frontend/node_modules/webpack/lib/cache/PackFileCacheStrategy.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/PackFileCacheStrategy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/PackFileCacheStrategy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1629 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const FileSystemInfo = require("../FileSystemInfo");
+const ProgressPlugin = require("../ProgressPlugin");
+const SerializerMiddleware = require("../serialization/SerializerMiddleware");
+const LazySet = require("../util/LazySet");
+const formatSize = require("../util/formatSize");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+const {
+	NOT_SERIALIZABLE,
+	createFileSerializer
+} = require("../util/serialization");
+
+/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
+/** @typedef {import("../Compilation").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("../Cache").Data} Data */
+/** @typedef {import("../Cache").Etag} Etag */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../FileSystemInfo").ResolveBuildDependenciesResult} ResolveBuildDependenciesResult */
+/** @typedef {import("../FileSystemInfo").ResolveResults} ResolveResults */
+/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
+/** @typedef {import("../logging/Logger").Logger} Logger */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
+
+/** @typedef {Set<string>} Items */
+/** @typedef {Set<string>} BuildDependencies */
+/** @typedef {Map<string, PackItemInfo>} ItemInfo */
+
+class PackContainer {
+	/**
+	 * Creates an instance of PackContainer.
+	 * @param {Pack} data stored data
+	 * @param {string} version version identifier
+	 * @param {Snapshot} buildSnapshot snapshot of all build dependencies
+	 * @param {BuildDependencies} buildDependencies list of all unresolved build dependencies captured
+	 * @param {ResolveResults} resolveResults result of the resolved build dependencies
+	 * @param {Snapshot} resolveBuildDependenciesSnapshot snapshot of the dependencies of the build dependencies resolving
+	 */
+	constructor(
+		data,
+		version,
+		buildSnapshot,
+		buildDependencies,
+		resolveResults,
+		resolveBuildDependenciesSnapshot
+	) {
+		/** @type {Pack | (() => Pack)} */
+		this.data = data;
+		/** @type {string} */
+		this.version = version;
+		/** @type {Snapshot} */
+		this.buildSnapshot = buildSnapshot;
+		/** @type {BuildDependencies} */
+		this.buildDependencies = buildDependencies;
+		/** @type {ResolveResults} */
+		this.resolveResults = resolveResults;
+		/** @type {Snapshot} */
+		this.resolveBuildDependenciesSnapshot = resolveBuildDependenciesSnapshot;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write, writeLazy }) {
+		write(this.version);
+		write(this.buildSnapshot);
+		write(this.buildDependencies);
+		write(this.resolveResults);
+		write(this.resolveBuildDependenciesSnapshot);
+		/** @type {NonNullable<ObjectSerializerContext["writeLazy"]>} */
+		(writeLazy)(this.data);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize({ read }) {
+		this.version = read();
+		this.buildSnapshot = read();
+		this.buildDependencies = read();
+		this.resolveResults = read();
+		this.resolveBuildDependenciesSnapshot = read();
+		this.data = read();
+	}
+}
+
+makeSerializable(
+	PackContainer,
+	"webpack/lib/cache/PackFileCacheStrategy",
+	"PackContainer"
+);
+
+const MIN_CONTENT_SIZE = 1024 * 1024; // 1 MB
+const CONTENT_COUNT_TO_MERGE = 10;
+const MIN_ITEMS_IN_FRESH_PACK = 100;
+const MAX_ITEMS_IN_FRESH_PACK = 50000;
+const MAX_TIME_IN_FRESH_PACK = 60 * 1000; // 1 min
+
+class PackItemInfo {
+	/**
+	 * Creates an instance of PackItemInfo.
+	 * @param {string} identifier identifier of item
+	 * @param {string | null | undefined} etag etag of item
+	 * @param {Data} value fresh value of item
+	 */
+	constructor(identifier, etag, value) {
+		/** @type {string} */
+		this.identifier = identifier;
+		/** @type {string | null | undefined} */
+		this.etag = etag;
+		/** @type {number} */
+		this.location = -1;
+		/** @type {number} */
+		this.lastAccess = Date.now();
+		/** @type {Data} */
+		this.freshValue = value;
+	}
+}
+
+class Pack {
+	/**
+	 * Creates an instance of Pack.
+	 * @param {Logger} logger a logger
+	 * @param {number} maxAge max age of cache items
+	 */
+	constructor(logger, maxAge) {
+		/** @type {ItemInfo} */
+		this.itemInfo = new Map();
+		/** @type {(string | undefined)[]} */
+		this.requests = [];
+		/** @type {undefined | NodeJS.Timeout} */
+		this.requestsTimeout = undefined;
+		/** @type {ItemInfo} */
+		this.freshContent = new Map();
+		/** @type {(undefined | PackContent)[]} */
+		this.content = [];
+		/** @type {boolean} */
+		this.invalid = false;
+		/** @type {Logger} */
+		this.logger = logger;
+		/** @type {number} */
+		this.maxAge = maxAge;
+	}
+
+	/**
+	 * Adds the provided identifier to the pack.
+	 * @param {string} identifier identifier
+	 */
+	_addRequest(identifier) {
+		this.requests.push(identifier);
+		if (this.requestsTimeout === undefined) {
+			this.requestsTimeout = setTimeout(() => {
+				this.requests.push(undefined);
+				this.requestsTimeout = undefined;
+			}, MAX_TIME_IN_FRESH_PACK);
+			if (this.requestsTimeout.unref) this.requestsTimeout.unref();
+		}
+	}
+
+	stopCapturingRequests() {
+		if (this.requestsTimeout !== undefined) {
+			clearTimeout(this.requestsTimeout);
+			this.requestsTimeout = undefined;
+		}
+	}
+
+	/**
+	 * Returns cached content.
+	 * @param {string} identifier unique name for the resource
+	 * @param {string | null} etag etag of the resource
+	 * @returns {Data} cached content
+	 */
+	get(identifier, etag) {
+		const info = this.itemInfo.get(identifier);
+		this._addRequest(identifier);
+		if (info === undefined) {
+			return;
+		}
+		if (info.etag !== etag) return null;
+		info.lastAccess = Date.now();
+		const loc = info.location;
+		if (loc === -1) {
+			return info.freshValue;
+		}
+		if (!this.content[loc]) {
+			return;
+		}
+		return /** @type {PackContent} */ (this.content[loc]).get(identifier);
+	}
+
+	/**
+	 * Updates value using the provided identifier.
+	 * @param {string} identifier unique name for the resource
+	 * @param {string | null} etag etag of the resource
+	 * @param {Data} data cached content
+	 * @returns {void}
+	 */
+	set(identifier, etag, data) {
+		if (!this.invalid) {
+			this.invalid = true;
+			this.logger.log(`Pack got invalid because of write to: ${identifier}`);
+		}
+		const info = this.itemInfo.get(identifier);
+		if (info === undefined) {
+			const newInfo = new PackItemInfo(identifier, etag, data);
+			this.itemInfo.set(identifier, newInfo);
+			this._addRequest(identifier);
+			this.freshContent.set(identifier, newInfo);
+		} else {
+			const loc = info.location;
+			if (loc >= 0) {
+				this._addRequest(identifier);
+				this.freshContent.set(identifier, info);
+				const content = /** @type {PackContent} */ (this.content[loc]);
+				content.delete(identifier);
+				if (content.items.size === 0) {
+					this.content[loc] = undefined;
+					this.logger.debug("Pack %d got empty and is removed", loc);
+				}
+			}
+			info.freshValue = data;
+			info.lastAccess = Date.now();
+			info.etag = etag;
+			info.location = -1;
+		}
+	}
+
+	getContentStats() {
+		let count = 0;
+		let size = 0;
+		for (const content of this.content) {
+			if (content !== undefined) {
+				count++;
+				const s = content.getSize();
+				if (s > 0) {
+					size += s;
+				}
+			}
+		}
+		return { count, size };
+	}
+
+	/**
+	 * Returns new location of data entries.
+	 * @returns {number} new location of data entries
+	 */
+	_findLocation() {
+		/** @type {number} */
+		let i;
+		for (i = 0; i < this.content.length && this.content[i] !== undefined; i++);
+		return i;
+	}
+
+	/**
+	 * Gc and update location.
+	 * @private
+	 * @param {Items} items items
+	 * @param {Items} usedItems used items
+	 * @param {number} newLoc new location
+	 */
+	_gcAndUpdateLocation(items, usedItems, newLoc) {
+		let count = 0;
+		/** @type {undefined | string} */
+		let lastGC;
+		const now = Date.now();
+		for (const identifier of items) {
+			const info = /** @type {PackItemInfo} */ (this.itemInfo.get(identifier));
+			if (now - info.lastAccess > this.maxAge) {
+				this.itemInfo.delete(identifier);
+				items.delete(identifier);
+				usedItems.delete(identifier);
+				count++;
+				lastGC = identifier;
+			} else {
+				info.location = newLoc;
+			}
+		}
+		if (count > 0) {
+			this.logger.log(
+				"Garbage Collected %d old items at pack %d (%d items remaining) e. g. %s",
+				count,
+				newLoc,
+				items.size,
+				lastGC
+			);
+		}
+	}
+
+	_persistFreshContent() {
+		/** @typedef {{ items: Items, map: Content, loc: number }} PackItem */
+		const itemsCount = this.freshContent.size;
+		if (itemsCount > 0) {
+			const packCount = Math.ceil(itemsCount / MAX_ITEMS_IN_FRESH_PACK);
+			const itemsPerPack = Math.ceil(itemsCount / packCount);
+			/** @type {PackItem[]} */
+			const packs = [];
+			let i = 0;
+			let ignoreNextTimeTick = false;
+			const createNextPack = () => {
+				const loc = this._findLocation();
+				this.content[loc] = /** @type {EXPECTED_ANY} */ (null); // reserve
+				/** @type {PackItem} */
+				const pack = {
+					items: new Set(),
+					map: new Map(),
+					loc
+				};
+				packs.push(pack);
+				return pack;
+			};
+			let pack = createNextPack();
+			if (this.requestsTimeout !== undefined) {
+				clearTimeout(this.requestsTimeout);
+			}
+			for (const identifier of this.requests) {
+				if (identifier === undefined) {
+					if (ignoreNextTimeTick) {
+						ignoreNextTimeTick = false;
+					} else if (pack.items.size >= MIN_ITEMS_IN_FRESH_PACK) {
+						i = 0;
+						pack = createNextPack();
+					}
+					continue;
+				}
+				const info = this.freshContent.get(identifier);
+				if (info === undefined) continue;
+				pack.items.add(identifier);
+				pack.map.set(identifier, info.freshValue);
+				info.location = pack.loc;
+				info.freshValue = undefined;
+				this.freshContent.delete(identifier);
+				if (++i > itemsPerPack) {
+					i = 0;
+					pack = createNextPack();
+					ignoreNextTimeTick = true;
+				}
+			}
+			this.requests.length = 0;
+			for (const pack of packs) {
+				this.content[pack.loc] = new PackContent(
+					pack.items,
+					new Set(pack.items),
+					new PackContentItems(pack.map)
+				);
+			}
+			this.logger.log(
+				`${itemsCount} fresh items in cache put into pack ${
+					packs.length > 1
+						? packs
+								.map((pack) => `${pack.loc} (${pack.items.size} items)`)
+								.join(", ")
+						: packs[0].loc
+				}`
+			);
+		}
+	}
+
+	/**
+	 * Merges small content files to a single content file
+	 */
+	_optimizeSmallContent() {
+		// 1. Find all small content files
+		// Treat unused content files separately to avoid
+		// a merge-split cycle
+		/** @type {number[]} */
+		const smallUsedContents = [];
+		/** @type {number} */
+		let smallUsedContentSize = 0;
+		/** @type {number[]} */
+		const smallUnusedContents = [];
+		/** @type {number} */
+		let smallUnusedContentSize = 0;
+		for (let i = 0; i < this.content.length; i++) {
+			const content = this.content[i];
+			if (content === undefined) continue;
+			if (content.outdated) continue;
+			const size = content.getSize();
+			if (size < 0 || size > MIN_CONTENT_SIZE) continue;
+			if (content.used.size > 0) {
+				smallUsedContents.push(i);
+				smallUsedContentSize += size;
+			} else {
+				smallUnusedContents.push(i);
+				smallUnusedContentSize += size;
+			}
+		}
+
+		// 2. Check if minimum number is reached
+		/** @type {number[]} */
+		let mergedIndices;
+		if (
+			smallUsedContents.length >= CONTENT_COUNT_TO_MERGE ||
+			smallUsedContentSize > MIN_CONTENT_SIZE
+		) {
+			mergedIndices = smallUsedContents;
+		} else if (
+			smallUnusedContents.length >= CONTENT_COUNT_TO_MERGE ||
+			smallUnusedContentSize > MIN_CONTENT_SIZE
+		) {
+			mergedIndices = smallUnusedContents;
+		} else {
+			return;
+		}
+
+		/** @type {PackContent[]} */
+		const mergedContent = [];
+
+		// 3. Remove old content entries
+		for (const i of mergedIndices) {
+			mergedContent.push(/** @type {PackContent} */ (this.content[i]));
+			this.content[i] = undefined;
+		}
+
+		// 4. Determine merged items
+		/** @type {Items} */
+		const mergedItems = new Set();
+		/** @type {Items} */
+		const mergedUsedItems = new Set();
+		/** @type {((map: Content) => Promise<void>)[]} */
+		const addToMergedMap = [];
+		for (const content of mergedContent) {
+			for (const identifier of content.items) {
+				mergedItems.add(identifier);
+			}
+			for (const identifier of content.used) {
+				mergedUsedItems.add(identifier);
+			}
+			addToMergedMap.push(async (map) => {
+				// unpack existing content
+				// after that values are accessible in .content
+				await content.unpack(
+					"it should be merged with other small pack contents"
+				);
+				for (const [identifier, value] of /** @type {Content} */ (
+					content.content
+				)) {
+					map.set(identifier, value);
+				}
+			});
+		}
+
+		// 5. GC and update location of merged items
+		const newLoc = this._findLocation();
+		this._gcAndUpdateLocation(mergedItems, mergedUsedItems, newLoc);
+
+		// 6. If not empty, store content somewhere
+		if (mergedItems.size > 0) {
+			this.content[newLoc] = new PackContent(
+				mergedItems,
+				mergedUsedItems,
+				memoize(async () => {
+					/** @type {Content} */
+					const map = new Map();
+					await Promise.all(addToMergedMap.map((fn) => fn(map)));
+					return new PackContentItems(map);
+				})
+			);
+			this.logger.log(
+				"Merged %d small files with %d cache items into pack %d",
+				mergedContent.length,
+				mergedItems.size,
+				newLoc
+			);
+		}
+	}
+
+	/**
+	 * Split large content files with used and unused items
+	 * into two parts to separate used from unused items
+	 */
+	_optimizeUnusedContent() {
+		// 1. Find a large content file with used and unused items
+		for (let i = 0; i < this.content.length; i++) {
+			const content = this.content[i];
+			if (content === undefined) continue;
+			const size = content.getSize();
+			if (size < MIN_CONTENT_SIZE) continue;
+			const used = content.used.size;
+			const total = content.items.size;
+			if (used > 0 && used < total) {
+				// 2. Remove this content
+				this.content[i] = undefined;
+
+				// 3. Determine items for the used content file
+				const usedItems = new Set(content.used);
+				const newLoc = this._findLocation();
+				this._gcAndUpdateLocation(usedItems, usedItems, newLoc);
+
+				// 4. Create content file for used items
+				if (usedItems.size > 0) {
+					this.content[newLoc] = new PackContent(
+						usedItems,
+						new Set(usedItems),
+						async () => {
+							await content.unpack(
+								"it should be splitted into used and unused items"
+							);
+							/** @type {Content} */
+							const map = new Map();
+							for (const identifier of usedItems) {
+								map.set(
+									identifier,
+									/** @type {Content} */
+									(content.content).get(identifier)
+								);
+							}
+							return new PackContentItems(map);
+						}
+					);
+				}
+
+				// 5. Determine items for the unused content file
+				const unusedItems = new Set(content.items);
+				/** @type {Items} */
+				const usedOfUnusedItems = new Set();
+				for (const identifier of usedItems) {
+					unusedItems.delete(identifier);
+				}
+				const newUnusedLoc = this._findLocation();
+				this._gcAndUpdateLocation(unusedItems, usedOfUnusedItems, newUnusedLoc);
+
+				// 6. Create content file for unused items
+				if (unusedItems.size > 0) {
+					this.content[newUnusedLoc] = new PackContent(
+						unusedItems,
+						usedOfUnusedItems,
+						async () => {
+							await content.unpack(
+								"it should be splitted into used and unused items"
+							);
+							/** @type {Content} */
+							const map = new Map();
+							for (const identifier of unusedItems) {
+								map.set(
+									identifier,
+									/** @type {Content} */
+									(content.content).get(identifier)
+								);
+							}
+							return new PackContentItems(map);
+						}
+					);
+				}
+
+				this.logger.log(
+					"Split pack %d into pack %d with %d used items and pack %d with %d unused items",
+					i,
+					newLoc,
+					usedItems.size,
+					newUnusedLoc,
+					unusedItems.size
+				);
+
+				// optimizing only one of them is good enough and
+				// reduces the amount of serialization needed
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Find the content with the oldest item and run GC on that.
+	 * Only runs for one content to avoid large invalidation.
+	 */
+	_gcOldestContent() {
+		/** @type {PackItemInfo | undefined} */
+		let oldest;
+		for (const info of this.itemInfo.values()) {
+			if (oldest === undefined || info.lastAccess < oldest.lastAccess) {
+				oldest = info;
+			}
+		}
+		if (
+			Date.now() - /** @type {PackItemInfo} */ (oldest).lastAccess >
+			this.maxAge
+		) {
+			const loc = /** @type {PackItemInfo} */ (oldest).location;
+			if (loc < 0) return;
+			const content = /** @type {PackContent} */ (this.content[loc]);
+			const items = new Set(content.items);
+			const usedItems = new Set(content.used);
+			this._gcAndUpdateLocation(items, usedItems, loc);
+
+			this.content[loc] =
+				items.size > 0
+					? new PackContent(items, usedItems, async () => {
+							await content.unpack(
+								"it contains old items that should be garbage collected"
+							);
+							/** @type {Content} */
+							const map = new Map();
+							for (const identifier of items) {
+								map.set(
+									identifier,
+									/** @type {Content} */
+									(content.content).get(identifier)
+								);
+							}
+							return new PackContentItems(map);
+						})
+					: undefined;
+		}
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write, writeSeparate }) {
+		this._persistFreshContent();
+		this._optimizeSmallContent();
+		this._optimizeUnusedContent();
+		this._gcOldestContent();
+		for (const identifier of this.itemInfo.keys()) {
+			write(identifier);
+		}
+		write(null); // null as marker of the end of keys
+		for (const info of this.itemInfo.values()) {
+			write(info.etag);
+		}
+		for (const info of this.itemInfo.values()) {
+			write(info.lastAccess);
+		}
+		for (let i = 0; i < this.content.length; i++) {
+			const content = this.content[i];
+			if (content !== undefined) {
+				write(content.items);
+				content.writeLazy((lazy) =>
+					/** @type {NonNullable<ObjectSerializerContext["writeSeparate"]>} */
+					(writeSeparate)(lazy, { name: `${i}` })
+				);
+			} else {
+				write(undefined); // undefined marks an empty content slot
+			}
+		}
+		write(null); // null as marker of the end of items
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext & { logger: Logger }} context context
+	 */
+	deserialize({ read, logger }) {
+		this.logger = logger;
+		{
+			const items = [];
+			let item = read();
+			while (item !== null) {
+				items.push(item);
+				item = read();
+			}
+			this.itemInfo.clear();
+			const infoItems = items.map((identifier) => {
+				const info = new PackItemInfo(identifier, undefined, undefined);
+				this.itemInfo.set(identifier, info);
+				return info;
+			});
+			for (const info of infoItems) {
+				info.etag = read();
+			}
+			for (const info of infoItems) {
+				info.lastAccess = read();
+			}
+		}
+		this.content.length = 0;
+		let items = read();
+		while (items !== null) {
+			if (items === undefined) {
+				this.content.push(items);
+			} else {
+				const idx = this.content.length;
+				const lazy = read();
+				this.content.push(
+					new PackContent(
+						items,
+						new Set(),
+						lazy,
+						logger,
+						`${this.content.length}`
+					)
+				);
+				for (const identifier of items) {
+					/** @type {PackItemInfo} */
+					(this.itemInfo.get(identifier)).location = idx;
+				}
+			}
+			items = read();
+		}
+	}
+}
+
+makeSerializable(Pack, "webpack/lib/cache/PackFileCacheStrategy", "Pack");
+
+/** @typedef {Map<string, Data>} Content */
+
+class PackContentItems {
+	/**
+	 * Creates an instance of PackContentItems.
+	 * @param {Content} map items
+	 */
+	constructor(map) {
+		this.map = map;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext & { logger: Logger, profile: boolean | undefined }} context context
+	 */
+	serialize({ write, snapshot, rollback, logger, profile }) {
+		if (profile) {
+			write(false);
+			for (const [key, value] of this.map) {
+				const s = snapshot();
+				try {
+					write(key);
+					const start = process.hrtime();
+					write(value);
+					const durationHr = process.hrtime(start);
+					const duration = durationHr[0] * 1000 + durationHr[1] / 1e6;
+					if (duration > 1) {
+						if (duration > 500) {
+							logger.error(`Serialization of '${key}': ${duration} ms`);
+						} else if (duration > 50) {
+							logger.warn(`Serialization of '${key}': ${duration} ms`);
+						} else if (duration > 10) {
+							logger.info(`Serialization of '${key}': ${duration} ms`);
+						} else if (duration > 5) {
+							logger.log(`Serialization of '${key}': ${duration} ms`);
+						} else {
+							logger.debug(`Serialization of '${key}': ${duration} ms`);
+						}
+					}
+				} catch (err) {
+					rollback(s);
+					if (err === NOT_SERIALIZABLE) continue;
+					const msg = "Skipped not serializable cache item";
+					const notSerializableErr = /** @type {Error} */ (err);
+					if (notSerializableErr.message.includes("ModuleBuildError")) {
+						logger.log(
+							`${msg} (in build error): ${notSerializableErr.message}`
+						);
+						logger.debug(
+							`${msg} '${key}' (in build error): ${notSerializableErr.stack}`
+						);
+					} else {
+						logger.warn(`${msg}: ${notSerializableErr.message}`);
+						logger.debug(`${msg} '${key}': ${notSerializableErr.stack}`);
+					}
+				}
+			}
+			write(null);
+			return;
+		}
+		// Try to serialize all at once
+		const s = snapshot();
+		try {
+			write(true);
+			write(this.map);
+		} catch (_err) {
+			rollback(s);
+
+			// Try to serialize each item on it's own
+			write(false);
+			for (const [key, value] of this.map) {
+				const s = snapshot();
+				try {
+					write(key);
+					write(value);
+				} catch (err) {
+					rollback(s);
+					if (err === NOT_SERIALIZABLE) continue;
+					const notSerializableErr = /** @type {Error} */ (err);
+					logger.warn(
+						`Skipped not serializable cache item '${key}': ${notSerializableErr.message}`
+					);
+					logger.debug(notSerializableErr.stack);
+				}
+			}
+			write(null);
+		}
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext & { logger: Logger, profile: boolean | undefined }} context context
+	 */
+	deserialize({ read, logger, profile }) {
+		if (read()) {
+			this.map = read();
+		} else if (profile) {
+			/** @type {Content} */
+			const map = new Map();
+			let key = read();
+			while (key !== null) {
+				const start = process.hrtime();
+				const value = read();
+				const durationHr = process.hrtime(start);
+				const duration = durationHr[0] * 1000 + durationHr[1] / 1e6;
+				if (duration > 1) {
+					if (duration > 100) {
+						logger.error(`Deserialization of '${key}': ${duration} ms`);
+					} else if (duration > 20) {
+						logger.warn(`Deserialization of '${key}': ${duration} ms`);
+					} else if (duration > 5) {
+						logger.info(`Deserialization of '${key}': ${duration} ms`);
+					} else if (duration > 2) {
+						logger.log(`Deserialization of '${key}': ${duration} ms`);
+					} else {
+						logger.debug(`Deserialization of '${key}': ${duration} ms`);
+					}
+				}
+				map.set(key, value);
+				key = read();
+			}
+			this.map = map;
+		} else {
+			/** @type {Content} */
+			const map = new Map();
+			let key = read();
+			while (key !== null) {
+				map.set(key, read());
+				key = read();
+			}
+			this.map = map;
+		}
+	}
+}
+
+makeSerializable(
+	PackContentItems,
+	"webpack/lib/cache/PackFileCacheStrategy",
+	"PackContentItems"
+);
+
+/** @typedef {(() => Promise<PackContentItems> | PackContentItems) & Partial<{ options: { size?: number } }>} LazyFunction */
+
+class PackContent {
+	/*
+		This class can be in these states:
+		   |   this.lazy    | this.content | this.outdated | state
+		A1 |   undefined    |     Map      |     false     | fresh content
+		A2 |   undefined    |     Map      |     true      | (will not happen)
+		B1 | lazy () => {}  |  undefined   |     false     | not deserialized
+		B2 | lazy () => {}  |  undefined   |     true      | not deserialized, but some items has been removed
+		C1 | lazy* () => {} |     Map      |     false     | deserialized
+		C2 | lazy* () => {} |     Map      |     true      | deserialized, and some items has been removed
+
+		this.used is a subset of this.items.
+		this.items is a subset of this.content.keys() resp. this.lazy().map.keys()
+		When this.outdated === false, this.items === this.content.keys() resp. this.lazy().map.keys()
+		When this.outdated === true, this.items should be used to recreated this.lazy/this.content.
+		When this.lazy and this.content is set, they contain the same data.
+		this.get must only be called with a valid item from this.items.
+		In state C this.lazy is unMemoized
+	*/
+
+	/**
+	 * Creates an instance of PackContent.
+	 * @param {Items} items keys
+	 * @param {Items} usedItems used keys
+	 * @param {PackContentItems | (() => Promise<PackContentItems>)} dataOrFn sync or async content
+	 * @param {Logger=} logger logger for logging
+	 * @param {string=} lazyName name of dataOrFn for logging
+	 */
+	constructor(items, usedItems, dataOrFn, logger, lazyName) {
+		/** @type {Items} */
+		this.items = items;
+		/** @type {LazyFunction | undefined} */
+		this.lazy = typeof dataOrFn === "function" ? dataOrFn : undefined;
+		/** @type {Content | undefined} */
+		this.content = typeof dataOrFn === "function" ? undefined : dataOrFn.map;
+		/** @type {boolean} */
+		this.outdated = false;
+		/** @type {Items} */
+		this.used = usedItems;
+		/** @type {Logger | undefined} */
+		this.logger = logger;
+		/** @type {string | undefined} */
+		this.lazyName = lazyName;
+	}
+
+	/**
+	 * Returns result.
+	 * @param {string} identifier identifier
+	 * @returns {string | Promise<string>} result
+	 */
+	get(identifier) {
+		this.used.add(identifier);
+		if (this.content) {
+			return this.content.get(identifier);
+		}
+
+		const logger = /** @type {Logger} */ (this.logger);
+		// We are in state B
+		const { lazyName } = this;
+		/** @type {string | undefined} */
+		let timeMessage;
+		if (lazyName) {
+			// only log once
+			this.lazyName = undefined;
+			timeMessage = `restore cache content ${lazyName} (${formatSize(
+				this.getSize()
+			)})`;
+			logger.log(
+				`starting to restore cache content ${lazyName} (${formatSize(
+					this.getSize()
+				)}) because of request to: ${identifier}`
+			);
+			logger.time(timeMessage);
+		}
+		const value = /** @type {LazyFunction} */ (this.lazy)();
+		if ("then" in value) {
+			return value.then((data) => {
+				const map = data.map;
+				if (timeMessage) {
+					logger.timeEnd(timeMessage);
+				}
+				// Move to state C
+				this.content = map;
+				this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy);
+				return map.get(identifier);
+			});
+		}
+
+		const map = value.map;
+		if (timeMessage) {
+			logger.timeEnd(timeMessage);
+		}
+		// Move to state C
+		this.content = map;
+		this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy);
+		return map.get(identifier);
+	}
+
+	/**
+	 * Returns maybe a promise if lazy.
+	 * @param {string} reason explanation why unpack is necessary
+	 * @returns {void | Promise<void>} maybe a promise if lazy
+	 */
+	unpack(reason) {
+		if (this.content) return;
+
+		const logger = /** @type {Logger} */ (this.logger);
+		// Move from state B to C
+		if (this.lazy) {
+			const { lazyName } = this;
+			/** @type {string | undefined} */
+			let timeMessage;
+			if (lazyName) {
+				// only log once
+				this.lazyName = undefined;
+				timeMessage = `unpack cache content ${lazyName} (${formatSize(
+					this.getSize()
+				)})`;
+				logger.log(
+					`starting to unpack cache content ${lazyName} (${formatSize(
+						this.getSize()
+					)}) because ${reason}`
+				);
+				logger.time(timeMessage);
+			}
+			const value =
+				/** @type {PackContentItems | Promise<PackContentItems>} */
+				(this.lazy());
+			if ("then" in value) {
+				return value.then((data) => {
+					if (timeMessage) {
+						logger.timeEnd(timeMessage);
+					}
+					this.content = data.map;
+				});
+			}
+			if (timeMessage) {
+				logger.timeEnd(timeMessage);
+			}
+			this.content = value.map;
+		}
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @returns {number} size of the content or -1 if not known
+	 */
+	getSize() {
+		if (!this.lazy) return -1;
+		const options =
+			/** @type {{ options: { size?: number } }} */
+			(this.lazy).options;
+		if (!options) return -1;
+		const size = options.size;
+		if (typeof size !== "number") return -1;
+		return size;
+	}
+
+	/**
+	 * Processes the provided identifier.
+	 * @param {string} identifier identifier
+	 */
+	delete(identifier) {
+		this.items.delete(identifier);
+		this.used.delete(identifier);
+		this.outdated = true;
+	}
+
+	/**
+	 * Processes the provided write.
+	 * @param {(lazy: LazyFunction) => (() => PackContentItems | Promise<PackContentItems>)} write write function
+	 * @returns {void}
+	 */
+	writeLazy(write) {
+		if (!this.outdated && this.lazy) {
+			// State B1 or C1
+			// this.lazy is still the valid deserialized version
+			write(this.lazy);
+			return;
+		}
+		if (!this.outdated && this.content) {
+			// State A1
+			const map = new Map(this.content);
+			// Move to state C1
+			this.lazy = SerializerMiddleware.unMemoizeLazy(
+				write(() => new PackContentItems(map))
+			);
+			return;
+		}
+		if (this.content) {
+			// State A2 or C2
+			/** @type {Content} */
+			const map = new Map();
+			for (const item of this.items) {
+				map.set(item, this.content.get(item));
+			}
+			// Move to state C1
+			this.outdated = false;
+			this.content = map;
+			this.lazy = SerializerMiddleware.unMemoizeLazy(
+				write(() => new PackContentItems(map))
+			);
+			return;
+		}
+		const logger = /** @type {Logger} */ (this.logger);
+		// State B2
+		const { lazyName } = this;
+		/** @type {string | undefined} */
+		let timeMessage;
+		if (lazyName) {
+			// only log once
+			this.lazyName = undefined;
+			timeMessage = `unpack cache content ${lazyName} (${formatSize(
+				this.getSize()
+			)})`;
+			logger.log(
+				`starting to unpack cache content ${lazyName} (${formatSize(
+					this.getSize()
+				)}) because it's outdated and need to be serialized`
+			);
+			logger.time(timeMessage);
+		}
+		const value = /** @type {LazyFunction} */ (this.lazy)();
+		this.outdated = false;
+		if ("then" in value) {
+			// Move to state B1
+			this.lazy = write(() =>
+				value.then((data) => {
+					if (timeMessage) {
+						logger.timeEnd(timeMessage);
+					}
+					const oldMap = data.map;
+					/** @type {Content} */
+					const map = new Map();
+					for (const item of this.items) {
+						map.set(item, oldMap.get(item));
+					}
+					// Move to state C1 (or maybe C2)
+					this.content = map;
+					this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy);
+
+					return new PackContentItems(map);
+				})
+			);
+		} else {
+			// Move to state C1
+			if (timeMessage) {
+				logger.timeEnd(timeMessage);
+			}
+			const oldMap = value.map;
+			/** @type {Content} */
+			const map = new Map();
+			for (const item of this.items) {
+				map.set(item, oldMap.get(item));
+			}
+			this.content = map;
+			this.lazy = write(() => new PackContentItems(map));
+		}
+	}
+}
+
+/**
+ * Allow collecting memory.
+ * @param {Buffer} buf buffer
+ * @returns {Buffer} buffer that can be collected
+ */
+const allowCollectingMemory = (buf) => {
+	const wasted = buf.buffer.byteLength - buf.byteLength;
+	if (wasted > 8192 && (wasted > 1048576 || wasted > buf.byteLength)) {
+		return Buffer.from(buf);
+	}
+	return buf;
+};
+
+class PackFileCacheStrategy {
+	/**
+	 * Creates an instance of PackFileCacheStrategy.
+	 * @param {object} options options
+	 * @param {Compiler} options.compiler the compiler
+	 * @param {IntermediateFileSystem} options.fs the filesystem
+	 * @param {string} options.context the context directory
+	 * @param {string} options.cacheLocation the location of the cache data
+	 * @param {string} options.version version identifier
+	 * @param {Logger} options.logger a logger
+	 * @param {SnapshotOptions} options.snapshot options regarding snapshotting
+	 * @param {number} options.maxAge max age of cache items
+	 * @param {boolean=} options.profile track and log detailed timing information for individual cache items
+	 * @param {boolean=} options.allowCollectingMemory allow to collect unused memory created during deserialization
+	 * @param {false | "gzip" | "brotli"=} options.compression compression used
+	 * @param {boolean=} options.readonly disable storing cache into filesystem
+	 */
+	constructor({
+		compiler,
+		fs,
+		context,
+		cacheLocation,
+		version,
+		logger,
+		snapshot,
+		maxAge,
+		profile,
+		allowCollectingMemory,
+		compression,
+		readonly
+	}) {
+		/** @type {import("../serialization/Serializer")<PackContainer, null, EXPECTED_OBJECT>} */
+		this.fileSerializer = createFileSerializer(
+			fs,
+			/** @type {HashFunction} */
+			(compiler.options.output.hashFunction)
+		);
+		/** @type {FileSystemInfo} */
+		this.fileSystemInfo = new FileSystemInfo(fs, {
+			managedPaths: snapshot.managedPaths,
+			immutablePaths: snapshot.immutablePaths,
+			logger: logger.getChildLogger("webpack.FileSystemInfo"),
+			hashFunction: compiler.options.output.hashFunction
+		});
+		/** @type {Compiler} */
+		this.compiler = compiler;
+		/** @type {string} */
+		this.context = context;
+		/** @type {string} */
+		this.cacheLocation = cacheLocation;
+		/** @type {string} */
+		this.version = version;
+		/** @type {Logger} */
+		this.logger = logger;
+		/** @type {number} */
+		this.maxAge = maxAge;
+		/** @type {boolean | undefined} */
+		this.profile = profile;
+		/** @type {boolean | undefined} */
+		this.readonly = readonly;
+		/** @type {boolean | undefined} */
+		this.allowCollectingMemory = allowCollectingMemory;
+		/** @type {false | "gzip" | "brotli" | undefined} */
+		this.compression = compression;
+		/** @type {string} */
+		this._extension =
+			compression === "brotli"
+				? ".pack.br"
+				: compression === "gzip"
+					? ".pack.gz"
+					: ".pack";
+		/** @type {SnapshotOptions} */
+		this.snapshot = snapshot;
+		/** @type {BuildDependencies} */
+		this.buildDependencies = new Set();
+		/** @type {FileSystemDependencies} */
+		this.newBuildDependencies = new LazySet();
+		/** @type {Snapshot | undefined} */
+		this.resolveBuildDependenciesSnapshot = undefined;
+		/** @type {ResolveResults | undefined} */
+		this.resolveResults = undefined;
+		/** @type {Snapshot | undefined} */
+		this.buildSnapshot = undefined;
+		/** @type {Promise<Pack> | undefined} */
+		this.packPromise = this._openPack();
+		/** @type {Promise<void>} */
+		this.storePromise = Promise.resolve();
+	}
+
+	/**
+	 * Returns pack.
+	 * @returns {Promise<Pack>} pack
+	 */
+	_getPack() {
+		if (this.packPromise === undefined) {
+			this.packPromise = this.storePromise.then(() => this._openPack());
+		}
+		return this.packPromise;
+	}
+
+	/**
+	 * Returns the pack.
+	 * @returns {Promise<Pack>} the pack
+	 */
+	_openPack() {
+		const { logger, profile, cacheLocation, version } = this;
+		/** @type {Snapshot} */
+		let buildSnapshot;
+		/** @type {BuildDependencies} */
+		let buildDependencies;
+		/** @type {BuildDependencies} */
+		let newBuildDependencies;
+		/** @type {Snapshot} */
+		let resolveBuildDependenciesSnapshot;
+		/** @type {ResolveResults | undefined} */
+		let resolveResults;
+		logger.time("restore cache container");
+		return this.fileSerializer
+			.deserialize(null, {
+				filename: `${cacheLocation}/index${this._extension}`,
+				extension: `${this._extension}`,
+				logger,
+				profile,
+				retainedBuffer: this.allowCollectingMemory
+					? allowCollectingMemory
+					: undefined
+			})
+			.catch((err) => {
+				if (err.code !== "ENOENT") {
+					logger.warn(
+						`Restoring pack failed from ${cacheLocation}${this._extension}: ${err}`
+					);
+					logger.debug(err.stack);
+				} else {
+					logger.debug(
+						`No pack exists at ${cacheLocation}${this._extension}: ${err}`
+					);
+				}
+				return undefined;
+			})
+			.then((packContainer) => {
+				logger.timeEnd("restore cache container");
+				if (!packContainer) return;
+				if (!(packContainer instanceof PackContainer)) {
+					logger.warn(
+						`Restored pack from ${cacheLocation}${this._extension}, but contained content is unexpected.`,
+						packContainer
+					);
+					return;
+				}
+				if (packContainer.version !== version) {
+					logger.log(
+						`Restored pack from ${cacheLocation}${this._extension}, but version doesn't match.`
+					);
+					return;
+				}
+				logger.time("check build dependencies");
+				return Promise.all([
+					new Promise((resolve, _reject) => {
+						this.fileSystemInfo.checkSnapshotValid(
+							packContainer.buildSnapshot,
+							(err, valid) => {
+								if (err) {
+									logger.log(
+										`Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of build dependencies errored: ${err}.`
+									);
+									logger.debug(err.stack);
+									return resolve(false);
+								}
+								if (!valid) {
+									logger.log(
+										`Restored pack from ${cacheLocation}${this._extension}, but build dependencies have changed.`
+									);
+									return resolve(false);
+								}
+								buildSnapshot = packContainer.buildSnapshot;
+								return resolve(true);
+							}
+						);
+					}),
+					new Promise((resolve, _reject) => {
+						this.fileSystemInfo.checkSnapshotValid(
+							packContainer.resolveBuildDependenciesSnapshot,
+							(err, valid) => {
+								if (err) {
+									logger.log(
+										`Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of resolving of build dependencies errored: ${err}.`
+									);
+									logger.debug(err.stack);
+									return resolve(false);
+								}
+								if (valid) {
+									resolveBuildDependenciesSnapshot =
+										packContainer.resolveBuildDependenciesSnapshot;
+									buildDependencies = packContainer.buildDependencies;
+									resolveResults = packContainer.resolveResults;
+									return resolve(true);
+								}
+								logger.log(
+									"resolving of build dependencies is invalid, will re-resolve build dependencies"
+								);
+								this.fileSystemInfo.checkResolveResultsValid(
+									packContainer.resolveResults,
+									(err, valid) => {
+										if (err) {
+											logger.log(
+												`Restored pack from ${cacheLocation}${this._extension}, but resolving of build dependencies errored: ${err}.`
+											);
+											logger.debug(err.stack);
+											return resolve(false);
+										}
+										if (valid) {
+											newBuildDependencies = packContainer.buildDependencies;
+											resolveResults = packContainer.resolveResults;
+											return resolve(true);
+										}
+										logger.log(
+											`Restored pack from ${cacheLocation}${this._extension}, but build dependencies resolve to different locations.`
+										);
+										return resolve(false);
+									}
+								);
+							}
+						);
+					})
+				])
+					.catch((err) => {
+						logger.timeEnd("check build dependencies");
+						throw err;
+					})
+					.then(([buildSnapshotValid, resolveValid]) => {
+						logger.timeEnd("check build dependencies");
+						if (buildSnapshotValid && resolveValid) {
+							logger.time("restore cache content metadata");
+							const d =
+								/** @type {() => Pack} */
+								(packContainer.data)();
+							logger.timeEnd("restore cache content metadata");
+							return d;
+						}
+						return undefined;
+					});
+			})
+			.then((pack) => {
+				if (pack) {
+					pack.maxAge = this.maxAge;
+					this.buildSnapshot = buildSnapshot;
+					if (buildDependencies) this.buildDependencies = buildDependencies;
+					if (newBuildDependencies) {
+						this.newBuildDependencies.addAll(newBuildDependencies);
+					}
+					this.resolveResults = resolveResults;
+					this.resolveBuildDependenciesSnapshot =
+						resolveBuildDependenciesSnapshot;
+					return pack;
+				}
+				return new Pack(logger, this.maxAge);
+			})
+			.catch((err) => {
+				this.logger.warn(
+					`Restoring pack from ${cacheLocation}${this._extension} failed: ${err}`
+				);
+				this.logger.debug(err.stack);
+				return new Pack(logger, this.maxAge);
+			});
+	}
+
+	/**
+	 * Returns promise.
+	 * @param {string} identifier unique name for the resource
+	 * @param {Etag | null} etag etag of the resource
+	 * @param {Data} data cached content
+	 * @returns {Promise<void>} promise
+	 */
+	store(identifier, etag, data) {
+		if (this.readonly) return Promise.resolve();
+
+		return this._getPack().then((pack) => {
+			pack.set(identifier, etag === null ? null : etag.toString(), data);
+		});
+	}
+
+	/**
+	 * Returns promise to the cached content.
+	 * @param {string} identifier unique name for the resource
+	 * @param {Etag | null} etag etag of the resource
+	 * @returns {Promise<Data>} promise to the cached content
+	 */
+	restore(identifier, etag) {
+		return this._getPack()
+			.then((pack) =>
+				pack.get(identifier, etag === null ? null : etag.toString())
+			)
+			.catch((err) => {
+				if (err && err.code !== "ENOENT") {
+					this.logger.warn(
+						`Restoring failed for ${identifier} from pack: ${err}`
+					);
+					this.logger.debug(err.stack);
+				}
+			});
+	}
+
+	/**
+	 * Stores build dependencies.
+	 * @param {FileSystemDependencies | Iterable<string>} dependencies dependencies to store
+	 */
+	storeBuildDependencies(dependencies) {
+		if (this.readonly) return;
+		this.newBuildDependencies.addAll(dependencies);
+	}
+
+	afterAllStored() {
+		const packPromise = this.packPromise;
+		if (packPromise === undefined) return Promise.resolve();
+		const reportProgress = ProgressPlugin.getReporter(this.compiler);
+		return (this.storePromise = packPromise
+			.then((pack) => {
+				pack.stopCapturingRequests();
+				if (!pack.invalid) return;
+				this.packPromise = undefined;
+				this.logger.log("Storing pack...");
+				/** @type {undefined | Promise<void>} */
+				let promise;
+				/** @type {Set<string>} */
+				const newBuildDependencies = new Set();
+				for (const dep of this.newBuildDependencies) {
+					if (!this.buildDependencies.has(dep)) {
+						newBuildDependencies.add(dep);
+					}
+				}
+				if (newBuildDependencies.size > 0 || !this.buildSnapshot) {
+					if (reportProgress) reportProgress(0.5, "resolve build dependencies");
+					this.logger.debug(
+						`Capturing build dependencies... (${[...newBuildDependencies].join(", ")})`
+					);
+					promise = new Promise(
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {(value?: undefined) => void} resolve resolve
+						 * @param {(reason?: Error) => void} reject reject
+						 */
+						(resolve, reject) => {
+							this.logger.time("resolve build dependencies");
+							this.fileSystemInfo.resolveBuildDependencies(
+								this.context,
+								newBuildDependencies,
+								(err, result) => {
+									this.logger.timeEnd("resolve build dependencies");
+									if (err) return reject(err);
+
+									this.logger.time("snapshot build dependencies");
+									const {
+										files,
+										directories,
+										missing,
+										resolveResults,
+										resolveDependencies
+									} = /** @type {ResolveBuildDependenciesResult} */ (result);
+									if (this.resolveResults) {
+										for (const [key, value] of resolveResults) {
+											this.resolveResults.set(key, value);
+										}
+									} else {
+										this.resolveResults = resolveResults;
+									}
+									if (reportProgress) {
+										reportProgress(
+											0.6,
+											"snapshot build dependencies",
+											"resolving"
+										);
+									}
+									this.fileSystemInfo.createSnapshot(
+										undefined,
+										resolveDependencies.files,
+										resolveDependencies.directories,
+										resolveDependencies.missing,
+										this.snapshot.resolveBuildDependencies,
+										(err, snapshot) => {
+											if (err) {
+												this.logger.timeEnd("snapshot build dependencies");
+												return reject(err);
+											}
+											if (!snapshot) {
+												this.logger.timeEnd("snapshot build dependencies");
+												return reject(
+													new Error("Unable to snapshot resolve dependencies")
+												);
+											}
+											if (this.resolveBuildDependenciesSnapshot) {
+												this.resolveBuildDependenciesSnapshot =
+													this.fileSystemInfo.mergeSnapshots(
+														this.resolveBuildDependenciesSnapshot,
+														snapshot
+													);
+											} else {
+												this.resolveBuildDependenciesSnapshot = snapshot;
+											}
+											if (reportProgress) {
+												reportProgress(
+													0.7,
+													"snapshot build dependencies",
+													"modules"
+												);
+											}
+											this.fileSystemInfo.createSnapshot(
+												undefined,
+												files,
+												directories,
+												missing,
+												this.snapshot.buildDependencies,
+												(err, snapshot) => {
+													this.logger.timeEnd("snapshot build dependencies");
+													if (err) return reject(err);
+													if (!snapshot) {
+														return reject(
+															new Error("Unable to snapshot build dependencies")
+														);
+													}
+													this.logger.debug("Captured build dependencies");
+
+													if (this.buildSnapshot) {
+														this.buildSnapshot =
+															this.fileSystemInfo.mergeSnapshots(
+																this.buildSnapshot,
+																snapshot
+															);
+													} else {
+														this.buildSnapshot = snapshot;
+													}
+
+													resolve();
+												}
+											);
+										}
+									);
+								}
+							);
+						}
+					);
+				} else {
+					promise = Promise.resolve();
+				}
+				return promise.then(() => {
+					if (reportProgress) reportProgress(0.8, "serialize pack");
+					this.logger.time("store pack");
+					const updatedBuildDependencies = new Set(this.buildDependencies);
+					for (const dep of newBuildDependencies) {
+						updatedBuildDependencies.add(dep);
+					}
+					const content = new PackContainer(
+						pack,
+						this.version,
+						/** @type {Snapshot} */
+						(this.buildSnapshot),
+						updatedBuildDependencies,
+						/** @type {ResolveResults} */
+						(this.resolveResults),
+						/** @type {Snapshot} */
+						(this.resolveBuildDependenciesSnapshot)
+					);
+					return this.fileSerializer
+						.serialize(content, {
+							filename: `${this.cacheLocation}/index${this._extension}`,
+							extension: `${this._extension}`,
+							logger: this.logger,
+							profile: this.profile
+						})
+						.then(() => {
+							for (const dep of newBuildDependencies) {
+								this.buildDependencies.add(dep);
+							}
+							this.newBuildDependencies.clear();
+							this.logger.timeEnd("store pack");
+							const stats = pack.getContentStats();
+							this.logger.log(
+								"Stored pack (%d items, %d files, %d MiB)",
+								pack.itemInfo.size,
+								stats.count,
+								Math.round(stats.size / 1024 / 1024)
+							);
+						})
+						.catch((err) => {
+							this.logger.timeEnd("store pack");
+							this.logger.warn(`Caching failed for pack: ${err}`);
+							this.logger.debug(err.stack);
+						});
+				});
+			})
+			.catch((err) => {
+				this.logger.warn(`Caching failed for pack: ${err}`);
+				this.logger.debug(err.stack);
+			}));
+	}
+
+	clear() {
+		this.fileSystemInfo.clear();
+		this.buildDependencies.clear();
+		this.newBuildDependencies.clear();
+		this.resolveBuildDependenciesSnapshot = undefined;
+		this.resolveResults = undefined;
+		this.buildSnapshot = undefined;
+		this.packPromise = undefined;
+	}
+}
+
+module.exports = PackFileCacheStrategy;
Index: frontend/node_modules/webpack/lib/cache/ResolverCachePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/ResolverCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/ResolverCachePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,459 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const LazySet = require("../util/LazySet");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
+/** @typedef {import("enhanced-resolve").ResolveOptions} ResolveOptions */
+/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
+/** @typedef {import("enhanced-resolve").Resolver} Resolver */
+/** @typedef {import("../CacheFacade").ItemCacheFacade} ItemCacheFacade */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../FileSystemInfo")} FileSystemInfo */
+/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
+/** @typedef {import("../FileSystemInfo").SnapshotOptions} SnapshotOptions */
+/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/**
+ * Defines the sync hook type used by this module.
+ * @template T
+ * @typedef {import("tapable").SyncHook<T>} SyncHook
+ */
+
+/** @typedef {Set<string>} Dependencies  */
+
+class CacheEntry {
+	/**
+	 * Creates an instance of CacheEntry.
+	 * @param {ResolveRequest} result result
+	 * @param {Snapshot} snapshot snapshot
+	 */
+	constructor(result, snapshot) {
+		this.result = result;
+		this.snapshot = snapshot;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this.result);
+		write(this.snapshot);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize({ read }) {
+		this.result = read();
+		this.snapshot = read();
+	}
+}
+
+makeSerializable(CacheEntry, "webpack/lib/cache/ResolverCachePlugin");
+
+/**
+ * Adds the provided set to the cache entry.
+ * @template T
+ * @param {Set<T> | LazySet<T>} set set to add items to
+ * @param {Set<T> | LazySet<T> | Iterable<T>} otherSet set to add items from
+ * @returns {void}
+ */
+const addAllToSet = (set, otherSet) => {
+	if (set instanceof LazySet) {
+		set.addAll(otherSet);
+	} else {
+		for (const item of otherSet) {
+			set.add(item);
+		}
+	}
+};
+
+/**
+ * Returns stringified version.
+ * @template {object} T
+ * @param {T} object an object
+ * @param {boolean} excludeContext if true, context is not included in string
+ * @returns {string} stringified version
+ */
+const objectToString = (object, excludeContext) => {
+	let str = "";
+	for (const key in object) {
+		if (excludeContext && key === "context") continue;
+		const value = object[key];
+		str +=
+			typeof value === "object" && value !== null
+				? `|${key}=[${objectToString(value, false)}|]`
+				: `|${key}=|${value}`;
+	}
+	return str;
+};
+
+/** @typedef {NonNullable<ResolveContext["yield"]>} Yield */
+
+const PLUGIN_NAME = "ResolverCachePlugin";
+
+class ResolverCachePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const cache = compiler.getCache(PLUGIN_NAME);
+		/** @type {FileSystemInfo} */
+		let fileSystemInfo;
+		/** @type {SnapshotOptions | undefined} */
+		let snapshotOptions;
+		let realResolves = 0;
+		let cachedResolves = 0;
+		let cacheInvalidResolves = 0;
+		let concurrentResolves = 0;
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			snapshotOptions = compilation.options.snapshot.resolve;
+			fileSystemInfo = compilation.fileSystemInfo;
+			compilation.hooks.finishModules.tap(PLUGIN_NAME, () => {
+				if (realResolves + cachedResolves > 0) {
+					const logger = compilation.getLogger(`webpack.${PLUGIN_NAME}`);
+					logger.log(
+						`${Math.round(
+							(100 * realResolves) / (realResolves + cachedResolves)
+						)}% really resolved (${realResolves} real resolves with ${cacheInvalidResolves} cached but invalid, ${cachedResolves} cached valid, ${concurrentResolves} concurrent)`
+					);
+					realResolves = 0;
+					cachedResolves = 0;
+					cacheInvalidResolves = 0;
+					concurrentResolves = 0;
+				}
+			});
+		});
+
+		/** @typedef {(err?: Error | null, resolveRequest?: ResolveRequest | null) => void} Callback */
+		/** @typedef {ResolveRequest & { _ResolverCachePluginCacheMiss: true }} ResolveRequestWithCacheMiss */
+
+		/**
+		 * Processes the provided item cache.
+		 * @param {ItemCacheFacade} itemCache cache
+		 * @param {Resolver} resolver the resolver
+		 * @param {ResolveContext} resolveContext context for resolving meta info
+		 * @param {ResolveRequest} request the request info object
+		 * @param {Callback} callback callback function
+		 * @returns {void}
+		 */
+		const doRealResolve = (
+			itemCache,
+			resolver,
+			resolveContext,
+			request,
+			callback
+		) => {
+			realResolves++;
+			const newRequest =
+				/** @type {ResolveRequestWithCacheMiss} */
+				({
+					_ResolverCachePluginCacheMiss: true,
+					...request
+				});
+			/** @type {ResolveContext} */
+			const newResolveContext = {
+				...resolveContext,
+				stack: new Set(),
+				missingDependencies: new LazySet(),
+				fileDependencies: new LazySet(),
+				contextDependencies: new LazySet()
+			};
+			/** @type {ResolveRequest[] | undefined} */
+			let yieldResult;
+			let withYield = false;
+			if (typeof newResolveContext.yield === "function") {
+				yieldResult = [];
+				withYield = true;
+				newResolveContext.yield = (obj) =>
+					/** @type {ResolveRequest[]} */
+					(yieldResult).push(obj);
+			}
+			/**
+			 * Processes the provided key.
+			 * @param {"fileDependencies" | "contextDependencies" | "missingDependencies"} key key
+			 */
+			const propagate = (key) => {
+				if (resolveContext[key]) {
+					addAllToSet(
+						/** @type {Dependencies} */ (resolveContext[key]),
+						/** @type {Dependencies} */ (newResolveContext[key])
+					);
+				}
+			};
+			const resolveTime = Date.now();
+			resolver.doResolve(
+				resolver.hooks.resolve,
+				newRequest,
+				"Cache miss",
+				newResolveContext,
+				(err, result) => {
+					propagate("fileDependencies");
+					propagate("contextDependencies");
+					propagate("missingDependencies");
+					if (err) return callback(err);
+					const fileDependencies = newResolveContext.fileDependencies;
+					const contextDependencies = newResolveContext.contextDependencies;
+					const missingDependencies = newResolveContext.missingDependencies;
+					fileSystemInfo.createSnapshot(
+						resolveTime,
+						/** @type {Dependencies} */
+						(fileDependencies),
+						/** @type {Dependencies} */
+						(contextDependencies),
+						/** @type {Dependencies} */
+						(missingDependencies),
+						snapshotOptions,
+						(err, snapshot) => {
+							if (err) return callback(err);
+							const resolveResult = withYield ? yieldResult : result;
+							// since we intercept resolve hook
+							// we still can get result in callback
+							if (withYield && result) {
+								/** @type {ResolveRequest[]} */
+								(yieldResult).push(result);
+							}
+							if (!snapshot) {
+								if (resolveResult) {
+									return callback(
+										null,
+										/** @type {ResolveRequest} */
+										(resolveResult)
+									);
+								}
+								return callback();
+							}
+							itemCache.store(
+								new CacheEntry(
+									/** @type {ResolveRequest} */
+									(resolveResult),
+									snapshot
+								),
+								(storeErr) => {
+									if (storeErr) return callback(storeErr);
+									if (resolveResult) {
+										return callback(
+											null,
+											/** @type {ResolveRequest} */
+											(resolveResult)
+										);
+									}
+									callback();
+								}
+							);
+						}
+					);
+				}
+			);
+		};
+		compiler.resolverFactory.hooks.resolver.intercept({
+			factory(type, _hook) {
+				/** @typedef {(err?: Error, resolveRequest?: ResolveRequest) => void} ActiveRequest */
+				/** @type {Map<string, ActiveRequest[]>} */
+				const activeRequests = new Map();
+				/** @type {Map<string, [ActiveRequest[], Yield[]]>} */
+				const activeRequestsWithYield = new Map();
+				const hook =
+					/** @type {SyncHook<[Resolver, ResolveOptions, ResolveOptionsWithDependencyType]>} */
+					(_hook);
+				hook.tap(PLUGIN_NAME, (resolver, options, userOptions) => {
+					if (
+						/** @type {ResolveOptions & { cache: boolean }} */
+						(options).cache !== true
+					) {
+						return;
+					}
+					const optionsIdent = objectToString(userOptions, false);
+					const cacheWithContext =
+						options.cacheWithContext !== undefined
+							? options.cacheWithContext
+							: false;
+					resolver.hooks.resolve.tapAsync(
+						{
+							name: PLUGIN_NAME,
+							stage: -100
+						},
+						(request, resolveContext, callback) => {
+							if (
+								/** @type {ResolveRequestWithCacheMiss} */
+								(request)._ResolverCachePluginCacheMiss ||
+								!fileSystemInfo
+							) {
+								return callback();
+							}
+							const withYield = typeof resolveContext.yield === "function";
+							const identifier = `${type}${
+								withYield ? "|yield" : "|default"
+							}${optionsIdent}${objectToString(request, !cacheWithContext)}`;
+
+							if (withYield) {
+								const activeRequest = activeRequestsWithYield.get(identifier);
+								if (activeRequest) {
+									activeRequest[0].push(callback);
+									activeRequest[1].push(
+										/** @type {Yield} */
+										(resolveContext.yield)
+									);
+									return;
+								}
+							} else {
+								const activeRequest = activeRequests.get(identifier);
+								if (activeRequest) {
+									activeRequest.push(callback);
+									return;
+								}
+							}
+							const itemCache = cache.getItemCache(identifier, null);
+							/** @type {Callback[] | false | undefined} */
+							let callbacks;
+							/** @type {Yield[] | undefined} */
+							let yields;
+
+							/**
+							 * @type {(err?: Error | null, result?: ResolveRequest | ResolveRequest[] | null) => void}
+							 */
+							const done = withYield
+								? (err, result) => {
+										if (callbacks === undefined) {
+											if (err) {
+												callback(err);
+											} else {
+												if (result) {
+													for (const r of /** @type {ResolveRequest[]} */ (
+														result
+													)) {
+														/** @type {Yield} */
+														(resolveContext.yield)(r);
+													}
+												}
+												callback(null, null);
+											}
+											yields = undefined;
+											callbacks = false;
+										} else {
+											const definedCallbacks =
+												/** @type {Callback[]} */
+												(callbacks);
+
+											if (err) {
+												for (const cb of definedCallbacks) cb(err);
+											} else {
+												for (let i = 0; i < definedCallbacks.length; i++) {
+													const cb = definedCallbacks[i];
+													const yield_ = /** @type {Yield[]} */ (yields)[i];
+													if (result) {
+														for (const r of /** @type {ResolveRequest[]} */ (
+															result
+														)) {
+															yield_(r);
+														}
+													}
+													cb(null, null);
+												}
+											}
+											activeRequestsWithYield.delete(identifier);
+											yields = undefined;
+											callbacks = false;
+										}
+									}
+								: (err, result) => {
+										if (callbacks === undefined) {
+											callback(err, /** @type {ResolveRequest} */ (result));
+											callbacks = false;
+										} else {
+											for (const callback of /** @type {Callback[]} */ (
+												callbacks
+											)) {
+												callback(err, /** @type {ResolveRequest} */ (result));
+											}
+											activeRequests.delete(identifier);
+											callbacks = false;
+										}
+									};
+							/**
+							 * Process cache result.
+							 * @param {(Error | null)=} err error if any
+							 * @param {(CacheEntry | null)=} cacheEntry cache entry
+							 * @returns {void}
+							 */
+							const processCacheResult = (err, cacheEntry) => {
+								if (err) return done(err);
+
+								if (cacheEntry) {
+									const { snapshot, result } = cacheEntry;
+									fileSystemInfo.checkSnapshotValid(snapshot, (err, valid) => {
+										if (err || !valid) {
+											cacheInvalidResolves++;
+											return doRealResolve(
+												itemCache,
+												resolver,
+												resolveContext,
+												request,
+												done
+											);
+										}
+										cachedResolves++;
+										if (resolveContext.missingDependencies) {
+											addAllToSet(
+												/** @type {Dependencies} */
+												(resolveContext.missingDependencies),
+												snapshot.getMissingIterable()
+											);
+										}
+										if (resolveContext.fileDependencies) {
+											addAllToSet(
+												/** @type {Dependencies} */
+												(resolveContext.fileDependencies),
+												snapshot.getFileIterable()
+											);
+										}
+										if (resolveContext.contextDependencies) {
+											addAllToSet(
+												/** @type {Dependencies} */
+												(resolveContext.contextDependencies),
+												snapshot.getContextIterable()
+											);
+										}
+										done(null, result);
+									});
+								} else {
+									doRealResolve(
+										itemCache,
+										resolver,
+										resolveContext,
+										request,
+										done
+									);
+								}
+							};
+							itemCache.get(processCacheResult);
+							if (withYield && callbacks === undefined) {
+								callbacks = [callback];
+								yields = [/** @type {Yield} */ (resolveContext.yield)];
+								activeRequestsWithYield.set(identifier, [callbacks, yields]);
+							} else if (callbacks === undefined) {
+								callbacks = [callback];
+								activeRequests.set(identifier, callbacks);
+							}
+						}
+					);
+				});
+				return hook;
+			}
+		});
+	}
+}
+
+module.exports = ResolverCachePlugin;
Index: frontend/node_modules/webpack/lib/cache/getLazyHashedEtag.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/getLazyHashedEtag.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/getLazyHashedEtag.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,95 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { DEFAULTS } = require("../config/defaults");
+const createHash = require("../util/createHash");
+
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {typeof import("../util/Hash")} HashConstructor */
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+
+/**
+ * Represents the lazy hashed etag runtime component.
+ * @typedef {object} HashableObject
+ * @property {(hash: Hash) => void} updateHash
+ */
+
+class LazyHashedEtag {
+	/**
+	 * Creates an instance of LazyHashedEtag.
+	 * @param {HashableObject} obj object with updateHash method
+	 * @param {HashFunction} hashFunction the hash function to use
+	 */
+	constructor(obj, hashFunction = DEFAULTS.HASH_FUNCTION) {
+		/** @type {HashableObject} */
+		this._obj = obj;
+		/** @type {undefined | string} */
+		this._hash = undefined;
+		/** @type {HashFunction} */
+		this._hashFunction = hashFunction;
+	}
+
+	/**
+	 * Returns a string representation.
+	 * @returns {string} hash of object
+	 */
+	toString() {
+		if (this._hash === undefined) {
+			const hash = createHash(this._hashFunction);
+			this._obj.updateHash(hash);
+			this._hash = hash.digest("base64");
+		}
+		return this._hash;
+	}
+}
+
+/** @typedef {WeakMap<HashableObject, LazyHashedEtag>} InnerCache */
+
+/** @type {Map<HashFunction, InnerCache>} */
+const mapStrings = new Map();
+
+/** @type {WeakMap<HashConstructor, InnerCache>} */
+const mapObjects = new WeakMap();
+
+/**
+ * Returns etag.
+ * @param {HashableObject} obj object with updateHash method
+ * @param {HashFunction=} hashFunction the hash function to use
+ * @returns {LazyHashedEtag} etag
+ */
+const getter = (obj, hashFunction = DEFAULTS.HASH_FUNCTION) => {
+	/** @type {undefined | InnerCache} */
+	let innerMap;
+	if (typeof hashFunction === "string") {
+		innerMap = mapStrings.get(hashFunction);
+		if (innerMap === undefined) {
+			const newHash = new LazyHashedEtag(obj, hashFunction);
+			/** @type {InnerCache} */
+			innerMap = new WeakMap();
+			innerMap.set(obj, newHash);
+			mapStrings.set(hashFunction, innerMap);
+			return newHash;
+		}
+	} else {
+		innerMap = mapObjects.get(hashFunction);
+		if (innerMap === undefined) {
+			const newHash = new LazyHashedEtag(obj, hashFunction);
+			/** @type {InnerCache} */
+			innerMap = new WeakMap();
+			innerMap.set(obj, newHash);
+			mapObjects.set(hashFunction, innerMap);
+			return newHash;
+		}
+	}
+	const hash = innerMap.get(obj);
+	if (hash !== undefined) return hash;
+	const newHash = new LazyHashedEtag(obj, hashFunction);
+	innerMap.set(obj, newHash);
+	return newHash;
+};
+
+module.exports = getter;
Index: frontend/node_modules/webpack/lib/cache/mergeEtags.js
===================================================================
--- frontend/node_modules/webpack/lib/cache/mergeEtags.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cache/mergeEtags.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,73 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Cache").Etag} Etag */
+
+class MergedEtag {
+	/**
+	 * Creates an instance of MergedEtag.
+	 * @param {Etag} a first
+	 * @param {Etag} b second
+	 */
+	constructor(a, b) {
+		this.a = a;
+		this.b = b;
+	}
+
+	toString() {
+		return `${this.a.toString()}|${this.b.toString()}`;
+	}
+}
+
+/** @type {WeakMap<Etag, WeakMap<Etag, MergedEtag>>} */
+const dualObjectMap = new WeakMap();
+/** @type {WeakMap<Etag, WeakMap<Etag, MergedEtag>>} */
+const objectStringMap = new WeakMap();
+
+/**
+ * Merges the provided values into a single result.
+ * @param {Etag} a first
+ * @param {Etag} b second
+ * @returns {string | MergedEtag} result
+ */
+const mergeEtags = (a, b) => {
+	if (typeof a === "string") {
+		if (typeof b === "string") {
+			return `${a}|${b}`;
+		}
+		const temp = b;
+		b = a;
+		a = temp;
+	} else if (typeof b !== "string") {
+		// both a and b are objects
+		let map = dualObjectMap.get(a);
+		if (map === undefined) {
+			dualObjectMap.set(a, (map = new WeakMap()));
+		}
+		const mergedEtag = map.get(b);
+		if (mergedEtag === undefined) {
+			const newMergedEtag = new MergedEtag(a, b);
+			map.set(b, newMergedEtag);
+			return newMergedEtag;
+		}
+		return mergedEtag;
+	}
+	// a is object, b is string
+	let map = objectStringMap.get(a);
+	if (map === undefined) {
+		objectStringMap.set(a, (map = new Map()));
+	}
+	const mergedEtag = map.get(b);
+	if (mergedEtag === undefined) {
+		const newMergedEtag = new MergedEtag(a, b);
+		map.set(b, newMergedEtag);
+		return newMergedEtag;
+	}
+	return mergedEtag;
+};
+
+module.exports = mergeEtags;
Index: frontend/node_modules/webpack/lib/cli.js
===================================================================
--- frontend/node_modules/webpack/lib/cli.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/cli.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,893 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const path = require("path");
+const tty = require("tty");
+const webpackSchema =
+	/** @type {EXPECTED_ANY} */
+	(require("../schemas/WebpackOptions.json"));
+
+/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
+/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
+/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
+/** @typedef {JSONSchema4 | JSONSchema6 | JSONSchema7} JSONSchema */
+/** @typedef {JSONSchema & { absolutePath: boolean, instanceof: string, cli: { helper?: boolean, exclude?: boolean, description?: string, negatedDescription?: string, resetDescription?: string } }} Schema */
+
+// TODO add originPath to PathItem for better errors
+/**
+ * Defines the path item type used by this module.
+ * @typedef {object} PathItem
+ * @property {Schema} schema the part of the schema
+ * @property {string} path the path in the config
+ */
+
+/** @typedef {"unknown-argument" | "unexpected-non-array-in-path" | "unexpected-non-object-in-path" | "multiple-values-unexpected" | "invalid-value"} ProblemType */
+
+/** @typedef {string | number | boolean | RegExp} Value */
+
+/**
+ * Defines the problem type used by this module.
+ * @typedef {object} Problem
+ * @property {ProblemType} type
+ * @property {string} path
+ * @property {string} argument
+ * @property {Value=} value
+ * @property {number=} index
+ * @property {string=} expected
+ */
+
+/**
+ * Defines the local problem type used by this module.
+ * @typedef {object} LocalProblem
+ * @property {ProblemType} type
+ * @property {string} path
+ * @property {string=} expected
+ */
+
+/** @typedef {{ [key: string]: EnumValue }} EnumValueObject */
+/** @typedef {EnumValue[]} EnumValueArray */
+/** @typedef {string | number | boolean | EnumValueObject | EnumValueArray | null} EnumValue */
+
+/**
+ * Defines the argument config type used by this module.
+ * @typedef {object} ArgumentConfig
+ * @property {string=} description
+ * @property {string=} negatedDescription
+ * @property {string} path
+ * @property {boolean} multiple
+ * @property {"enum" | "string" | "path" | "number" | "boolean" | "RegExp" | "reset"} type
+ * @property {EnumValue[]=} values
+ */
+
+/** @typedef {"string" | "number" | "boolean"} SimpleType */
+
+/**
+ * Defines the argument type used by this module.
+ * @typedef {object} Argument
+ * @property {string | undefined} description
+ * @property {SimpleType} simpleType
+ * @property {boolean} multiple
+ * @property {ArgumentConfig[]} configs
+ */
+
+/** @typedef {Record<string, Argument>} Flags */
+
+/** @typedef {Record<string, EXPECTED_ANY>} ObjectConfiguration */
+
+/**
+ * Returns object of arguments.
+ * @param {Schema=} schema a json schema to create arguments for (by default webpack schema is used)
+ * @returns {Flags} object of arguments
+ */
+const getArguments = (schema = webpackSchema) => {
+	/** @type {Flags} */
+	const flags = {};
+
+	/**
+	 * Path to argument name.
+	 * @param {string} input input
+	 * @returns {string} result
+	 */
+	const pathToArgumentName = (input) =>
+		input
+			.replace(/\./g, "-")
+			.replace(/\[\]/g, "")
+			.replace(
+				/(\p{Uppercase_Letter}+|\p{Lowercase_Letter}|\d)(\p{Uppercase_Letter}+)/gu,
+				"$1-$2"
+			)
+			.replace(/-?[^\p{Uppercase_Letter}\p{Lowercase_Letter}\d]+/gu, "-")
+			.toLowerCase();
+
+	/**
+	 * Returns schema part.
+	 * @param {string} path path
+	 * @returns {Schema} schema part
+	 */
+	const getSchemaPart = (path) => {
+		const newPath = path.split("/");
+
+		let schemaPart = schema;
+
+		for (let i = 1; i < newPath.length; i++) {
+			const inner = schemaPart[/** @type {keyof Schema} */ (newPath[i])];
+
+			if (!inner) {
+				break;
+			}
+
+			schemaPart = inner;
+		}
+
+		return schemaPart;
+	};
+
+	/**
+	 * Returns description.
+	 * @param {PathItem[]} path path in the schema
+	 * @returns {string | undefined} description
+	 */
+	const getDescription = (path) => {
+		for (const { schema } of path) {
+			if (schema.cli) {
+				if (schema.cli.helper) continue;
+				if (schema.cli.description) return schema.cli.description;
+			}
+			if (schema.description) return schema.description;
+		}
+	};
+
+	/**
+	 * Gets negated description.
+	 * @param {PathItem[]} path path in the schema
+	 * @returns {string | undefined} negative description
+	 */
+	const getNegatedDescription = (path) => {
+		for (const { schema } of path) {
+			if (schema.cli) {
+				if (schema.cli.helper) continue;
+				if (schema.cli.negatedDescription) return schema.cli.negatedDescription;
+			}
+		}
+	};
+
+	/**
+	 * Gets reset description.
+	 * @param {PathItem[]} path path in the schema
+	 * @returns {string | undefined} reset description
+	 */
+	const getResetDescription = (path) => {
+		for (const { schema } of path) {
+			if (schema.cli) {
+				if (schema.cli.helper) continue;
+				if (schema.cli.resetDescription) return schema.cli.resetDescription;
+			}
+		}
+	};
+
+	/**
+	 * Schema to argument config.
+	 * @param {Schema} schemaPart schema
+	 * @returns {Pick<ArgumentConfig, "type" | "values"> | undefined} partial argument config
+	 */
+	const schemaToArgumentConfig = (schemaPart) => {
+		if (schemaPart.enum) {
+			return {
+				type: "enum",
+				values: schemaPart.enum
+			};
+		}
+		switch (schemaPart.type) {
+			case "number":
+				return {
+					type: "number"
+				};
+			case "string":
+				return {
+					type: schemaPart.absolutePath ? "path" : "string"
+				};
+			case "boolean":
+				return {
+					type: "boolean"
+				};
+		}
+		if (schemaPart.instanceof === "RegExp") {
+			return {
+				type: "RegExp"
+			};
+		}
+		return undefined;
+	};
+
+	/**
+	 * Adds the provided path to this object.
+	 * @param {PathItem[]} path path in the schema
+	 * @returns {void}
+	 */
+	const addResetFlag = (path) => {
+		const schemaPath = path[0].path;
+		const name = pathToArgumentName(`${schemaPath}.reset`);
+		const description =
+			getResetDescription(path) ||
+			`Clear all items provided in '${schemaPath}' configuration. ${getDescription(
+				path
+			)}`;
+		flags[name] = {
+			configs: [
+				{
+					type: "reset",
+					multiple: false,
+					description,
+					path: schemaPath
+				}
+			],
+			description: undefined,
+			simpleType:
+				/** @type {SimpleType} */
+				(/** @type {unknown} */ (undefined)),
+			multiple: /** @type {boolean} */ (/** @type {unknown} */ (undefined))
+		};
+	};
+
+	/**
+	 * Adds the provided path to this object.
+	 * @param {PathItem[]} path full path in schema
+	 * @param {boolean} multiple inside of an array
+	 * @returns {number} number of arguments added
+	 */
+	const addFlag = (path, multiple) => {
+		const argConfigBase = schemaToArgumentConfig(path[0].schema);
+		if (!argConfigBase) return 0;
+
+		const negatedDescription = getNegatedDescription(path);
+		const name = pathToArgumentName(path[0].path);
+		/** @type {ArgumentConfig} */
+		const argConfig = {
+			...argConfigBase,
+			multiple,
+			description: getDescription(path),
+			path: path[0].path
+		};
+
+		if (negatedDescription) {
+			argConfig.negatedDescription = negatedDescription;
+		}
+
+		if (!flags[name]) {
+			flags[name] = {
+				configs: [],
+				description: undefined,
+				simpleType:
+					/** @type {SimpleType} */
+					(/** @type {unknown} */ (undefined)),
+				multiple: /** @type {boolean} */ (/** @type {unknown} */ (undefined))
+			};
+		}
+
+		if (
+			flags[name].configs.some(
+				(item) => JSON.stringify(item) === JSON.stringify(argConfig)
+			)
+		) {
+			return 0;
+		}
+
+		if (
+			flags[name].configs.some(
+				(item) => item.type === argConfig.type && item.multiple !== multiple
+			)
+		) {
+			if (multiple) {
+				throw new Error(
+					`Conflicting schema for ${path[0].path} with ${argConfig.type} type (array type must be before single item type)`
+				);
+			}
+			return 0;
+		}
+
+		flags[name].configs.push(argConfig);
+
+		return 1;
+	};
+
+	// TODO support `not` and `if/then/else`
+	// TODO support `const`, but we don't use it on our schema
+	/**
+	 * Returns added arguments.
+	 * @param {Schema} schemaPart the current schema
+	 * @param {string} schemaPath the current path in the schema
+	 * @param {PathItem[]} path all previous visited schemaParts
+	 * @param {string | null} inArray if inside of an array, the path to the array
+	 * @returns {number} added arguments
+	 */
+	const traverse = (schemaPart, schemaPath = "", path = [], inArray = null) => {
+		while (schemaPart.$ref) {
+			schemaPart = getSchemaPart(schemaPart.$ref);
+		}
+
+		const repetitions = path.filter(({ schema }) => schema === schemaPart);
+		if (
+			repetitions.length >= 2 ||
+			repetitions.some(({ path }) => path === schemaPath)
+		) {
+			return 0;
+		}
+
+		if (schemaPart.cli && schemaPart.cli.exclude) return 0;
+
+		/** @type {PathItem[]} */
+		const fullPath = [{ schema: schemaPart, path: schemaPath }, ...path];
+
+		let addedArguments = 0;
+
+		addedArguments += addFlag(fullPath, Boolean(inArray));
+
+		if (schemaPart.type === "object") {
+			if (schemaPart.properties) {
+				for (const property of Object.keys(schemaPart.properties)) {
+					addedArguments += traverse(
+						/** @type {Schema} */
+						(schemaPart.properties[property]),
+						schemaPath ? `${schemaPath}.${property}` : property,
+						fullPath,
+						inArray
+					);
+				}
+			}
+
+			return addedArguments;
+		}
+
+		if (schemaPart.type === "array") {
+			if (inArray) {
+				return 0;
+			}
+			if (Array.isArray(schemaPart.items)) {
+				const i = 0;
+				for (const item of schemaPart.items) {
+					addedArguments += traverse(
+						/** @type {Schema} */
+						(item),
+						`${schemaPath}.${i}`,
+						fullPath,
+						schemaPath
+					);
+				}
+
+				return addedArguments;
+			}
+
+			addedArguments += traverse(
+				/** @type {Schema} */
+				(schemaPart.items),
+				`${schemaPath}[]`,
+				fullPath,
+				schemaPath
+			);
+
+			if (addedArguments > 0) {
+				addResetFlag(fullPath);
+				addedArguments++;
+			}
+
+			return addedArguments;
+		}
+
+		const maybeOf = schemaPart.oneOf || schemaPart.anyOf || schemaPart.allOf;
+
+		if (maybeOf) {
+			const items = maybeOf;
+
+			for (let i = 0; i < items.length; i++) {
+				addedArguments += traverse(
+					/** @type {Schema} */
+					(items[i]),
+					schemaPath,
+					fullPath,
+					inArray
+				);
+			}
+
+			return addedArguments;
+		}
+
+		return addedArguments;
+	};
+
+	traverse(schema);
+
+	// Summarize flags
+	for (const name of Object.keys(flags)) {
+		/** @type {Argument} */
+		const argument = flags[name];
+		argument.description = argument.configs.reduce((desc, { description }) => {
+			if (!desc) return description;
+			if (!description) return desc;
+			if (desc.includes(description)) return desc;
+			return `${desc} ${description}`;
+		}, /** @type {string | undefined} */ (undefined));
+		argument.simpleType =
+			/** @type {SimpleType} */
+			(
+				argument.configs.reduce((t, argConfig) => {
+					/** @type {SimpleType} */
+					let type = "string";
+					switch (argConfig.type) {
+						case "number":
+							type = "number";
+							break;
+						case "reset":
+						case "boolean":
+							type = "boolean";
+							break;
+						case "enum": {
+							const values =
+								/** @type {NonNullable<ArgumentConfig["values"]>} */
+								(argConfig.values);
+
+							if (values.every((v) => typeof v === "boolean")) type = "boolean";
+							if (values.every((v) => typeof v === "number")) type = "number";
+							break;
+						}
+					}
+					if (t === undefined) return type;
+					return t === type ? t : "string";
+				}, /** @type {SimpleType | undefined} */ (undefined))
+			);
+		argument.multiple = argument.configs.some((c) => c.multiple);
+	}
+
+	return flags;
+};
+
+/** @type {WeakMap<EXPECTED_OBJECT, number>} */
+const cliAddedItems = new WeakMap();
+
+/** @typedef {string | number} Property */
+
+/**
+ * Gets object and property.
+ * @param {ObjectConfiguration} config configuration
+ * @param {string} schemaPath path in the config
+ * @param {number | undefined} index index of value when multiple values are provided, otherwise undefined
+ * @returns {{ problem?: LocalProblem, object?: ObjectConfiguration, property?: Property, value?: EXPECTED_OBJECT | EXPECTED_ANY[] }} problem or object with property and value
+ */
+const getObjectAndProperty = (config, schemaPath, index = 0) => {
+	if (!schemaPath) return { value: config };
+	const parts = schemaPath.split(".");
+	const property = /** @type {string} */ (parts.pop());
+	let current = config;
+	let i = 0;
+	for (const part of parts) {
+		const isArray = part.endsWith("[]");
+		const name = isArray ? part.slice(0, -2) : part;
+		let value = current[name];
+		if (isArray) {
+			if (value === undefined) {
+				value = {};
+				current[name] = [...Array.from({ length: index }), value];
+				cliAddedItems.set(current[name], index + 1);
+			} else if (!Array.isArray(value)) {
+				return {
+					problem: {
+						type: "unexpected-non-array-in-path",
+						path: parts.slice(0, i).join(".")
+					}
+				};
+			} else {
+				let addedItems = cliAddedItems.get(value) || 0;
+				while (addedItems <= index) {
+					value.push(undefined);
+					addedItems++;
+				}
+				cliAddedItems.set(value, addedItems);
+				const x = value.length - addedItems + index;
+				if (value[x] === undefined) {
+					value[x] = {};
+				} else if (value[x] === null || typeof value[x] !== "object") {
+					return {
+						problem: {
+							type: "unexpected-non-object-in-path",
+							path: parts.slice(0, i).join(".")
+						}
+					};
+				}
+				value = value[x];
+			}
+		} else if (value === undefined) {
+			value = current[name] = {};
+		} else if (value === null || typeof value !== "object") {
+			return {
+				problem: {
+					type: "unexpected-non-object-in-path",
+					path: parts.slice(0, i).join(".")
+				}
+			};
+		}
+		current = value;
+		i++;
+	}
+	const value = current[property];
+	if (property.endsWith("[]")) {
+		const name = property.slice(0, -2);
+		const value = current[name];
+		if (value === undefined) {
+			current[name] = [...Array.from({ length: index }), undefined];
+			cliAddedItems.set(current[name], index + 1);
+			return { object: current[name], property: index, value: undefined };
+		} else if (!Array.isArray(value)) {
+			current[name] = [value, ...Array.from({ length: index }), undefined];
+			cliAddedItems.set(current[name], index + 1);
+			return { object: current[name], property: index + 1, value: undefined };
+		}
+		let addedItems = cliAddedItems.get(value) || 0;
+		while (addedItems <= index) {
+			value.push(undefined);
+			addedItems++;
+		}
+		cliAddedItems.set(value, addedItems);
+		const x = value.length - addedItems + index;
+		if (value[x] === undefined) {
+			value[x] = {};
+		} else if (value[x] === null || typeof value[x] !== "object") {
+			return {
+				problem: {
+					type: "unexpected-non-object-in-path",
+					path: schemaPath
+				}
+			};
+		}
+		return {
+			object: value,
+			property: x,
+			value: value[x]
+		};
+	}
+	return { object: current, property, value };
+};
+
+/**
+ * Updates value using the provided config.
+ * @param {ObjectConfiguration} config configuration
+ * @param {string} schemaPath path in the config
+ * @param {ParsedValue} value parsed value
+ * @param {number | undefined} index index of value when multiple values are provided, otherwise undefined
+ * @returns {LocalProblem | null} problem or null for success
+ */
+const setValue = (config, schemaPath, value, index) => {
+	const { problem, object, property } = getObjectAndProperty(
+		config,
+		schemaPath,
+		index
+	);
+	if (problem) return problem;
+	/** @type {ObjectConfiguration} */
+	(object)[/** @type {Property} */ (property)] = value;
+	return null;
+};
+
+/**
+ * Process argument config.
+ * @param {ArgumentConfig} argConfig processing instructions
+ * @param {ObjectConfiguration} config configuration
+ * @param {Value} value the value
+ * @param {number | undefined} index the index if multiple values provided
+ * @returns {LocalProblem | null} a problem if any
+ */
+const processArgumentConfig = (argConfig, config, value, index) => {
+	if (index !== undefined && !argConfig.multiple) {
+		return {
+			type: "multiple-values-unexpected",
+			path: argConfig.path
+		};
+	}
+	const parsed = parseValueForArgumentConfig(argConfig, value);
+	if (parsed === undefined) {
+		return {
+			type: "invalid-value",
+			path: argConfig.path,
+			expected: getExpectedValue(argConfig)
+		};
+	}
+	const problem = setValue(config, argConfig.path, parsed, index);
+	if (problem) return problem;
+	return null;
+};
+
+/**
+ * Gets expected value.
+ * @param {ArgumentConfig} argConfig processing instructions
+ * @returns {string | undefined} expected message
+ */
+const getExpectedValue = (argConfig) => {
+	switch (argConfig.type) {
+		case "boolean":
+			return "true | false";
+		case "RegExp":
+			return "regular expression (example: /ab?c*/)";
+		case "enum":
+			return /** @type {NonNullable<ArgumentConfig["values"]>} */ (
+				argConfig.values
+			)
+				.map((v) => `${v}`)
+				.join(" | ");
+		case "reset":
+			return "true (will reset the previous value to an empty array)";
+		default:
+			return argConfig.type;
+	}
+};
+
+/** @typedef {null | string | number | boolean | RegExp | EnumValue | []} ParsedValue */
+
+const DECIMAL_NUMBER_REGEXP = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i;
+
+/**
+ * Parses value for argument config.
+ * @param {ArgumentConfig} argConfig processing instructions
+ * @param {Value} value the value
+ * @returns {ParsedValue | undefined} parsed value
+ */
+const parseValueForArgumentConfig = (argConfig, value) => {
+	switch (argConfig.type) {
+		case "string":
+			if (typeof value === "string") {
+				return value;
+			}
+			break;
+		case "path":
+			if (typeof value === "string") {
+				return path.resolve(value);
+			}
+			break;
+		case "number":
+			if (typeof value === "number") return value;
+			if (typeof value === "string" && DECIMAL_NUMBER_REGEXP.test(value)) {
+				const n = Number(value);
+				if (!Number.isNaN(n)) return n;
+			}
+			break;
+		case "boolean":
+			if (typeof value === "boolean") return value;
+			if (value === "true") return true;
+			if (value === "false") return false;
+			break;
+		case "RegExp":
+			if (value instanceof RegExp) return value;
+			if (typeof value === "string") {
+				// cspell:word yugi
+				const match = /^\/(.*)\/([yugi]*)$/.exec(value);
+				if (match && !/[^\\]\//.test(match[1])) {
+					return new RegExp(match[1], match[2]);
+				}
+			}
+			break;
+		case "enum": {
+			const values =
+				/** @type {EnumValue[]} */
+				(argConfig.values);
+			if (values.includes(/** @type {Exclude<Value, RegExp>} */ (value))) {
+				return value;
+			}
+			for (const item of values) {
+				if (`${item}` === value) return item;
+			}
+			break;
+		}
+		case "reset":
+			if (value === true) return [];
+			break;
+	}
+};
+
+/** @typedef {Record<string, Value[]>} Values */
+
+/**
+ * Processes the provided arg.
+ * @param {Flags} args object of arguments
+ * @param {ObjectConfiguration} config configuration
+ * @param {Values} values object with values
+ * @returns {Problem[] | null} problems or null for success
+ */
+const processArguments = (args, config, values) => {
+	/** @type {Problem[]} */
+	const problems = [];
+	for (const key of Object.keys(values)) {
+		const arg = args[key];
+		if (!arg) {
+			problems.push({
+				type: "unknown-argument",
+				path: "",
+				argument: key
+			});
+			continue;
+		}
+		/**
+		 * Processes the provided value.
+		 * @param {Value} value value
+		 * @param {number | undefined} i index
+		 */
+		const processValue = (value, i) => {
+			/** @type {Problem[]} */
+			const currentProblems = [];
+			for (const argConfig of arg.configs) {
+				const problem = processArgumentConfig(argConfig, config, value, i);
+				if (!problem) {
+					return;
+				}
+				currentProblems.push({
+					...problem,
+					argument: key,
+					value,
+					index: i
+				});
+			}
+			problems.push(...currentProblems);
+		};
+		const value = values[key];
+		if (Array.isArray(value)) {
+			for (let i = 0; i < value.length; i++) {
+				processValue(value[i], i);
+			}
+		} else {
+			processValue(value, undefined);
+		}
+	}
+	if (problems.length === 0) return null;
+	return problems;
+};
+
+/**
+ * Checks whether this object is color supported.
+ * @returns {boolean} true when colors supported, otherwise false
+ */
+const isColorSupported = () => {
+	const { env = {}, argv = [], platform = "" } = process;
+
+	const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
+	const isForced = "FORCE_COLOR" in env || argv.includes("--color");
+	const isWindows = platform === "win32";
+	const isDumbTerminal = env.TERM === "dumb";
+
+	const isCompatibleTerminal = tty.isatty(1) && env.TERM && !isDumbTerminal;
+
+	const isCI =
+		"CI" in env &&
+		("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
+
+	return (
+		!isDisabled &&
+		(isForced || (isWindows && !isDumbTerminal) || isCompatibleTerminal || isCI)
+	);
+};
+
+/**
+ * Returns result.
+ * @param {number} index index
+ * @param {string} string string
+ * @param {string} close close
+ * @param {string=} replace replace
+ * @param {string=} head head
+ * @param {string=} tail tail
+ * @param {number=} next next
+ * @returns {string} result
+ */
+const replaceClose = (
+	index,
+	string,
+	close,
+	replace,
+	head = string.slice(0, Math.max(0, index)) + replace,
+	tail = string.slice(Math.max(0, index + close.length)),
+	next = tail.indexOf(close)
+) => head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
+
+/**
+ * Returns result.
+ * @param {number} index index to replace
+ * @param {string} string string
+ * @param {string} open open string
+ * @param {string} close close string
+ * @param {string=} replace extra replace
+ * @returns {string} result
+ */
+const clearBleed = (index, string, open, close, replace) =>
+	index < 0
+		? open + string + close
+		: open + replaceClose(index, string, close, replace) + close;
+
+/** @typedef {(value: EXPECTED_ANY) => string} PrintFunction */
+
+/**
+ * Returns function to create color.
+ * @param {string} open open string
+ * @param {string} close close string
+ * @param {string=} replace extra replace
+ * @param {number=} at at
+ * @returns {PrintFunction} function to create color
+ */
+const filterEmpty =
+	(open, close, replace = open, at = open.length + 1) =>
+	(string) =>
+		string || !(string === "" || string === undefined)
+			? clearBleed(`${string}`.indexOf(close, at), string, open, close, replace)
+			: "";
+
+/**
+ * Returns result.
+ * @param {number} open open code
+ * @param {number} close close code
+ * @param {string=} replace extra replace
+ * @returns {PrintFunction} result
+ */
+const init = (open, close, replace) =>
+	filterEmpty(`\u001B[${open}m`, `\u001B[${close}m`, replace);
+
+/**
+ * Defines the colors type used by this module.
+ * @typedef {{ reset: PrintFunction, bold: PrintFunction, dim: PrintFunction, italic: PrintFunction, underline: PrintFunction, inverse: PrintFunction, hidden: PrintFunction, strikethrough: PrintFunction, black: PrintFunction, red: PrintFunction, green: PrintFunction, yellow: PrintFunction, blue: PrintFunction, magenta: PrintFunction, cyan: PrintFunction, white: PrintFunction, gray: PrintFunction, bgBlack: PrintFunction, bgRed: PrintFunction, bgGreen: PrintFunction, bgYellow: PrintFunction, bgBlue: PrintFunction, bgMagenta: PrintFunction, bgCyan: PrintFunction, bgWhite: PrintFunction, blackBright: PrintFunction, redBright: PrintFunction, greenBright: PrintFunction, yellowBright: PrintFunction, blueBright: PrintFunction, magentaBright: PrintFunction, cyanBright: PrintFunction, whiteBright: PrintFunction, bgBlackBright: PrintFunction, bgRedBright: PrintFunction, bgGreenBright: PrintFunction, bgYellowBright: PrintFunction, bgBlueBright: PrintFunction, bgMagentaBright: PrintFunction, bgCyanBright: PrintFunction, bgWhiteBright: PrintFunction }} Colors
+ */
+
+/**
+ * Defines the colors options type used by this module.
+ * @typedef {object} ColorsOptions
+ * @property {boolean=} useColor force use colors
+ */
+
+/**
+ * Creates a colors from the provided colors option.
+ * @param {ColorsOptions=} options options
+ * @returns {Colors} colors
+ */
+const createColors = ({ useColor = isColorSupported() } = {}) => ({
+	reset: useColor ? init(0, 0) : String,
+	bold: useColor ? init(1, 22, "\u001B[22m\u001B[1m") : String,
+	dim: useColor ? init(2, 22, "\u001B[22m\u001B[2m") : String,
+	italic: useColor ? init(3, 23) : String,
+	underline: useColor ? init(4, 24) : String,
+	inverse: useColor ? init(7, 27) : String,
+	hidden: useColor ? init(8, 28) : String,
+	strikethrough: useColor ? init(9, 29) : String,
+	black: useColor ? init(30, 39) : String,
+	red: useColor ? init(31, 39) : String,
+	green: useColor ? init(32, 39) : String,
+	yellow: useColor ? init(33, 39) : String,
+	blue: useColor ? init(34, 39) : String,
+	magenta: useColor ? init(35, 39) : String,
+	cyan: useColor ? init(36, 39) : String,
+	white: useColor ? init(37, 39) : String,
+	gray: useColor ? init(90, 39) : String,
+	bgBlack: useColor ? init(40, 49) : String,
+	bgRed: useColor ? init(41, 49) : String,
+	bgGreen: useColor ? init(42, 49) : String,
+	bgYellow: useColor ? init(43, 49) : String,
+	bgBlue: useColor ? init(44, 49) : String,
+	bgMagenta: useColor ? init(45, 49) : String,
+	bgCyan: useColor ? init(46, 49) : String,
+	bgWhite: useColor ? init(47, 49) : String,
+	blackBright: useColor ? init(90, 39) : String,
+	redBright: useColor ? init(91, 39) : String,
+	greenBright: useColor ? init(92, 39) : String,
+	yellowBright: useColor ? init(93, 39) : String,
+	blueBright: useColor ? init(94, 39) : String,
+	magentaBright: useColor ? init(95, 39) : String,
+	cyanBright: useColor ? init(96, 39) : String,
+	whiteBright: useColor ? init(97, 39) : String,
+	bgBlackBright: useColor ? init(100, 49) : String,
+	bgRedBright: useColor ? init(101, 49) : String,
+	bgGreenBright: useColor ? init(102, 49) : String,
+	bgYellowBright: useColor ? init(103, 49) : String,
+	bgBlueBright: useColor ? init(104, 49) : String,
+	bgMagentaBright: useColor ? init(105, 49) : String,
+	bgCyanBright: useColor ? init(106, 49) : String,
+	bgWhiteBright: useColor ? init(107, 49) : String
+});
+
+module.exports.createColors = createColors;
+module.exports.getArguments = getArguments;
+module.exports.isColorSupported = isColorSupported;
+module.exports.processArguments = processArguments;
Index: frontend/node_modules/webpack/lib/config/browserslistTargetHandler.js
===================================================================
--- frontend/node_modules/webpack/lib/config/browserslistTargetHandler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/config/browserslistTargetHandler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,390 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const path = require("path");
+const browserslist = require("browserslist");
+
+/** @typedef {import("./target").ApiTargetProperties} ApiTargetProperties */
+/** @typedef {import("./target").EcmaTargetProperties} EcmaTargetProperties */
+/** @typedef {import("./target").PlatformTargetProperties} PlatformTargetProperties */
+
+// [[C:]/path/to/config][:env]
+const inputRx = /^(?:((?:[A-Z]:)?[/\\].*?))?(?::(.+?))?$/i;
+
+/**
+ * Returns selected browsers.
+ * @param {string | null | undefined} input input string
+ * @param {string} context the context directory
+ * @returns {string[] | undefined} selected browsers
+ */
+const load = (input, context) => {
+	// browserslist:path-to-config
+	// browserslist:path-to-config:env
+	if (input && path.isAbsolute(input)) {
+		const [, configPath, env] = inputRx.exec(input) || [];
+
+		const config = browserslist.loadConfig({
+			config: configPath,
+			env
+		});
+
+		return browserslist(config, { env });
+	}
+
+	const env = input || undefined;
+
+	const config = browserslist.loadConfig({
+		path: context,
+		env
+	});
+
+	// browserslist
+	// browserslist:env
+	if (config) {
+		try {
+			return browserslist(config, { env, throwOnMissing: true });
+		} catch (_err) {
+			// Nothing, no `env` was found in browserslist, maybe input is `queries`
+		}
+	}
+
+	// browserslist:query
+	if (env) {
+		return browserslist(env);
+	}
+};
+
+/**
+ * Returns target properties.
+ * @param {string[]} browsers supported browsers list
+ * @returns {EcmaTargetProperties & PlatformTargetProperties & ApiTargetProperties} target properties
+ */
+const resolve = (browsers) => {
+	/**
+	 * Checks all against a version number
+	 * @param {Record<string, number | [number, number]>} versions first supported version
+	 * @returns {boolean} true if supports
+	 */
+	const rawChecker = (versions) =>
+		browsers.every((v) => {
+			const [name, parsedVersion] = v.split(" ");
+			if (!name) return false;
+			const requiredVersion = versions[name];
+			if (!requiredVersion) return false;
+			const [parsedMajor, parserMinor] =
+				// safari TP supports all features for normal safari
+				parsedVersion === "TP"
+					? [Infinity, Infinity]
+					: parsedVersion.includes("-")
+						? parsedVersion.split("-")[0].split(".")
+						: parsedVersion.split(".");
+			if (typeof requiredVersion === "number") {
+				return Number(parsedMajor) >= requiredVersion;
+			}
+			return requiredVersion[0] === Number(parsedMajor)
+				? Number(parserMinor) >= requiredVersion[1]
+				: Number(parsedMajor) > requiredVersion[0];
+		});
+	const anyNode = browsers.some((b) => b.startsWith("node "));
+	const anyBrowser = browsers.some((b) => /^(?!node)/.test(b));
+	const browserProperty = !anyBrowser ? false : anyNode ? null : true;
+	const nodeProperty = !anyNode ? false : anyBrowser ? null : true;
+
+	return {
+		/* eslint-disable camelcase */
+		const: rawChecker({
+			chrome: 49,
+			and_chr: 49,
+			edge: 12,
+			// Prior to Firefox 13, <code>const</code> is implemented, but re-assignment is not failing.
+			// Prior to Firefox 46, a <code>TypeError</code> was thrown on redeclaration instead of a <code>SyntaxError</code>.
+			firefox: 36,
+			and_ff: 36,
+			// Not supported in for-in and for-of loops
+			// ie: Not supported
+			opera: 36,
+			op_mob: 36,
+			safari: [10, 0],
+			ios_saf: [10, 0],
+			// Before 5.0 supported correctly in strict mode, otherwise supported without block scope
+			samsung: [5, 0],
+			android: 37,
+			and_qq: [10, 4],
+			// Supported correctly in strict mode, otherwise supported without block scope
+			baidu: [13, 18],
+			and_uc: [12, 12],
+			kaios: [2, 5],
+			node: [6, 0]
+		}),
+		methodShorthand: rawChecker({
+			chrome: 47,
+			and_chr: 47,
+			edge: 12,
+			firefox: 34,
+			and_ff: 34,
+			// ie: Not supported,
+			opera: 34,
+			op_mob: 34,
+			safari: 9,
+			ios_saf: 9,
+			samsung: 5,
+			android: 47,
+			// baidu: Not tracked,
+			and_qq: [14, 9],
+			and_uc: [15, 5],
+			kaios: [2, 5],
+			node: [4, 9]
+		}),
+		arrowFunction: rawChecker({
+			chrome: 45,
+			and_chr: 45,
+			edge: 12,
+			// The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of <code>'use strict';</code> is now required.
+			// Prior to Firefox 39, a line terminator (<code>\\n</code>) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like <code>() \\n => {}</code> will now throw a <code>SyntaxError</code> in this and later versions.
+			firefox: 39,
+			and_ff: 39,
+			// ie: Not supported,
+			opera: 32,
+			op_mob: 32,
+			safari: 10,
+			ios_saf: 10,
+			samsung: [5, 0],
+			android: 45,
+			and_qq: [10, 4],
+			baidu: [7, 12],
+			and_uc: [12, 12],
+			kaios: [2, 5],
+			node: [6, 0]
+		}),
+		forOf: rawChecker({
+			chrome: 38,
+			and_chr: 38,
+			edge: 12,
+			// Prior to Firefox 51, using the for...of loop construct with the const keyword threw a SyntaxError ("missing = in const declaration").
+			firefox: 51,
+			and_ff: 51,
+			// ie: Not supported,
+			opera: 25,
+			op_mob: 25,
+			safari: 7,
+			ios_saf: 7,
+			samsung: [3, 0],
+			android: 38,
+			and_qq: [10, 4],
+			// baidu: Unknown support
+			and_uc: [12, 12],
+			kaios: [3, 0],
+			node: [0, 12]
+		}),
+		destructuring: rawChecker({
+			chrome: 49,
+			and_chr: 49,
+			edge: 14,
+			firefox: 41,
+			and_ff: 41,
+			// ie: Not supported,
+			opera: 36,
+			op_mob: 36,
+			safari: 8,
+			ios_saf: 8,
+			samsung: [5, 0],
+			android: 49,
+			and_qq: [10, 4],
+			// baidu: Unknown support
+			and_uc: [12, 12],
+			kaios: [2, 5],
+			node: [6, 0]
+		}),
+		bigIntLiteral: rawChecker({
+			chrome: 67,
+			and_chr: 67,
+			edge: 79,
+			firefox: 68,
+			and_ff: 68,
+			// ie: Not supported,
+			opera: 54,
+			op_mob: 48,
+			safari: 14,
+			ios_saf: 14,
+			samsung: [9, 2],
+			android: 67,
+			and_qq: [13, 1],
+			baidu: [13, 18],
+			and_uc: [15, 5],
+			kaios: [3, 0],
+			node: [10, 4]
+		}),
+		// Support syntax `import` and `export` and no limitations and bugs on Node.js
+		// Not include `export * as namespace`
+		module: rawChecker({
+			chrome: 61,
+			and_chr: 61,
+			edge: 16,
+			firefox: 60,
+			and_ff: 60,
+			// ie: Not supported,
+			opera: 48,
+			op_mob: 45,
+			safari: [10, 1],
+			ios_saf: [10, 3],
+			samsung: [8, 0],
+			android: 61,
+			and_qq: [10, 4],
+			baidu: [13, 18],
+			and_uc: [15, 5],
+			kaios: [3, 0],
+			node: [12, 17]
+		}),
+		dynamicImport: rawChecker({
+			chrome: 63,
+			and_chr: 63,
+			edge: 79,
+			firefox: 67,
+			and_ff: 67,
+			// ie: Not supported
+			opera: 50,
+			op_mob: 46,
+			safari: [11, 1],
+			ios_saf: [11, 3],
+			samsung: [8, 2],
+			android: 63,
+			and_qq: [10, 4],
+			baidu: [13, 18],
+			and_uc: [15, 5],
+			kaios: [3, 0],
+			node: [12, 17]
+		}),
+		dynamicImportInWorker: rawChecker({
+			chrome: 80,
+			and_chr: 80,
+			edge: 80,
+			firefox: 114,
+			and_ff: 114,
+			// ie: Not supported
+			opera: 67,
+			op_mob: 57,
+			safari: [15, 0],
+			ios_saf: [15, 0],
+			samsung: [13, 0],
+			android: 80,
+			and_qq: [10, 4],
+			baidu: [13, 18],
+			and_uc: [15, 5],
+			kaios: [3, 0],
+			node: [12, 17]
+		}),
+		// browserslist does not have info about globalThis
+		// so this is based on mdn-browser-compat-data
+		globalThis: rawChecker({
+			chrome: 71,
+			and_chr: 71,
+			edge: 79,
+			firefox: 65,
+			and_ff: 65,
+			// ie: Not supported,
+			opera: 58,
+			op_mob: 50,
+			safari: [12, 1],
+			ios_saf: [12, 2],
+			samsung: [10, 1],
+			android: 71,
+			and_qq: [13, 1],
+			// baidu: Unknown support
+			and_uc: [15, 5],
+			kaios: [3, 0],
+			node: 12
+		}),
+		optionalChaining: rawChecker({
+			chrome: 80,
+			and_chr: 80,
+			edge: 80,
+			firefox: 74,
+			and_ff: 79,
+			// ie: Not supported,
+			opera: 67,
+			op_mob: 64,
+			safari: [13, 1],
+			ios_saf: [13, 4],
+			samsung: 13,
+			android: 80,
+			and_qq: [13, 1],
+			// baidu: Not supported
+			and_uc: [15, 5],
+			kaios: [3, 0],
+			node: 14
+		}),
+		templateLiteral: rawChecker({
+			chrome: 41,
+			and_chr: 41,
+			edge: 13,
+			firefox: 34,
+			and_ff: 34,
+			// ie: Not supported,
+			opera: 29,
+			op_mob: 64,
+			safari: [9, 1],
+			ios_saf: 9,
+			samsung: 4,
+			android: 41,
+			and_qq: [10, 4],
+			baidu: [7, 12],
+			and_uc: [12, 12],
+			kaios: [2, 5],
+			node: 4
+		}),
+		asyncFunction: rawChecker({
+			chrome: 55,
+			and_chr: 55,
+			edge: 15,
+			firefox: 52,
+			and_ff: 52,
+			// ie: Not supported,
+			opera: 42,
+			op_mob: 42,
+			safari: 11,
+			ios_saf: 11,
+			samsung: [6, 2],
+			android: 55,
+			and_qq: [10, 4],
+			baidu: [13, 18],
+			and_uc: [12, 12],
+			kaios: 3,
+			node: [7, 6]
+		}),
+		/* eslint-enable camelcase */
+		browser: browserProperty,
+		electron: false,
+		node: nodeProperty,
+		nwjs: false,
+		web: browserProperty,
+		webworker: false,
+
+		document: browserProperty,
+		fetchWasm: browserProperty,
+		global: nodeProperty,
+		importScripts: false,
+		importScriptsInWorker: Boolean(browserProperty),
+		nodeBuiltins: nodeProperty,
+		nodePrefixForCoreModules:
+			nodeProperty &&
+			!browsers.some((b) => b.startsWith("node 15")) &&
+			rawChecker({
+				node: [14, 18]
+			}),
+		importMetaDirnameAndFilename:
+			nodeProperty &&
+			rawChecker({
+				node: [22, 16]
+			}),
+		require: nodeProperty
+	};
+};
+
+module.exports = {
+	load,
+	resolve
+};
Index: frontend/node_modules/webpack/lib/config/defaults.js
===================================================================
--- frontend/node_modules/webpack/lib/config/defaults.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/config/defaults.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2320 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const fs = require("fs");
+const path = require("path");
+const {
+	CSS_TYPE,
+	JAVASCRIPT_TYPE,
+	UNKNOWN_TYPE
+} = require("../ModuleSourceTypeConstants");
+const {
+	ASSET_MODULE_TYPE,
+	ASSET_MODULE_TYPE_BYTES,
+	ASSET_MODULE_TYPE_INLINE,
+	ASSET_MODULE_TYPE_RESOURCE,
+	ASSET_MODULE_TYPE_SOURCE,
+	CSS_MODULE_TYPE,
+	CSS_MODULE_TYPE_AUTO,
+	CSS_MODULE_TYPE_GLOBAL,
+	CSS_MODULE_TYPE_MODULE,
+	HTML_MODULE_TYPE,
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM,
+	JSON_MODULE_TYPE,
+	WEBASSEMBLY_MODULE_TYPE_ASYNC,
+	WEBASSEMBLY_MODULE_TYPE_SYNC
+} = require("../ModuleTypeConstants");
+const Template = require("../Template");
+const { cleverMerge } = require("../util/cleverMerge");
+const {
+	getDefaultTarget,
+	getTargetProperties,
+	getTargetsProperties
+} = require("./target");
+
+/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptionsNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").Context} Context */
+/** @typedef {import("../../declarations/WebpackOptions").DevTool} Devtool */
+/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */
+/** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
+/** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
+/** @typedef {import("../../declarations/WebpackOptions").Environment} Environment */
+/** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
+/** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */
+/** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
+/** @typedef {import("../../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */
+/** @typedef {import("../../declarations/WebpackOptions").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */
+/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../../declarations/WebpackOptions").JsonGeneratorOptions} JsonGeneratorOptions */
+/** @typedef {import("../../declarations/WebpackOptions").Library} Library */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../../declarations/WebpackOptions").Loader} Loader */
+/** @typedef {import("../../declarations/WebpackOptions").Mode} Mode */
+/** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("../../declarations/WebpackOptions").HashSalt} HashSalt */
+/** @typedef {import("../../declarations/WebpackOptions").HashDigest} HashDigest */
+/** @typedef {import("../../declarations/WebpackOptions").HashDigestLength} HashDigestLength */
+/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
+/** @typedef {import("../../declarations/WebpackOptions").Node} WebpackNode */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationNormalized} Optimization */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */
+/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */
+/** @typedef {import("../../declarations/WebpackOptions").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */
+/** @typedef {import("../../declarations/WebpackOptions").Performance} Performance */
+/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */
+/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
+/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../javascript/EnableChunkLoadingPlugin").ChunkLoadingTypes} ChunkLoadingTypes */
+/** @typedef {import("../wasm/EnableWasmLoadingPlugin").WasmLoadingTypes} WasmLoadingTypes */
+/** @typedef {import("./target").PlatformTargetProperties} PlatformTargetProperties */
+/** @typedef {import("./target").TargetProperties} TargetProperties */
+
+/**
+ * Defines the recursive non nullable type used by this module.
+ * @template T
+ * @typedef {{ [P in keyof T]-?: T[P] extends object ? RecursiveNonNullable<NonNullable<T[P]>> : NonNullable<T[P]> }} RecursiveNonNullable
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Output & {
+ * uniqueName: NonNullable<Output["uniqueName"]>,
+ * filename: NonNullable<Output["filename"]>,
+ * cssFilename: NonNullable<Output["cssFilename"]>,
+ * chunkFilename: NonNullable<Output["chunkFilename"]>,
+ * cssChunkFilename: NonNullable<Output["cssChunkFilename"]>,
+ * hotUpdateChunkFilename: NonNullable<Output["hotUpdateChunkFilename"]>,
+ * hotUpdateGlobal: NonNullable<Output["hotUpdateGlobal"]>,
+ * assetModuleFilename: NonNullable<Output["assetModuleFilename"]>,
+ * webassemblyModuleFilename: NonNullable<Output["webassemblyModuleFilename"]>,
+ * sourceMapFilename: NonNullable<Output["sourceMapFilename"]>,
+ * hotUpdateMainFilename: NonNullable<Output["hotUpdateMainFilename"]>,
+ * devtoolNamespace: NonNullable<Output["devtoolNamespace"]>,
+ * publicPath: NonNullable<Output["publicPath"]>,
+ * workerPublicPath: NonNullable<Output["workerPublicPath"]>,
+ * workerWasmLoading: NonNullable<Output["workerWasmLoading"]>,
+ * workerChunkLoading: NonNullable<Output["workerChunkLoading"]>,
+ * chunkFormat: NonNullable<Output["chunkFormat"]>,
+ * module: NonNullable<Output["module"]>,
+ * asyncChunks: NonNullable<Output["asyncChunks"]>,
+ * charset: NonNullable<Output["charset"]>,
+ * iife: NonNullable<Output["iife"]>,
+ * globalObject: NonNullable<Output["globalObject"]>,
+ * scriptType: NonNullable<Output["scriptType"]>,
+ * path: NonNullable<Output["path"]>,
+ * pathinfo: NonNullable<Output["pathinfo"]>,
+ * hashFunction: NonNullable<Output["hashFunction"]>,
+ * hashDigest: NonNullable<Output["hashDigest"]>,
+ * hashDigestLength: NonNullable<Output["hashDigestLength"]>,
+ * chunkLoadTimeout: NonNullable<Output["chunkLoadTimeout"]>,
+ * chunkLoading: NonNullable<Output["chunkLoading"]>,
+ * chunkLoadingGlobal: NonNullable<Output["chunkLoadingGlobal"]>,
+ * compareBeforeEmit: NonNullable<Output["compareBeforeEmit"]>,
+ * strictModuleErrorHandling: NonNullable<Output["strictModuleErrorHandling"]>,
+ * strictModuleExceptionHandling: NonNullable<Output["strictModuleExceptionHandling"]>,
+ * importFunctionName: NonNullable<Output["importFunctionName"]>,
+ * importMetaName: NonNullable<Output["importMetaName"]>,
+ * environment: RecursiveNonNullable<Output["environment"]>,
+ * crossOriginLoading: NonNullable<Output["crossOriginLoading"]>,
+ * wasmLoading: NonNullable<Output["wasmLoading"]>,
+ * }} OutputNormalizedWithDefaults
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {SnapshotOptions & {
+ * managedPaths: NonNullable<SnapshotOptions["managedPaths"]>,
+ * unmanagedPaths: NonNullable<SnapshotOptions["unmanagedPaths"]>,
+ * immutablePaths: NonNullable<SnapshotOptions["immutablePaths"]>,
+ * resolveBuildDependencies: NonNullable<SnapshotOptions["resolveBuildDependencies"]>,
+ * buildDependencies: NonNullable<SnapshotOptions["buildDependencies"]>,
+ * module: NonNullable<SnapshotOptions["module"]>,
+ * resolve: NonNullable<SnapshotOptions["resolve"]>,
+ * }} SnapshotNormalizedWithDefaults
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Optimization & {
+ * runtimeChunk: NonNullable<Optimization["runtimeChunk"]>,
+ * splitChunks: NonNullable<Optimization["splitChunks"]>,
+ * mergeDuplicateChunks: NonNullable<Optimization["mergeDuplicateChunks"]>,
+ * removeAvailableModules: NonNullable<Optimization["removeAvailableModules"]>,
+ * removeEmptyChunks: NonNullable<Optimization["removeEmptyChunks"]>,
+ * flagIncludedChunks: NonNullable<Optimization["flagIncludedChunks"]>,
+ * moduleIds: NonNullable<Optimization["moduleIds"]>,
+ * chunkIds: NonNullable<Optimization["chunkIds"]>,
+ * sideEffects: NonNullable<Optimization["sideEffects"]>,
+ * providedExports: NonNullable<Optimization["providedExports"]>,
+ * usedExports: NonNullable<Optimization["usedExports"]>,
+ * mangleExports: NonNullable<Optimization["mangleExports"]>,
+ * innerGraph: NonNullable<Optimization["innerGraph"]>,
+ * concatenateModules: NonNullable<Optimization["concatenateModules"]>,
+ * avoidEntryIife: NonNullable<Optimization["avoidEntryIife"]>,
+ * emitOnErrors: NonNullable<Optimization["emitOnErrors"]>,
+ * checkWasmTypes: NonNullable<Optimization["checkWasmTypes"]>,
+ * mangleWasmImports: NonNullable<Optimization["mangleWasmImports"]>,
+ * portableRecords: NonNullable<Optimization["portableRecords"]>,
+ * realContentHash: NonNullable<Optimization["realContentHash"]>,
+ * minimize: NonNullable<Optimization["minimize"]>,
+ * minimizer: NonNullable<Exclude<Optimization["minimizer"], "...">>,
+ * nodeEnv: NonNullable<Optimization["nodeEnv"]>,
+ * }} OptimizationNormalizedWithDefaults
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {ExternalsPresets & {
+ * web: NonNullable<ExternalsPresets["web"]>,
+ * node: NonNullable<ExternalsPresets["node"]>,
+ * nwjs: NonNullable<ExternalsPresets["nwjs"]>,
+ * electron: NonNullable<ExternalsPresets["electron"]>,
+ * electronMain: NonNullable<ExternalsPresets["electronMain"]>,
+ * electronPreload: NonNullable<ExternalsPresets["electronPreload"]>,
+ * electronRenderer: NonNullable<ExternalsPresets["electronRenderer"]>,
+ * }} ExternalsPresetsNormalizedWithDefaults
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {InfrastructureLogging & {
+ * stream: NonNullable<InfrastructureLogging["stream"]>,
+ * level: NonNullable<InfrastructureLogging["level"]>,
+ * debug: NonNullable<InfrastructureLogging["debug"]>,
+ * colors: NonNullable<InfrastructureLogging["colors"]>,
+ * appendOnly: NonNullable<InfrastructureLogging["appendOnly"]>,
+ * }} InfrastructureLoggingNormalizedWithDefaults
+ */
+
+/**
+ * Defines the webpack options normalized with base defaults type used by this module.
+ * @typedef {WebpackOptionsNormalized & { context: NonNullable<WebpackOptionsNormalized["context"]> } & { infrastructureLogging: InfrastructureLoggingNormalizedWithDefaults }} WebpackOptionsNormalizedWithBaseDefaults
+ */
+
+/**
+ * Defines the webpack options normalized with defaults type used by this module.
+ * @typedef {WebpackOptionsNormalizedWithBaseDefaults & { target: NonNullable<WebpackOptionsNormalized["target"]> } & { output: OutputNormalizedWithDefaults } & { optimization: OptimizationNormalizedWithDefaults } & { devtool: NonNullable<WebpackOptionsNormalized["devtool"]> } & { stats: NonNullable<WebpackOptionsNormalized["stats"]> } & { node: NonNullable<WebpackOptionsNormalized["node"]> } & { profile: NonNullable<WebpackOptionsNormalized["profile"]> } & { parallelism: NonNullable<WebpackOptionsNormalized["parallelism"]> } & { snapshot: SnapshotNormalizedWithDefaults } & { externalsPresets: ExternalsPresetsNormalizedWithDefaults } & { externalsType: NonNullable<WebpackOptionsNormalized["externalsType"]> } & { watch: NonNullable<WebpackOptionsNormalized["watch"]> } & { performance: NonNullable<WebpackOptionsNormalized["performance"]> } & { recordsInputPath: NonNullable<WebpackOptionsNormalized["recordsInputPath"]> } & { recordsOutputPath: NonNullable<WebpackOptionsNormalized["recordsOutputPath"]> } & { dotenv: NonNullable<WebpackOptionsNormalized["dotenv"]> }} WebpackOptionsNormalizedWithDefaults
+ */
+
+/**
+ * Defines the resolved options type used by this module.
+ * @typedef {object} ResolvedOptions
+ * @property {PlatformTargetProperties | false} platform - platform target properties
+ */
+
+const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i;
+const DEFAULT_CACHE_NAME = "default";
+const DEFAULTS = {
+	// TODO webpack 6 - use xxhash64
+	HASH_FUNCTION: "md4"
+};
+
+/**
+ * Processes the provided obj.
+ * @template T
+ * @template {keyof T} P
+ * @param {T} obj an object
+ * @param {P} prop a property of this object
+ * @param {T[P]} value a default value of the property
+ * @returns {void}
+ */
+const D = (obj, prop, value) => {
+	if (obj[prop] === undefined) {
+		obj[prop] = value;
+	}
+};
+
+/**
+ * Processes the provided obj.
+ * @template T
+ * @template {keyof T} P
+ * @param {T} obj an object
+ * @param {P} prop a property of this object
+ * @param {() => T[P]} factory a default value factory for the property
+ * @returns {void}
+ */
+const F = (obj, prop, factory) => {
+	if (obj[prop] === undefined) {
+		obj[prop] = factory();
+	}
+};
+
+/**
+ * Sets a dynamic default value when undefined, by calling the factory function.
+ * factory must return an array or undefined
+ * When the current value is already an array an contains "..." it's replaced with
+ * the result of the factory function
+ * @template T
+ * @template {keyof T} P
+ * @param {T} obj an object
+ * @param {P} prop a property of this object
+ * @param {() => T[P]} factory a default value factory for the property
+ * @returns {void}
+ */
+const A = (obj, prop, factory) => {
+	const value = obj[prop];
+	if (value === undefined) {
+		obj[prop] = factory();
+	} else if (Array.isArray(value)) {
+		/** @type {EXPECTED_ANY[] | undefined} */
+		let newArray;
+		for (let i = 0; i < value.length; i++) {
+			const item = value[i];
+			if (item === "...") {
+				if (newArray === undefined) {
+					newArray = value.slice(0, i);
+					obj[prop] = /** @type {T[P]} */ (/** @type {unknown} */ (newArray));
+				}
+				const items =
+					/** @type {EXPECTED_ANY[]} */
+					(/** @type {unknown} */ (factory()));
+				if (items !== undefined) {
+					for (const item of items) {
+						newArray.push(item);
+					}
+				}
+			} else if (newArray !== undefined) {
+				newArray.push(item);
+			}
+		}
+	}
+};
+
+/**
+ * Apply webpack options base defaults.
+ * @param {WebpackOptionsNormalized} options options to be modified
+ * @returns {void}
+ */
+const applyWebpackOptionsBaseDefaults = (options) => {
+	F(options, "context", () => process.cwd());
+	applyInfrastructureLoggingDefaults(options.infrastructureLogging);
+};
+
+/**
+ * Apply webpack options defaults.
+ * @param {WebpackOptionsNormalized} options options to be modified
+ * @param {number=} compilerIndex index of compiler
+ * @returns {ResolvedOptions} Resolved options after apply defaults
+ */
+const applyWebpackOptionsDefaults = (options, compilerIndex) => {
+	F(options, "context", () => process.cwd());
+	F(options, "target", () =>
+		getDefaultTarget(/** @type {string} */ (options.context))
+	);
+
+	const { mode, name, target } = options;
+
+	const targetProperties =
+		target === false
+			? /** @type {false} */ (false)
+			: typeof target === "string"
+				? getTargetProperties(target, /** @type {Context} */ (options.context))
+				: getTargetsProperties(
+						/** @type {string[]} */ (target),
+						/** @type {Context} */ (options.context)
+					);
+
+	const development = mode === "development";
+	const production = mode === "production" || !mode;
+
+	if (typeof options.entry !== "function") {
+		for (const key of Object.keys(options.entry)) {
+			F(
+				options.entry[key],
+				"import",
+				() => /** @type {[string]} */ (["./src"])
+			);
+		}
+	}
+
+	F(
+		options,
+		"devtool",
+		() =>
+			/** @type {Devtool} */ (
+				development
+					? [
+							options.experiments.css
+								? {
+										type: "css",
+										use: "source-map"
+									}
+								: undefined,
+							{
+								type: "javascript",
+								use: "eval"
+							}
+						].filter(Boolean)
+					: false
+			)
+	);
+
+	D(options, "watch", false);
+	D(options, "profile", false);
+	D(options, "parallelism", 100);
+	D(options, "recordsInputPath", false);
+	D(options, "recordsOutputPath", false);
+
+	applyExperimentsDefaults(options.experiments, {
+		production,
+		development,
+		targetProperties
+	});
+
+	const futureDefaults =
+		/** @type {NonNullable<ExperimentsNormalized["futureDefaults"]>} */
+		(options.experiments.futureDefaults);
+
+	F(options, "validate", () => !(futureDefaults === true && production));
+
+	F(options, "cache", () =>
+		development ? { type: /** @type {"memory"} */ ("memory") } : false
+	);
+	applyCacheDefaults(options.cache, {
+		name: name || DEFAULT_CACHE_NAME,
+		mode: mode || "production",
+		development,
+		cacheUnaffected: options.experiments.cacheUnaffected,
+		futureDefaults,
+		compilerIndex
+	});
+	const cache = Boolean(options.cache);
+
+	applySnapshotDefaults(options.snapshot, {
+		production,
+		futureDefaults
+	});
+
+	applyOutputDefaults(options.output, {
+		context: /** @type {Context} */ (options.context),
+		targetProperties,
+		isAffectedByBrowserslist:
+			target === undefined ||
+			(typeof target === "string" && target.startsWith("browserslist")) ||
+			(Array.isArray(target) &&
+				target.some((target) => target.startsWith("browserslist"))),
+		outputModule:
+			/** @type {NonNullable<ExperimentsNormalized["outputModule"]>} */
+			(options.experiments.outputModule),
+		development,
+		entry: options.entry,
+		futureDefaults,
+		asyncWebAssembly:
+			/** @type {NonNullable<ExperimentsNormalized["asyncWebAssembly"]>} */
+			(options.experiments.asyncWebAssembly)
+	});
+
+	applyModuleDefaults(options.module, {
+		cache,
+		hashSalt: /** @type {NonNullable<Output["hashSalt"]>} */ (
+			options.output.hashSalt
+		),
+		hashFunction: /** @type {NonNullable<Output["hashFunction"]>} */ (
+			options.output.hashFunction
+		),
+		syncWebAssembly:
+			/** @type {NonNullable<ExperimentsNormalized["syncWebAssembly"]>} */
+			(options.experiments.syncWebAssembly),
+		asyncWebAssembly:
+			/** @type {NonNullable<ExperimentsNormalized["asyncWebAssembly"]>} */
+			(options.experiments.asyncWebAssembly),
+		css:
+			/** @type {NonNullable<ExperimentsNormalized["css"]>} */
+			(options.experiments.css),
+		html:
+			/** @type {NonNullable<ExperimentsNormalized["html"]>} */
+			(options.experiments.html),
+		typescript:
+			/** @type {NonNullable<ExperimentsNormalized["typescript"]>} */
+			(options.experiments.typescript),
+		deferImport:
+			/** @type {NonNullable<ExperimentsNormalized["deferImport"]>} */
+			(options.experiments.deferImport),
+		sourceImport:
+			/** @type {NonNullable<ExperimentsNormalized["sourceImport"]>} */
+			(options.experiments.sourceImport),
+		futureDefaults,
+		isNode: targetProperties && targetProperties.node === true,
+		uniqueName: /** @type {string} */ (options.output.uniqueName),
+		targetProperties,
+		mode: options.mode,
+		outputModule:
+			/** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */
+			(options.output.module),
+		library: options.output.library
+	});
+
+	applyExternalsPresetsDefaults(options.externalsPresets, {
+		targetProperties,
+		buildHttp: Boolean(options.experiments.buildHttp),
+		outputModule:
+			/** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */
+			(options.output.module)
+	});
+
+	applyLoaderDefaults(
+		/** @type {NonNullable<WebpackOptionsNormalized["loader"]>} */ (
+			options.loader
+		),
+		{ targetProperties, environment: options.output.environment }
+	);
+
+	F(options, "externalsType", () => {
+		const validExternalTypes = require("../../schemas/WebpackOptions.json")
+			.definitions.ExternalsType.enum;
+
+		return options.output.library &&
+			validExternalTypes.includes(options.output.library.type)
+			? /** @type {ExternalsType} */ (options.output.library.type)
+			: options.output.module
+				? "module-import"
+				: "var";
+	});
+
+	applyNodeDefaults(options.node, {
+		futureDefaults:
+			/** @type {NonNullable<WebpackOptionsNormalized["experiments"]["futureDefaults"]>} */
+			(options.experiments.futureDefaults),
+		outputModule:
+			/** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */
+			(options.output.module),
+		targetProperties
+	});
+
+	F(options, "performance", () =>
+		production &&
+		targetProperties &&
+		(targetProperties.browser || targetProperties.browser === null)
+			? {}
+			: false
+	);
+	applyPerformanceDefaults(
+		/** @type {NonNullable<WebpackOptionsNormalized["performance"]>} */
+		(options.performance),
+		{
+			production
+		}
+	);
+
+	applyOptimizationDefaults(options.optimization, {
+		development,
+		production,
+		css:
+			/** @type {NonNullable<ExperimentsNormalized["css"]>} */
+			(options.experiments.css),
+		records: Boolean(options.recordsInputPath || options.recordsOutputPath)
+	});
+
+	options.resolve = cleverMerge(
+		getResolveDefaults({
+			cache,
+			context: /** @type {Context} */ (options.context),
+			targetProperties,
+			mode: /** @type {Mode} */ (options.mode),
+			css:
+				/** @type {NonNullable<ExperimentsNormalized["css"]>} */
+				(options.experiments.css),
+			typescript:
+				/** @type {NonNullable<ExperimentsNormalized["typescript"]>} */
+				(options.experiments.typescript)
+		}),
+		options.resolve
+	);
+
+	options.resolveLoader = cleverMerge(
+		getResolveLoaderDefaults({ cache }),
+		options.resolveLoader
+	);
+
+	return {
+		platform:
+			targetProperties === false
+				? targetProperties
+				: {
+						web: targetProperties.web,
+						browser: targetProperties.browser,
+						webworker: targetProperties.webworker,
+						node: targetProperties.node,
+						nwjs: targetProperties.nwjs,
+						electron: targetProperties.electron
+					}
+	};
+};
+
+/**
+ * Apply experiments defaults.
+ * @param {ExperimentsNormalized} experiments options
+ * @param {object} options options
+ * @param {boolean} options.production is production
+ * @param {boolean} options.development is development mode
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @returns {void}
+ */
+const applyExperimentsDefaults = (
+	experiments,
+	{ production, development, targetProperties }
+) => {
+	D(experiments, "futureDefaults", false);
+	D(experiments, "backCompat", !experiments.futureDefaults);
+	// TODO do we need sync web assembly in webpack@6?
+	D(experiments, "syncWebAssembly", false);
+	D(experiments, "asyncWebAssembly", experiments.futureDefaults);
+	D(experiments, "outputModule", false);
+	D(experiments, "lazyCompilation", undefined);
+	D(experiments, "buildHttp", undefined);
+	D(experiments, "cacheUnaffected", experiments.futureDefaults);
+	D(experiments, "deferImport", false);
+	D(experiments, "sourceImport", false);
+	F(experiments, "css", () => (experiments.futureDefaults ? true : undefined));
+	F(experiments, "html", () => (experiments.futureDefaults ? true : undefined));
+	F(experiments, "typescript", () =>
+		experiments.futureDefaults ? true : undefined
+	);
+
+	if (typeof experiments.buildHttp === "object") {
+		D(experiments.buildHttp, "frozen", production);
+		D(experiments.buildHttp, "upgrade", false);
+	}
+};
+
+/**
+ * Apply cache defaults.
+ * @param {CacheOptionsNormalized} cache options
+ * @param {object} options options
+ * @param {string} options.name name
+ * @param {Mode} options.mode mode
+ * @param {boolean} options.futureDefaults is future defaults enabled
+ * @param {boolean} options.development is development mode
+ * @param {number=} options.compilerIndex index of compiler
+ * @param {Experiments["cacheUnaffected"]} options.cacheUnaffected the cacheUnaffected experiment is enabled
+ * @returns {void}
+ */
+const applyCacheDefaults = (
+	cache,
+	{ name, mode, development, cacheUnaffected, compilerIndex, futureDefaults }
+) => {
+	if (cache === false) return;
+	switch (cache.type) {
+		case "filesystem":
+			F(cache, "name", () =>
+				compilerIndex !== undefined
+					? `${`${name}-${mode}`}__compiler${compilerIndex + 1}__`
+					: `${name}-${mode}`
+			);
+			D(cache, "version", "");
+			F(cache, "cacheDirectory", () => {
+				const cwd = process.cwd();
+				/** @type {string | undefined} */
+				let dir = cwd;
+				for (;;) {
+					try {
+						if (fs.statSync(path.join(dir, "package.json")).isFile()) break;
+						// eslint-disable-next-line no-empty
+					} catch (_err) {}
+					const parent = path.dirname(dir);
+					if (dir === parent) {
+						dir = undefined;
+						break;
+					}
+					dir = parent;
+				}
+				if (!dir) {
+					return path.resolve(cwd, ".cache/webpack");
+				} else if (process.versions.pnp === "1") {
+					return path.resolve(dir, ".pnp/.cache/webpack");
+				} else if (process.versions.pnp === "3") {
+					return path.resolve(dir, ".yarn/.cache/webpack");
+				}
+				return path.resolve(dir, "node_modules/.cache/webpack");
+			});
+			F(cache, "cacheLocation", () =>
+				path.resolve(
+					/** @type {NonNullable<FileCacheOptions["cacheDirectory"]>} */
+					(cache.cacheDirectory),
+					/** @type {NonNullable<FileCacheOptions["name"]>} */ (cache.name)
+				)
+			);
+			D(cache, "hashAlgorithm", futureDefaults ? "xxhash64" : "md4");
+			D(cache, "store", "pack");
+			D(cache, "compression", false);
+			D(cache, "profile", false);
+			D(cache, "idleTimeout", 60000);
+			D(cache, "idleTimeoutForInitialStore", 5000);
+			D(cache, "idleTimeoutAfterLargeChanges", 1000);
+			D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
+			D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
+			D(cache, "allowCollectingMemory", development);
+			D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
+			D(cache, "readonly", false);
+			D(
+				/** @type {NonNullable<FileCacheOptions["buildDependencies"]>} */
+				(cache.buildDependencies),
+				"defaultWebpack",
+				[path.resolve(__dirname, "..") + path.sep]
+			);
+			break;
+		case "memory":
+			D(cache, "maxGenerations", Infinity);
+			D(cache, "cacheUnaffected", development && cacheUnaffected);
+			break;
+	}
+};
+
+/**
+ * Apply snapshot defaults.
+ * @param {SnapshotOptions} snapshot options
+ * @param {object} options options
+ * @param {boolean} options.production is production
+ * @param {boolean} options.futureDefaults is future defaults enabled
+ * @returns {void}
+ */
+const applySnapshotDefaults = (snapshot, { production, futureDefaults }) => {
+	if (futureDefaults) {
+		F(snapshot, "managedPaths", () =>
+			process.versions.pnp === "3"
+				? [
+						/^(.+?(?:[\\/]\.yarn[\\/]unplugged[\\/][^\\/]+)?[\\/]node_modules[\\/])/
+					]
+				: [/^(.+?[\\/]node_modules[\\/])/]
+		);
+		F(snapshot, "immutablePaths", () =>
+			process.versions.pnp === "3"
+				? [/^(.+?[\\/]cache[\\/][^\\/]+\.zip[\\/]node_modules[\\/])/]
+				: []
+		);
+	} else {
+		A(snapshot, "managedPaths", () => {
+			if (process.versions.pnp === "3") {
+				const match =
+					/^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
+						require.resolve("watchpack")
+					);
+				if (match) {
+					return [path.resolve(match[1], "unplugged")];
+				}
+			} else {
+				const match = /^(.+?[\\/]node_modules[\\/])/.exec(
+					require.resolve("watchpack")
+				);
+				if (match) {
+					return [match[1]];
+				}
+			}
+			return [];
+		});
+		A(snapshot, "immutablePaths", () => {
+			if (process.versions.pnp === "1") {
+				const match =
+					/^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec(
+						require.resolve("watchpack")
+					);
+				if (match) {
+					return [match[1]];
+				}
+			} else if (process.versions.pnp === "3") {
+				const match =
+					/^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
+						require.resolve("watchpack")
+					);
+				if (match) {
+					return [match[1]];
+				}
+			}
+			return [];
+		});
+	}
+	F(snapshot, "unmanagedPaths", () => []);
+	F(snapshot, "resolveBuildDependencies", () => ({
+		timestamp: true,
+		hash: true
+	}));
+	F(snapshot, "buildDependencies", () => ({ timestamp: true, hash: true }));
+	F(snapshot, "module", () =>
+		production ? { timestamp: true, hash: true } : { timestamp: true }
+	);
+	F(snapshot, "contextModule", () => ({ timestamp: true }));
+	F(snapshot, "resolve", () =>
+		production ? { timestamp: true, hash: true } : { timestamp: true }
+	);
+};
+
+/**
+ * Apply javascript parser options defaults.
+ * @param {JavascriptParserOptions} parserOptions parser options
+ * @param {object} options options
+ * @param {boolean} options.futureDefaults is future defaults enabled
+ * @param {boolean} options.deferImport is defer import enabled
+ * @param {boolean} options.sourceImport is import source enabled
+ * @param {boolean} options.isNode is node target platform
+ * @param {boolean} options.outputModule is output.module enabled
+ * @param {WebpackOptionsNormalized["output"]["library"]} options.library library options
+ * @param {boolean} options.typescript is typescript enabled
+ * @returns {void}
+ */
+const applyJavascriptParserOptionsDefaults = (
+	parserOptions,
+	{
+		futureDefaults,
+		deferImport,
+		sourceImport,
+		isNode,
+		outputModule,
+		library,
+		typescript
+	}
+) => {
+	D(parserOptions, "unknownContextRequest", ".");
+	D(parserOptions, "unknownContextRegExp", false);
+	D(parserOptions, "unknownContextRecursive", true);
+	D(parserOptions, "unknownContextCritical", true);
+	D(parserOptions, "exprContextRequest", ".");
+	D(parserOptions, "exprContextRegExp", false);
+	D(parserOptions, "exprContextRecursive", true);
+	D(parserOptions, "exprContextCritical", true);
+	D(parserOptions, "wrappedContextRegExp", /.*/);
+	D(parserOptions, "wrappedContextRecursive", true);
+	D(parserOptions, "wrappedContextCritical", false);
+	D(parserOptions, "strictThisContextOnImports", false);
+	D(parserOptions, "importMeta", outputModule ? "preserve-unknown" : true);
+	D(parserOptions, "dynamicImportMode", "lazy");
+	D(parserOptions, "dynamicImportPrefetch", false);
+	D(parserOptions, "dynamicImportPreload", false);
+	D(parserOptions, "dynamicImportFetchPriority", false);
+	D(parserOptions, "createRequire", isNode);
+	D(parserOptions, "dynamicUrl", true);
+	D(parserOptions, "deferImport", deferImport);
+	D(parserOptions, "sourceImport", sourceImport);
+	D(parserOptions, "typescript", typescript);
+	if (futureDefaults) D(parserOptions, "exportsPresence", "error");
+	D(parserOptions, "anonymousDefaultExportName", !library);
+};
+
+/**
+ * Apply json generator options defaults.
+ * @param {JsonGeneratorOptions} generatorOptions generator options
+ * @returns {void}
+ */
+const applyJsonGeneratorOptionsDefaults = (generatorOptions) => {
+	D(generatorOptions, "JSONParse", true);
+};
+
+/**
+ * Apply css generator options defaults.
+ * @param {CssGeneratorOptions} generatorOptions generator options
+ * @param {object} options options
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @returns {void}
+ */
+const applyCssGeneratorOptionsDefaults = (
+	generatorOptions,
+	{ targetProperties }
+) => {
+	D(
+		generatorOptions,
+		"exportsOnly",
+		!targetProperties || targetProperties.document === false
+	);
+	D(generatorOptions, "esModule", true);
+};
+
+/**
+ * Apply module defaults.
+ * @param {ModuleOptions} module options
+ * @param {object} options options
+ * @param {boolean} options.cache is caching enabled
+ * @param {boolean} options.syncWebAssembly is syncWebAssembly enabled
+ * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
+ * @param {boolean} options.typescript is typescript enabled
+ * @param {boolean} options.css is css enabled
+ * @param {boolean} options.html is html enabled
+ * @param {boolean} options.futureDefaults is future defaults enabled
+ * @param {string} options.uniqueName the unique name
+ * @param {boolean} options.isNode is node target platform
+ * @param {boolean} options.deferImport is defer import enabled
+ * @param {boolean} options.sourceImport is import source enabled
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @param {Mode | undefined} options.mode mode
+ * @param {HashSalt} options.hashSalt hash salt
+ * @param {HashFunction} options.hashFunction hash function
+ * @param {boolean} options.outputModule is output.module enabled
+ * @param {WebpackOptionsNormalized["output"]["library"]} options.library library options
+ * @returns {void}
+ */
+const applyModuleDefaults = (
+	module,
+	{
+		hashSalt,
+		hashFunction,
+		cache,
+		syncWebAssembly,
+		asyncWebAssembly,
+		css,
+		html,
+		typescript,
+		futureDefaults,
+		isNode,
+		uniqueName,
+		targetProperties,
+		mode,
+		deferImport,
+		sourceImport,
+		outputModule,
+		library
+	}
+) => {
+	if (cache) {
+		D(
+			module,
+			"unsafeCache",
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {Module} module module
+			 * @returns {boolean} true, if we want to cache the module
+			 */
+			(module) => {
+				const name = module.nameForCondition();
+				if (!name) {
+					return false;
+				}
+				return NODE_MODULES_REGEXP.test(name);
+			}
+		);
+	} else {
+		D(module, "unsafeCache", false);
+	}
+
+	F(module.parser, ASSET_MODULE_TYPE, () => ({}));
+	F(
+		/** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
+		(module.parser[ASSET_MODULE_TYPE]),
+		"dataUrlCondition",
+		() => ({})
+	);
+	if (
+		typeof (
+			/** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
+			(module.parser[ASSET_MODULE_TYPE]).dataUrlCondition
+		) === "object"
+	) {
+		D(
+			/** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
+			(module.parser[ASSET_MODULE_TYPE]).dataUrlCondition,
+			"maxSize",
+			8096
+		);
+	}
+
+	F(module.parser, "javascript", () => ({}));
+	F(module.parser, JSON_MODULE_TYPE, () => ({}));
+	D(
+		/** @type {NonNullable<ParserOptionsByModuleTypeKnown[JSON_MODULE_TYPE]>} */
+		(module.parser[JSON_MODULE_TYPE]),
+		"exportsDepth",
+		mode === "development" ? 1 : Infinity
+	);
+
+	applyJavascriptParserOptionsDefaults(
+		/** @type {NonNullable<ParserOptionsByModuleTypeKnown["javascript"]>} */
+		(module.parser.javascript),
+		{
+			futureDefaults,
+			deferImport,
+			sourceImport,
+			isNode,
+			outputModule,
+			library,
+			typescript
+		}
+	);
+
+	F(module.generator, "json", () => ({}));
+
+	applyJsonGeneratorOptionsDefaults(
+		/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown["json"]>} */
+		(module.generator.json)
+	);
+
+	if (css) {
+		F(module.parser, CSS_MODULE_TYPE, () => ({}));
+
+		D(
+			/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
+			(module.parser[CSS_MODULE_TYPE]),
+			"import",
+			true
+		);
+		D(
+			/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
+			(module.parser[CSS_MODULE_TYPE]),
+			"url",
+			true
+		);
+		D(
+			/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
+			(module.parser[CSS_MODULE_TYPE]),
+			"namedExports",
+			true
+		);
+
+		for (const type of [
+			CSS_MODULE_TYPE_AUTO,
+			CSS_MODULE_TYPE_MODULE,
+			CSS_MODULE_TYPE_GLOBAL
+		]) {
+			F(module.parser, type, () => ({}));
+
+			D(
+				/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.parser[type]),
+				"animation",
+				true
+			);
+			D(
+				/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.parser[type]),
+				"container",
+				true
+			);
+			D(
+				/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.parser[type]),
+				"customIdents",
+				true
+			);
+			D(
+				/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.parser[type]),
+				"dashedIdents",
+				true
+			);
+			D(
+				/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.parser[type]),
+				"function",
+				true
+			);
+			D(
+				/** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.parser[type]),
+				"grid",
+				true
+			);
+		}
+
+		F(module.generator, CSS_MODULE_TYPE, () => ({}));
+
+		applyCssGeneratorOptionsDefaults(
+			/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
+			(module.generator[CSS_MODULE_TYPE]),
+			{ targetProperties }
+		);
+
+		const localIdentName =
+			mode === "development"
+				? uniqueName.length > 0
+					? "[uniqueName]-[id]-[local]"
+					: "[id]-[local]"
+				: "[fullhash]";
+		const localIdentHashSalt = hashSalt;
+		const localIdentHashDigest = "base64url";
+		const localIdentHashDigestLength = 6;
+		const exportsConvention = "as-is";
+
+		for (const type of [
+			CSS_MODULE_TYPE_AUTO,
+			CSS_MODULE_TYPE_MODULE,
+			CSS_MODULE_TYPE_GLOBAL
+		]) {
+			F(module.generator, type, () => ({}));
+
+			D(
+				/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.generator[type]),
+				"localIdentName",
+				localIdentName
+			);
+
+			D(
+				/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.generator[type]),
+				"localIdentHashSalt",
+				localIdentHashSalt
+			);
+
+			D(
+				/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
+				(module.generator[type]),
+				"localIdentHashFunction",
+				hashFunction
+			);
+
+			D(
+				/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
+				(module.generator[type]),
+				"localIdentHashDigest",
+				localIdentHashDigest
+			);
+
+			D(
+				/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
+				(module.generator[type]),
+				"localIdentHashDigestLength",
+				localIdentHashDigestLength
+			);
+
+			D(
+				/** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
+				(module.generator[type]),
+				"exportsConvention",
+				exportsConvention
+			);
+		}
+	}
+
+	if (html) {
+		// `module.generator.html.extract` is intentionally left undefined by
+		// default: HtmlGenerator treats undefined as "extract iff this HTML
+		// module is a compilation entry", which is the HTML-entry-point
+		// behaviour. Setting `extract: true` forces extraction for all HTML
+		// modules (including imported ones); `extract: false` disables it
+		// everywhere.
+		F(module.generator, HTML_MODULE_TYPE, () => ({}));
+	}
+
+	A(module, "defaultRules", () => {
+		const esm = {
+			type: JAVASCRIPT_MODULE_TYPE_ESM,
+			resolve: {
+				byDependency: {
+					esm: {
+						fullySpecified: true
+					}
+				}
+			}
+		};
+		const commonjs = {
+			type: JAVASCRIPT_MODULE_TYPE_DYNAMIC
+		};
+		/** @type {RuleSetRules} */
+		const rules = [
+			{
+				mimetype: "application/node",
+				type: JAVASCRIPT_MODULE_TYPE_AUTO
+			},
+			{
+				test: /\.json$/i,
+				type: JSON_MODULE_TYPE
+			},
+			{
+				mimetype: "application/json",
+				type: JSON_MODULE_TYPE
+			},
+			{
+				test: /\.mjs$/i,
+				...esm
+			},
+			{
+				test: /\.js$/i,
+				descriptionData: {
+					type: "module"
+				},
+				...esm
+			},
+			{
+				test: /\.cjs$/i,
+				...commonjs
+			},
+			{
+				test: /\.js$/i,
+				descriptionData: {
+					type: "commonjs"
+				},
+				...commonjs
+			},
+			{
+				mimetype: {
+					or: ["text/javascript", "application/javascript"]
+				},
+				...esm
+			}
+		];
+
+		if (asyncWebAssembly) {
+			const wasm = {
+				type: WEBASSEMBLY_MODULE_TYPE_ASYNC,
+				rules: [
+					{
+						descriptionData: {
+							type: "module"
+						},
+						resolve: {
+							fullySpecified: true
+						}
+					}
+				]
+			};
+			rules.push({
+				test: /\.wasm$/i,
+				...wasm
+			});
+			rules.push({
+				mimetype: "application/wasm",
+				...wasm
+			});
+		} else if (syncWebAssembly) {
+			const wasm = {
+				type: WEBASSEMBLY_MODULE_TYPE_SYNC,
+				rules: [
+					{
+						descriptionData: {
+							type: "module"
+						},
+						resolve: {
+							fullySpecified: true
+						}
+					}
+				]
+			};
+			rules.push({
+				test: /\.wasm$/i,
+				...wasm
+			});
+			rules.push({
+				mimetype: "application/wasm",
+				...wasm
+			});
+		}
+
+		if (css) {
+			const resolve = {
+				fullySpecified: true,
+				preferRelative: true
+			};
+			rules.push({
+				test: /\.css$/i,
+				type: CSS_MODULE_TYPE_AUTO,
+				resolve
+			});
+			rules.push({
+				mimetype: "text/css+module",
+				type: CSS_MODULE_TYPE_MODULE,
+				resolve
+			});
+			rules.push({
+				mimetype: "text/css",
+				type: CSS_MODULE_TYPE,
+				resolve
+			});
+			// For CSS modules, i.e. `.class { composes: className from "./style.css" }`
+			// We inherit for such constructions, but skip files that are already
+			// detected as CSS modules by extension (`.module.<ext>`) — they get
+			// the same modules-mode behavior from the auto rule, and forcing a
+			// different type stamp here would create a duplicate module instance.
+			const moduleExtension = /\.module\.\w+$/i;
+			rules.push({
+				dependency: /css-import-local-module/,
+				exclude: moduleExtension,
+				type: CSS_MODULE_TYPE_MODULE,
+				resolve
+			});
+			rules.push({
+				dependency: /css-import-global-module/,
+				exclude: moduleExtension,
+				type: CSS_MODULE_TYPE_GLOBAL,
+				resolve
+			});
+
+			rules.push(
+				{
+					with: { type: "css" },
+					parser: {
+						exportType: "css-style-sheet"
+					},
+					resolve
+				},
+				{
+					assert: { type: "css" },
+					parser: {
+						exportType: "css-style-sheet"
+					},
+					resolve
+				}
+			);
+		}
+		if (html) {
+			const resolve = {
+				fullySpecified: true,
+				preferRelative: true
+			};
+
+			rules.push({
+				test: /\.html$/i,
+				type: HTML_MODULE_TYPE,
+				resolve
+			});
+			rules.push({
+				mimetype: "text/html",
+				type: HTML_MODULE_TYPE,
+				resolve
+			});
+			if (css) {
+				// Inline `<style>` content in an HTML module is fed into the
+				// CSS pipeline as a `data:text/css` virtual module. We force
+				// `exportType: "text"` so the CSS module exposes the
+				// processed CSS text on the `css-text` codegen channel that
+				// `HtmlInlineStyleDependency.Template` reads back into the
+				// `<style>` tag.
+				rules.push({
+					dependency: "html-style",
+					parser: {
+						exportType: "text"
+					},
+					resolve
+				});
+			}
+		}
+
+		if (typescript) {
+			rules.push(
+				{
+					test: /\.mts$/i,
+					...esm
+				},
+				{
+					test: /\.ts$/i,
+					descriptionData: {
+						type: "module"
+					},
+					...esm
+				},
+				{
+					test: /\.cts$/i,
+					...commonjs
+				},
+				{
+					test: /\.ts$/i,
+					descriptionData: {
+						type: "commonjs"
+					},
+					...commonjs
+				},
+				{
+					mimetype: {
+						or: ["text/typescript", "application/typescript"]
+					},
+					...esm
+				}
+			);
+		}
+
+		rules.push(
+			{
+				dependency: "url",
+				oneOf: [
+					{
+						scheme: /^data$/,
+						type: ASSET_MODULE_TYPE_INLINE
+					},
+					{
+						type: ASSET_MODULE_TYPE_RESOURCE
+					}
+				]
+			},
+			{
+				with: { type: JSON_MODULE_TYPE },
+				type: JSON_MODULE_TYPE,
+				parser: { namedExports: false }
+			},
+			{
+				assert: { type: JSON_MODULE_TYPE },
+				type: JSON_MODULE_TYPE,
+				parser: { namedExports: false }
+			},
+			{
+				with: { type: "text" },
+				type: ASSET_MODULE_TYPE_SOURCE
+			},
+			{
+				with: { type: "bytes" },
+				type: ASSET_MODULE_TYPE_BYTES
+			}
+		);
+		return rules;
+	});
+};
+
+/**
+ * Apply output defaults.
+ * @param {Output} output options
+ * @param {object} options options
+ * @param {string} options.context context
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @param {boolean} options.isAffectedByBrowserslist is affected by browserslist
+ * @param {boolean} options.outputModule is outputModule experiment enabled
+ * @param {boolean} options.development is development mode
+ * @param {Entry} options.entry entry option
+ * @param {boolean} options.futureDefaults is future defaults enabled
+ * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
+ * @returns {void}
+ */
+const applyOutputDefaults = (
+	output,
+	{
+		context,
+		targetProperties: tp,
+		isAffectedByBrowserslist,
+		outputModule,
+		development,
+		entry,
+		futureDefaults,
+		asyncWebAssembly
+	}
+) => {
+	/**
+	 * Returns a readable library name.
+	 * @param {Library=} library the library option
+	 * @returns {string} a readable library name
+	 */
+	const getLibraryName = (library) => {
+		const libraryName =
+			typeof library === "object" &&
+			library &&
+			!Array.isArray(library) &&
+			"type" in library
+				? library.name
+				: /** @type {LibraryName} */ (library);
+		if (Array.isArray(libraryName)) {
+			return libraryName.join(".");
+		} else if (typeof libraryName === "object") {
+			return getLibraryName(libraryName.root);
+		} else if (typeof libraryName === "string") {
+			return libraryName;
+		}
+		return "";
+	};
+
+	F(output, "uniqueName", () => {
+		const libraryName = getLibraryName(output.library).replace(
+			/^\[(\\*[\w:]+\\*)\](\.)|(\.)\[(\\*[\w:]+\\*)\](?=\.|$)|\[(\\*[\w:]+\\*)\]/g,
+			(m, a, d1, d2, b, c) => {
+				const content = a || b || c;
+				return content.startsWith("\\") && content.endsWith("\\")
+					? `${d2 || ""}[${content.slice(1, -1)}]${d1 || ""}`
+					: "";
+			}
+		);
+		if (libraryName) return libraryName;
+		const pkgPath = path.resolve(context, "package.json");
+		try {
+			const packageInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
+			return packageInfo.name || "";
+		} catch (err) {
+			if (/** @type {Error & { code: string }} */ (err).code !== "ENOENT") {
+				/** @type {Error & { code: string }} */
+				(err).message +=
+					`\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`;
+				throw err;
+			}
+			return "";
+		}
+	});
+
+	F(output, "module", () => Boolean(outputModule));
+
+	const environment = /** @type {Environment} */ (output.environment);
+	/**
+	 * Returns true, when v is truthy or undefined.
+	 * @param {boolean | undefined} v value
+	 * @returns {boolean} true, when v is truthy or undefined
+	 */
+	const optimistic = (v) => v || v === undefined;
+	/**
+	 * Conditionally optimistic.
+	 * @param {boolean | undefined} v value
+	 * @param {boolean | undefined} c condition
+	 * @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy
+	 */
+	const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
+
+	F(
+		environment,
+		"globalThis",
+		() => /** @type {boolean | undefined} */ (tp && tp.globalThis)
+	);
+	F(
+		environment,
+		"bigIntLiteral",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.bigIntLiteral))
+	);
+	F(
+		environment,
+		"const",
+		() => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
+	);
+	F(
+		environment,
+		"methodShorthand",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.methodShorthand))
+	);
+	F(
+		environment,
+		"arrowFunction",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.arrowFunction))
+	);
+	F(
+		environment,
+		"asyncFunction",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.asyncFunction))
+	);
+	F(
+		environment,
+		"forOf",
+		() => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
+	);
+	F(
+		environment,
+		"destructuring",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.destructuring))
+	);
+	F(
+		environment,
+		"optionalChaining",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.optionalChaining))
+	);
+	F(
+		environment,
+		"nodePrefixForCoreModules",
+		() =>
+			tp &&
+			optimistic(
+				/** @type {boolean | undefined} */ (tp.nodePrefixForCoreModules)
+			)
+	);
+	F(
+		environment,
+		"importMetaDirnameAndFilename",
+		() =>
+			// No optimistic, because it is new
+			tp && /** @type {boolean | undefined} */ (tp.importMetaDirnameAndFilename)
+	);
+	F(
+		environment,
+		"templateLiteral",
+		() =>
+			tp && optimistic(/** @type {boolean | undefined} */ (tp.templateLiteral))
+	);
+	F(environment, "dynamicImport", () =>
+		conditionallyOptimistic(
+			/** @type {boolean | undefined} */ (tp && tp.dynamicImport),
+			output.module
+		)
+	);
+	F(environment, "dynamicImportInWorker", () =>
+		conditionallyOptimistic(
+			/** @type {boolean | undefined} */ (tp && tp.dynamicImportInWorker),
+			output.module
+		)
+	);
+	F(environment, "module", () =>
+		conditionallyOptimistic(
+			/** @type {boolean | undefined} */ (tp && tp.module),
+			output.module
+		)
+	);
+	F(
+		environment,
+		"document",
+		() => tp && optimistic(/** @type {boolean | undefined} */ (tp.document))
+	);
+
+	D(output, "filename", output.module ? "[name].mjs" : "[name].js");
+	F(output, "iife", () => !output.module);
+	D(output, "importFunctionName", "import");
+	D(output, "importMetaName", "import.meta");
+	F(output, "chunkFilename", () => {
+		const filename =
+			/** @type {NonNullable<Output["chunkFilename"]>} */
+			(output.filename);
+		if (typeof filename !== "function") {
+			const hasName = filename.includes("[name]");
+			const hasId = filename.includes("[id]");
+			const hasChunkHash = filename.includes("[chunkhash]");
+			const hasContentHash = filename.includes("[contenthash]");
+			// Anything changing depending on chunk is fine
+			if (hasChunkHash || hasContentHash || hasName || hasId) return filename;
+			// Otherwise prefix "[id]." in front of the basename to make it changing
+			return filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2");
+		}
+		return output.module ? "[id].mjs" : "[id].js";
+	});
+	F(output, "cssFilename", () => {
+		const filename =
+			/** @type {NonNullable<Output["cssFilename"]>} */
+			(output.filename);
+		if (typeof filename !== "function") {
+			return filename.replace(/\.[mc]?js(\?|$)/, ".css$1");
+		}
+		return "[id].css";
+	});
+	F(output, "cssChunkFilename", () => {
+		const chunkFilename =
+			/** @type {NonNullable<Output["cssChunkFilename"]>} */
+			(output.chunkFilename);
+		if (typeof chunkFilename !== "function") {
+			return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1");
+		}
+		return "[id].css";
+	});
+	// Derive html filename defaults from `output.filename` / `output.chunkFilename`
+	// (the same shape the CSS pipeline uses), but if the derived template lacks
+	// any per-module differentiator, fall back to `[name].html` so multiple
+	// extracted HTML modules in one compilation don't collide on the same
+	// emitted file. For example: `output.filename: "bundle.js"` would derive
+	// `bundle.html` — two `.html` modules extracted in the same build would
+	// both want that name and conflict at emit time.
+	const HAS_PATH_PLACEHOLDER_REGEXP =
+		/\[(name|id|chunkhash|contenthash|fullhash|hash)/;
+	/**
+	 * @param {string} template html filename template derived from `output.filename`
+	 * @returns {string} same template, or `[name].html` if it has no per-module placeholder
+	 */
+	const ensureUniqueHtmlTemplate = (template) =>
+		HAS_PATH_PLACEHOLDER_REGEXP.test(template) ? template : "[name].html";
+	F(output, "htmlFilename", () => {
+		const filename =
+			/** @type {NonNullable<Output["htmlFilename"]>} */
+			(output.filename);
+		if (typeof filename !== "function") {
+			return ensureUniqueHtmlTemplate(
+				filename.replace(/\.[mc]?js(\?|$)/, ".html$1")
+			);
+		}
+		return "[name].html";
+	});
+	F(output, "htmlChunkFilename", () => {
+		const chunkFilename =
+			/** @type {NonNullable<Output["htmlChunkFilename"]>} */
+			(output.chunkFilename);
+		if (typeof chunkFilename !== "function") {
+			return ensureUniqueHtmlTemplate(
+				chunkFilename.replace(/\.[mc]?js(\?|$)/, ".html$1")
+			);
+		}
+		return "[name].html";
+	});
+	D(output, "assetModuleFilename", "[hash][ext][query][fragment]");
+	D(output, "webassemblyModuleFilename", "[hash].module.wasm");
+	D(output, "compareBeforeEmit", true);
+	D(output, "charset", !futureDefaults);
+	const uniqueNameId = Template.toIdentifier(
+		/** @type {NonNullable<Output["uniqueName"]>} */ (output.uniqueName)
+	);
+	F(output, "hotUpdateGlobal", () => `webpackHotUpdate${uniqueNameId}`);
+	F(output, "chunkLoadingGlobal", () => `webpackChunk${uniqueNameId}`);
+	F(output, "globalObject", () => {
+		if (tp) {
+			if (tp.global) return "global";
+			if (tp.globalThis) return "globalThis";
+			// For universal target (i.e. code can be run in browser/node/worker etc.)
+			if (tp.web === null && tp.node === null && tp.module) return "globalThis";
+		}
+		return "self";
+	});
+	F(output, "chunkFormat", () => {
+		if (tp) {
+			const helpMessage = isAffectedByBrowserslist
+				? "Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly."
+				: "Select an appropriate 'target' to allow selecting one by default, or specify the 'output.chunkFormat' directly.";
+			if (output.module) {
+				if (environment.dynamicImport) return "module";
+				if (tp.document) return "array-push";
+				throw new Error(
+					"For the selected environment is no default ESM chunk format available:\n" +
+						"ESM exports can be chosen when 'import()' is available.\n" +
+						`JSONP Array push can be chosen when 'document' is available.\n${helpMessage}`
+				);
+			} else {
+				if (tp.document) return "array-push";
+				if (tp.require) return "commonjs";
+				if (tp.nodeBuiltins) return "commonjs";
+				if (tp.importScripts) return "array-push";
+				throw new Error(
+					"For the selected environment is no default script chunk format available:\n" +
+						`${
+							tp.module
+								? "Module ('module') can be chosen when ES modules are available (please set 'experiments.outputModule' and 'output.module' to `true`)"
+								: ""
+						}\n` +
+						"JSONP Array push ('array-push') can be chosen when 'document' or 'importScripts' is available.\n" +
+						`CommonJs exports ('commonjs') can be chosen when 'require' or node builtins are available.\n${helpMessage}`
+				);
+			}
+		}
+		throw new Error(
+			"Chunk format can't be selected by default when no target is specified"
+		);
+	});
+	D(output, "asyncChunks", true);
+	F(output, "chunkLoading", () => {
+		if (tp) {
+			switch (output.chunkFormat) {
+				case "array-push":
+					if (tp.document) return "jsonp";
+					if (tp.importScripts) return "import-scripts";
+					break;
+				case "commonjs":
+					if (tp.require) return "require";
+					if (tp.nodeBuiltins) return "async-node";
+					break;
+				case "module":
+					if (environment.dynamicImport) return "import";
+					break;
+			}
+			if (
+				(tp.require === null ||
+					tp.nodeBuiltins === null ||
+					tp.document === null ||
+					tp.importScripts === null) &&
+				output.module &&
+				environment.dynamicImport
+			) {
+				return "import";
+			}
+		}
+		return false;
+	});
+	F(output, "workerChunkLoading", () => {
+		if (tp) {
+			switch (output.chunkFormat) {
+				case "array-push":
+					if (tp.importScriptsInWorker) return "import-scripts";
+					break;
+				case "commonjs":
+					if (tp.require) return "require";
+					if (tp.nodeBuiltins) return "async-node";
+					break;
+				case "module":
+					if (environment.dynamicImportInWorker) return "import";
+					break;
+			}
+			if (
+				(tp.require === null ||
+					tp.nodeBuiltins === null ||
+					tp.importScriptsInWorker === null) &&
+				output.module &&
+				environment.dynamicImportInWorker
+			) {
+				return "import";
+			}
+		}
+		return false;
+	});
+	F(output, "wasmLoading", () => {
+		if (tp) {
+			if (tp.fetchWasm) return "fetch";
+			if (tp.nodeBuiltins) return "async-node";
+			if (
+				(tp.nodeBuiltins === null || tp.fetchWasm === null) &&
+				output.module &&
+				environment.dynamicImport
+			) {
+				return "universal";
+			}
+		}
+		return false;
+	});
+	F(output, "workerWasmLoading", () => output.wasmLoading);
+	F(output, "devtoolNamespace", () => output.uniqueName);
+	if (output.library) {
+		F(output.library, "type", () => (output.module ? "module" : "var"));
+	}
+	F(output, "path", () => path.join(process.cwd(), "dist"));
+	F(output, "pathinfo", () => development);
+	D(output, "sourceMapFilename", "[file].map[query]");
+	D(
+		output,
+		"hotUpdateChunkFilename",
+		`[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}`
+	);
+	D(
+		output,
+		"hotUpdateMainFilename",
+		`[runtime].[fullhash].hot-update.${output.module ? "json.mjs" : "json"}`
+	);
+	D(output, "crossOriginLoading", false);
+	F(output, "scriptType", () => (output.module ? "module" : false));
+	D(
+		output,
+		"publicPath",
+		(tp && (tp.document || tp.importScripts)) || output.scriptType === "module"
+			? "auto"
+			: ""
+	);
+	D(output, "workerPublicPath", "");
+	D(output, "chunkLoadTimeout", 120000);
+	F(output, "hashFunction", () => {
+		if (futureDefaults) {
+			DEFAULTS.HASH_FUNCTION = "xxhash64";
+			return "xxhash64";
+		}
+
+		return "md4";
+	});
+	D(output, "hashDigest", "hex");
+	D(output, "hashDigestLength", futureDefaults ? 16 : 20);
+	D(output, "strictModuleErrorHandling", false);
+	D(output, "strictModuleExceptionHandling", false);
+
+	const { trustedTypes } = output;
+	if (trustedTypes) {
+		F(
+			trustedTypes,
+			"policyName",
+			() =>
+				/** @type {NonNullable<Output["uniqueName"]>} */
+				(output.uniqueName).replace(/[^a-z0-9\-#=_/@.%]+/gi, "_") || "webpack"
+		);
+		D(trustedTypes, "onPolicyCreationFailure", "stop");
+	}
+
+	/**
+	 * Processes the provided fn.
+	 * @param {(entryDescription: EntryDescription) => void} fn iterator
+	 * @returns {void}
+	 */
+	const forEachEntry = (fn) => {
+		for (const name of Object.keys(entry)) {
+			fn(/** @type {{ [k: string]: EntryDescription }} */ (entry)[name]);
+		}
+	};
+	A(output, "enabledLibraryTypes", () => {
+		/** @type {LibraryType[]} */
+		const enabledLibraryTypes = [];
+		if (output.library) {
+			enabledLibraryTypes.push(output.library.type);
+		}
+		forEachEntry((desc) => {
+			if (desc.library) {
+				enabledLibraryTypes.push(desc.library.type);
+			}
+		});
+		return enabledLibraryTypes;
+	});
+
+	A(output, "enabledChunkLoadingTypes", () => {
+		/** @type {ChunkLoadingTypes} */
+		const enabledChunkLoadingTypes = new Set();
+		if (output.chunkLoading) {
+			enabledChunkLoadingTypes.add(output.chunkLoading);
+		}
+		if (output.workerChunkLoading) {
+			enabledChunkLoadingTypes.add(output.workerChunkLoading);
+		}
+		forEachEntry((desc) => {
+			if (desc.chunkLoading) {
+				enabledChunkLoadingTypes.add(desc.chunkLoading);
+			}
+		});
+		return [...enabledChunkLoadingTypes];
+	});
+
+	A(output, "enabledWasmLoadingTypes", () => {
+		/** @type {WasmLoadingTypes} */
+		const enabledWasmLoadingTypes = new Set();
+		if (output.wasmLoading) {
+			enabledWasmLoadingTypes.add(output.wasmLoading);
+		}
+		if (output.workerWasmLoading) {
+			enabledWasmLoadingTypes.add(output.workerWasmLoading);
+		}
+		forEachEntry((desc) => {
+			if (desc.wasmLoading) {
+				enabledWasmLoadingTypes.add(desc.wasmLoading);
+			}
+		});
+		return [...enabledWasmLoadingTypes];
+	});
+};
+
+/**
+ * Apply externals presets defaults.
+ * @param {ExternalsPresets} externalsPresets options
+ * @param {object} options options
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @param {boolean} options.buildHttp buildHttp experiment enabled
+ * @param {boolean} options.outputModule is output type is module
+ * @returns {void}
+ */
+const applyExternalsPresetsDefaults = (
+	externalsPresets,
+	{ targetProperties, buildHttp, outputModule }
+) => {
+	/**
+	 * Checks whether this object is universal.
+	 * @param {keyof TargetProperties} key a key
+	 * @returns {boolean} true when target is universal, otherwise false
+	 */
+	const isUniversal = (key) =>
+		Boolean(outputModule && targetProperties && targetProperties[key] === null);
+
+	D(
+		externalsPresets,
+		"web",
+		/** @type {boolean | undefined} */
+		(
+			!buildHttp &&
+				targetProperties &&
+				(targetProperties.web || isUniversal("node"))
+		)
+	);
+	D(
+		externalsPresets,
+		"node",
+		/** @type {boolean | undefined} */
+		(targetProperties && (targetProperties.node || isUniversal("node")))
+	);
+	D(
+		externalsPresets,
+		"nwjs",
+		/** @type {boolean | undefined} */
+		(targetProperties && (targetProperties.nwjs || isUniversal("nwjs")))
+	);
+	D(
+		externalsPresets,
+		"electron",
+		/** @type {boolean | undefined} */
+		((targetProperties && targetProperties.electron) || isUniversal("electron"))
+	);
+	D(
+		externalsPresets,
+		"electronMain",
+		/** @type {boolean | undefined} */
+		(
+			targetProperties &&
+				targetProperties.electron &&
+				(targetProperties.electronMain || isUniversal("electronMain"))
+		)
+	);
+	D(
+		externalsPresets,
+		"electronPreload",
+		/** @type {boolean | undefined} */
+		(
+			targetProperties &&
+				targetProperties.electron &&
+				(targetProperties.electronPreload || isUniversal("electronPreload"))
+		)
+	);
+	D(
+		externalsPresets,
+		"electronRenderer",
+		/** @type {boolean | undefined} */
+		(
+			targetProperties &&
+				targetProperties.electron &&
+				(targetProperties.electronRenderer || isUniversal("electronRenderer"))
+		)
+	);
+};
+
+/**
+ * Apply loader defaults.
+ * @param {Loader} loader options
+ * @param {object} options options
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @param {Environment} options.environment environment
+ * @returns {void}
+ */
+const applyLoaderDefaults = (loader, { targetProperties, environment }) => {
+	F(loader, "target", () => {
+		if (targetProperties) {
+			if (targetProperties.electron) {
+				if (targetProperties.electronMain) return "electron-main";
+				if (targetProperties.electronPreload) return "electron-preload";
+				if (targetProperties.electronRenderer) return "electron-renderer";
+				return "electron";
+			}
+			if (targetProperties.nwjs) return "nwjs";
+			if (targetProperties.node) return "node";
+			if (targetProperties.web) return "web";
+		}
+	});
+	D(loader, "environment", environment);
+};
+
+/**
+ * Apply node defaults.
+ * @param {WebpackNode} node options
+ * @param {object} options options
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @param {boolean} options.futureDefaults is future defaults enabled
+ * @param {boolean} options.outputModule is output type is module
+ * @returns {void}
+ */
+const applyNodeDefaults = (
+	node,
+	{ futureDefaults, outputModule, targetProperties }
+) => {
+	if (node === false) return;
+
+	F(node, "global", () => {
+		if (targetProperties && targetProperties.global) return false;
+		// We use `warm` because overriding `global` with `globalThis` (or a polyfill) is sometimes safe (global.URL), sometimes unsafe (global.process), but we need to warn about it
+		return futureDefaults ? "warn" : true;
+	});
+
+	const handlerForNames = () => {
+		// TODO webpack@6 remove `node-module` in favor of `eval-only`
+		if (targetProperties) {
+			if (targetProperties.node) {
+				return "eval-only";
+			}
+
+			// For the "universal" target we only evaluate these values
+			if (
+				outputModule &&
+				targetProperties.node === null &&
+				targetProperties.web === null
+			) {
+				return "eval-only";
+			}
+		}
+
+		// TODO webpack@6 should we use `warn-even-only`?
+		return futureDefaults ? "warn-mock" : "mock";
+	};
+
+	F(node, "__filename", handlerForNames);
+	F(node, "__dirname", handlerForNames);
+};
+
+/**
+ * Apply performance defaults.
+ * @param {Performance} performance options
+ * @param {object} options options
+ * @param {boolean} options.production is production
+ * @returns {void}
+ */
+const applyPerformanceDefaults = (performance, { production }) => {
+	if (performance === false) return;
+	D(performance, "maxAssetSize", 250000);
+	D(performance, "maxEntrypointSize", 250000);
+	F(performance, "hints", () => (production ? "warning" : false));
+};
+
+/**
+ * Apply optimization defaults.
+ * @param {Optimization} optimization options
+ * @param {object} options options
+ * @param {boolean} options.production is production
+ * @param {boolean} options.development is development
+ * @param {boolean} options.css is css enabled
+ * @param {boolean} options.records using records
+ * @returns {void}
+ */
+const applyOptimizationDefaults = (
+	optimization,
+	{ production, development, css, records }
+) => {
+	D(optimization, "removeAvailableModules", false);
+	D(optimization, "removeEmptyChunks", true);
+	D(optimization, "mergeDuplicateChunks", true);
+	D(optimization, "flagIncludedChunks", production);
+	F(optimization, "moduleIds", () => {
+		if (production) return "deterministic";
+		if (development) return "named";
+		return "natural";
+	});
+	F(optimization, "chunkIds", () => {
+		if (production) return "deterministic";
+		if (development) return "named";
+		return "natural";
+	});
+	F(optimization, "sideEffects", () => (production ? true : "flag"));
+	D(optimization, "providedExports", true);
+	D(optimization, "usedExports", production);
+	D(optimization, "innerGraph", production);
+	D(optimization, "mangleExports", production);
+	D(optimization, "concatenateModules", production);
+	D(optimization, "avoidEntryIife", production);
+	D(optimization, "runtimeChunk", false);
+	D(optimization, "emitOnErrors", !production);
+	D(optimization, "checkWasmTypes", production);
+	D(optimization, "mangleWasmImports", false);
+	D(optimization, "portableRecords", records);
+	D(optimization, "realContentHash", production);
+	D(optimization, "minimize", production);
+	A(optimization, "minimizer", () => [
+		{
+			apply: (compiler) => {
+				// Lazy load the Terser plugin
+				const TerserPlugin = require("terser-webpack-plugin");
+
+				new TerserPlugin({
+					terserOptions: {
+						compress: {
+							passes: 2
+						}
+					}
+				}).apply(/** @type {EXPECTED_ANY} */ (compiler));
+			}
+		}
+	]);
+	F(optimization, "nodeEnv", () => {
+		if (production) return "production";
+		if (development) return "development";
+		return false;
+	});
+	const { splitChunks } = optimization;
+	if (splitChunks) {
+		A(splitChunks, "defaultSizeTypes", () =>
+			css
+				? [JAVASCRIPT_TYPE, CSS_TYPE, UNKNOWN_TYPE]
+				: [JAVASCRIPT_TYPE, UNKNOWN_TYPE]
+		);
+		D(splitChunks, "hidePathInfo", production);
+		D(splitChunks, "chunks", "async");
+		D(splitChunks, "usedExports", optimization.usedExports === true);
+		D(splitChunks, "minChunks", 1);
+		F(splitChunks, "minSize", () => (production ? 20000 : 10000));
+		F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined));
+		F(splitChunks, "enforceSizeThreshold", () => (production ? 50000 : 30000));
+		F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity));
+		F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity));
+		D(splitChunks, "automaticNameDelimiter", "-");
+		const cacheGroups =
+			/** @type {NonNullable<OptimizationSplitChunksOptions["cacheGroups"]>} */
+			(splitChunks.cacheGroups);
+		F(cacheGroups, "default", () => ({
+			idHint: "",
+			reuseExistingChunk: true,
+			minChunks: 2,
+			priority: -20
+		}));
+		F(cacheGroups, "defaultVendors", () => ({
+			idHint: "vendors",
+			reuseExistingChunk: true,
+			test: NODE_MODULES_REGEXP,
+			priority: -10
+		}));
+	}
+};
+
+/**
+ * Gets resolve defaults.
+ * @param {object} options options
+ * @param {boolean} options.cache is cache enable
+ * @param {string} options.context build context
+ * @param {TargetProperties | false} options.targetProperties target properties
+ * @param {Mode} options.mode mode
+ * @param {boolean} options.css is css enabled
+ * @param {boolean} options.typescript is typescript enabled
+ * @returns {ResolveOptions} resolve options
+ */
+const getResolveDefaults = ({
+	cache,
+	context,
+	targetProperties,
+	mode,
+	css,
+	typescript
+}) => {
+	/** @type {string[]} */
+	const conditions = ["webpack"];
+
+	conditions.push(mode === "development" ? "development" : "production");
+
+	if (targetProperties) {
+		if (targetProperties.webworker) conditions.push("worker");
+		if (targetProperties.node) conditions.push("node");
+		if (targetProperties.web) conditions.push("browser");
+		if (targetProperties.electron) conditions.push("electron");
+		if (targetProperties.nwjs) conditions.push("nwjs");
+	}
+
+	const jsExtensions = typescript
+		? [".ts", ".js", ".json", ".wasm"]
+		: [".js", ".json", ".wasm"];
+
+	const tp = targetProperties;
+	const browserField =
+		tp && tp.web && (!tp.node || (tp.electron && tp.electronRenderer));
+
+	// When `experiments.typescript` is on, also honor the `typescript`
+	// conditional-exports key so monorepo packages can ship .ts sources via
+	// `package.json#exports` — same convention Node.js's amaro uses.
+	const tsConditionPrefix = typescript ? ["typescript"] : [];
+
+	/** @type {() => ResolveOptions} */
+	const cjsDeps = () => ({
+		aliasFields: browserField ? ["browser"] : [],
+		mainFields: browserField ? ["browser", "module", "..."] : ["module", "..."],
+		conditionNames: [
+			...tsConditionPrefix,
+			"require",
+			"module-sync",
+			"module",
+			"..."
+		],
+		extensions: [...jsExtensions]
+	});
+	/** @type {() => ResolveOptions} */
+	const esmDeps = () => ({
+		aliasFields: browserField ? ["browser"] : [],
+		mainFields: browserField ? ["browser", "module", "..."] : ["module", "..."],
+		conditionNames: [
+			...tsConditionPrefix,
+			"import",
+			"module-sync",
+			"module",
+			"..."
+		],
+		extensions: [...jsExtensions]
+	});
+
+	/** @type {() => ResolveOptions} */
+	const workerDeps = () => {
+		const options = esmDeps();
+
+		const conditionNames = options.conditionNames
+			? ["worker", ...options.conditionNames]
+			: options.conditionNames;
+		return {
+			...options,
+			conditionNames,
+			preferRelative: true
+		};
+	};
+
+	/** @type {ResolveOptions} */
+	const resolveOptions = {
+		cache,
+		modules: ["node_modules"],
+		conditionNames: conditions,
+		mainFiles: ["index"],
+		extensions: [],
+		aliasFields: [],
+		exportsFields: ["exports"],
+		roots: [context],
+		mainFields: ["main"],
+		importsFields: ["imports"],
+		byDependency: {
+			wasm: esmDeps(),
+			esm: esmDeps(),
+			loaderImport: esmDeps(),
+			url: {
+				preferRelative: true
+			},
+			worker: workerDeps(),
+			commonjs: cjsDeps(),
+			amd: cjsDeps(),
+			// for backward-compat: loadModule
+			loader: cjsDeps(),
+			// for backward-compat: Custom Dependency
+			unknown: cjsDeps(),
+			// for backward-compat: getResolve without dependencyType
+			undefined: cjsDeps()
+		}
+	};
+
+	if (css) {
+		/** @type {string[]} */
+		const styleConditions = [];
+
+		styleConditions.push("webpack");
+		styleConditions.push(mode === "development" ? "development" : "production");
+		styleConditions.push("style");
+
+		/** @type {ResolveOptions} */
+		const cssResolveOptions = {
+			// We avoid using any main files because we have to be consistent with CSS `@import`
+			// and CSS `@import` does not handle `main` files in directories,
+			// you should always specify the full URL for styles
+			mainFiles: [],
+			mainFields: ["style", "..."],
+			conditionNames: styleConditions,
+			extensions: [".css"],
+			preferRelative: true
+		};
+
+		/** @type {NonNullable<ResolveOptions["byDependency"]>} */
+		(resolveOptions.byDependency)["css-import"] = cssResolveOptions;
+		// For CSS modules, i.e. `.class { composes: className from "./style.css" }`
+		// We inherit for such constructions
+		/** @type {NonNullable<ResolveOptions["byDependency"]>} */
+		(resolveOptions.byDependency)["css-import-local-module"] =
+			cssResolveOptions;
+		/** @type {NonNullable<ResolveOptions["byDependency"]>} */
+		(resolveOptions.byDependency)["css-import-global-module"] =
+			cssResolveOptions;
+	}
+
+	if (typescript) {
+		resolveOptions.tsconfig = true;
+		resolveOptions.extensionAlias = {
+			".js": [".js", ".ts"],
+			".cjs": [".cjs", ".cts"],
+			".mjs": [".mjs", ".mts"]
+		};
+	}
+
+	return resolveOptions;
+};
+
+/**
+ * Gets resolve loader defaults.
+ * @param {object} options options
+ * @param {boolean} options.cache is cache enable
+ * @returns {ResolveOptions} resolve options
+ */
+const getResolveLoaderDefaults = ({ cache }) => {
+	/** @type {ResolveOptions} */
+	const resolveOptions = {
+		cache,
+		conditionNames: ["loader", "require", "node"],
+		exportsFields: ["exports"],
+		mainFields: ["loader", "main"],
+		extensions: [".js"],
+		mainFiles: ["index"]
+	};
+
+	return resolveOptions;
+};
+
+/**
+ * Apply infrastructure logging defaults.
+ * @param {InfrastructureLogging} infrastructureLogging options
+ * @returns {void}
+ */
+const applyInfrastructureLoggingDefaults = (infrastructureLogging) => {
+	F(infrastructureLogging, "stream", () => process.stderr);
+	const tty =
+		/** @type {NonNullable<InfrastructureLogging["stream"]>} */
+		(infrastructureLogging.stream).isTTY && process.env.TERM !== "dumb";
+	D(infrastructureLogging, "level", "info");
+	D(infrastructureLogging, "debug", false);
+	D(infrastructureLogging, "colors", tty);
+	D(infrastructureLogging, "appendOnly", !tty);
+};
+
+module.exports.DEFAULTS = DEFAULTS;
+module.exports.applyWebpackOptionsBaseDefaults =
+	applyWebpackOptionsBaseDefaults;
+module.exports.applyWebpackOptionsDefaults = applyWebpackOptionsDefaults;
Index: frontend/node_modules/webpack/lib/config/normalization.js
===================================================================
--- frontend/node_modules/webpack/lib/config/normalization.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/config/normalization.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,696 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+
+/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */
+/** @typedef {import("../../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").EntryStatic} EntryStatic */
+/** @typedef {import("../../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").Externals} Externals */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptionsNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationNormalized} OptimizationNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationRuntimeChunk} OptimizationRuntimeChunk */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationRuntimeChunkNormalized} OptimizationRuntimeChunkNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").PluginsNormalized} PluginsNormalized */
+/** @typedef {import("../../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
+/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+
+/**
+ * Defines the webpack options interception type used by this module.
+ * @typedef {object} WebpackOptionsInterception
+ * @property {WebpackOptionsNormalized["devtool"]=} devtool
+ */
+
+const handledDeprecatedNoEmitOnErrors = util.deprecate(
+	/**
+	 * Handles the callback logic for this hook.
+	 * @param {boolean} noEmitOnErrors no emit on errors
+	 * @param {boolean | undefined} emitOnErrors emit on errors
+	 * @returns {boolean} emit on errors
+	 */
+	(noEmitOnErrors, emitOnErrors) => {
+		if (emitOnErrors !== undefined && !noEmitOnErrors === !emitOnErrors) {
+			throw new Error(
+				"Conflicting use of 'optimization.noEmitOnErrors' and 'optimization.emitOnErrors'. Remove deprecated 'optimization.noEmitOnErrors' from config."
+			);
+		}
+		return !noEmitOnErrors;
+	},
+	"optimization.noEmitOnErrors is deprecated in favor of optimization.emitOnErrors",
+	"DEP_WEBPACK_CONFIGURATION_OPTIMIZATION_NO_EMIT_ON_ERRORS"
+);
+
+/**
+ * Returns result value.
+ * @template T
+ * @template R
+ * @param {T | undefined} value value or not
+ * @param {(value: T) => R} fn nested handler
+ * @returns {R} result value
+ */
+const nestedConfig = (value, fn) =>
+	value === undefined ? fn(/** @type {T} */ ({})) : fn(value);
+
+/**
+ * Returns result value.
+ * @template T
+ * @param {T | undefined} value value or not
+ * @returns {T} result value
+ */
+const cloneObject = (value) => /** @type {T} */ ({ ...value });
+/**
+ * Optional nested config.
+ * @template T
+ * @template R
+ * @param {T | undefined} value value or not
+ * @param {(value: T) => R} fn nested handler
+ * @returns {R | undefined} result value
+ */
+const optionalNestedConfig = (value, fn) =>
+	value === undefined ? undefined : fn(value);
+
+/**
+ * Returns cloned value.
+ * @template T
+ * @template R
+ * @param {T[] | undefined} value array or not
+ * @param {(value: T[]) => R[]} fn nested handler
+ * @returns {R[] | undefined} cloned value
+ */
+const nestedArray = (value, fn) => (Array.isArray(value) ? fn(value) : fn([]));
+
+/**
+ * Optional nested array.
+ * @template T
+ * @template R
+ * @param {T[] | undefined} value array or not
+ * @param {(value: T[]) => R[]} fn nested handler
+ * @returns {R[] | undefined} cloned value
+ */
+const optionalNestedArray = (value, fn) =>
+	Array.isArray(value) ? fn(value) : undefined;
+
+/**
+ * Keyed nested config.
+ * @template T
+ * @template R
+ * @param {Record<string, T> | undefined} value value or not
+ * @param {(value: T) => R} fn nested handler
+ * @param {Record<string, (value: T) => R>=} customKeys custom nested handler for some keys
+ * @returns {Record<string, R>} result value
+ */
+const keyedNestedConfig = (value, fn, customKeys) => {
+	/* eslint-disable no-sequences */
+	const result =
+		value === undefined
+			? {}
+			: Object.keys(value).reduce(
+					(obj, key) => (
+						(obj[key] = (
+							customKeys && key in customKeys ? customKeys[key] : fn
+						)(value[key])),
+						obj
+					),
+					/** @type {Record<string, R>} */ ({})
+				);
+	/* eslint-enable no-sequences */
+	if (customKeys) {
+		for (const key of Object.keys(customKeys)) {
+			if (!(key in result)) {
+				result[key] = customKeys[key](/** @type {T} */ ({}));
+			}
+		}
+	}
+	return result;
+};
+
+/**
+ * Gets normalized webpack options.
+ * @param {WebpackOptions} config input config
+ * @returns {WebpackOptionsNormalized} normalized options
+ */
+const getNormalizedWebpackOptions = (config) => ({
+	amd: config.amd,
+	bail: config.bail,
+	cache:
+		/** @type {NonNullable<CacheOptions>} */
+		(
+			optionalNestedConfig(config.cache, (cache) => {
+				if (cache === false) return false;
+				if (cache === true) {
+					return {
+						type: "memory",
+						maxGenerations: undefined
+					};
+				}
+				switch (cache.type) {
+					case "filesystem":
+						return {
+							type: "filesystem",
+							allowCollectingMemory: cache.allowCollectingMemory,
+							maxMemoryGenerations: cache.maxMemoryGenerations,
+							maxAge: cache.maxAge,
+							profile: cache.profile,
+							buildDependencies: cloneObject(cache.buildDependencies),
+							cacheDirectory: cache.cacheDirectory,
+							cacheLocation: cache.cacheLocation,
+							hashAlgorithm: cache.hashAlgorithm,
+							compression: cache.compression,
+							idleTimeout: cache.idleTimeout,
+							idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore,
+							idleTimeoutAfterLargeChanges: cache.idleTimeoutAfterLargeChanges,
+							name: cache.name,
+							store: cache.store,
+							version: cache.version,
+							readonly: cache.readonly
+						};
+					case undefined:
+					case "memory":
+						return {
+							type: "memory",
+							maxGenerations: cache.maxGenerations
+						};
+					default:
+						// @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339)
+						throw new Error(`Not implemented cache.type ${cache.type}`);
+				}
+			})
+		),
+	context: config.context,
+	dependencies: config.dependencies,
+	devServer: optionalNestedConfig(config.devServer, (devServer) => {
+		if (devServer === false) return false;
+		return { ...devServer };
+	}),
+	devtool: config.devtool,
+	dotenv: config.dotenv,
+	entry:
+		config.entry === undefined
+			? { main: {} }
+			: typeof config.entry === "function"
+				? (
+						(fn) => () =>
+							Promise.resolve().then(fn).then(getNormalizedEntryStatic)
+					)(config.entry)
+				: getNormalizedEntryStatic(config.entry),
+	experiments: nestedConfig(config.experiments, (experiments) => ({
+		...experiments,
+		buildHttp: optionalNestedConfig(experiments.buildHttp, (options) =>
+			Array.isArray(options) ? { allowedUris: options } : options
+		),
+		lazyCompilation: optionalNestedConfig(
+			experiments.lazyCompilation,
+			(options) => (options === true ? {} : options)
+		)
+	})),
+	externals: /** @type {NonNullable<Externals>} */ (config.externals),
+	externalsPresets: cloneObject(config.externalsPresets),
+	externalsType: config.externalsType,
+	ignoreWarnings: config.ignoreWarnings
+		? config.ignoreWarnings.map((ignore) => {
+				if (typeof ignore === "function") return ignore;
+				const i = ignore instanceof RegExp ? { message: ignore } : ignore;
+				return (warning, { requestShortener }) => {
+					if (!i.message && !i.module && !i.file) return false;
+					if (i.message && !i.message.test(warning.message)) {
+						return false;
+					}
+					if (
+						i.module &&
+						(!(/** @type {WebpackError} */ (warning).module) ||
+							!i.module.test(
+								/** @type {WebpackError} */
+								(warning).module.readableIdentifier(requestShortener)
+							))
+					) {
+						return false;
+					}
+					if (
+						i.file &&
+						(!(/** @type {WebpackError} */ (warning).file) ||
+							!i.file.test(/** @type {WebpackError} */ (warning).file))
+					) {
+						return false;
+					}
+					return true;
+				};
+			})
+		: undefined,
+	infrastructureLogging: cloneObject(config.infrastructureLogging),
+	loader: cloneObject(config.loader),
+	mode: config.mode,
+	module:
+		/** @type {ModuleOptionsNormalized} */
+		(
+			nestedConfig(config.module, (module) => ({
+				noParse: module.noParse,
+				unsafeCache: module.unsafeCache,
+				parser: keyedNestedConfig(module.parser, cloneObject, {
+					javascript: (parserOptions) => ({
+						// TODO webpack 6 remove from `ModuleOptions`, keep only `*ByModuleType`
+						unknownContextRequest: module.unknownContextRequest,
+						unknownContextRegExp: module.unknownContextRegExp,
+						unknownContextRecursive: module.unknownContextRecursive,
+						unknownContextCritical: module.unknownContextCritical,
+						exprContextRequest: module.exprContextRequest,
+						exprContextRegExp: module.exprContextRegExp,
+						exprContextRecursive: module.exprContextRecursive,
+						exprContextCritical: module.exprContextCritical,
+						wrappedContextRegExp: module.wrappedContextRegExp,
+						wrappedContextRecursive: module.wrappedContextRecursive,
+						wrappedContextCritical: module.wrappedContextCritical,
+						strictExportPresence: module.strictExportPresence,
+						strictThisContextOnImports: module.strictThisContextOnImports,
+						...parserOptions
+					})
+				}),
+				generator: cloneObject(module.generator),
+				defaultRules: optionalNestedArray(module.defaultRules, (r) => [...r]),
+				rules: nestedArray(module.rules, (r) => [...r])
+			}))
+		),
+	name: config.name,
+	node: nestedConfig(
+		config.node,
+		(node) =>
+			node && {
+				...node
+			}
+	),
+	optimization: nestedConfig(config.optimization, (optimization) => ({
+		...optimization,
+		runtimeChunk: getNormalizedOptimizationRuntimeChunk(
+			optimization.runtimeChunk
+		),
+		splitChunks: nestedConfig(
+			optimization.splitChunks,
+			(splitChunks) =>
+				splitChunks && {
+					...splitChunks,
+					defaultSizeTypes: splitChunks.defaultSizeTypes
+						? [...splitChunks.defaultSizeTypes]
+						: ["..."],
+					cacheGroups: cloneObject(splitChunks.cacheGroups)
+				}
+		),
+		minimizer:
+			optimization.minimizer !== undefined
+				? /** @type {OptimizationNormalized["minimizer"]} */ (
+						nestedArray(optimization.minimizer, (p) => p.filter(Boolean))
+					)
+				: optimization.minimizer,
+		emitOnErrors:
+			optimization.noEmitOnErrors !== undefined
+				? handledDeprecatedNoEmitOnErrors(
+						optimization.noEmitOnErrors,
+						optimization.emitOnErrors
+					)
+				: optimization.emitOnErrors
+	})),
+	output: nestedConfig(config.output, (output) => {
+		const { library } = output;
+		const libraryAsName = /** @type {LibraryName} */ (library);
+		const libraryBase =
+			typeof library === "object" &&
+			library &&
+			!Array.isArray(library) &&
+			"type" in library
+				? library
+				: libraryAsName || output.libraryTarget
+					? /** @type {LibraryOptions} */ ({
+							name: libraryAsName
+						})
+					: undefined;
+		/** @type {OutputNormalized} */
+		const result = {
+			assetModuleFilename: output.assetModuleFilename,
+			asyncChunks: output.asyncChunks,
+			charset: output.charset,
+			chunkFilename: output.chunkFilename,
+			chunkFormat: output.chunkFormat,
+			chunkLoading: output.chunkLoading,
+			chunkLoadingGlobal: output.chunkLoadingGlobal,
+			chunkLoadTimeout: output.chunkLoadTimeout,
+			cssFilename: output.cssFilename,
+			cssChunkFilename: output.cssChunkFilename,
+			clean: output.clean,
+			compareBeforeEmit: output.compareBeforeEmit,
+			crossOriginLoading: output.crossOriginLoading,
+			devtoolFallbackModuleFilenameTemplate:
+				output.devtoolFallbackModuleFilenameTemplate,
+			devtoolModuleFilenameTemplate: output.devtoolModuleFilenameTemplate,
+			devtoolNamespace: output.devtoolNamespace,
+			environment: cloneObject(output.environment),
+			enabledChunkLoadingTypes: output.enabledChunkLoadingTypes
+				? [...output.enabledChunkLoadingTypes]
+				: ["..."],
+			enabledLibraryTypes: output.enabledLibraryTypes
+				? [...output.enabledLibraryTypes]
+				: ["..."],
+			enabledWasmLoadingTypes: output.enabledWasmLoadingTypes
+				? [...output.enabledWasmLoadingTypes]
+				: ["..."],
+			filename: output.filename,
+			globalObject: output.globalObject,
+			hashDigest: output.hashDigest,
+			hashDigestLength: output.hashDigestLength,
+			hashFunction: output.hashFunction,
+			hashSalt: output.hashSalt,
+			hotUpdateChunkFilename: output.hotUpdateChunkFilename,
+			hotUpdateGlobal: output.hotUpdateGlobal,
+			hotUpdateMainFilename: output.hotUpdateMainFilename,
+			htmlChunkFilename: output.htmlChunkFilename,
+			htmlFilename: output.htmlFilename,
+			ignoreBrowserWarnings: output.ignoreBrowserWarnings,
+			iife: output.iife,
+			importFunctionName: output.importFunctionName,
+			importMetaName: output.importMetaName,
+			scriptType: output.scriptType,
+			// TODO webpack 6 remove `libraryTarget`/`auxiliaryComment`/`amdContainer`/etc in favor of the `library` option
+			library: libraryBase && {
+				type:
+					output.libraryTarget !== undefined
+						? output.libraryTarget
+						: libraryBase.type,
+				auxiliaryComment:
+					output.auxiliaryComment !== undefined
+						? output.auxiliaryComment
+						: libraryBase.auxiliaryComment,
+				amdContainer:
+					output.amdContainer !== undefined
+						? output.amdContainer
+						: libraryBase.amdContainer,
+				export:
+					output.libraryExport !== undefined
+						? output.libraryExport
+						: libraryBase.export,
+				name: libraryBase.name,
+				umdNamedDefine:
+					output.umdNamedDefine !== undefined
+						? output.umdNamedDefine
+						: libraryBase.umdNamedDefine
+			},
+			module: output.module,
+			path: output.path,
+			pathinfo: output.pathinfo,
+			publicPath: output.publicPath,
+			sourceMapFilename: output.sourceMapFilename,
+			sourcePrefix: output.sourcePrefix,
+			strictModuleErrorHandling: output.strictModuleErrorHandling,
+			strictModuleExceptionHandling: output.strictModuleExceptionHandling,
+			trustedTypes: optionalNestedConfig(
+				output.trustedTypes,
+				(trustedTypes) => {
+					if (trustedTypes === true) return {};
+					if (typeof trustedTypes === "string") {
+						return { policyName: trustedTypes };
+					}
+					return { ...trustedTypes };
+				}
+			),
+			uniqueName: output.uniqueName,
+			wasmLoading: output.wasmLoading,
+			webassemblyModuleFilename: output.webassemblyModuleFilename,
+			workerPublicPath: output.workerPublicPath,
+			workerChunkLoading: output.workerChunkLoading,
+			workerWasmLoading: output.workerWasmLoading
+		};
+		return result;
+	}),
+	parallelism: config.parallelism,
+	validate: config.validate,
+	performance: optionalNestedConfig(config.performance, (performance) => {
+		if (performance === false) return false;
+		return {
+			...performance
+		};
+	}),
+	plugins: /** @type {PluginsNormalized} */ (
+		nestedArray(config.plugins, (p) => p.filter(Boolean))
+	),
+	profile: config.profile,
+	recordsInputPath:
+		config.recordsInputPath !== undefined
+			? config.recordsInputPath
+			: config.recordsPath,
+	recordsOutputPath:
+		config.recordsOutputPath !== undefined
+			? config.recordsOutputPath
+			: config.recordsPath,
+	resolve: nestedConfig(config.resolve, (resolve) => ({
+		...resolve,
+		byDependency: keyedNestedConfig(resolve.byDependency, cloneObject)
+	})),
+	resolveLoader: cloneObject(config.resolveLoader),
+	snapshot: nestedConfig(config.snapshot, (snapshot) => ({
+		resolveBuildDependencies: optionalNestedConfig(
+			snapshot.resolveBuildDependencies,
+			(resolveBuildDependencies) => ({
+				timestamp: resolveBuildDependencies.timestamp,
+				hash: resolveBuildDependencies.hash
+			})
+		),
+		buildDependencies: optionalNestedConfig(
+			snapshot.buildDependencies,
+			(buildDependencies) => ({
+				timestamp: buildDependencies.timestamp,
+				hash: buildDependencies.hash
+			})
+		),
+		resolve: optionalNestedConfig(snapshot.resolve, (resolve) => ({
+			timestamp: resolve.timestamp,
+			hash: resolve.hash
+		})),
+		module: optionalNestedConfig(snapshot.module, (module) => ({
+			timestamp: module.timestamp,
+			hash: module.hash
+		})),
+		contextModule: optionalNestedConfig(
+			snapshot.contextModule,
+			(contextModule) => ({
+				timestamp: contextModule.timestamp,
+				hash: contextModule.hash
+			})
+		),
+		immutablePaths: optionalNestedArray(snapshot.immutablePaths, (p) => [...p]),
+		managedPaths: optionalNestedArray(snapshot.managedPaths, (p) => [...p]),
+		unmanagedPaths: optionalNestedArray(snapshot.unmanagedPaths, (p) => [...p])
+	})),
+	stats: nestedConfig(config.stats, (stats) => {
+		if (stats === false) {
+			return {
+				preset: "none"
+			};
+		}
+		if (stats === true) {
+			return {
+				preset: "normal"
+			};
+		}
+		if (typeof stats === "string") {
+			return {
+				preset: stats
+			};
+		}
+		return {
+			...stats
+		};
+	}),
+	target: config.target,
+	watch: config.watch,
+	watchOptions: cloneObject(config.watchOptions)
+});
+
+/**
+ * Gets normalized entry static.
+ * @param {EntryStatic} entry static entry options
+ * @returns {EntryStaticNormalized} normalized static entry options
+ */
+const getNormalizedEntryStatic = (entry) => {
+	if (typeof entry === "string") {
+		return {
+			main: {
+				import: [entry]
+			}
+		};
+	}
+	if (Array.isArray(entry)) {
+		return {
+			main: {
+				import: entry
+			}
+		};
+	}
+	/** @type {EntryStaticNormalized} */
+	const result = {};
+	for (const key of Object.keys(entry)) {
+		const value = entry[key];
+		if (typeof value === "string") {
+			result[key] = {
+				import: [value]
+			};
+		} else if (Array.isArray(value)) {
+			result[key] = {
+				import: value
+			};
+		} else {
+			result[key] = {
+				import:
+					/** @type {EntryDescriptionNormalized["import"]} */
+					(
+						value.import &&
+							(Array.isArray(value.import) ? value.import : [value.import])
+					),
+				filename: value.filename,
+				layer: value.layer,
+				runtime: value.runtime,
+				baseUri: value.baseUri,
+				publicPath: value.publicPath,
+				chunkLoading: value.chunkLoading,
+				asyncChunks: value.asyncChunks,
+				wasmLoading: value.wasmLoading,
+				dependOn:
+					/** @type {EntryDescriptionNormalized["dependOn"]} */
+					(
+						value.dependOn &&
+							(Array.isArray(value.dependOn)
+								? value.dependOn
+								: [value.dependOn])
+					),
+				library: value.library
+			};
+		}
+	}
+	return result;
+};
+
+/**
+ * Gets normalized optimization runtime chunk.
+ * @param {OptimizationRuntimeChunk=} runtimeChunk runtimeChunk option
+ * @returns {OptimizationRuntimeChunkNormalized=} normalized runtimeChunk option
+ */
+const getNormalizedOptimizationRuntimeChunk = (runtimeChunk) => {
+	if (runtimeChunk === undefined) return;
+	if (runtimeChunk === false) return false;
+	if (runtimeChunk === "single") {
+		return {
+			name: () => "runtime"
+		};
+	}
+	if (runtimeChunk === true || runtimeChunk === "multiple") {
+		return {
+			name: (entrypoint) => `runtime~${entrypoint.name}`
+		};
+	}
+	const { name } = runtimeChunk;
+	return {
+		name:
+			typeof name === "function"
+				? /** @type {Exclude<OptimizationRuntimeChunkNormalized, false>["name"]} */
+					(name)
+				: () => /** @type {string} */ (name)
+	};
+};
+
+/**
+ * Apply webpack options interception.
+ * @param {WebpackOptionsNormalized} options options to be intercepted
+ * @returns {{ options: WebpackOptionsNormalized, interception?: WebpackOptionsInterception }} options and interception
+ */
+const applyWebpackOptionsInterception = (options) => {
+	// Return origin options when backCompat is disabled
+	if (options.experiments.futureDefaults) {
+		return {
+			options
+		};
+	}
+
+	// TODO webpack 6 - remove compatibility logic and move `devtools` fully into `devtool` with multi-type support
+	let _devtool = options.devtool;
+	/** @type {WebpackOptionsNormalized["devtool"]} */
+	let cached;
+
+	const devtoolBackCompat = () => {
+		if (Array.isArray(_devtool)) {
+			if (cached) return cached;
+			// Prefer `all`, then `javascript`, then `css`
+			const match = ["all", "javascript", "css"]
+				.map((type) =>
+					/** @type {Extract<WebpackOptionsNormalized["devtool"], EXPECTED_ANY[]>} */ (
+						_devtool
+					).find((item) => item.type === type)
+				)
+				.find(Boolean);
+
+			// If `devtool: []` is specified, return `false` here
+			return (cached = match ? match.use : false);
+		}
+		return _devtool;
+	};
+
+	/** @type {ProxyHandler<WebpackOptionsNormalized>} */
+	const handler = Object.create(null);
+	handler.get = (target, prop, receiver) => {
+		if (prop === "devtool") {
+			return devtoolBackCompat();
+		}
+		return Reflect.get(target, prop, receiver);
+	};
+	handler.set = (target, prop, value, receiver) => {
+		if (prop === "devtool") {
+			_devtool = value;
+			cached = undefined;
+			return true;
+		}
+		return Reflect.set(target, prop, value, receiver);
+	};
+	handler.deleteProperty = (target, prop) => {
+		if (prop === "devtool") {
+			_devtool = undefined;
+			cached = undefined;
+			return true;
+		}
+		return Reflect.deleteProperty(target, prop);
+	};
+	handler.defineProperty = (target, prop, descriptor) => {
+		if (prop === "devtool") {
+			_devtool = descriptor.value;
+			cached = undefined;
+			return true;
+		}
+		return Reflect.defineProperty(target, prop, descriptor);
+	};
+	handler.getOwnPropertyDescriptor = (target, prop) => {
+		if (prop === "devtool") {
+			return {
+				configurable: true,
+				enumerable: true,
+				value: devtoolBackCompat(),
+				writable: true
+			};
+		}
+		return Reflect.getOwnPropertyDescriptor(target, prop);
+	};
+
+	return {
+		options: new Proxy(options, handler),
+		interception: {
+			get devtool() {
+				return _devtool;
+			}
+		}
+	};
+};
+
+module.exports.applyWebpackOptionsInterception =
+	applyWebpackOptionsInterception;
+module.exports.getNormalizedWebpackOptions = getNormalizedWebpackOptions;
Index: frontend/node_modules/webpack/lib/config/target.js
===================================================================
--- frontend/node_modules/webpack/lib/config/target.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/config/target.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,400 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const memoize = require("../util/memoize");
+
+const getBrowserslistTargetHandler = memoize(() =>
+	require("./browserslistTargetHandler")
+);
+
+/**
+ * Gets default target.
+ * @param {string} context the context directory
+ * @returns {string} default target
+ */
+const getDefaultTarget = (context) => {
+	const browsers = getBrowserslistTargetHandler().load(undefined, context);
+	return browsers ? "browserslist" : "web";
+};
+
+/**
+ * Defines the platform target properties type used by this module.
+ * @typedef {object} PlatformTargetProperties
+ * @property {boolean | null=} web web platform, importing of http(s) and std: is available
+ * @property {boolean | null=} browser browser platform, running in a normal web browser
+ * @property {boolean | null=} webworker (Web)Worker platform, running in a web/shared/service worker
+ * @property {boolean | null=} node node platform, require of node built-in modules is available
+ * @property {boolean | null=} nwjs nwjs platform, require of legacy nw.gui is available
+ * @property {boolean | null=} electron electron platform, require of some electron built-in modules is available
+ */
+
+/**
+ * Defines the electron context target properties type used by this module.
+ * @typedef {object} ElectronContextTargetProperties
+ * @property {boolean | null} electronMain in main context
+ * @property {boolean | null} electronPreload in preload context
+ * @property {boolean | null} electronRenderer in renderer context with node integration
+ */
+
+/**
+ * Defines the api target properties type used by this module.
+ * @typedef {object} ApiTargetProperties
+ * @property {boolean | null} require has require function available
+ * @property {boolean | null} nodeBuiltins has node.js built-in modules available
+ * @property {boolean | null} nodePrefixForCoreModules node.js allows to use `node:` prefix for core modules
+ * @property {boolean | null} importMetaDirnameAndFilename node.js allows to use `import.meta.dirname` and `import.meta.filename`
+ * @property {boolean | null} document has document available (allows script tags)
+ * @property {boolean | null} importScripts has importScripts available
+ * @property {boolean | null} importScriptsInWorker has importScripts available when creating a worker
+ * @property {boolean | null} fetchWasm has fetch function available for WebAssembly
+ * @property {boolean | null} global has global variable available
+ */
+
+/**
+ * Defines the ecma target properties type used by this module.
+ * @typedef {object} EcmaTargetProperties
+ * @property {boolean | null} globalThis has globalThis variable available
+ * @property {boolean | null} bigIntLiteral big int literal syntax is available
+ * @property {boolean | null} const const and let variable declarations are available
+ * @property {boolean | null} methodShorthand object method shorthand is available
+ * @property {boolean | null} arrowFunction arrow functions are available
+ * @property {boolean | null} forOf for of iteration is available
+ * @property {boolean | null} destructuring destructuring is available
+ * @property {boolean | null} dynamicImport async import() is available
+ * @property {boolean | null} dynamicImportInWorker async import() is available when creating a worker
+ * @property {boolean | null} module ESM syntax is available (when in module)
+ * @property {boolean | null} optionalChaining optional chaining is available
+ * @property {boolean | null} templateLiteral template literal is available
+ * @property {boolean | null} asyncFunction async functions and await are available
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {{ [P in keyof T]?: never }} Never<T>
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @template A
+ * @template B
+ * @typedef {(A & Never<B>) | (Never<A> & B) | (A & B)} Mix<A, B>
+ */
+
+/** @typedef {Mix<Mix<PlatformTargetProperties, ElectronContextTargetProperties>, Mix<ApiTargetProperties, EcmaTargetProperties>>} TargetProperties */
+
+/**
+ * Returns check if version is greater or equal.
+ * @param {string} major major version
+ * @param {string | undefined} minor minor version
+ * @returns {(vMajor: number, vMinor?: number) => boolean | undefined} check if version is greater or equal
+ */
+const versionDependent = (major, minor) => {
+	if (!major) {
+		return () => /** @type {undefined} */ (undefined);
+	}
+	/** @type {number} */
+	const nMajor = Number(major);
+	/** @type {number} */
+	const nMinor = minor ? Number(minor) : 0;
+	return (vMajor, vMinor = 0) =>
+		nMajor > vMajor || (nMajor === vMajor && nMinor >= vMinor);
+};
+
+/** @type {[string, string, RegExp, (...args: string[]) => Partial<TargetProperties>][]} */
+const TARGETS = [
+	[
+		"browserslist / browserslist:env / browserslist:query / browserslist:path-to-config / browserslist:path-to-config:env",
+		"Resolve features from browserslist. Will resolve browserslist config automatically. Only browser or node queries are supported (electron is not supported). Examples: 'browserslist:modern' to use 'modern' environment from browserslist config",
+		/^browserslist(?::(.+))?$/,
+		(rest, context) => {
+			const browserslistTargetHandler = getBrowserslistTargetHandler();
+			const browsers = browserslistTargetHandler.load(
+				rest ? rest.trim() : null,
+				context
+			);
+			if (!browsers) {
+				throw new Error(`No browserslist config found to handle the 'browserslist' target.
+See https://github.com/browserslist/browserslist#queries for possible ways to provide a config.
+The recommended way is to add a 'browserslist' key to your package.json and list supported browsers (resp. node.js versions).
+You can also more options via the 'target' option: 'browserslist' / 'browserslist:env' / 'browserslist:query' / 'browserslist:path-to-config' / 'browserslist:path-to-config:env'`);
+			}
+
+			return browserslistTargetHandler.resolve(browsers);
+		}
+	],
+	[
+		"web",
+		"Web browser.",
+		/^web$/,
+		() => ({
+			node: false,
+			web: true,
+			webworker: null,
+			browser: true,
+			electron: false,
+			nwjs: false,
+
+			document: true,
+			importScriptsInWorker: true,
+			fetchWasm: true,
+			nodeBuiltins: false,
+			importScripts: false,
+			require: false,
+			global: false
+		})
+	],
+	[
+		"webworker",
+		"Web Worker, SharedWorker or Service Worker.",
+		/^webworker$/,
+		() => ({
+			node: false,
+			web: true,
+			webworker: true,
+			browser: true,
+			electron: false,
+			nwjs: false,
+
+			importScripts: true,
+			importScriptsInWorker: true,
+			fetchWasm: true,
+			nodeBuiltins: false,
+			require: false,
+			document: false,
+			global: false
+		})
+	],
+	[
+		"[async-]node[X[.Y]]",
+		"Node.js in version X.Y. The 'async-' prefix will load chunks asynchronously via 'fs' and 'vm' instead of 'require()'. Examples: node14.5, async-node10.",
+		/^(async-)?node((\d+)(?:\.(\d+))?)?$/,
+		(asyncFlag, _, major, minor) => {
+			const v = versionDependent(major, minor);
+			// see https://node.green/
+			return {
+				node: true,
+				web: false,
+				webworker: false,
+				browser: false,
+				electron: false,
+				nwjs: false,
+
+				require: !asyncFlag,
+				nodeBuiltins: true,
+				// v16.0.0, v14.18.0
+				nodePrefixForCoreModules: Number(major) < 15 ? v(14, 18) : v(16),
+				// Added in: v21.2.0, v20.11.0, but Node.js will output experimental warning, we don't want it
+				// v24.0.0, v22.16.0 - This property is no longer experimental.
+				importMetaDirnameAndFilename: v(22, 16),
+				global: true,
+				document: false,
+				fetchWasm: false,
+				importScripts: false,
+				importScriptsInWorker: false,
+
+				globalThis: v(12),
+				const: v(6),
+				templateLiteral: v(4),
+				optionalChaining: v(14),
+				methodShorthand: v(4),
+				arrowFunction: v(6),
+				asyncFunction: v(7, 6),
+				forOf: v(5),
+				destructuring: v(6),
+				bigIntLiteral: v(10, 4),
+				dynamicImport: v(12, 17),
+				dynamicImportInWorker: v(12, 17),
+				module: v(12, 17)
+			};
+		}
+	],
+	[
+		"electron[X[.Y]]-main/preload/renderer",
+		"Electron in version X.Y. Script is running in main, preload resp. renderer context.",
+		/^electron((\d+)(?:\.(\d+))?)?-(main|preload|renderer)$/,
+		(_, major, minor, context) => {
+			const v = versionDependent(major, minor);
+			// see https://node.green/ + https://github.com/electron/releases
+			return {
+				node: true,
+				web: context !== "main",
+				webworker: false,
+				browser: false,
+				electron: true,
+				nwjs: false,
+
+				electronMain: context === "main",
+				electronPreload: context === "preload",
+				electronRenderer: context === "renderer",
+
+				global: true,
+				nodeBuiltins: true,
+				// 15.0.0	- Node.js	v16.5
+				// 14.0.0 - Mode.js v14.17, but prefixes only since v14.18
+				nodePrefixForCoreModules: v(15),
+				// 37.0.0 - Node.js v22.16
+				importMetaDirnameAndFilename: v(37),
+
+				require: true,
+				document: context === "renderer",
+				fetchWasm: context === "renderer",
+				importScripts: false,
+				importScriptsInWorker: true,
+
+				globalThis: v(5),
+				const: v(1, 1),
+				templateLiteral: v(1, 1),
+				optionalChaining: v(8),
+				methodShorthand: v(1, 1),
+				arrowFunction: v(1, 1),
+				asyncFunction: v(1, 7),
+				forOf: v(0, 36),
+				destructuring: v(1, 1),
+				bigIntLiteral: v(4),
+				dynamicImport: v(11),
+				dynamicImportInWorker: v(11),
+				module: v(11)
+			};
+		}
+	],
+	[
+		"nwjs[X[.Y]] / node-webkit[X[.Y]]",
+		"NW.js in version X.Y.",
+		/^(?:nwjs|node-webkit)((\d+)(?:\.(\d+))?)?$/,
+		(_, major, minor) => {
+			const v = versionDependent(major, minor);
+			// see https://node.green/ + https://github.com/nwjs/nw.js/blob/nw48/CHANGELOG.md
+			return {
+				node: true,
+				web: true,
+				webworker: null,
+				browser: false,
+				electron: false,
+				nwjs: true,
+
+				global: true,
+				nodeBuiltins: true,
+				document: false,
+				importScriptsInWorker: false,
+				fetchWasm: false,
+				importScripts: false,
+				require: false,
+
+				globalThis: v(0, 43),
+				const: v(0, 15),
+				templateLiteral: v(0, 13),
+				optionalChaining: v(0, 44),
+				methodShorthand: v(0, 15),
+				arrowFunction: v(0, 15),
+				asyncFunction: v(0, 21),
+				forOf: v(0, 13),
+				destructuring: v(0, 15),
+				bigIntLiteral: v(0, 32),
+				dynamicImport: v(0, 43),
+				dynamicImportInWorker: v(0, 44),
+				module: v(0, 43)
+			};
+		}
+	],
+	[
+		"esX",
+		"EcmaScript in this version. Examples: es2020, es5.",
+		/^es(\d+)$/,
+		(version) => {
+			let v = Number(version);
+			if (v < 1000) v += 2009;
+			return {
+				const: v >= 2015,
+				templateLiteral: v >= 2015,
+				optionalChaining: v >= 2020,
+				methodShorthand: v >= 2015,
+				arrowFunction: v >= 2015,
+				forOf: v >= 2015,
+				destructuring: v >= 2015,
+				module: v >= 2015,
+				asyncFunction: v >= 2017,
+				globalThis: v >= 2020,
+				bigIntLiteral: v >= 2020,
+				dynamicImport: v >= 2020,
+				dynamicImportInWorker: v >= 2020
+			};
+		}
+	]
+];
+
+/**
+ * Gets target properties.
+ * @param {string} target the target
+ * @param {string} context the context directory
+ * @returns {TargetProperties} target properties
+ */
+const getTargetProperties = (target, context) => {
+	for (const [, , regExp, handler] of TARGETS) {
+		const match = regExp.exec(target);
+		if (match) {
+			const [, ...args] = match;
+			const result = handler(...args, context);
+			if (result) return /** @type {TargetProperties} */ (result);
+		}
+	}
+	throw new Error(
+		`Unknown target '${target}'. The following targets are supported:\n${TARGETS.map(
+			([name, description]) => `* ${name}: ${description}`
+		).join("\n")}`
+	);
+};
+
+/**
+ * Merges target properties.
+ * @param {TargetProperties[]} targetProperties array of target properties
+ * @returns {TargetProperties} merged target properties
+ */
+const mergeTargetProperties = (targetProperties) => {
+	/** @type {Set<keyof TargetProperties>} */
+	const keys = new Set();
+	for (const tp of targetProperties) {
+		for (const key of Object.keys(tp)) {
+			keys.add(/** @type {keyof TargetProperties} */ (key));
+		}
+	}
+	/** @type {TargetProperties} */
+	const result = {};
+	for (const key of keys) {
+		let hasTrue = false;
+		let hasFalse = false;
+		for (const tp of targetProperties) {
+			const value = tp[key];
+			switch (value) {
+				case true:
+					hasTrue = true;
+					break;
+				case false:
+					hasFalse = true;
+					break;
+			}
+		}
+		if (hasTrue || hasFalse) {
+			/** @type {TargetProperties} */
+			(result)[key] = hasFalse && hasTrue ? null : Boolean(hasTrue);
+		}
+	}
+	return result;
+};
+
+/**
+ * Gets targets properties.
+ * @param {string[]} targets the targets
+ * @param {string} context the context directory
+ * @returns {TargetProperties} target properties
+ */
+const getTargetsProperties = (targets, context) =>
+	mergeTargetProperties(targets.map((t) => getTargetProperties(t, context)));
+
+module.exports.getDefaultTarget = getDefaultTarget;
+module.exports.getTargetProperties = getTargetProperties;
+module.exports.getTargetsProperties = getTargetsProperties;
Index: frontend/node_modules/webpack/lib/container/ContainerEntryDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ContainerEntryDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ContainerEntryDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,52 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("./ContainerEntryModule").ExposesList} ExposesList */
+
+class ContainerEntryDependency extends Dependency {
+	/**
+	 * Creates an instance of ContainerEntryDependency.
+	 * @param {string} name entry name
+	 * @param {ExposesList} exposes list of exposed modules
+	 * @param {string} shareScope name of the share scope
+	 */
+	constructor(name, exposes, shareScope) {
+		super();
+		/** @type {string} */
+		this.name = name;
+		/** @type {ExposesList} */
+		this.exposes = exposes;
+		/** @type {string} */
+		this.shareScope = shareScope;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return `container-entry-${this.name}`;
+	}
+
+	get type() {
+		return "container entry";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	ContainerEntryDependency,
+	"webpack/lib/container/ContainerEntryDependency"
+);
+
+module.exports = ContainerEntryDependency;
Index: frontend/node_modules/webpack/lib/container/ContainerEntryModule.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ContainerEntryModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ContainerEntryModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,315 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
+*/
+
+"use strict";
+
+const { OriginalSource, RawSource } = require("webpack-sources");
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const Module = require("../Module");
+const {
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const makeSerializable = require("../util/makeSerializable");
+const ContainerExposedDependency = require("./ContainerExposedDependency");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+/**
+ * Defines the expose options type used by this module.
+ * @typedef {object} ExposeOptions
+ * @property {string[]} import requests to exposed modules (last one is exported)
+ * @property {string} name custom chunk name for the exposed module
+ */
+
+/** @typedef {[string, ExposeOptions][]} ExposesList */
+
+class ContainerEntryModule extends Module {
+	/**
+	 * Creates an instance of ContainerEntryModule.
+	 * @param {string} name container entry name
+	 * @param {ExposesList} exposes list of exposed modules
+	 * @param {string} shareScope name of the share scope
+	 */
+	constructor(name, exposes, shareScope) {
+		super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);
+		/** @type {string} */
+		this._name = name;
+		/** @type {ExposesList} */
+		this._exposes = exposes;
+		/** @type {string} */
+		this._shareScope = shareScope;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return `container entry (${this._shareScope}) ${JSON.stringify(
+			this._exposes
+		)}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return "container entry";
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return `${this.layer ? `(${this.layer})/` : ""}webpack/container/entry/${
+			this._name
+		}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, !this.buildMeta);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {
+			strict: true,
+			topLevelDeclarations: new Set(["moduleMap", "get", "init"])
+		};
+		this.buildMeta.exportsType = "namespace";
+
+		this.clearDependenciesAndBlocks();
+
+		for (const [name, options] of this._exposes) {
+			const block = new AsyncDependenciesBlock(
+				{
+					name: options.name
+				},
+				{ name },
+				options.import[options.import.length - 1]
+			);
+			let idx = 0;
+			for (const request of options.import) {
+				const dep = new ContainerExposedDependency(name, request);
+				dep.loc = {
+					name,
+					index: idx++
+				};
+
+				block.addDependency(dep);
+			}
+			this.addBlock(block);
+		}
+		this.addDependency(new StaticExportsDependency(["get", "init"], false));
+
+		callback();
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({ moduleGraph, chunkGraph, runtimeTemplate }) {
+		/** @type {Sources} */
+		const sources = new Map();
+		const runtimeRequirements = new Set([
+			RuntimeGlobals.definePropertyGetters,
+			RuntimeGlobals.hasOwnProperty,
+			RuntimeGlobals.exports
+		]);
+		/** @type {string[]} */
+		const getters = [];
+
+		for (const block of this.blocks) {
+			const { dependencies } = block;
+
+			const modules = dependencies.map((dependency) => {
+				const dep = /** @type {ContainerExposedDependency} */ (dependency);
+				return {
+					name: dep.exposedName,
+					module: moduleGraph.getModule(dep),
+					request: dep.userRequest
+				};
+			});
+
+			/** @type {string} */
+			let str;
+
+			if (modules.some((m) => !m.module)) {
+				str = runtimeTemplate.throwMissingModuleErrorBlock({
+					request: modules.map((m) => m.request).join(", ")
+				});
+			} else {
+				str = `return ${runtimeTemplate.blockPromise({
+					block,
+					message: "",
+					chunkGraph,
+					runtimeRequirements
+				})}.then(${runtimeTemplate.returningFunction(
+					runtimeTemplate.returningFunction(
+						`(${modules
+							.map(({ module, request }) =>
+								runtimeTemplate.moduleRaw({
+									module,
+									chunkGraph,
+									request,
+									weak: false,
+									runtimeRequirements
+								})
+							)
+							.join(", ")})`
+					)
+				)});`;
+			}
+
+			getters.push(
+				`${JSON.stringify(modules[0].name)}: ${runtimeTemplate.basicFunction(
+					"",
+					str
+				)}`
+			);
+		}
+
+		const source = Template.asString([
+			"var moduleMap = {",
+			Template.indent(getters.join(",\n")),
+			"};",
+			`var get = ${runtimeTemplate.basicFunction("module, getScope", [
+				`${RuntimeGlobals.currentRemoteGetScope} = getScope;`,
+				// reusing the getScope variable to avoid creating a new var (and module is also used later)
+				"getScope = (",
+				Template.indent([
+					`${RuntimeGlobals.hasOwnProperty}(moduleMap, module)`,
+					Template.indent([
+						"? moduleMap[module]()",
+						`: Promise.resolve().then(${runtimeTemplate.basicFunction(
+							"",
+							"throw new Error('Module \"' + module + '\" does not exist in container.');"
+						)})`
+					])
+				]),
+				");",
+				`${RuntimeGlobals.currentRemoteGetScope} = undefined;`,
+				"return getScope;"
+			])};`,
+			`var init = ${runtimeTemplate.basicFunction("shareScope, initScope", [
+				`if (!${RuntimeGlobals.shareScopeMap}) return;`,
+				`var name = ${JSON.stringify(this._shareScope)}`,
+				`var oldScope = ${RuntimeGlobals.shareScopeMap}[name];`,
+				'if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");',
+				`${RuntimeGlobals.shareScopeMap}[name] = shareScope;`,
+				`return ${RuntimeGlobals.initializeSharing}(name, initScope);`
+			])};`,
+			"",
+			"// This exports getters to disallow modifications",
+			`${RuntimeGlobals.definePropertyGetters}(exports, {`,
+			Template.indent([
+				`get: ${runtimeTemplate.returningFunction("get")},`,
+				`init: ${runtimeTemplate.returningFunction("init")}`
+			]),
+			"});"
+		]);
+
+		sources.set(
+			JAVASCRIPT_TYPE,
+			this.useSourceMap || this.useSimpleSourceMap
+				? new OriginalSource(source, "webpack/container-entry")
+				: new RawSource(source)
+		);
+
+		return {
+			sources,
+			runtimeRequirements
+		};
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this._name);
+		write(this._exposes);
+		write(this._shareScope);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {ContainerEntryModule} deserialized container entry module
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		const obj = new ContainerEntryModule(read(), read(), read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	ContainerEntryModule,
+	"webpack/lib/container/ContainerEntryModule"
+);
+
+module.exports = ContainerEntryModule;
Index: frontend/node_modules/webpack/lib/container/ContainerEntryModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ContainerEntryModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ContainerEntryModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
+*/
+
+"use strict";
+
+const ModuleFactory = require("../ModuleFactory");
+const ContainerEntryModule = require("./ContainerEntryModule");
+
+/** @typedef {import("../ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./ContainerEntryDependency")} ContainerEntryDependency */
+
+module.exports = class ContainerEntryModuleFactory extends ModuleFactory {
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create({ dependencies: [dependency] }, callback) {
+		const dep = /** @type {ContainerEntryDependency} */ (dependency);
+		callback(null, {
+			module: new ContainerEntryModule(dep.name, dep.exposes, dep.shareScope)
+		});
+	}
+};
Index: frontend/node_modules/webpack/lib/container/ContainerExposedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ContainerExposedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ContainerExposedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,66 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ContainerExposedDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ContainerExposedDependency.
+	 * @param {string} exposedName public name
+	 * @param {string} request request to module
+	 */
+	constructor(exposedName, request) {
+		super(request);
+		/** @type {string} */
+		this.exposedName = exposedName;
+	}
+
+	get type() {
+		return "container exposed";
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return `exposed dependency ${this.exposedName}=${this.request}`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		context.write(this.exposedName);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		this.exposedName = context.read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ContainerExposedDependency,
+	"webpack/lib/container/ContainerExposedDependency"
+);
+
+module.exports = ContainerExposedDependency;
Index: frontend/node_modules/webpack/lib/container/ContainerPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ContainerPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ContainerPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,123 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
+*/
+
+"use strict";
+
+const memoize = require("../util/memoize");
+const ContainerEntryDependency = require("./ContainerEntryDependency");
+const ContainerEntryModuleFactory = require("./ContainerEntryModuleFactory");
+const ContainerExposedDependency = require("./ContainerExposedDependency");
+const { parseOptions } = require("./options");
+
+/** @typedef {import("../../declarations/plugins/container/ContainerPlugin").ContainerPluginOptions} ContainerPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./ContainerEntryModule").ExposesList} ExposesList */
+
+const getModuleFederationPlugin = memoize(() =>
+	require("./ModuleFederationPlugin")
+);
+
+const PLUGIN_NAME = "ContainerPlugin";
+
+class ContainerPlugin {
+	/**
+	 * Creates an instance of ContainerPlugin.
+	 * @param {ContainerPluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {ContainerPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/container/ContainerPlugin.json"),
+				this.options,
+				{
+					name: "Container Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/container/ContainerPlugin.check")(
+						options
+					)
+			);
+		});
+
+		const library = this.options.library || {
+			type: "var",
+			name: this.options.name
+		};
+
+		if (!compiler.options.output.enabledLibraryTypes.includes(library.type)) {
+			compiler.options.output.enabledLibraryTypes.push(library.type);
+		}
+
+		const exposes = /** @type {ExposesList} */ (
+			parseOptions(
+				this.options.exposes,
+				(item) => ({
+					import: Array.isArray(item) ? item : [item],
+					name: undefined
+				}),
+				(item) => ({
+					import: Array.isArray(item.import) ? item.import : [item.import],
+					name: item.name || undefined
+				})
+			)
+		);
+
+		const shareScope = this.options.shareScope || "default";
+
+		compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
+			const hooks =
+				getModuleFederationPlugin().getCompilationHooks(compilation);
+			const dep = new ContainerEntryDependency(
+				this.options.name,
+				exposes,
+				shareScope
+			);
+			dep.loc = { name: this.options.name };
+			compilation.addEntry(
+				compilation.options.context,
+				dep,
+				{
+					name: this.options.name,
+					filename: this.options.filename,
+					runtime: this.options.runtime,
+					library
+				},
+				(error) => {
+					if (error) return callback(error);
+					hooks.addContainerEntryDependency.call(dep);
+					callback();
+				}
+			);
+		});
+
+		compiler.hooks.thisCompilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					ContainerEntryDependency,
+					new ContainerEntryModuleFactory()
+				);
+
+				compilation.dependencyFactories.set(
+					ContainerExposedDependency,
+					normalModuleFactory
+				);
+			}
+		);
+	}
+}
+
+module.exports = ContainerPlugin;
Index: frontend/node_modules/webpack/lib/container/ContainerReferencePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ContainerReferencePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ContainerReferencePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,156 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const ExternalModule = require("../ExternalModule");
+const ExternalsPlugin = require("../ExternalsPlugin");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const FallbackDependency = require("./FallbackDependency");
+const FallbackItemDependency = require("./FallbackItemDependency");
+const FallbackModuleFactory = require("./FallbackModuleFactory");
+const RemoteModule = require("./RemoteModule");
+const RemoteRuntimeModule = require("./RemoteRuntimeModule");
+const RemoteToExternalDependency = require("./RemoteToExternalDependency");
+const { parseOptions } = require("./options");
+
+/** @typedef {import("../../declarations/plugins/container/ContainerReferencePlugin").ContainerReferencePluginOptions} ContainerReferencePluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+
+const slashCode = "/".charCodeAt(0);
+const PLUGIN_NAME = "ContainerReferencePlugin";
+
+class ContainerReferencePlugin {
+	/**
+	 * Creates an instance of ContainerReferencePlugin.
+	 * @param {ContainerReferencePluginOptions} options options
+	 */
+	constructor(options) {
+		/** @typedef {ContainerReferencePluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/container/ContainerReferencePlugin.json"),
+				this.options,
+				{
+					name: "Container Reference Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/container/ContainerReferencePlugin.check")(
+						options
+					)
+			);
+		});
+
+		const { remoteType } = this.options;
+		const remotes = parseOptions(
+			this.options.remotes,
+			(item) => ({
+				external: Array.isArray(item) ? item : [item],
+				shareScope: this.options.shareScope || "default"
+			}),
+			(item) => ({
+				external: Array.isArray(item.external)
+					? item.external
+					: [item.external],
+				shareScope: item.shareScope || this.options.shareScope || "default"
+			})
+		);
+
+		/** @type {Record<string, string>} */
+		const remoteExternals = {};
+		for (const [key, config] of remotes) {
+			let i = 0;
+			for (const external of config.external) {
+				if (external.startsWith("internal ")) continue;
+				remoteExternals[
+					`webpack/container/reference/${key}${i ? `/fallback-${i}` : ""}`
+				] = external;
+				i++;
+			}
+		}
+
+		new ExternalsPlugin(remoteType, remoteExternals).apply(compiler);
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					RemoteToExternalDependency,
+					normalModuleFactory
+				);
+
+				compilation.dependencyFactories.set(
+					FallbackItemDependency,
+					normalModuleFactory
+				);
+
+				compilation.dependencyFactories.set(
+					FallbackDependency,
+					new FallbackModuleFactory()
+				);
+
+				normalModuleFactory.hooks.factorize.tap(PLUGIN_NAME, (data) => {
+					if (!data.request.includes("!")) {
+						for (const [key, config] of remotes) {
+							if (
+								data.request.startsWith(`${key}`) &&
+								(data.request.length === key.length ||
+									data.request.charCodeAt(key.length) === slashCode)
+							) {
+								return new RemoteModule(
+									data.request,
+									config.external.map((external, i) =>
+										external.startsWith("internal ")
+											? external.slice(9)
+											: `webpack/container/reference/${key}${
+													i ? `/fallback-${i}` : ""
+												}`
+									),
+									`.${data.request.slice(key.length)}`,
+									config.shareScope
+								);
+							}
+						}
+					}
+				});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.ensureChunkHandlers)
+					.tap(PLUGIN_NAME, (chunk, set) => {
+						set.add(RuntimeGlobals.module);
+						set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+						set.add(RuntimeGlobals.hasOwnProperty);
+						set.add(RuntimeGlobals.initializeSharing);
+						set.add(RuntimeGlobals.shareScopeMap);
+						compilation.addRuntimeModule(chunk, new RemoteRuntimeModule());
+					});
+
+				const { chunkCondition } =
+					ExternalModule.getCompilationHooks(compilation);
+
+				// External modules issued by remote modules should be placed in entry chunks
+				// to ensure they are loaded and initialize first
+				chunkCondition.tap(
+					PLUGIN_NAME,
+					(chunk, compilation) =>
+						compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0
+				);
+			}
+		);
+	}
+}
+
+module.exports = ContainerReferencePlugin;
Index: frontend/node_modules/webpack/lib/container/FallbackDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/container/FallbackDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/FallbackDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("./RemoteModule").ExternalRequests} ExternalRequests */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class FallbackDependency extends Dependency {
+	/**
+	 * Creates an instance of FallbackDependency.
+	 * @param {ExternalRequests} requests requests
+	 */
+	constructor(requests) {
+		super();
+		/** @type {ExternalRequests} */
+		this.requests = requests;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return `fallback ${this.requests.join(" ")}`;
+	}
+
+	get type() {
+		return "fallback";
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.requests);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {FallbackDependency} deserialize fallback dependency
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		const obj = new FallbackDependency(read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	FallbackDependency,
+	"webpack/lib/container/FallbackDependency"
+);
+
+module.exports = FallbackDependency;
Index: frontend/node_modules/webpack/lib/container/FallbackItemDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/container/FallbackItemDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/FallbackItemDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+class FallbackItemDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of FallbackItemDependency.
+	 * @param {string} request request
+	 */
+	constructor(request) {
+		/** @type {string} */
+		super(request);
+	}
+
+	get type() {
+		return "fallback item";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	FallbackItemDependency,
+	"webpack/lib/container/FallbackItemDependency"
+);
+
+module.exports = FallbackItemDependency;
Index: frontend/node_modules/webpack/lib/container/FallbackModule.js
===================================================================
--- frontend/node_modules/webpack/lib/container/FallbackModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/FallbackModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,205 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Module = require("../Module");
+const {
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { WEBPACK_MODULE_TYPE_FALLBACK } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const makeSerializable = require("../util/makeSerializable");
+const FallbackItemDependency = require("./FallbackItemDependency");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NameForCondition} NameForCondition */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./RemoteModule").ExternalRequests} ExternalRequests */
+
+const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
+
+class FallbackModule extends Module {
+	/**
+	 * Creates an instance of FallbackModule.
+	 * @param {ExternalRequests} requests list of requests to choose one
+	 */
+	constructor(requests) {
+		super(WEBPACK_MODULE_TYPE_FALLBACK);
+		/** @type {ExternalRequests} */
+		this.requests = requests;
+		/** @type {string} */
+		this._identifier = `fallback ${this.requests.join(" ")}`;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this._identifier;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return this._identifier;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return `${this.layer ? `(${this.layer})/` : ""}webpack/container/fallback/${
+			this.requests[0]
+		}/and ${this.requests.length - 1} more`;
+	}
+
+	/**
+	 * Returns true if the module can be placed in the chunk.
+	 * @param {Chunk} chunk the chunk which condition should be checked
+	 * @param {Compilation} compilation the compilation
+	 * @returns {boolean} true if the module can be placed in the chunk
+	 */
+	chunkCondition(chunk, { chunkGraph }) {
+		return chunkGraph.getNumberOfEntryModules(chunk) > 0;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		callback(null, !this.buildInfo);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {
+			strict: true
+		};
+
+		this.clearDependenciesAndBlocks();
+		for (const request of this.requests) {
+			this.addDependency(new FallbackItemDependency(request));
+		}
+
+		callback();
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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 this.requests.length * 5 + 42;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
+		const ids = this.dependencies.map((dep) =>
+			chunkGraph.getModuleId(/** @type {Module} */ (moduleGraph.getModule(dep)))
+		);
+		const code = Template.asString([
+			`var ids = ${JSON.stringify(ids)};`,
+			"var error, result, i = 0;",
+			`var loop = ${runtimeTemplate.basicFunction("next", [
+				"while(i < ids.length) {",
+				Template.indent([
+					`try { next = ${RuntimeGlobals.require}(ids[i++]); } catch(e) { return handleError(e); }`,
+					"if(next) return next.then ? next.then(handleResult, handleError) : handleResult(next);"
+				]),
+				"}",
+				"if(error) throw error;"
+			])}`,
+			`var handleResult = ${runtimeTemplate.basicFunction("result", [
+				"if(result) return result;",
+				"return loop();"
+			])};`,
+			`var handleError = ${runtimeTemplate.basicFunction("e", [
+				"error = e;",
+				"return loop();"
+			])};`,
+			"module.exports = loop();"
+		]);
+		/** @type {Sources} */
+		const sources = new Map();
+		sources.set(JAVASCRIPT_TYPE, new RawSource(code));
+		return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS };
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.requests);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {FallbackModule} deserialized fallback module
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		const obj = new FallbackModule(read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(FallbackModule, "webpack/lib/container/FallbackModule");
+
+module.exports = FallbackModule;
Index: frontend/node_modules/webpack/lib/container/FallbackModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/container/FallbackModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/FallbackModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
+*/
+
+"use strict";
+
+const ModuleFactory = require("../ModuleFactory");
+const FallbackModule = require("./FallbackModule");
+
+/** @typedef {import("../ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./FallbackDependency")} FallbackDependency */
+
+module.exports = class FallbackModuleFactory extends ModuleFactory {
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create({ dependencies: [dependency] }, callback) {
+		const dep = /** @type {FallbackDependency} */ (dependency);
+		callback(null, {
+			module: new FallbackModule(dep.requests)
+		});
+	}
+};
Index: frontend/node_modules/webpack/lib/container/HoistContainerReferencesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/container/HoistContainerReferencesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/HoistContainerReferencesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,256 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const ExternalModule = require("../ExternalModule");
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+const memoize = require("../util/memoize");
+const { forEachRuntime } = require("../util/runtime");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Module")} Module */
+
+const getModuleFederationPlugin = memoize(() =>
+	require("./ModuleFederationPlugin")
+);
+
+const PLUGIN_NAME = "HoistContainerReferences";
+
+/**
+ * This class is used to hoist container references in the code.
+ */
+class HoistContainerReferences {
+	/**
+	 * Apply the plugin to the compiler.
+	 * @param {Compiler} compiler The webpack compiler instance.
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const hooks =
+				getModuleFederationPlugin().getCompilationHooks(compilation);
+			/** @type {Set<Dependency>} */
+			const depsToTrace = new Set();
+			/** @type {Set<Dependency>} */
+			const entryExternalsToHoist = new Set();
+			hooks.addContainerEntryDependency.tap(PLUGIN_NAME, (dep) => {
+				depsToTrace.add(dep);
+			});
+			hooks.addFederationRuntimeDependency.tap(PLUGIN_NAME, (dep) => {
+				depsToTrace.add(dep);
+			});
+
+			compilation.hooks.addEntry.tap(PLUGIN_NAME, (entryDep) => {
+				if (entryDep.type === "entry") {
+					entryExternalsToHoist.add(entryDep);
+				}
+			});
+
+			// Hook into the optimizeChunks phase
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					// advanced stage is where SplitChunksPlugin runs.
+					stage: STAGE_ADVANCED + 1
+				},
+				(_chunks) => {
+					this.hoistModulesInChunks(
+						compilation,
+						depsToTrace,
+						entryExternalsToHoist
+					);
+				}
+			);
+		});
+	}
+
+	/**
+	 * Hoist modules in chunks.
+	 * @param {Compilation} compilation The webpack compilation instance.
+	 * @param {Set<Dependency>} depsToTrace Set of container entry dependencies.
+	 * @param {Set<Dependency>} entryExternalsToHoist Set of container entry dependencies to hoist.
+	 */
+	hoistModulesInChunks(compilation, depsToTrace, entryExternalsToHoist) {
+		const { chunkGraph, moduleGraph } = compilation;
+
+		// loop over entry points
+		for (const dep of entryExternalsToHoist) {
+			const entryModule = moduleGraph.getModule(dep);
+			if (!entryModule) continue;
+			// get all the external module types and hoist them to the runtime chunk, this will get RemoteModule externals
+			const allReferencedModules = getAllReferencedModules(
+				compilation,
+				entryModule,
+				"external",
+				false
+			);
+
+			const containerRuntimes = chunkGraph.getModuleRuntimes(entryModule);
+			/** @type {Set<string>} */
+			const runtimes = new Set();
+
+			for (const runtimeSpec of containerRuntimes) {
+				forEachRuntime(runtimeSpec, (runtimeKey) => {
+					if (runtimeKey) {
+						runtimes.add(runtimeKey);
+					}
+				});
+			}
+
+			for (const runtime of runtimes) {
+				const runtimeChunk = compilation.namedChunks.get(runtime);
+				if (!runtimeChunk) continue;
+
+				for (const module of allReferencedModules) {
+					if (!chunkGraph.isModuleInChunk(module, runtimeChunk)) {
+						chunkGraph.connectChunkAndModule(runtimeChunk, module);
+					}
+				}
+			}
+			this.cleanUpChunks(compilation, allReferencedModules);
+		}
+
+		// handle container entry specifically
+		for (const dep of depsToTrace) {
+			const containerEntryModule = moduleGraph.getModule(dep);
+			if (!containerEntryModule) continue;
+			const allReferencedModules = getAllReferencedModules(
+				compilation,
+				containerEntryModule,
+				"initial",
+				false
+			);
+
+			const allRemoteReferences = getAllReferencedModules(
+				compilation,
+				containerEntryModule,
+				"external",
+				false
+			);
+
+			for (const remote of allRemoteReferences) {
+				allReferencedModules.add(remote);
+			}
+
+			const containerRuntimes =
+				chunkGraph.getModuleRuntimes(containerEntryModule);
+			/** @type {Set<string>} */
+			const runtimes = new Set();
+
+			for (const runtimeSpec of containerRuntimes) {
+				forEachRuntime(runtimeSpec, (runtimeKey) => {
+					if (runtimeKey) {
+						runtimes.add(runtimeKey);
+					}
+				});
+			}
+
+			for (const runtime of runtimes) {
+				const runtimeChunk = compilation.namedChunks.get(runtime);
+				if (!runtimeChunk) continue;
+
+				for (const module of allReferencedModules) {
+					if (!chunkGraph.isModuleInChunk(module, runtimeChunk)) {
+						chunkGraph.connectChunkAndModule(runtimeChunk, module);
+					}
+				}
+			}
+			this.cleanUpChunks(compilation, allReferencedModules);
+		}
+	}
+
+	/**
+	 * Clean up chunks by disconnecting unused modules.
+	 * @param {Compilation} compilation The webpack compilation instance.
+	 * @param {Set<Module>} modules Set of modules to clean up.
+	 */
+	cleanUpChunks(compilation, modules) {
+		const { chunkGraph } = compilation;
+		for (const module of modules) {
+			for (const chunk of chunkGraph.getModuleChunks(module)) {
+				if (!chunk.hasRuntime()) {
+					chunkGraph.disconnectChunkAndModule(chunk, module);
+					if (
+						chunkGraph.getNumberOfChunkModules(chunk) === 0 &&
+						chunkGraph.getNumberOfEntryModules(chunk) === 0
+					) {
+						chunkGraph.disconnectChunk(chunk);
+						compilation.chunks.delete(chunk);
+						if (chunk.name) {
+							compilation.namedChunks.delete(chunk.name);
+						}
+					}
+				}
+			}
+		}
+		modules.clear();
+	}
+}
+
+/**
+ * Helper method to collect all referenced modules recursively.
+ * @param {Compilation} compilation The webpack compilation instance.
+ * @param {Module} module The module to start collecting from.
+ * @param {string} type The type of modules to collect ("initial", "external", or "all").
+ * @param {boolean} includeInitial Should include the referenced module passed
+ * @returns {Set<Module>} Set of collected modules.
+ */
+function getAllReferencedModules(compilation, module, type, includeInitial) {
+	const collectedModules = new Set(includeInitial ? [module] : []);
+	/** @type {WeakSet<Module>} */
+	const visitedModules = new WeakSet([module]);
+	/** @type {Module[]} */
+	const stack = [module];
+
+	while (stack.length > 0) {
+		const currentModule = stack.pop();
+		if (!currentModule) continue;
+
+		const outgoingConnections =
+			compilation.moduleGraph.getOutgoingConnections(currentModule);
+		if (outgoingConnections) {
+			for (const connection of outgoingConnections) {
+				const connectedModule = connection.module;
+
+				// Skip if module has already been visited
+				if (!connectedModule || visitedModules.has(connectedModule)) {
+					continue;
+				}
+
+				// Handle 'initial' type (skipping async blocks)
+				if (type === "initial") {
+					const parentBlock = compilation.moduleGraph.getParentBlock(
+						/** @type {Dependency} */
+						(connection.dependency)
+					);
+					if (parentBlock instanceof AsyncDependenciesBlock) {
+						continue;
+					}
+				}
+
+				// Handle 'external' type (collecting only external modules)
+				if (type === "external") {
+					if (connection.module instanceof ExternalModule) {
+						collectedModules.add(connectedModule);
+					}
+				} else {
+					// Handle 'all' or unspecified types
+					collectedModules.add(connectedModule);
+				}
+
+				// Add connected module to the stack and mark it as visited
+				visitedModules.add(connectedModule);
+				stack.push(connectedModule);
+			}
+		}
+	}
+
+	return collectedModules;
+}
+
+module.exports = HoistContainerReferences;
Index: frontend/node_modules/webpack/lib/container/ModuleFederationPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/container/ModuleFederationPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/ModuleFederationPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,137 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const { SyncHook } = require("tapable");
+const isValidExternalsType = require("../../schemas/plugins/container/ExternalsType.check");
+const Compilation = require("../Compilation");
+const SharePlugin = require("../sharing/SharePlugin");
+const ContainerPlugin = require("./ContainerPlugin");
+const ContainerReferencePlugin = require("./ContainerReferencePlugin");
+const HoistContainerReferences = require("./HoistContainerReferencesPlugin");
+
+/** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").ExternalsType} ExternalsType */
+/** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").ModuleFederationPluginOptions} ModuleFederationPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+
+/**
+ * Defines the compilation hooks type used by this module.
+ * @typedef {object} CompilationHooks
+ * @property {SyncHook<Dependency>} addContainerEntryDependency
+ * @property {SyncHook<Dependency>} addFederationRuntimeDependency
+ */
+
+/** @type {WeakMap<Compilation, CompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+const PLUGIN_NAME = "ModuleFederationPlugin";
+
+class ModuleFederationPlugin {
+	/**
+	 * Creates an instance of ModuleFederationPlugin.
+	 * @param {ModuleFederationPluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {ModuleFederationPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Get the compilation hooks associated with this plugin.
+	 * @param {Compilation} compilation The compilation instance.
+	 * @returns {CompilationHooks} The hooks for the compilation.
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (!hooks) {
+			hooks = {
+				addContainerEntryDependency: new SyncHook(["dependency"]),
+				addFederationRuntimeDependency: new SyncHook(["dependency"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/container/ModuleFederationPlugin.json"),
+				this.options,
+				{
+					name: "Module Federation Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/container/ModuleFederationPlugin.check")(
+						options
+					)
+			);
+		});
+		const { options } = this;
+		const library = options.library || { type: "var", name: options.name };
+		const remoteType =
+			options.remoteType ||
+			(options.library && isValidExternalsType(options.library.type)
+				? /** @type {ExternalsType} */ (options.library.type)
+				: "script");
+		if (
+			library &&
+			!compiler.options.output.enabledLibraryTypes.includes(library.type)
+		) {
+			compiler.options.output.enabledLibraryTypes.push(library.type);
+		}
+		compiler.hooks.afterPlugins.tap(PLUGIN_NAME, () => {
+			if (
+				options.exposes &&
+				(Array.isArray(options.exposes)
+					? options.exposes.length > 0
+					: Object.keys(options.exposes).length > 0)
+			) {
+				new ContainerPlugin({
+					name: /** @type {string} */ (options.name),
+					library,
+					filename: options.filename,
+					runtime: options.runtime,
+					shareScope: options.shareScope,
+					exposes: options.exposes
+				}).apply(compiler);
+			}
+			if (
+				options.remotes &&
+				(Array.isArray(options.remotes)
+					? options.remotes.length > 0
+					: Object.keys(options.remotes).length > 0)
+			) {
+				new ContainerReferencePlugin({
+					remoteType,
+					shareScope: options.shareScope,
+					remotes: options.remotes
+				}).apply(compiler);
+			}
+			if (options.shared) {
+				new SharePlugin({
+					shared: options.shared,
+					shareScope: options.shareScope
+				}).apply(compiler);
+			}
+			new HoistContainerReferences().apply(compiler);
+		});
+	}
+}
+
+module.exports = ModuleFederationPlugin;
Index: frontend/node_modules/webpack/lib/container/RemoteModule.js
===================================================================
--- frontend/node_modules/webpack/lib/container/RemoteModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/RemoteModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,238 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Module = require("../Module");
+const {
+	JAVASCRIPT_TYPES,
+	REMOTE_AND_SHARE_INIT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { WEBPACK_MODULE_TYPE_REMOTE } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const FallbackDependency = require("./FallbackDependency");
+const RemoteToExternalDependency = require("./RemoteToExternalDependency");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NameForCondition} NameForCondition */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../Module").ExportsType} ExportsType */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../Module").BasicSourceTypes} BasicSourceTypes */
+
+const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
+
+/** @typedef {string[]} ExternalRequests */
+
+class RemoteModule extends Module {
+	/**
+	 * Creates an instance of RemoteModule.
+	 * @param {string} request request string
+	 * @param {ExternalRequests} externalRequests list of external requests to containers
+	 * @param {string} internalRequest name of exposed module in container
+	 * @param {string} shareScope the used share scope name
+	 */
+	constructor(request, externalRequests, internalRequest, shareScope) {
+		super(WEBPACK_MODULE_TYPE_REMOTE);
+		/** @type {string} */
+		this.request = request;
+		/** @type {ExternalRequests} */
+		this.externalRequests = externalRequests;
+		/** @type {string} */
+		this.internalRequest = internalRequest;
+		/** @type {string} */
+		this.shareScope = shareScope;
+		/** @type {string} */
+		this._identifier = `remote (${shareScope}) ${this.externalRequests.join(
+			" "
+		)} ${this.internalRequest}`;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this._identifier;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `remote ${this.request}`;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return `${this.layer ? `(${this.layer})/` : ""}webpack/container/remote/${
+			this.request
+		}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		callback(null, !this.buildInfo);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {
+			strict: true
+		};
+
+		this.clearDependenciesAndBlocks();
+		if (this.externalRequests.length === 1) {
+			this.addDependency(
+				new RemoteToExternalDependency(this.externalRequests[0])
+			);
+		} else {
+			this.addDependency(new FallbackDependency(this.externalRequests));
+		}
+
+		callback();
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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 6;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return REMOTE_AND_SHARE_INIT_TYPES;
+	}
+
+	/**
+	 * Basic source types are high-level categories like javascript, css, webassembly, etc.
+	 * We only have built-in knowledge about the javascript basic type here; other basic types may be
+	 * added or changed over time by generators and do not need to be handled or detected here.
+	 *
+	 * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
+	 * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
+	 * @returns {BasicSourceTypes} types available (do not mutate)
+	 */
+	getSourceBasicTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns export type.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {boolean | undefined} strict the importing module is strict
+	 * @returns {ExportsType} export type
+	 * "namespace": Exports is already a namespace object. namespace = exports.
+	 * "dynamic": Check at runtime if __esModule is set. When set: namespace = { ...exports, default: exports }. When not set: namespace = { default: exports }.
+	 * "default-only": Provide a namespace object with only default export. namespace = { default: exports }
+	 * "default-with-named": Provide a namespace object with named and default export. namespace = { ...exports, default: exports }
+	 */
+	getExportsType(moduleGraph, strict) {
+		return "dynamic";
+	}
+
+	/**
+	 * Returns the path used when matching this module against rule conditions.
+	 * @returns {NameForCondition | null} absolute path which should be used for condition matching (usually the resource path)
+	 */
+	nameForCondition() {
+		return this.request;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({ moduleGraph, chunkGraph }) {
+		const module = moduleGraph.getModule(this.dependencies[0]);
+		const id = module && chunkGraph.getModuleId(module);
+		/** @type {Sources} */
+		const sources = new Map();
+		sources.set("remote", new RawSource(""));
+		/** @type {CodeGenerationResultData} */
+		const data = new Map();
+		data.set("share-init", [
+			{
+				shareScope: this.shareScope,
+				initStage: 20,
+				init: id === undefined ? "" : `initExternal(${JSON.stringify(id)});`
+			}
+		]);
+		return { sources, data, runtimeRequirements: RUNTIME_REQUIREMENTS };
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.request);
+		write(this.externalRequests);
+		write(this.internalRequest);
+		write(this.shareScope);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {RemoteModule} deserialized module
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		const obj = new RemoteModule(read(), read(), read(), read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(RemoteModule, "webpack/lib/container/RemoteModule");
+
+module.exports = RemoteModule;
Index: frontend/node_modules/webpack/lib/container/RemoteRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/container/RemoteRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/RemoteRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,145 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("./RemoteModule")} RemoteModule */
+
+class RemoteRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("remotes loading");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const { runtimeTemplate, moduleGraph } = compilation;
+		/** @type {Record<ChunkId, ModuleId[]>} */
+		const chunkToRemotesMapping = {};
+		/** @type {Record<ModuleId, [string, string, ModuleId]>} */
+		const idToExternalAndNameMapping = {};
+		for (const chunk of /** @type {Chunk} */ (
+			this.chunk
+		).getAllReferencedChunks()) {
+			const modules = chunkGraph.getChunkModulesIterableBySourceType(
+				chunk,
+				"remote"
+			);
+			if (!modules) continue;
+			/** @type {ModuleId[]} */
+			const remotes = (chunkToRemotesMapping[
+				/** @type {ChunkId} */
+				(chunk.id)
+			] = []);
+			for (const m of modules) {
+				const module = /** @type {RemoteModule} */ (m);
+				const name = module.internalRequest;
+				const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+				const shareScope = module.shareScope;
+				const dep = module.dependencies[0];
+				const externalModule = moduleGraph.getModule(dep);
+				const externalModuleId =
+					/** @type {ModuleId} */
+					(externalModule && chunkGraph.getModuleId(externalModule));
+				remotes.push(id);
+				idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId];
+			}
+		}
+		return Template.asString([
+			`var chunkMapping = ${JSON.stringify(
+				chunkToRemotesMapping,
+				null,
+				"\t"
+			)};`,
+			`var idToExternalAndNameMapping = ${JSON.stringify(
+				idToExternalAndNameMapping,
+				null,
+				"\t"
+			)};`,
+			`${
+				RuntimeGlobals.ensureChunkHandlers
+			}.remotes = ${runtimeTemplate.basicFunction("chunkId, promises", [
+				`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
+				Template.indent([
+					`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction("id", [
+						`var getScope = ${RuntimeGlobals.currentRemoteGetScope};`,
+						"if(!getScope) getScope = [];",
+						"var data = idToExternalAndNameMapping[id];",
+						"if(getScope.indexOf(data) >= 0) return;",
+						"getScope.push(data);",
+						"if(data.p) return promises.push(data.p);",
+						`var onError = ${runtimeTemplate.basicFunction("error", [
+							'if(!error) error = new Error("Container missing");',
+							'if(typeof error.message === "string")',
+							Template.indent(
+								"error.message += '\\nwhile loading \"' + data[1] + '\" from ' + data[2];"
+							),
+							`${
+								RuntimeGlobals.moduleFactories
+							}[id] = ${runtimeTemplate.basicFunction("", ["throw error;"])}`,
+							"data.p = 0;"
+						])};`,
+						`var handleFunction = ${runtimeTemplate.basicFunction(
+							"fn, arg1, arg2, d, next, first",
+							[
+								"try {",
+								Template.indent([
+									"var promise = fn(arg1, arg2);",
+									"if(promise && promise.then) {",
+									Template.indent([
+										`var p = promise.then(${runtimeTemplate.returningFunction(
+											"next(result, d)",
+											"result"
+										)}, onError);`,
+										"if(first) promises.push(data.p = p); else return p;"
+									]),
+									"} else {",
+									Template.indent(["return next(promise, d, first);"]),
+									"}"
+								]),
+								"} catch(error) {",
+								Template.indent(["onError(error);"]),
+								"}"
+							]
+						)}`,
+						`var onExternal = ${runtimeTemplate.returningFunction(
+							`external ? handleFunction(${RuntimeGlobals.initializeSharing}, data[0], 0, external, onInitialized, first) : onError()`,
+							"external, _, first"
+						)};`,
+						`var onInitialized = ${runtimeTemplate.returningFunction(
+							"handleFunction(external.get, data[1], getScope, 0, onFactory, first)",
+							"_, external, first"
+						)};`,
+						`var onFactory = ${runtimeTemplate.basicFunction("factory", [
+							"data.p = 1;",
+							`${
+								RuntimeGlobals.moduleFactories
+							}[id] = ${runtimeTemplate.basicFunction("module", [
+								"module.exports = factory();"
+							])}`
+						])};`,
+						`handleFunction(${RuntimeGlobals.require}, data[2], 0, 0, onExternal, 1);`
+					])});`
+				]),
+				"}"
+			])}`
+		]);
+	}
+}
+
+module.exports = RemoteRuntimeModule;
Index: frontend/node_modules/webpack/lib/container/RemoteToExternalDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/container/RemoteToExternalDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/RemoteToExternalDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+class RemoteToExternalDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of RemoteToExternalDependency.
+	 * @param {string} request request
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "remote to external";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	RemoteToExternalDependency,
+	"webpack/lib/container/RemoteToExternalDependency"
+);
+
+module.exports = RemoteToExternalDependency;
Index: frontend/node_modules/webpack/lib/container/options.js
===================================================================
--- frontend/node_modules/webpack/lib/container/options.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/container/options.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,112 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Defines the item type used by this module.
+ * @template T
+ * @typedef {Record<string, string | string[] | T>} Item
+ */
+
+/**
+ * Defines the container options format type used by this module.
+ * @template T
+ * @typedef {(string | Item<T>)[] | Item<T>} ContainerOptionsFormat
+ */
+
+/**
+ * Processes the provided t.
+ * @template T
+ * @template N
+ * @param {ContainerOptionsFormat<T>} options options passed by the user
+ * @param {(item: string | string[], itemOrKey: string) => N} normalizeSimple normalize a simple item
+ * @param {(value: T, key: string) => N} normalizeOptions normalize a complex item
+ * @param {(item: string, normalized: N) => void} fn processing function
+ * @returns {void}
+ */
+const process = (options, normalizeSimple, normalizeOptions, fn) => {
+	/**
+	 * Processes the provided item.
+	 * @param {(string | Item<T>)[]} items items
+	 */
+	const array = (items) => {
+		for (const item of items) {
+			if (typeof item === "string") {
+				fn(item, normalizeSimple(item, item));
+			} else if (item && typeof item === "object") {
+				object(item);
+			} else {
+				throw new Error("Unexpected options format");
+			}
+		}
+	};
+	/**
+	 * Processes the provided obj.
+	 * @param {Item<T>} obj an object
+	 */
+	const object = (obj) => {
+		for (const [key, value] of Object.entries(obj)) {
+			if (typeof value === "string" || Array.isArray(value)) {
+				fn(key, normalizeSimple(value, key));
+			} else {
+				fn(key, normalizeOptions(value, key));
+			}
+		}
+	};
+	if (!options) {
+		// Do nothing
+	} else if (Array.isArray(options)) {
+		array(options);
+	} else if (typeof options === "object") {
+		object(options);
+	} else {
+		throw new Error("Unexpected options format");
+	}
+};
+
+/**
+ * Returns parsed options.
+ * @template T
+ * @template R
+ * @param {ContainerOptionsFormat<T>} options options passed by the user
+ * @param {(item: string | string[], itemOrKey: string) => R} normalizeSimple normalize a simple item
+ * @param {(value: T, key: string) => R} normalizeOptions normalize a complex item
+ * @returns {[string, R][]} parsed options
+ */
+const parseOptions = (options, normalizeSimple, normalizeOptions) => {
+	/** @type {[string, R][]} */
+	const items = [];
+	process(options, normalizeSimple, normalizeOptions, (key, value) => {
+		items.push([key, value]);
+	});
+	return items;
+};
+
+/**
+ * Returns options to spread or pass.
+ * @template T
+ * @param {string} scope scope name
+ * @param {ContainerOptionsFormat<T>} options options passed by the user
+ * @returns {Record<string, string | string[] | T>} options to spread or pass
+ */
+const scope = (scope, options) => {
+	/** @type {Record<string, string | string[] | T>} */
+	const obj = {};
+	process(
+		options,
+		(item) => /** @type {string | string[] | T} */ (item),
+		(item) => /** @type {string | string[] | T} */ (item),
+		(key, value) => {
+			obj[
+				key.startsWith("./") ? `${scope}${key.slice(1)}` : `${scope}/${key}`
+			] = value;
+		}
+	);
+	return obj;
+};
+
+module.exports.parseOptions = parseOptions;
+module.exports.scope = scope;
Index: frontend/node_modules/webpack/lib/css/CssGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/css/CssGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/CssGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,937 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const {
+	ConcatSource,
+	OriginalSource,
+	RawSource,
+	ReplaceSource,
+	SourceMapSource
+} = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const Generator = require("../Generator");
+const InitFragment = require("../InitFragment");
+const {
+	CSS_TEXT_TYPE,
+	CSS_TEXT_TYPES,
+	CSS_TYPE,
+	CSS_TYPES,
+	JAVASCRIPT_AND_CSS_TEXT_TYPES,
+	JAVASCRIPT_AND_CSS_TYPES,
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const CssImportDependency = require("../dependencies/CssImportDependency");
+const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
+
+const { encodeMappings } = require("../util/createMappings");
+const memoize = require("../util/memoize");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */
+/** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").CssData} CssData */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("./CssModulesPlugin").ModuleFactoryCacheEntry} ModuleFactoryCacheEntry */
+/** @typedef {import("./CssModule")} CssModule */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../../declarations/WebpackOptions").CssParserExportType} CssParserExportType */
+
+/** @typedef {{ line: number, column: number }} SourcePosition */
+/** @typedef {Map<string, SourcePosition>} ExportLocsMap */
+
+const getPropertyName = memoize(() => require("../util/property"));
+const getCssModulesPlugin = memoize(() => require("./CssModulesPlugin"));
+
+/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
+
+/**
+ * Build a v3 source map that maps each line in `generatedJs` containing a
+ * known CSS-class export entry back to the corresponding selector position
+ * in the original CSS. Lines without an associated export are left
+ * unmapped — devtools simply shows them as part of the bundled JS.
+ * @param {string} generatedJs the generated JS string
+ * @param {ExportLocsMap} exportLocs map of export names to CSS source location
+ * @param {string} cssContent original CSS source content
+ * @param {string} sourceName source identifier to use in the map
+ * @returns {RawSourceMap} a v3 RawSourceMap
+ */
+const buildExportsSourceMap = (
+	generatedJs,
+	exportLocs,
+	cssContent,
+	sourceName
+) => {
+	const lines = generatedJs.split("\n");
+
+	const lineByExport = new Map();
+	for (const [exportName] of exportLocs) {
+		const needle = `${JSON.stringify(exportName)}:`;
+		for (let i = 0; i < lines.length; i++) {
+			if (lines[i].includes(needle)) {
+				lineByExport.set(exportName, i);
+				break;
+			}
+		}
+	}
+
+	/** @type {(import("../util/createMappings").LineMappings)[]} */
+	const perLine = lines.map(() => null);
+	for (const [exportName, genLine] of lineByExport) {
+		const pos = /** @type {SourcePosition} */ (exportLocs.get(exportName));
+		// Source-map V3 uses 0-based lines and 0-based columns. webpack's
+		// dependency `loc` uses 1-based lines and 0-based columns, so subtract
+		// one from the line.
+		perLine[genLine] = {
+			generatedColumn: 0,
+			sourceIndex: 0,
+			originalLine: pos.line - 1,
+			originalColumn: pos.column
+		};
+	}
+
+	return {
+		version: 3,
+		file: "",
+		sources: [sourceName],
+		sourcesContent: [cssContent],
+		names: [],
+		mappings: encodeMappings(perLine)
+	};
+};
+
+class CssGenerator extends Generator {
+	/**
+	 * Creates an instance of CssGenerator.
+	 * @param {CssModuleGeneratorOptions} options options
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 */
+	constructor(options, moduleGraph) {
+		super();
+		this.options = options;
+		this._exportsOnly = options.exportsOnly;
+		this._esModule = options.esModule;
+		this._moduleGraph = moduleGraph;
+		/** @type {WeakMap<Source, ModuleFactoryCacheEntry>} */
+		this._moduleFactoryCache = new WeakMap();
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		if (!this._esModule) {
+			return "Module is not an ECMAScript module";
+		}
+
+		return undefined;
+	}
+
+	/**
+	 * Returns the `@charset` that will appear at the start of this module's
+	 * default export, walking through text imports when the module has no
+	 * local `@charset` of its own.
+	 * @param {NormalModule} module the module
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {WeakSet<NormalModule>=} visited cycle guard
+	 * @returns {string | undefined} the effective charset
+	 */
+	_getEffectiveCharset(module, moduleGraph, visited = new WeakSet()) {
+		if (!module || visited.has(module)) return undefined;
+		const exportType = /** @type {CssModule} */ (module).exportType;
+		if (exportType !== "text" && exportType !== "css-style-sheet") {
+			return undefined;
+		}
+		visited.add(module);
+		const own =
+			module.buildInfo && /** @type {BuildInfo} */ (module.buildInfo).charset;
+		if (own !== undefined) return own;
+		if (exportType !== "text") return undefined;
+		for (const dep of module.dependencies) {
+			if (dep instanceof CssImportDependency) {
+				const depModule = /** @type {NormalModule} */ (
+					moduleGraph.getModule(dep)
+				);
+				const inherited = this._getEffectiveCharset(
+					depModule,
+					moduleGraph,
+					visited
+				);
+				if (inherited !== undefined) return inherited;
+			}
+		}
+		return undefined;
+	}
+
+	/**
+	 * Generate JavaScript expressions that evaluate each `@import`'d module
+	 * for side effects. Only used by `style` exportType, where each imported
+	 * style module injects its own `<style>` element independently — no
+	 * content merging happens at the parent. `text` and `css-style-sheet`
+	 * instead inline their imports at build time via
+	 * {@link CssGenerator#_generateMergedContentSource}.
+	 * @param {NormalModule} module the module to generate CSS text for
+	 * @param {GenerateContext} generateContext the generate context
+	 * @returns {string[]} JS expressions, one per `@import` dependency
+	 */
+	_generateImportSideEffects(module, generateContext) {
+		const { moduleGraph, concatenationScope } = generateContext;
+		const parts = [];
+
+		for (const dep of module.dependencies) {
+			if (!(dep instanceof CssImportDependency)) continue;
+			const depModule = /** @type {CssModule} */ (moduleGraph.getModule(dep));
+			// Concat-scoped deps are inlined into the same module; their side
+			// effect (own `<style>` injection) is emitted at the dep's own
+			// site, so no explicit reference is needed here.
+			if (concatenationScope && concatenationScope.isModuleInScope(depModule)) {
+				continue;
+			}
+			parts.push(
+				generateContext.runtimeTemplate.moduleExports({
+					module: depModule,
+					chunkGraph: generateContext.chunkGraph,
+					request: depModule.userRequest,
+					weak: false,
+					runtimeRequirements: generateContext.runtimeRequirements
+				})
+			);
+		}
+
+		return parts;
+	}
+
+	/**
+	 * Build a single CSS `Source` that contains, in source order, the rendered
+	 * CSS text of every transitively `@import`'d module followed by the
+	 * current module's own CSS text. Imports are inlined at build time so
+	 * the resulting `Source` carries a single, accurate source map covering
+	 * every contributing file — no runtime merge helper required.
+	 *
+	 * Only `text` / `css-style-sheet` imports contribute CSS text; `link` and
+	 * `style` imports are emitted separately (own `.css` file or own
+	 * `<style>` injection) and are skipped here.
+	 *
+	 * `ancestors` tracks the path from the top-level caller down to the
+	 * current module — not every module ever visited. A module reappearing
+	 * along a sibling branch (a "diamond import" like two different files
+	 * each `@import`'ing the same shared module) must be inlined every time,
+	 * matching the prior runtime behavior where each `default` getter was
+	 * invoked at every import site.
+	 * @param {NormalModule} module the module to render
+	 * @param {GenerateContext} generateContext the generate context
+	 * @param {Set<NormalModule>} ancestors modules on the current path
+	 * @returns {Source | null} merged CSS source, or null when the module has no content
+	 */
+	_generateMergedContentSource(module, generateContext, ancestors) {
+		if (ancestors.has(module)) return null;
+		ancestors.add(module);
+		try {
+			const { moduleGraph } = generateContext;
+			/** @type {Source[]} */
+			const parts = [];
+
+			for (const dep of module.dependencies) {
+				if (!(dep instanceof CssImportDependency)) continue;
+				const depModule = /** @type {CssModule} */ (moduleGraph.getModule(dep));
+				if (!depModule) continue;
+				const depExportType = depModule.exportType;
+				if (depExportType !== "text" && depExportType !== "css-style-sheet") {
+					continue;
+				}
+				const depMerged = this._generateMergedContentSource(
+					depModule,
+					generateContext,
+					ancestors
+				);
+				if (depMerged) parts.push(depMerged);
+			}
+
+			const own = this._generateContentSource(module, generateContext);
+			if (own) parts.push(own);
+
+			if (parts.length === 0) return null;
+			if (parts.length === 1) return parts[0];
+			return new ConcatSource(...parts);
+		} finally {
+			ancestors.delete(module);
+		}
+	}
+
+	/**
+	 * Generate CSS source for the current module
+	 * @param {NormalModule} module the module to generate CSS source for
+	 * @param {GenerateContext} generateContext the generate context
+	 * @returns {Source | null} the CSS source
+	 */
+	_generateContentSource(module, generateContext) {
+		const moduleSourceContent = /** @type {Source} */ (
+			this.generate(module, {
+				...generateContext,
+				type: CSS_TYPE
+			})
+		);
+
+		if (!moduleSourceContent) {
+			return null;
+		}
+
+		const compilation = generateContext.runtimeTemplate.compilation;
+		// For non-link exportTypes (style, text, css-style-sheet), url() in the CSS
+		// is resolved relative to the document URL (for <style> tags and CSSStyleSheet),
+		// not relative to any output file. Use empty undoPath so urls are relative to
+		// the output root.
+		const undoPath = "";
+
+		const CssModulesPlugin = getCssModulesPlugin();
+		const hooks = CssModulesPlugin.getCompilationHooks(compilation);
+		return CssModulesPlugin.renderModule(
+			/** @type {CssModule} */ (module),
+			{
+				undoPath,
+				moduleSourceContent,
+				moduleFactoryCache: this._moduleFactoryCache,
+				runtimeTemplate: generateContext.runtimeTemplate
+			},
+			hooks
+		);
+	}
+
+	/**
+	 * Serialize a CSS Source into a JS string literal with an optional
+	 * inline `sourceMappingURL` data URI so DevTools can resolve the
+	 * original sources at runtime.
+	 * @param {Source} cssSource the CSS source
+	 * @param {import("../../declarations/WebpackOptions").DevTool | undefined} devtool the devtool option
+	 * @returns {Source} a Source representing a JS string literal
+	 */
+	_cssToJsLiteral(cssSource, devtool) {
+		const { source, map } = cssSource.sourceAndMap();
+		let content = /** @type {string} */ (source);
+		if (map) {
+			const inlineMap =
+				typeof devtool === "string" && devtool.includes("nosources")
+					? { ...map, sourcesContent: undefined }
+					: map;
+			const base64Map = Buffer.from(JSON.stringify(inlineMap), "utf8").toString(
+				"base64"
+			);
+			const trailingNewline = content.endsWith("\n") ? "" : "\n";
+			content += `${trailingNewline}/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}*/`;
+		}
+		return new RawSource(JSON.stringify(content));
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {NormalModule} module the current module
+	 * @param {Dependency} dependency the dependency to generate
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext & { cssData: CssData }} generateContext the render context
+	 * @returns {void}
+	 */
+	sourceDependency(module, dependency, initFragments, source, generateContext) {
+		const constructor =
+			/** @type {DependencyConstructor} */
+			(dependency.constructor);
+		const template = generateContext.dependencyTemplates.get(constructor);
+		if (!template) {
+			throw new Error(
+				`No template for dependency: ${dependency.constructor.name}`
+			);
+		}
+
+		/** @type {DependencyTemplateContext} */
+		/** @type {InitFragment<GenerateContext>[] | undefined} */
+		let chunkInitFragments;
+		/** @type {DependencyTemplateContext} */
+		const templateContext = {
+			runtimeTemplate: generateContext.runtimeTemplate,
+			dependencyTemplates: generateContext.dependencyTemplates,
+			moduleGraph: generateContext.moduleGraph,
+			chunkGraph: generateContext.chunkGraph,
+			module,
+			runtime: generateContext.runtime,
+			runtimeRequirements: generateContext.runtimeRequirements,
+			concatenationScope: generateContext.concatenationScope,
+			codeGenerationResults:
+				/** @type {CodeGenerationResults} */
+				(generateContext.codeGenerationResults),
+			initFragments,
+			cssData: generateContext.cssData,
+			type: generateContext.type,
+			get chunkInitFragments() {
+				if (!chunkInitFragments) {
+					const data =
+						/** @type {NonNullable<GenerateContext["getData"]>} */
+						(generateContext.getData)();
+					chunkInitFragments = data.get("chunkInitFragments");
+					if (!chunkInitFragments) {
+						chunkInitFragments = [];
+						data.set("chunkInitFragments", chunkInitFragments);
+					}
+				}
+
+				return chunkInitFragments;
+			}
+		};
+
+		template.apply(dependency, source, templateContext);
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {NormalModule} module the module to generate
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext & { cssData: CssData }} generateContext the generateContext
+	 * @returns {void}
+	 */
+	sourceModule(module, initFragments, source, generateContext) {
+		for (const dependency of module.dependencies) {
+			this.sourceDependency(
+				module,
+				dependency,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+
+		if (module.presentationalDependencies !== undefined) {
+			for (const dependency of module.presentationalDependencies) {
+				this.sourceDependency(
+					module,
+					dependency,
+					initFragments,
+					source,
+					generateContext
+				);
+			}
+		}
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const exportType = /** @type {CssModule} */ (module).exportType || "link";
+		const source =
+			generateContext.type === JAVASCRIPT_TYPE && exportType === "link"
+				? new ReplaceSource(new RawSource(""))
+				: new ReplaceSource(/** @type {Source} */ (module.originalSource()));
+		/** @type {InitFragment<GenerateContext>[]} */
+		const initFragments = [];
+		/** @type {CssData} */
+		const cssData = {
+			esModule: /** @type {boolean} */ (this._esModule),
+			exports: new Map(),
+			exportLocs: new Map()
+		};
+
+		this.sourceModule(module, initFragments, source, {
+			...generateContext,
+			cssData
+		});
+
+		switch (generateContext.type) {
+			case JAVASCRIPT_TYPE: {
+				const compilation = generateContext.runtimeTemplate.compilation;
+				const devtool = compilation.options.devtool;
+				const isCssModule = /** @type {BuildMeta} */ (module.buildMeta)
+					.isCssModule;
+
+				const generateContentCode = () => {
+					switch (exportType) {
+						case "style": {
+							const cssSource = this._generateContentSource(
+								module,
+								generateContext
+							);
+							if (!cssSource) return "";
+
+							generateContext.runtimeRequirements.add(
+								RuntimeGlobals.cssInjectStyle
+							);
+
+							const moduleId = generateContext.chunkGraph.getModuleId(module);
+
+							if (generateContext.concatenationScope) {
+								return new ConcatSource(
+									`__webpack_css_styles__.push([${JSON.stringify(moduleId)}, `,
+									this._cssToJsLiteral(cssSource, devtool),
+									"]);"
+								);
+							}
+
+							return new ConcatSource(
+								`${RuntimeGlobals.cssInjectStyle}(${JSON.stringify(moduleId)}, `,
+								this._cssToJsLiteral(cssSource, devtool),
+								");"
+							);
+						}
+
+						default:
+							return "";
+					}
+				};
+				const generateImportCode = () => {
+					switch (exportType) {
+						case "style": {
+							return this._generateImportSideEffects(module, generateContext)
+								.map((expr) => `${expr};`)
+								.join("\n");
+						}
+						default:
+							return "";
+					}
+				};
+				const generateExportCode = () => {
+					/** @returns {Source} generated CSS text as JS expression */
+					const generateCssText = () => {
+						const cssSource = this._generateMergedContentSource(
+							module,
+							generateContext,
+							new Set()
+						);
+
+						let jsLiteral = cssSource
+							? this._cssToJsLiteral(cssSource, devtool)
+							: new RawSource('""');
+
+						const effectiveCharset =
+							exportType === "css-style-sheet" || exportType === "text"
+								? this._getEffectiveCharset(module, generateContext.moduleGraph)
+								: undefined;
+						if (effectiveCharset !== undefined) {
+							jsLiteral = new ConcatSource(
+								`'@charset "${effectiveCharset}";\\n' + `,
+								jsLiteral
+							);
+						}
+
+						return jsLiteral;
+					};
+					/**
+					 * Generates js default export.
+					 * @returns {Source | null} the default export
+					 */
+					const generateJSDefaultExport = () => {
+						switch (exportType) {
+							case "text": {
+								return generateCssText();
+							}
+							case "css-style-sheet": {
+								// Build a constructable stylesheet from the statically
+								// merged CSS text. The merged literal carries a single
+								// inline source map covering every contributing module.
+								const fnPrefix =
+									generateContext.runtimeTemplate.supportsArrowFunction()
+										? "() => {\n"
+										: "function() {\n";
+								const constOrVar =
+									generateContext.runtimeTemplate.renderConst();
+								return new ConcatSource(
+									`(${fnPrefix}${constOrVar} sheet = new CSSStyleSheet();\nsheet.replaceSync(`,
+									generateCssText(),
+									");\nreturn sheet;\n})()"
+								);
+							}
+							default:
+								return null;
+						}
+					};
+
+					/** @type {Source | null} */
+					const defaultExport = generateJSDefaultExport();
+
+					/** @type {BuildInfo} */
+					(module.buildInfo).cssData = cssData;
+
+					// Required for HMR
+					if (module.hot) {
+						generateContext.runtimeRequirements.add(RuntimeGlobals.module);
+					}
+
+					if (!defaultExport && cssData.exports.size === 0 && !isCssModule) {
+						return new RawSource("");
+					}
+
+					if (generateContext.concatenationScope) {
+						const source = new ConcatSource();
+						/** @type {Set<string>} */
+						const usedIdentifiers = new Set();
+						const { RESERVED_IDENTIFIER } = getPropertyName();
+
+						if (defaultExport) {
+							const usedName = generateContext.moduleGraph
+								.getExportInfo(module, "default")
+								.getUsedName("default", generateContext.runtime);
+							if (usedName) {
+								let identifier = Template.toIdentifier(usedName);
+								if (RESERVED_IDENTIFIER.has(identifier)) {
+									identifier = `_${identifier}`;
+								}
+								usedIdentifiers.add(identifier);
+								generateContext.concatenationScope.registerExport(
+									"default",
+									identifier
+								);
+								source.add(
+									`${generateContext.runtimeTemplate.renderConst()} ${identifier} = `
+								);
+								source.add(defaultExport);
+								source.add(";\n");
+							}
+						}
+
+						for (const [name, v] of cssData.exports) {
+							const usedName = generateContext.moduleGraph
+								.getExportInfo(module, name)
+								.getUsedName(name, generateContext.runtime);
+							if (!usedName) {
+								continue;
+							}
+
+							let identifier = Template.toIdentifier(usedName);
+							if (RESERVED_IDENTIFIER.has(identifier)) {
+								identifier = `_${identifier}`;
+							}
+							let i = 0;
+							while (usedIdentifiers.has(identifier)) {
+								identifier = Template.toIdentifier(name + i);
+								i += 1;
+							}
+							usedIdentifiers.add(identifier);
+							generateContext.concatenationScope.registerExport(
+								name,
+								identifier
+							);
+							source.add(
+								`${generateContext.runtimeTemplate.renderConst()} ${identifier} = ${JSON.stringify(v)};\n`
+							);
+						}
+						return source;
+					}
+
+					const needNsObj =
+						this._esModule &&
+						generateContext.moduleGraph
+							.getExportsInfo(module)
+							.otherExportsInfo.getUsed(generateContext.runtime) !==
+							UsageState.Unused;
+
+					if (needNsObj) {
+						generateContext.runtimeRequirements.add(
+							RuntimeGlobals.makeNamespaceObject
+						);
+					}
+
+					// Should be after `concatenationScope` to allow module inlining
+					generateContext.runtimeRequirements.add(RuntimeGlobals.module);
+
+					if (!isCssModule && !needNsObj) {
+						return new ConcatSource(
+							`${module.moduleArgument}.exports = `,
+							/** @type {Source} */ (defaultExport)
+						);
+					}
+
+					const result = new ConcatSource();
+					result.add(
+						`${needNsObj ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${
+							module.moduleArgument
+						}.exports = {\n`
+					);
+
+					if (defaultExport) {
+						result.add('\t"default": ');
+						result.add(defaultExport);
+						if (cssData.exports.size > 0) {
+							result.add(",\n");
+						}
+					}
+
+					/** @type {string[]} */
+					const exportEntries = [];
+					for (const [name, v] of cssData.exports) {
+						exportEntries.push(
+							`\t${JSON.stringify(name)}: ${JSON.stringify(v)}`
+						);
+					}
+					if (exportEntries.length > 0) {
+						result.add(exportEntries.join(",\n"));
+					}
+
+					result.add(`\n}${needNsObj ? ")" : ""};`);
+					return result;
+				};
+
+				const codeParts = this._exportsOnly
+					? [generateExportCode()]
+					: [generateImportCode(), generateContentCode(), generateExportCode()];
+
+				const source = new ConcatSource();
+				for (const part of codeParts) {
+					if (part) {
+						source.add(part);
+						source.add("\n");
+					}
+				}
+				// For link-type modules without any JS emit, skip source wrapping
+				if (
+					exportType === "link" &&
+					!isCssModule &&
+					cssData.exports.size === 0
+				) {
+					return source;
+				}
+
+				const generatedJs = /** @type {string} */ (source.source());
+				const sourceName = module.readableIdentifier(
+					compilation.requestShortener
+				);
+
+				// When per-export source positions are available, emit a
+				// SourceMapSource mapping each export line back to its CSS
+				// selector; otherwise fall back to OriginalSource.
+				if (
+					/** @type {ExportLocsMap} */
+					(cssData.exportLocs).size > 0
+				) {
+					const cssOriginal = module.originalSource();
+					if (cssOriginal) {
+						const sourceMap = buildExportsSourceMap(
+							generatedJs,
+							/** @type {ExportLocsMap} */
+							(cssData.exportLocs),
+							/** @type {string} */ (cssOriginal.source()),
+							sourceName
+						);
+						return new SourceMapSource(generatedJs, sourceName, sourceMap);
+					}
+				}
+				return new OriginalSource(generatedJs, sourceName);
+			}
+			case CSS_TYPE: {
+				if (!(this._exportsOnly || (exportType && exportType !== "link"))) {
+					generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules);
+				}
+
+				return InitFragment.addToSource(source, initFragments, generateContext);
+			}
+			case CSS_TEXT_TYPE: {
+				// The merged CSS text — what consumers like
+				// `HtmlInlineStyleDependency.Template` need when they want to
+				// drop the processed CSS straight into an inline `<style>`
+				// tag. Mirrors the JS-side `generateCssText()` (charset
+				// prefix included), without the JS string-literal wrapper.
+				const cssSource = this._generateMergedContentSource(
+					module,
+					generateContext,
+					new Set()
+				);
+
+				const effectiveCharset = this._getEffectiveCharset(
+					module,
+					generateContext.moduleGraph
+				);
+				const charsetPrefix =
+					effectiveCharset !== undefined
+						? `@charset "${effectiveCharset}";\n`
+						: "";
+
+				if (!cssSource) {
+					return charsetPrefix
+						? new RawSource(charsetPrefix)
+						: new RawSource("");
+				}
+				return charsetPrefix
+					? new ConcatSource(charsetPrefix, cssSource)
+					: cssSource;
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		switch (generateContext.type) {
+			case JAVASCRIPT_TYPE: {
+				return new RawSource(
+					`throw new Error(${JSON.stringify(error.message)});`
+				);
+			}
+			case CSS_TYPE: {
+				return new RawSource(`/**\n ${error.message} \n**/`);
+			}
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		const exportType = /** @type {CssModule} */ (module).exportType || "link";
+		if (exportType === "style") {
+			return JAVASCRIPT_TYPES;
+		}
+
+		const sourceTypes = new Set();
+		const connections = this._moduleGraph.getIncomingConnections(module);
+
+		for (const connection of connections) {
+			if (
+				exportType === "link" &&
+				connection.dependency instanceof CssImportDependency
+			) {
+				continue;
+			}
+
+			// when no hmr required, css module js output contains no sideEffects at all
+			// js sideeffect connection doesn't require js type output
+			if (connection.dependency instanceof HarmonyImportSideEffectDependency) {
+				continue;
+			}
+
+			// Inline `<style>` blocks in HTML modules read the merged CSS
+			// text directly via the `css-text` source type — they don't go
+			// through the JS-string wrapper that other consumers use.
+			// Matched by dependency category so the CSS package doesn't
+			// have to import HtmlInlineStyleDependency.
+			if (
+				connection.dependency &&
+				connection.dependency.category === "html-style"
+			) {
+				sourceTypes.add(CSS_TEXT_TYPE);
+				continue;
+			}
+
+			if (!connection.originModule) {
+				continue;
+			}
+
+			if (connection.originModule.type.split("/")[0] !== CSS_TYPE) {
+				sourceTypes.add(JAVASCRIPT_TYPE);
+			} else {
+				const originModule = /** @type {CssModule} */ connection.originModule;
+				const originExportType = /** @type {CssModule} */ (originModule)
+					.exportType;
+				if (
+					/** @type {boolean} */ (
+						originExportType && originExportType !== "link"
+					)
+				) {
+					sourceTypes.add(JAVASCRIPT_TYPE);
+				}
+			}
+		}
+		if (
+			this._exportsOnly ||
+			/** @type {boolean} */ (exportType && exportType !== "link")
+		) {
+			const hasJs = sourceTypes.has(JAVASCRIPT_TYPE);
+			const hasCssText = sourceTypes.has(CSS_TEXT_TYPE);
+			if (hasJs && hasCssText) return JAVASCRIPT_AND_CSS_TEXT_TYPES;
+			if (hasJs) return JAVASCRIPT_TYPES;
+			if (hasCssText) return CSS_TEXT_TYPES;
+			return new Set();
+		}
+		if (sourceTypes.has(JAVASCRIPT_TYPE)) {
+			return JAVASCRIPT_AND_CSS_TYPES;
+		}
+		return CSS_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		switch (type) {
+			case JAVASCRIPT_TYPE: {
+				const cssData = /** @type {BuildInfo} */ (module.buildInfo).cssData;
+				if (!cssData) {
+					return 42;
+				}
+				if (cssData.exports.size === 0) {
+					if (/** @type {BuildMeta} */ (module.buildMeta).isCssModule) {
+						return 42;
+					}
+					return 0;
+				}
+				const exports = cssData.exports;
+				/** @type {Record<string, string>} */
+				const exportsObj = {};
+				for (const [key, value] of exports) {
+					exportsObj[key] = value;
+				}
+				const stringifiedExports = JSON.stringify(exportsObj);
+
+				return stringifiedExports.length + 42;
+			}
+			case CSS_TYPE: {
+				const originalSource = module.originalSource();
+
+				if (!originalSource) {
+					return 0;
+				}
+
+				return originalSource.size();
+			}
+			default:
+				return 0;
+		}
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash that will be modified
+	 * @param {UpdateHashContext} updateHashContext context for updating hash
+	 */
+	updateHash(hash, { module }) {
+		hash.update(/** @type {boolean} */ (this._esModule).toString());
+		hash.update(/** @type {boolean} */ (this._exportsOnly).toString());
+	}
+}
+
+module.exports = CssGenerator;
Index: frontend/node_modules/webpack/lib/css/CssInjectStyleRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/css/CssInjectStyleRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/CssInjectStyleRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,182 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+/**
+ * @typedef {object} CssInjectCompilationHooks
+ * @property {SyncWaterfallHook<[string, Chunk]>} createStyle
+ */
+
+/** @type {WeakMap<Compilation, CssInjectCompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class CssInjectStyleRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CssInjectCompilationHooks} hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				createStyle: new SyncWaterfallHook(["source", "chunk"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("css inject style", RuntimeModule.STAGE_ATTACH);
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this._runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate, outputOptions } = compilation;
+		const { uniqueName } = outputOptions;
+		const { _runtimeRequirements } = this;
+
+		/** @type {boolean} */
+		const withHmr =
+			_runtimeRequirements &&
+			_runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers);
+
+		const { createStyle } =
+			CssInjectStyleRuntimeModule.getCompilationHooks(compilation);
+
+		// Only emit the nonce check when scriptNonce is part of the runtime
+		// requirements. Otherwise referencing `__webpack_require__.nc` would
+		// keep the require runtime alive for nothing.
+		const withScriptNonce =
+			_runtimeRequirements &&
+			_runtimeRequirements.has(RuntimeGlobals.scriptNonce);
+
+		const createStyleElementCode = Template.asString([
+			"var style = document.createElement('style');",
+			"",
+			...(withScriptNonce
+				? [
+						`if (${RuntimeGlobals.scriptNonce}) {`,
+						Template.indent(
+							`style.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+						),
+						"}"
+					]
+				: []),
+			'style.setAttribute("data-webpack", getDataWebpackId(key));'
+		]);
+
+		return Template.asString([
+			`var dataWebpackPrefix = ${uniqueName ? JSON.stringify(`${uniqueName}:`) : '"webpack:"'};`,
+			"",
+			"function getDataWebpackId(identifier) {",
+			Template.indent("return dataWebpackPrefix + identifier;"),
+			"}",
+			"",
+			"function findStyleElement(identifier) {",
+			Template.indent([
+				"var elements = document.getElementsByTagName('style');",
+				"for (var i = 0; i < elements.length; i++) {",
+				Template.indent([
+					"var el = elements[i];",
+					"if (el.getAttribute('data-webpack') === getDataWebpackId(identifier)) {",
+					Template.indent("return el;"),
+					"}"
+				]),
+				"}",
+				"return null;"
+			]),
+			"}",
+			"",
+			"function insertStyleElement(key) {",
+			Template.indent([
+				createStyle.call(
+					createStyleElementCode,
+					/** @type {Chunk} */ (this.chunk)
+				),
+				"",
+				"document.head.appendChild(style);",
+				"",
+				"return style;"
+			]),
+			"}",
+			"",
+			`${RuntimeGlobals.cssInjectStyle} = ${runtimeTemplate.basicFunction(
+				"identifier, css",
+				[
+					"var element = findStyleElement(identifier) || insertStyleElement(identifier);",
+					"element.textContent = css;"
+				]
+			)};`,
+			"",
+			withHmr
+				? Template.asString([
+						"",
+						"function removeStyleElement(styleElement) {",
+						Template.indent([
+							"if (styleElement.parentNode) {",
+							Template.indent(
+								"styleElement.parentNode.removeChild(styleElement);"
+							),
+							"}"
+						]),
+						"}",
+						`${RuntimeGlobals.cssInjectStyle}.removeModules = ${runtimeTemplate.basicFunction(
+							"removedModules",
+							[
+								"if (!removedModules) return;",
+								"var identifiers = Array.isArray(removedModules) ? removedModules : [removedModules];",
+								"for (var i = 0; i < identifiers.length; i++) {",
+								Template.indent([
+									"var identifier = identifiers[i];",
+									"var element = findStyleElement(identifier);",
+									"if (element) {",
+									Template.indent("removeStyleElement(element);"),
+									"}"
+								]),
+								"}"
+							]
+						)};`,
+						`${RuntimeGlobals.hmrDownloadUpdateHandlers}.cssInjectStyle = ${runtimeTemplate.basicFunction(
+							"chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList, css",
+							[
+								"if (removedModules) {",
+								Template.indent(
+									`${RuntimeGlobals.cssInjectStyle}.removeModules(removedModules);`
+								),
+								"}"
+							]
+						)};`
+					])
+				: "// no css inject style HMR download handler"
+		]);
+	}
+}
+
+module.exports = CssInjectStyleRuntimeModule;
Index: frontend/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,529 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const { CSS_TYPE } = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+const { chunkHasCss } = require("./CssModulesPlugin");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+/**
+ * @typedef {object} CssLoadingRuntimeModulePluginHooks
+ * @property {SyncWaterfallHook<[string, Chunk]>} createStylesheet
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkInsert
+ */
+
+/** @type {WeakMap<Compilation, CssLoadingRuntimeModulePluginHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class CssLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CssLoadingRuntimeModulePluginHooks} hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				createStylesheet: new SyncWaterfallHook(["source", "chunk"]),
+				linkPreload: new SyncWaterfallHook(["source", "chunk"]),
+				linkPrefetch: new SyncWaterfallHook(["source", "chunk"]),
+				linkInsert: new SyncWaterfallHook(["source", "chunk"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("css loading", 10);
+
+		this._runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { _runtimeRequirements } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const {
+			chunkGraph,
+			runtimeTemplate,
+			outputOptions: {
+				crossOriginLoading,
+				uniqueName,
+				chunkLoadTimeout: loadTimeout,
+				charset
+			}
+		} = compilation;
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const conditionMap = chunkGraph.getChunkConditionMap(
+			chunk,
+			/**
+			 * @param {Chunk} chunk the chunk
+			 * @param {ChunkGraph} chunkGraph the chunk graph
+			 * @returns {boolean} true, if the chunk has css
+			 */
+			(chunk, chunkGraph) =>
+				Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_TYPE))
+		);
+		const hasCssMatcher = compileBooleanMatcher(conditionMap);
+
+		const withLoading =
+			_runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) &&
+			hasCssMatcher !== false;
+		/** @type {boolean} */
+		const withHmr = _runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		/** @type {Set<ChunkId>} */
+		const initialChunkIds = new Set();
+		for (const c of chunk.getAllInitialChunks()) {
+			if (chunkHasCss(c, chunkGraph)) {
+				initialChunkIds.add(/** @type {ChunkId} */ (c.id));
+			}
+		}
+
+		if (!withLoading && !withHmr) {
+			return null;
+		}
+
+		const environment = compilation.outputOptions.environment;
+		const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
+		const withPrefetch =
+			this._runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers) &&
+			(environment.document || isNeutralPlatform) &&
+			chunk.hasChildByOrder(chunkGraph, "prefetch", true, chunkHasCss);
+		const withPreload =
+			this._runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers) &&
+			(environment.document || isNeutralPlatform) &&
+			chunk.hasChildByOrder(chunkGraph, "preload", true, chunkHasCss);
+
+		const { linkPreload, linkPrefetch, createStylesheet, linkInsert } =
+			CssLoadingRuntimeModule.getCompilationHooks(compilation);
+
+		const withFetchPriority = _runtimeRequirements.has(
+			RuntimeGlobals.hasFetchPriority
+		);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_css`
+			: undefined;
+
+		const code = Template.asString([
+			"link = document.createElement('link');",
+			charset ? "link.charset = 'utf-8';" : "",
+			`if (${RuntimeGlobals.scriptNonce}) {`,
+			Template.indent(
+				`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+			),
+			"}",
+			uniqueName
+				? 'link.setAttribute("data-webpack", uniqueName + ":" + key);'
+				: "",
+			withFetchPriority
+				? Template.asString([
+						"if(fetchPriority) {",
+						Template.indent(
+							'link.setAttribute("fetchpriority", fetchPriority);'
+						),
+						"}"
+					])
+				: "",
+			"link.setAttribute(loadingAttribute, 1);",
+			'link.rel = "stylesheet";',
+			"link.href = url;",
+			crossOriginLoading
+				? crossOriginLoading === "use-credentials"
+					? 'link.crossOrigin = "use-credentials";'
+					: Template.asString([
+							"if (link.href.indexOf(window.location.origin + '/') !== 0) {",
+							Template.indent(
+								`link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
+							),
+							"}"
+						])
+				: ""
+		]);
+
+		return Template.asString([
+			"// object to store loaded and loading chunks",
+			"// undefined = chunk not loaded, null = chunk preloaded/prefetched",
+			"// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded",
+			`var installedChunks = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{`,
+			Template.indent(
+				Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(
+					",\n"
+				)
+			),
+			"};",
+			"",
+			uniqueName
+				? `var uniqueName = ${JSON.stringify(
+						runtimeTemplate.outputOptions.uniqueName
+					)};`
+				: "// data-webpack is not used as build has no uniqueName",
+			withLoading || withHmr
+				? Template.asString([
+						'var loadingAttribute = "data-webpack-loading";',
+						`var loadStylesheet = ${runtimeTemplate.basicFunction(
+							`chunkId, url, done${
+								withFetchPriority ? ", fetchPriority" : ""
+							}${withHmr ? ", hmr" : ""}`,
+							[
+								'var link, needAttach, key = "chunk-" + chunkId;',
+								withHmr ? "if(!hmr) {" : "",
+								'var links = document.getElementsByTagName("link");',
+								"for(var i = 0; i < links.length; i++) {",
+								Template.indent([
+									"var l = links[i];",
+									`if(l.rel == "stylesheet" && (${
+										withHmr
+											? 'l.href.startsWith(url) || l.getAttribute("href").startsWith(url)'
+											: 'l.href == url || l.getAttribute("href") == url'
+									}${
+										uniqueName
+											? ' || l.getAttribute("data-webpack") == uniqueName + ":" + key'
+											: ""
+									})) { link = l; break; }`
+								]),
+								"}",
+								"if(!done) return link;",
+								withHmr ? "}" : "",
+								"if(!link) {",
+								Template.indent([
+									"needAttach = true;",
+									createStylesheet.call(code, /** @type {Chunk} */ (this.chunk))
+								]),
+								"}",
+								`var onLinkComplete = ${runtimeTemplate.basicFunction(
+									"prev, event",
+									Template.asString([
+										"link.onerror = link.onload = null;",
+										"link.removeAttribute(loadingAttribute);",
+										"clearTimeout(timeout);",
+										'if(event && event.type != "load") link.parentNode.removeChild(link)',
+										"done(event);",
+										"if(prev) return prev(event);"
+									])
+								)};`,
+								"if(link.getAttribute(loadingAttribute)) {",
+								Template.indent([
+									`var timeout = setTimeout(onLinkComplete.bind(null, undefined, { type: 'timeout', target: link }), ${loadTimeout});`,
+									"link.onerror = onLinkComplete.bind(null, link.onerror);",
+									"link.onload = onLinkComplete.bind(null, link.onload);"
+								]),
+								"} else onLinkComplete(undefined, { type: 'load', target: link });", // We assume any existing stylesheet is render blocking
+								withHmr && withFetchPriority
+									? 'if (hmr && hmr.getAttribute("fetchpriority")) link.setAttribute("fetchpriority", hmr.getAttribute("fetchpriority"));'
+									: "",
+								linkInsert.call(
+									withHmr
+										? Template.asString([
+												"if (hmr) {",
+												Template.indent(
+													"hmr.parentNode.insertBefore(link, hmr);"
+												),
+												"} else if (needAttach) {",
+												Template.indent("document.head.appendChild(link);"),
+												"}"
+											])
+										: Template.asString([
+												"if (needAttach) {",
+												Template.indent("document.head.appendChild(link);"),
+												"}"
+											]),
+									/** @type {Chunk} */ (this.chunk)
+								),
+								"return link;"
+							]
+						)};`
+					])
+				: "",
+			withLoading
+				? Template.asString([
+						`${fn}.css = ${runtimeTemplate.basicFunction(
+							`chunkId, promises${withFetchPriority ? " , fetchPriority" : ""}`,
+							[
+								"// css chunk loading",
+								`var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
+								'if(installedChunkData !== 0) { // 0 means "already installed".',
+								Template.indent([
+									"",
+									'// a Promise means "currently loading".',
+									"if(installedChunkData) {",
+									Template.indent(["promises.push(installedChunkData[2]);"]),
+									"} else {",
+									Template.indent([
+										hasCssMatcher === true
+											? "if(true) { // all chunks have CSS"
+											: `if(${hasCssMatcher("chunkId")}) {`,
+										Template.indent([
+											"// setup Promise in chunk cache",
+											`var promise = new Promise(${runtimeTemplate.expressionFunction(
+												"installedChunkData = installedChunks[chunkId] = [resolve, reject]",
+												"resolve, reject"
+											)});`,
+											"promises.push(installedChunkData[2] = promise);",
+											"",
+											"// start chunk loading",
+											`var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
+											"// create error before stack unwound to get useful stacktrace later",
+											"var error = new Error();",
+											`var loadingEnded = ${runtimeTemplate.basicFunction(
+												"event",
+												[
+													`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
+													Template.indent([
+														"installedChunkData = installedChunks[chunkId];",
+														"if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
+														"if(installedChunkData) {",
+														Template.indent([
+															'if(event.type !== "load") {',
+															Template.indent([
+																"var errorType = event && event.type;",
+																"var realHref = event && event.target && event.target.href;",
+																"error.message = 'Loading css chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realHref + ')';",
+																"error.name = 'ChunkLoadError';",
+																"error.type = errorType;",
+																"error.request = realHref;",
+																"installedChunkData[1](error);"
+															]),
+															"} else {",
+															Template.indent([
+																"installedChunks[chunkId] = 0;",
+																"installedChunkData[0]();"
+															]),
+															"}"
+														]),
+														"}"
+													]),
+													"}"
+												]
+											)};`,
+											isNeutralPlatform
+												? "if (typeof document !== 'undefined') {"
+												: "",
+											Template.indent([
+												`loadStylesheet(chunkId, url, loadingEnded${
+													withFetchPriority ? ", fetchPriority" : ""
+												});`
+											]),
+											isNeutralPlatform
+												? "} else { loadingEnded({ type: 'load' }); }"
+												: ""
+										]),
+										"} else installedChunks[chunkId] = 0;"
+									]),
+									"}"
+								]),
+								"}"
+							]
+						)};`
+					])
+				: "// no chunk loading",
+			"",
+			withPrefetch && hasCssMatcher !== false
+				? `${
+						RuntimeGlobals.prefetchChunkHandlers
+					}.s = ${runtimeTemplate.basicFunction("chunkId", [
+						`if((!${
+							RuntimeGlobals.hasOwnProperty
+						}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
+							hasCssMatcher === true ? "true" : hasCssMatcher("chunkId")
+						}) {`,
+						Template.indent([
+							"installedChunks[chunkId] = null;",
+							isNeutralPlatform
+								? "if (typeof document === 'undefined') return;"
+								: "",
+							linkPrefetch.call(
+								Template.asString([
+									"var link = document.createElement('link');",
+									charset ? "link.charset = 'utf-8';" : "",
+									crossOriginLoading
+										? `link.crossOrigin = ${JSON.stringify(
+												crossOriginLoading
+											)};`
+										: "",
+									`if (${RuntimeGlobals.scriptNonce}) {`,
+									Template.indent(
+										`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+									),
+									"}",
+									'link.rel = "prefetch";',
+									'link.as = "style";',
+									`link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`
+								]),
+								chunk
+							),
+							"document.head.appendChild(link);"
+						]),
+						"}"
+					])};`
+				: "// no prefetching",
+			"",
+			withPreload && hasCssMatcher !== false
+				? `${
+						RuntimeGlobals.preloadChunkHandlers
+					}.s = ${runtimeTemplate.basicFunction("chunkId", [
+						`if((!${
+							RuntimeGlobals.hasOwnProperty
+						}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
+							hasCssMatcher === true ? "true" : hasCssMatcher("chunkId")
+						}) {`,
+						Template.indent([
+							"installedChunks[chunkId] = null;",
+							isNeutralPlatform
+								? "if (typeof document === 'undefined') return;"
+								: "",
+							linkPreload.call(
+								Template.asString([
+									"var link = document.createElement('link');",
+									charset ? "link.charset = 'utf-8';" : "",
+									`if (${RuntimeGlobals.scriptNonce}) {`,
+									Template.indent(
+										`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+									),
+									"}",
+									'link.rel = "preload";',
+									'link.as = "style";',
+									`link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
+									crossOriginLoading
+										? crossOriginLoading === "use-credentials"
+											? 'link.crossOrigin = "use-credentials";'
+											: Template.asString([
+													"if (link.href.indexOf(window.location.origin + '/') !== 0) {",
+													Template.indent(
+														`link.crossOrigin = ${JSON.stringify(
+															crossOriginLoading
+														)};`
+													),
+													"}"
+												])
+										: ""
+								]),
+								chunk
+							),
+							"document.head.appendChild(link);"
+						]),
+						"}"
+					])};`
+				: "// no preloaded",
+			withHmr
+				? Template.asString([
+						"var oldTags = [];",
+						"var newTags = [];",
+						`var applyHandler = ${runtimeTemplate.basicFunction("options", [
+							`return { dispose: ${runtimeTemplate.basicFunction("", [
+								"while(oldTags.length) {",
+								Template.indent([
+									"var oldTag = oldTags.pop();",
+									"if(oldTag && oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);"
+								]),
+								"}"
+							])}, apply: ${runtimeTemplate.basicFunction("", [
+								"while(newTags.length) {",
+								Template.indent([
+									"var newTag = newTags.pop();",
+									"newTag.sheet.disabled = false"
+								]),
+								"}"
+							])} };`
+						])}`,
+						`var cssTextKey = ${runtimeTemplate.returningFunction(
+							`Array.from(link.sheet.cssRules, ${runtimeTemplate.returningFunction(
+								"r.cssText",
+								"r"
+							)}).join()`,
+							"link"
+						)};`,
+						`${
+							RuntimeGlobals.hmrDownloadUpdateHandlers
+						}.css = ${runtimeTemplate.basicFunction(
+							"chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList, css",
+							[
+								isNeutralPlatform
+									? "if (typeof document === 'undefined') return;"
+									: "",
+								"applyHandlers.push(applyHandler);",
+								"// Read CSS removed chunks from update manifest",
+								"var cssRemovedChunks = css && css.r;",
+								`chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
+									`var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
+									`var url = ${RuntimeGlobals.publicPath} + filename;`,
+									"var oldTag = loadStylesheet(chunkId, url);",
+									`if(!oldTag && !${withHmr} ) return;`,
+									"// Skip if CSS was removed",
+									"if(cssRemovedChunks && cssRemovedChunks.indexOf(chunkId) >= 0) {",
+									Template.indent(["oldTags.push(oldTag);", "return;"]),
+									"}",
+									"",
+									"// create error before stack unwound to get useful stacktrace later",
+									"var error = new Error();",
+									`promises.push(new Promise(${runtimeTemplate.basicFunction(
+										"resolve, reject",
+										[
+											`var link = loadStylesheet(chunkId, url + (url.indexOf("?") < 0 ? "?" : "&") + "hmr=" + Date.now(), ${runtimeTemplate.basicFunction(
+												"event",
+												[
+													'if(event.type !== "load") {',
+													Template.indent([
+														"var errorType = event && event.type;",
+														"var realHref = event && event.target && event.target.href;",
+														"error.message = 'Loading css hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realHref + ')';",
+														"error.name = 'ChunkLoadError';",
+														"error.type = errorType;",
+														"error.request = realHref;",
+														"reject(error);"
+													]),
+													"} else {",
+													Template.indent([
+														"try { if(cssTextKey(oldTag) == cssTextKey(link)) { if(link.parentNode) link.parentNode.removeChild(link); return resolve(); } } catch(e) {}",
+														"link.sheet.disabled = true;",
+														"oldTags.push(oldTag);",
+														"newTags.push(link);",
+														"resolve();"
+													]),
+													"}"
+												]
+											)}, ${withFetchPriority ? "undefined," : ""} oldTag);`
+										]
+									)}));`
+								])});`
+							]
+						)}`
+					])
+				: "// no hmr"
+		]);
+	}
+}
+
+module.exports = CssLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/css/CssModule.js
===================================================================
--- frontend/node_modules/webpack/lib/css/CssModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/CssModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,200 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @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 {import("../../declarations/WebpackOptions").CssParserExportType} CssParserExportType */
+
+/** @typedef {string | undefined} CssLayer */
+/** @typedef {string | undefined} Supports */
+/** @typedef {string | undefined} Media */
+/** @typedef {[CssLayer, Supports, Media]} InheritanceItem */
+/** @typedef {InheritanceItem[]} Inheritance */
+
+/** @typedef {NormalModuleCreateData & { cssLayer: CssLayer, supports: Supports, media: Media, inheritance?: Inheritance, exportType?: CssParserExportType }} CssModuleCreateData */
+
+class CssModule extends NormalModule {
+	/**
+	 * Creates an instance of CssModule.
+	 * @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
+		/** @type {CssModuleCreateData['cssLayer']} */
+		this.cssLayer = options.cssLayer;
+		/** @type {CssModuleCreateData['supports']} */
+		this.supports = options.supports;
+		/** @type {CssModuleCreateData['media']} */
+		this.media = options.media;
+		/** @type {CssModuleCreateData['inheritance']} */
+		this.inheritance = options.inheritance;
+		/** @type {CssModuleCreateData['exportType']} */
+		this.exportType = options.exportType;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @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("|")}`;
+		}
+
+		if (this.exportType) {
+			identifier += `|${this.exportType}`;
+		}
+
+		// We generate extra code for HMR, so we need to invalidate the module
+		if (this.hot) {
+			identifier += `|${this.hot}`;
+		}
+
+		return identifier;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @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})`;
+		}
+
+		if (this.exportType) {
+			identifier += ` (exportType: ${this.exportType})`;
+		}
+
+		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;
+		this.exportType = m.exportType;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.cssLayer);
+		write(this.supports);
+		write(this.media);
+		write(this.inheritance);
+		write(this.exportType);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {CssModule} the deserialized object
+	 */
+	static deserialize(context) {
+		const obj = new CssModule({
+			// will be deserialized by Module
+			layer: /** @type {EXPECTED_ANY} */ (null),
+			type: "",
+			// will be filled by updateCacheModule
+			resource: "",
+			context: "",
+			request: /** @type {EXPECTED_ANY} */ (null),
+			userRequest: /** @type {EXPECTED_ANY} */ (null),
+			rawRequest: /** @type {EXPECTED_ANY} */ (null),
+			loaders: /** @type {EXPECTED_ANY} */ (null),
+			matchResource: /** @type {EXPECTED_ANY} */ (null),
+			parser: /** @type {EXPECTED_ANY} */ (null),
+			parserOptions: /** @type {EXPECTED_ANY} */ (null),
+			generator: /** @type {EXPECTED_ANY} */ (null),
+			generatorOptions: /** @type {EXPECTED_ANY} */ (null),
+			resolveOptions: /** @type {EXPECTED_ANY} */ (null),
+			cssLayer: /** @type {EXPECTED_ANY} */ (null),
+			supports: /** @type {EXPECTED_ANY} */ (null),
+			media: /** @type {EXPECTED_ANY} */ (null),
+			inheritance: /** @type {EXPECTED_ANY} */ (null),
+			extractSourceMap: /** @type {EXPECTED_ANY} */ (null),
+			exportType: /** @type {EXPECTED_ANY} */ (null)
+		});
+		obj.deserialize(context);
+		return obj;
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.cssLayer = read();
+		this.supports = read();
+		this.media = read();
+		this.inheritance = read();
+		this.exportType = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(CssModule, "webpack/lib/CssModule");
+
+module.exports = CssModule;
Index: frontend/node_modules/webpack/lib/css/CssModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/css/CssModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/CssModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1184 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncBailHook, SyncHook, SyncWaterfallHook } = require("tapable");
+const {
+	CachedSource,
+	ConcatSource,
+	PrefixSource,
+	RawSource,
+	ReplaceSource
+} = require("webpack-sources");
+const Compilation = require("../Compilation");
+const HotUpdateChunk = require("../HotUpdateChunk");
+const { CSS_IMPORT_TYPE, CSS_TYPE } = require("../ModuleSourceTypeConstants");
+const {
+	CSS_MODULE_TYPE,
+	CSS_MODULE_TYPE_AUTO,
+	CSS_MODULE_TYPE_GLOBAL,
+	CSS_MODULE_TYPE_MODULE
+} = require("../ModuleTypeConstants");
+const NormalModule = require("../NormalModule");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const CssIcssExportDependency = require("../dependencies/CssIcssExportDependency");
+const CssIcssImportDependency = require("../dependencies/CssIcssImportDependency");
+const CssIcssSymbolDependency = require("../dependencies/CssIcssSymbolDependency");
+const CssImportDependency = require("../dependencies/CssImportDependency");
+const CssUrlDependency = require("../dependencies/CssUrlDependency");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const { tryRunOrWebpackError } = require("../errors/HookWebpackError");
+const WebpackError = require("../errors/WebpackError");
+const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
+const ConcatenatedModule = require("../optimize/ConcatenatedModule");
+const { compareModulesByFullName } = require("../util/comparators");
+const createHash = require("../util/createHash");
+const { getUndoPath } = require("../util/identifier");
+const memoize = require("../util/memoize");
+const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
+const removeBOM = require("../util/removeBOM");
+const CssGenerator = require("./CssGenerator");
+const CssModule = require("./CssModule");
+const CssParser = require("./CssParser");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./CssModule").Inheritance} Inheritance */
+/** @typedef {import("./CssModule").CssModuleCreateData} CssModuleCreateData */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../Template").RuntimeTemplate} RuntimeTemplate */
+/** @typedef {import("../Chunk").ChunkFilenameTemplate} ChunkFilenameTemplate */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+
+/**
+ * Defines the render context type used by this module.
+ * @typedef {object} RenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {string} uniqueName the unique name
+ * @property {string} undoPath undo path to css file
+ * @property {string=} hash compilation hash
+ * @property {CssModule[]} modules modules
+ */
+
+/**
+ * Defines the chunk render context type used by this module.
+ * @typedef {object} ChunkRenderContext
+ * @property {Chunk=} chunk the chunk
+ * @property {ChunkGraph=} chunkGraph the chunk graph
+ * @property {CodeGenerationResults=} codeGenerationResults results of code generation
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {string} undoPath undo path to css file
+ * @property {string=} hash compilation hash
+ * @property {WeakMap<Source, ModuleFactoryCacheEntry>} moduleFactoryCache moduleFactoryCache
+ * @property {Source} moduleSourceContent content
+ */
+
+/**
+ * Defines the compilation hooks type used by this module.
+ * @typedef {object} CompilationHooks
+ * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
+ * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
+ * @property {SyncBailHook<[Chunk, Module[], Compilation], Module[] | undefined | void>} orderModules called for each CSS source type (CSS_IMPORT_TYPE, CSS_TYPE) with the chunk's modules pre-sorted by full module name; return an ordered `Module[]` to override the default import-order topological sort, or return `undefined` to keep the default
+ */
+
+/**
+ * Defines the module factory cache entry type used by this module.
+ * @typedef {object} ModuleFactoryCacheEntry
+ * @property {string} undoPath - The undo path to the CSS file
+ * @property {string | undefined} hash - The compilation hash
+ * @property {Inheritance} inheritance - The inheritance chain
+ * @property {CachedSource} source - The cached source
+ */
+
+const getCssLoadingRuntimeModule = memoize(() =>
+	require("./CssLoadingRuntimeModule")
+);
+const getCssInjectStyleRuntimeModule = memoize(() =>
+	require("./CssInjectStyleRuntimeModule")
+);
+
+/**
+ * Returns ], definitions: import("../../schemas/WebpackOptions.json")["definitions"] }} schema.
+ * @param {string} name name
+ * @returns {{ oneOf: [{ $ref: string }], definitions: import("../../schemas/WebpackOptions.json")["definitions"] }} schema
+ */
+const getSchema = (name) => {
+	const { definitions } = require("../../schemas/WebpackOptions.json");
+
+	return {
+		definitions,
+		oneOf: [{ $ref: `#/definitions/${name}` }]
+	};
+};
+
+const parserValidationOptions = {
+	name: "Css Modules Plugin",
+	baseDataPath: "parser"
+};
+
+const generatorValidationOptions = {
+	name: "Css Modules Plugin",
+	baseDataPath: "generator"
+};
+
+/** @type {WeakMap<Compilation, CompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+const PLUGIN_NAME = "CssModulesPlugin";
+
+class CssModulesPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CompilationHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				renderModulePackage: new SyncWaterfallHook([
+					"source",
+					"module",
+					"renderContext"
+				]),
+				chunkHash: new SyncHook(["chunk", "hash", "context"]),
+				orderModules: new SyncBailHook(["chunk", "modules", "compilation"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	constructor() {
+		/** @type {WeakMap<Source, ModuleFactoryCacheEntry>} */
+		this._moduleFactoryCache = new WeakMap();
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const hooks = CssModulesPlugin.getCompilationHooks(compilation);
+				compilation.dependencyFactories.set(
+					CssImportDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CssImportDependency,
+					new CssImportDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					CssUrlDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CssUrlDependency,
+					new CssUrlDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					CssIcssImportDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CssIcssImportDependency,
+					new CssIcssImportDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					CssIcssExportDependency,
+					new CssIcssExportDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					CssIcssSymbolDependency,
+					new CssIcssSymbolDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					StaticExportsDependency,
+					new StaticExportsDependency.Template()
+				);
+				for (const type of [
+					CSS_MODULE_TYPE,
+					CSS_MODULE_TYPE_GLOBAL,
+					CSS_MODULE_TYPE_MODULE,
+					CSS_MODULE_TYPE_AUTO
+				]) {
+					normalModuleFactory.hooks.createParser
+						.for(type)
+						.tap(PLUGIN_NAME, (parserOptions) => {
+							/** @type {undefined | "global" | "local" | "auto"} */
+							let defaultMode;
+
+							switch (type) {
+								case CSS_MODULE_TYPE: {
+									compiler.validate(
+										() => getSchema("CssParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssParserOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_GLOBAL: {
+									defaultMode = "global";
+									compiler.validate(
+										() => getSchema("CssModuleParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleParserOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+								case CSS_MODULE_TYPE_MODULE: {
+									defaultMode = "local";
+									compiler.validate(
+										() => getSchema("CssAutoOrModuleParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssAutoOrModuleParserOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+								case CSS_MODULE_TYPE_AUTO: {
+									defaultMode = "auto";
+									compiler.validate(
+										() => getSchema("CssAutoOrModuleParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssAutoOrModuleParserOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+							}
+
+							return new CssParser({
+								defaultMode,
+								...parserOptions
+							});
+						});
+					normalModuleFactory.hooks.createGenerator
+						.for(type)
+						.tap(PLUGIN_NAME, (generatorOptions) => {
+							switch (type) {
+								case CSS_MODULE_TYPE: {
+									compiler.validate(
+										() => getSchema("CssGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_GLOBAL: {
+									compiler.validate(
+										() => getSchema("CssModuleGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_MODULE: {
+									compiler.validate(
+										() => getSchema("CssModuleGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_AUTO: {
+									compiler.validate(
+										() => getSchema("CssModuleGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+							}
+
+							return new CssGenerator(
+								generatorOptions,
+								compilation.moduleGraph
+							);
+						});
+					normalModuleFactory.hooks.createModuleClass
+						.for(type)
+						.tap(PLUGIN_NAME, (createData, resolveData) => {
+							const exportType =
+								/** @type {CssParser} */
+								(createData.parser).options.exportType;
+							if (resolveData.dependencies.length > 0) {
+								// When CSS is imported from CSS there is only one dependency
+								const dependency = resolveData.dependencies[0];
+
+								if (dependency instanceof CssImportDependency) {
+									const parent =
+										/** @type {CssModule} */
+										(compilation.moduleGraph.getParentModule(dependency));
+
+									if (parent instanceof CssModule) {
+										/** @type {Inheritance | undefined} */
+										let inheritance;
+
+										if (
+											parent.cssLayer !== undefined ||
+											parent.supports ||
+											parent.media
+										) {
+											if (!inheritance) {
+												inheritance = [];
+											}
+
+											inheritance.push([
+												parent.cssLayer,
+												parent.supports,
+												parent.media
+											]);
+										}
+
+										if (parent.inheritance) {
+											if (!inheritance) {
+												inheritance = [];
+											}
+
+											inheritance.push(...parent.inheritance);
+										}
+
+										return new CssModule(
+											/** @type {CssModuleCreateData} */
+											({
+												...createData,
+												cssLayer: dependency.layer,
+												supports: dependency.supports,
+												media: dependency.media,
+												inheritance,
+												exportType: parent.exportType || exportType
+											})
+										);
+									}
+
+									return new CssModule(
+										/** @type {CssModuleCreateData} */
+										({
+											...createData,
+											cssLayer: dependency.layer,
+											supports: dependency.supports,
+											media: dependency.media,
+											exportType
+										})
+									);
+								}
+							}
+
+							return new CssModule(
+								/** @type {CssModuleCreateData} */
+								(
+									/** @type {unknown} */ ({
+										...createData,
+										exportType
+									})
+								)
+							);
+						});
+
+					NormalModule.getCompilationHooks(compilation).processResult.tap(
+						PLUGIN_NAME,
+						(result, module) => {
+							if (module.type === type) {
+								const [source, ...rest] = result;
+
+								return [removeBOM(source), ...rest];
+							}
+
+							return result;
+						}
+					);
+				}
+
+				JavascriptModulesPlugin.getCompilationHooks(
+					compilation
+				).renderModuleContent.tap(PLUGIN_NAME, (source, module) => {
+					const injectCssStylesVar =
+						module instanceof ConcatenatedModule &&
+						module.modules.find(
+							(m) =>
+								m instanceof CssModule &&
+								m.exportType === "style" &&
+								!(/** @type {CssGenerator} */ (m.generator)._exportsOnly)
+						);
+					const injectHMRCode =
+						(module instanceof CssModule && module.hot) ||
+						(module instanceof ConcatenatedModule &&
+							module.rootModule instanceof CssModule &&
+							module.rootModule.hot);
+
+					if (injectCssStylesVar) {
+						source = new ConcatSource(
+							"var __webpack_css_styles__ = [];",
+							"\n",
+							source
+						);
+					}
+					if (injectHMRCode) {
+						const currentModule = /** @type {CssModule} */ (
+							module instanceof ConcatenatedModule ? module.rootModule : module
+						);
+						const exportType = currentModule.exportType || "link";
+						// When exportType !== "link", modules behave like JavaScript modules
+						if (["link", "style"].includes(exportType)) {
+							// For exportType === "link", we can optimize with self-acceptance
+							const cssData = /** @type {BuildInfo} */ (module.buildInfo)
+								.cssData;
+							if (!cssData) {
+								return source;
+							}
+							const exports = cssData.exports;
+							/** @type {Record<string, string>} */
+							const exportsObj = {};
+							for (const [key, value] of exports) {
+								exportsObj[key] = value;
+							}
+							const stringifiedExports = JSON.stringify(
+								JSON.stringify(exportsObj)
+							);
+
+							const hmrCode = Template.asString([
+								"",
+								`var __webpack_css_exports__ = ${stringifiedExports};`,
+								"// only invalidate when locals change",
+								"if (module.hot.data && module.hot.data.__webpack_css_exports__ && module.hot.data.__webpack_css_exports__ != __webpack_css_exports__) {",
+								Template.indent("module.hot.invalidate();"),
+								"} else {",
+								Template.indent("module.hot.accept();"),
+								"}",
+								"module.hot.dispose(function(data) {",
+								Template.indent([
+									"data.__webpack_css_exports__ = __webpack_css_exports__;"
+								]),
+								"});"
+							]);
+
+							source = new ConcatSource(source, "\n", new RawSource(hmrCode));
+						}
+					}
+					if (injectCssStylesVar) {
+						/** @type {ConcatSource} */
+						(source).add(
+							"for (let i = 0; i < __webpack_css_styles__.length; i++) {\n" +
+								`${RuntimeGlobals.cssInjectStyle}(__webpack_css_styles__[i][0], __webpack_css_styles__[i][1]);\n` +
+								"}"
+						);
+					}
+
+					return source;
+				});
+				/** @type {WeakMap<Chunk, CssModule[]>} */
+				const orderedCssModulesPerChunk = new WeakMap();
+				compilation.hooks.afterCodeGeneration.tap(PLUGIN_NAME, () => {
+					const { chunkGraph } = compilation;
+					for (const chunk of compilation.chunks) {
+						if (CssModulesPlugin.chunkHasCss(chunk, chunkGraph)) {
+							orderedCssModulesPerChunk.set(
+								chunk,
+								this.getOrderedChunkCssModules(chunk, chunkGraph, compilation)
+							);
+						}
+					}
+				});
+				compilation.hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash, context) => {
+					hooks.chunkHash.call(chunk, hash, context);
+				});
+				compilation.hooks.contentHash.tap(PLUGIN_NAME, (chunk) => {
+					const {
+						chunkGraph,
+						moduleGraph,
+						runtimeTemplate,
+						outputOptions: {
+							hashSalt,
+							hashDigest,
+							hashDigestLength,
+							hashFunction
+						}
+					} = compilation;
+					const hash = createHash(hashFunction);
+					if (hashSalt) hash.update(hashSalt);
+					const codeGenerationResults =
+						/** @type {CodeGenerationResults} */
+						(compilation.codeGenerationResults);
+					hooks.chunkHash.call(chunk, hash, {
+						chunkGraph,
+						codeGenerationResults,
+						moduleGraph,
+						runtimeTemplate
+					});
+					const modules = orderedCssModulesPerChunk.get(chunk);
+					if (modules) {
+						for (const module of modules) {
+							hash.update(chunkGraph.getModuleHash(module, chunk.runtime));
+						}
+					}
+					const digest = hash.digest(hashDigest);
+					chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength);
+				});
+				compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
+					const { chunkGraph } = compilation;
+					const { hash, chunk, codeGenerationResults, runtimeTemplate } =
+						options;
+
+					if (chunk instanceof HotUpdateChunk) return result;
+
+					/** @type {CssModule[] | undefined} */
+					const modules = orderedCssModulesPerChunk.get(chunk);
+					if (modules !== undefined) {
+						const { path: filename, info } = compilation.getPathWithInfo(
+							CssModulesPlugin.getChunkFilenameTemplate(
+								chunk,
+								compilation.outputOptions
+							),
+							{
+								hash,
+								runtime: chunk.runtime,
+								chunk,
+								contentHashType: "css"
+							}
+						);
+						const undoPath = getUndoPath(
+							filename,
+							compilation.outputOptions.path,
+							false
+						);
+						result.push({
+							render: () =>
+								this.renderChunk(
+									{
+										chunk,
+										chunkGraph,
+										codeGenerationResults,
+										uniqueName: compilation.outputOptions.uniqueName,
+										undoPath,
+										hash,
+										modules,
+										runtimeTemplate
+									},
+									hooks
+								),
+							filename,
+							info,
+							identifier: `css${chunk.id}`,
+							hash: chunk.contentHash.css
+						});
+					}
+					return result;
+				});
+				const globalChunkLoading = compilation.outputOptions.chunkLoading;
+				/**
+				 * Checks whether this css modules plugin is enabled for chunk.
+				 * @param {Chunk} chunk the chunk
+				 * @returns {boolean} true, when enabled
+				 */
+				const isEnabledForChunk = (chunk) => {
+					const options = chunk.getEntryOptions();
+					const chunkLoading =
+						options && options.chunkLoading !== undefined
+							? options.chunkLoading
+							: globalChunkLoading;
+					return chunkLoading === "jsonp" || chunkLoading === "import";
+				};
+				/** @type {WeakSet<Chunk>} */
+				const onceForChunkSet = new WeakSet();
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Chunk} chunk chunk to check
+				 * @param {RuntimeRequirements} set runtime requirements
+				 */
+				const handler = (chunk, set) => {
+					if (onceForChunkSet.has(chunk)) return;
+					onceForChunkSet.add(chunk);
+					if (!isEnabledForChunk(chunk)) return;
+
+					const CssLoadingRuntimeModule = getCssLoadingRuntimeModule();
+					compilation.addRuntimeModule(chunk, new CssLoadingRuntimeModule(set));
+				};
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.hasCssModules)
+					.tap(PLUGIN_NAME, handler);
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.ensureChunkHandlers)
+					.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+						if (!isEnabledForChunk(chunk)) return;
+						if (
+							!chunkGraph.hasModuleInGraph(
+								chunk,
+								(m) =>
+									m.type === CSS_MODULE_TYPE ||
+									m.type === CSS_MODULE_TYPE_GLOBAL ||
+									m.type === CSS_MODULE_TYPE_MODULE ||
+									m.type === CSS_MODULE_TYPE_AUTO
+							)
+						) {
+							return;
+						}
+
+						set.add(RuntimeGlobals.hasOwnProperty);
+						set.add(RuntimeGlobals.publicPath);
+						set.add(RuntimeGlobals.getChunkCssFilename);
+					});
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+					.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+						if (!isEnabledForChunk(chunk)) return;
+						if (
+							!chunkGraph.hasModuleInGraph(
+								chunk,
+								(m) =>
+									m.type === CSS_MODULE_TYPE ||
+									m.type === CSS_MODULE_TYPE_GLOBAL ||
+									m.type === CSS_MODULE_TYPE_MODULE ||
+									m.type === CSS_MODULE_TYPE_AUTO
+							)
+						) {
+							return;
+						}
+						set.add(RuntimeGlobals.publicPath);
+						set.add(RuntimeGlobals.getChunkCssFilename);
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.cssInjectStyle)
+					.tap(PLUGIN_NAME, (chunk, set) => {
+						// Same as above: namespace stub is enough.
+						set.add(RuntimeGlobals.requireScope);
+						const CssInjectStyleRuntimeModule =
+							getCssInjectStyleRuntimeModule();
+						compilation.addRuntimeModule(
+							chunk,
+							new CssInjectStyleRuntimeModule(set)
+						);
+					});
+			}
+		);
+	}
+
+	/**
+	 * Gets modules in order.
+	 * @param {Chunk} chunk chunk
+	 * @param {Iterable<Module> | undefined} modules unordered modules
+	 * @param {Compilation} compilation compilation
+	 * @returns {Module[]} ordered modules
+	 */
+	getModulesInOrder(chunk, modules, compilation) {
+		if (!modules) return [];
+
+		/** @type {Module[]} */
+		const modulesList = [...modules];
+
+		// Get ordered list of modules per chunk group
+		// Lists are in reverse order to allow to use Array.pop()
+		const modulesByChunkGroup = Array.from(
+			chunk.groupsIterable,
+			(chunkGroup) => {
+				const sortedModules = modulesList
+					.map((module) => ({
+						module,
+						index: chunkGroup.getModulePostOrderIndex(module)
+					}))
+					.filter((item) => item.index !== undefined)
+					.sort(
+						(a, b) =>
+							/** @type {number} */ (b.index) - /** @type {number} */ (a.index)
+					)
+					.map((item) => item.module);
+
+				return { list: sortedModules, set: new Set(sortedModules) };
+			}
+		);
+
+		if (modulesByChunkGroup.length === 1) {
+			return modulesByChunkGroup[0].list.reverse();
+		}
+
+		const boundCompareModulesByFullName = compareModulesByFullName(
+			compilation.compiler
+		);
+
+		/**
+		 * Compares module lists.
+		 * @param {{ list: Module[] }} a a
+		 * @param {{ list: Module[] }} b b
+		 * @returns {-1 | 0 | 1} result
+		 */
+		const compareModuleLists = ({ list: a }, { list: b }) => {
+			if (a.length === 0) {
+				return b.length === 0 ? 0 : 1;
+			}
+			if (b.length === 0) return -1;
+			return boundCompareModulesByFullName(a[a.length - 1], b[b.length - 1]);
+		};
+
+		modulesByChunkGroup.sort(compareModuleLists);
+
+		/** @type {Module[]} */
+		const finalModules = [];
+
+		for (;;) {
+			/** @type {Set<Module>} */
+			const failedModules = new Set();
+			const list = modulesByChunkGroup[0].list;
+			if (list.length === 0) {
+				// done, everything empty
+				break;
+			}
+			/** @type {Module} */
+			let selectedModule = list[list.length - 1];
+			/** @type {undefined | false | Module} */
+			let hasFailed;
+			outer: for (;;) {
+				for (const { list, set } of modulesByChunkGroup) {
+					if (list.length === 0) continue;
+					const lastModule = list[list.length - 1];
+					if (lastModule === selectedModule) continue;
+					if (!set.has(selectedModule)) continue;
+					failedModules.add(selectedModule);
+					if (failedModules.has(lastModule)) {
+						// There is a conflict, try other alternatives
+						hasFailed = lastModule;
+						continue;
+					}
+					selectedModule = lastModule;
+					hasFailed = false;
+					continue outer; // restart
+				}
+				break;
+			}
+			if (hasFailed) {
+				const fallbackModule = /** @type {Module} */ (hasFailed);
+
+				const fallbackIssuers = [
+					...compilation.moduleGraph
+						.getIncomingConnectionsByOriginModule(fallbackModule)
+						.keys()
+				].filter(Boolean);
+
+				const selectedIssuers = [
+					...compilation.moduleGraph
+						.getIncomingConnectionsByOriginModule(selectedModule)
+						.keys()
+				].filter(Boolean);
+
+				const allIssuers = [
+					...new Set([...fallbackIssuers, ...selectedIssuers])
+				]
+					.map((m) =>
+						/** @type {Module} */ (m).readableIdentifier(
+							compilation.requestShortener
+						)
+					)
+					.sort();
+
+				// There is a not resolve-able conflict with the selectedModule
+				compilation.warnings.push(
+					new WebpackError(
+						`chunk ${
+							chunk.name || chunk.id
+						}\nConflicting order between ${fallbackModule.readableIdentifier(
+							compilation.requestShortener
+						)} and ${selectedModule.readableIdentifier(
+							compilation.requestShortener
+						)}\nCSS modules are imported in:\n  - ${allIssuers.join("\n  - ")}`
+					)
+				);
+				selectedModule = fallbackModule;
+			}
+			// Insert the selected module into the final modules list
+			finalModules.push(selectedModule);
+			// Remove the selected module from all lists
+			for (const { list, set } of modulesByChunkGroup) {
+				const lastModule = list[list.length - 1];
+				if (lastModule === selectedModule) {
+					list.pop();
+				} else if (hasFailed && set.has(selectedModule)) {
+					const idx = list.indexOf(selectedModule);
+					if (idx >= 0) list.splice(idx, 1);
+				}
+			}
+			modulesByChunkGroup.sort(compareModuleLists);
+		}
+		return finalModules;
+	}
+
+	/**
+	 * Gets ordered chunk css modules.
+	 * @param {Chunk} chunk chunk
+	 * @param {ChunkGraph} chunkGraph chunk graph
+	 * @param {Compilation} compilation compilation
+	 * @returns {CssModule[]} ordered css modules
+	 */
+	getOrderedChunkCssModules(chunk, chunkGraph, compilation) {
+		/** @type {string | undefined} */
+		let charset;
+
+		const hooks = CssModulesPlugin.getCompilationHooks(compilation);
+
+		/**
+		 * @param {Iterable<Module> | undefined} iter modules pre-sorted by full module name
+		 * @returns {Module[]} ordered modules
+		 */
+		const orderModules = (iter) => {
+			const modules = iter ? [...iter] : [];
+			const result = hooks.orderModules.call(chunk, modules, compilation);
+			if (result !== undefined) return result;
+			return this.getModulesInOrder(chunk, modules, compilation);
+		};
+
+		return /** @type {CssModule[]} */ ([
+			...orderModules(
+				chunkGraph.getOrderedChunkModulesIterableBySourceType(
+					chunk,
+					CSS_IMPORT_TYPE,
+					compareModulesByFullName(compilation.compiler)
+				)
+			),
+			...orderModules(
+				chunkGraph.getOrderedChunkModulesIterableBySourceType(
+					chunk,
+					CSS_TYPE,
+					compareModulesByFullName(compilation.compiler)
+				)
+			).map((module) => {
+				if (
+					typeof (/** @type {BuildInfo} */ (module.buildInfo).charset) !==
+					"undefined"
+				) {
+					if (
+						typeof charset !== "undefined" &&
+						charset !== /** @type {BuildInfo} */ (module.buildInfo).charset
+					) {
+						const err = new WebpackError(
+							`Conflicting @charset at-rules detected: the module ${module.readableIdentifier(
+								compilation.requestShortener
+							)} (in chunk ${chunk.name || chunk.id}) specifies "${
+								/** @type {BuildInfo} */ (module.buildInfo).charset
+							}", but "${charset}" was expected, all modules must use the same character set`
+						);
+
+						err.chunk = chunk;
+						err.module = module;
+						err.hideStack = true;
+
+						compilation.warnings.push(err);
+					}
+
+					if (typeof charset === "undefined") {
+						charset = /** @type {BuildInfo} */ (module.buildInfo).charset;
+					}
+				}
+
+				return module;
+			})
+		]);
+	}
+
+	/**
+	 * Renders css module source.
+	 * @param {CssModule} module css module
+	 * @param {ChunkRenderContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {Source | null} css module source
+	 */
+	static renderModule(module, renderContext, hooks) {
+		const { undoPath, hash, moduleFactoryCache, moduleSourceContent } =
+			renderContext;
+		const cacheEntry = moduleFactoryCache.get(moduleSourceContent);
+
+		/** @type {Inheritance} */
+		const inheritance = [[module.cssLayer, module.supports, module.media]];
+		if (module.inheritance) {
+			inheritance.push(...module.inheritance);
+		}
+
+		/** @type {CachedSource} */
+		let source;
+		if (
+			cacheEntry &&
+			cacheEntry.undoPath === undoPath &&
+			cacheEntry.hash === hash &&
+			cacheEntry.inheritance.length === inheritance.length &&
+			cacheEntry.inheritance.every(([layer, supports, media], i) => {
+				const item = inheritance[i];
+				if (Array.isArray(item)) {
+					return layer === item[0] && supports === item[1] && media === item[2];
+				}
+				return false;
+			})
+		) {
+			source = cacheEntry.source;
+		} else {
+			if (!moduleSourceContent) return null;
+			const moduleSourceCode =
+				/** @type {string} */
+				(moduleSourceContent.source());
+			const replaceSource = new ReplaceSource(moduleSourceContent);
+
+			const autoPlaceholder = CssUrlDependency.PUBLIC_PATH_AUTO;
+			const autoPlaceholderLen = autoPlaceholder.length;
+			for (
+				let idx = moduleSourceCode.indexOf(autoPlaceholder);
+				idx !== -1;
+				idx = moduleSourceCode.indexOf(
+					autoPlaceholder,
+					idx + autoPlaceholderLen
+				)
+			) {
+				replaceSource.replace(idx, idx + autoPlaceholderLen - 1, undoPath);
+			}
+
+			if (hash) {
+				const hashPrefix = CssUrlDependency.PUBLIC_PATH_FULL_HASH;
+				const hashPrefixLen = hashPrefix.length;
+				const sourceLen = moduleSourceCode.length;
+				let idx = moduleSourceCode.indexOf(hashPrefix);
+				while (idx !== -1) {
+					let digitEnd = idx + hashPrefixLen;
+					while (digitEnd < sourceLen) {
+						const cc = moduleSourceCode.charCodeAt(digitEnd);
+						if (cc < 48 || cc > 57) break;
+						digitEnd++;
+					}
+					let nextSearch;
+					if (
+						digitEnd > idx + hashPrefixLen &&
+						digitEnd + 1 < sourceLen &&
+						moduleSourceCode.charCodeAt(digitEnd) === 95 &&
+						moduleSourceCode.charCodeAt(digitEnd + 1) === 95
+					) {
+						const length = Number.parseInt(
+							moduleSourceCode.slice(idx + hashPrefixLen, digitEnd),
+							10
+						);
+						replaceSource.replace(
+							idx,
+							digitEnd + 1,
+							length === 0 ? hash : hash.slice(0, length)
+						);
+						nextSearch = digitEnd + 2;
+					} else {
+						nextSearch = idx + hashPrefixLen;
+					}
+					idx = moduleSourceCode.indexOf(hashPrefix, nextSearch);
+				}
+			}
+
+			/** @type {Source} */
+			let moduleSource = replaceSource;
+
+			for (let i = 0; i < inheritance.length; i++) {
+				const layer = inheritance[i][0];
+				const supports = inheritance[i][1];
+				const media = inheritance[i][2];
+
+				if (media) {
+					moduleSource = new ConcatSource(
+						`@media ${media} {\n`,
+						new PrefixSource("\t", moduleSource),
+						"}\n"
+					);
+				}
+
+				if (supports) {
+					moduleSource = new ConcatSource(
+						`@supports (${supports}) {\n`,
+						new PrefixSource("\t", moduleSource),
+						"}\n"
+					);
+				}
+
+				// Layer can be anonymous
+				if (layer !== undefined && layer !== null) {
+					moduleSource = new ConcatSource(
+						`@layer${layer ? ` ${layer}` : ""} {\n`,
+						new PrefixSource("\t", moduleSource),
+						"}\n"
+					);
+				}
+			}
+
+			if (moduleSource) {
+				moduleSource = new ConcatSource(moduleSource, "\n");
+			}
+
+			source = new CachedSource(moduleSource);
+			moduleFactoryCache.set(moduleSourceContent, {
+				inheritance,
+				undoPath,
+				hash,
+				source
+			});
+		}
+
+		return tryRunOrWebpackError(
+			() => hooks.renderModulePackage.call(source, module, renderContext),
+			"CssModulesPlugin.getCompilationHooks().renderModulePackage"
+		);
+	}
+
+	/**
+	 * Renders generated source.
+	 * @param {RenderContext} renderContext the render context
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {Source} generated source
+	 */
+	renderChunk(
+		{
+			undoPath,
+			chunk,
+			codeGenerationResults,
+			modules,
+			runtimeTemplate,
+			chunkGraph,
+			hash
+		},
+		hooks
+	) {
+		const source = new ConcatSource();
+
+		/** @type {string | undefined} */
+		let charset;
+
+		for (const module of modules) {
+			if (
+				typeof (/** @type {BuildInfo} */ (module.buildInfo).charset) !==
+					"undefined" &&
+				typeof charset === "undefined"
+			) {
+				charset = /** @type {BuildInfo} */ (module.buildInfo).charset;
+			}
+
+			try {
+				const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
+				const moduleSourceContent =
+					/** @type {Source} */
+					(
+						codeGenResult.sources.get(CSS_TYPE) ||
+							codeGenResult.sources.get(CSS_IMPORT_TYPE)
+					);
+				const moduleSource = CssModulesPlugin.renderModule(
+					module,
+					{
+						undoPath,
+						hash,
+						chunk,
+						chunkGraph,
+						codeGenerationResults,
+						moduleSourceContent,
+						moduleFactoryCache: this._moduleFactoryCache,
+						runtimeTemplate
+					},
+					hooks
+				);
+				if (moduleSource) {
+					source.add(moduleSource);
+				}
+			} catch (err) {
+				/** @type {Error} */
+				(err).message += `\nduring rendering of css ${module.identifier()}`;
+				throw err;
+			}
+		}
+
+		chunk.rendered = true;
+
+		if (charset) {
+			return new ConcatSource(`@charset "${charset}";\n`, source);
+		}
+
+		return source;
+	}
+
+	/**
+	 * Gets chunk filename template.
+	 * @param {Chunk} chunk chunk
+	 * @param {OutputOptions} outputOptions output options
+	 * @returns {ChunkFilenameTemplate} used filename template
+	 */
+	static getChunkFilenameTemplate(chunk, outputOptions) {
+		if (chunk.cssFilenameTemplate) {
+			return chunk.cssFilenameTemplate;
+		} else if (chunk.canBeInitial()) {
+			return outputOptions.cssFilename;
+		}
+		return outputOptions.cssChunkFilename;
+	}
+
+	/**
+	 * Returns true, when the chunk has css.
+	 * @param {Chunk} chunk chunk
+	 * @param {ChunkGraph} chunkGraph chunk graph
+	 * @returns {boolean} true, when the chunk has css
+	 */
+	static chunkHasCss(chunk, chunkGraph) {
+		return (
+			Boolean(
+				chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_TYPE)
+			) ||
+			Boolean(
+				chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_IMPORT_TYPE)
+			)
+		);
+	}
+}
+
+module.exports = CssModulesPlugin;
Index: frontend/node_modules/webpack/lib/css/CssParser.js
===================================================================
--- frontend/node_modules/webpack/lib/css/CssParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/CssParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3085 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const path = require("path");
+const vm = require("vm");
+const { CSS_MODULE_TYPE_AUTO } = require("../ModuleTypeConstants");
+const Parser = require("../Parser");
+const ConstDependency = require("../dependencies/ConstDependency");
+const CssIcssExportDependency = require("../dependencies/CssIcssExportDependency");
+const CssIcssImportDependency = require("../dependencies/CssIcssImportDependency");
+const CssIcssSymbolDependency = require("../dependencies/CssIcssSymbolDependency");
+const CssImportDependency = require("../dependencies/CssImportDependency");
+const CssUrlDependency = require("../dependencies/CssUrlDependency");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
+const ModuleDependencyWarning = require("../errors/ModuleDependencyWarning");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const WebpackError = require("../errors/WebpackError");
+const LocConverter = require("../util/LocConverter");
+const binarySearchBounds = require("../util/binarySearchBounds");
+const { parseResource } = require("../util/identifier");
+const {
+	createMagicCommentContext,
+	webpackCommentRegExp
+} = require("../util/magicComment");
+const topologicalSort = require("../util/topologicalSort");
+const walkCssTokens = require("./walkCssTokens");
+
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+/** @typedef {import("./walkCssTokens").CssTokenCallbacks} CssTokenCallbacks */
+/** @typedef {import("../../declarations/WebpackOptions").CssAutoOrModuleParserOptions} CssAutoOrModuleParserOptions */
+/** @typedef {import("../../declarations/WebpackOptions").CssModuleParserOptions} CssModuleParserOptions */
+/** @typedef {import("./CssModule")} CssModule */
+
+/** @typedef {[number, number]} Range */
+/** @typedef {{ line: number, column: number }} Position */
+/** @typedef {{ value: string, range: Range, loc: { start: Position, end: Position } }} Comment */
+
+const CC_COLON = ":".charCodeAt(0);
+const CC_SEMICOLON = ";".charCodeAt(0);
+const CC_COMMA = ",".charCodeAt(0);
+const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
+const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
+const CC_LOWER_F = "f".charCodeAt(0);
+const CC_UPPER_F = "F".charCodeAt(0);
+const CC_RIGHT_CURLY = "}".charCodeAt(0);
+const CC_HYPHEN_MINUS = "-".charCodeAt(0);
+const CC_TILDE = "~".charCodeAt(0);
+const CC_EQUAL = "=".charCodeAt(0);
+const CC_FULL_STOP = ".".charCodeAt(0);
+const CC_EXCLAMATION = "!".charCodeAt(0);
+const CC_AMPERSAND = "&".charCodeAt(0);
+
+// https://www.w3.org/TR/css-syntax-3/#newline
+// We don't have `preprocessing` stage, so we need specify all of them
+const STRING_MULTILINE = /\\[\n\r\f]/g;
+// https://www.w3.org/TR/css-syntax-3/#whitespace
+const TRIM_WHITE_SPACES = /(^[ \t\n\r\f]*|[ \t\n\r\f]*$)/g;
+const UNESCAPE = /\\([0-9a-f]{1,6}[ \t\n\r\f]?|[\s\S])/gi;
+const IMAGE_SET_FUNCTION = /^(?:-\w+-)?image-set$/i;
+const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(?:-\w+-)?keyframes$/;
+const COMPOSES_PROPERTY = /^(?:composes|compose-with)$/i;
+const IS_MODULES = /\.modules?\.[^.]+$/i;
+const CSS_COMMENT = /\/\*((?!\*\/)[\s\S]*?)\*\//g;
+
+/**
+ * Returns matches.
+ * @param {RegExp} regexp a regexp
+ * @param {string} str a string
+ * @returns {RegExpExecArray[]} matches
+ */
+const matchAll = (regexp, str) => {
+	/** @type {RegExpExecArray[]} */
+	const result = [];
+
+	/** @type {null | RegExpExecArray} */
+	let match;
+
+	// Use a while loop with exec() to find all matches
+	while ((match = regexp.exec(str)) !== null) {
+		result.push(match);
+	}
+	// Return an array to be easily iterable (note: a true spec-compliant polyfill
+	// returns an iterator object, but an array spread often suffices for basic use)
+	return result;
+};
+
+/**
+ * Returns normalized url.
+ * @param {string} str url string
+ * @param {boolean} isString is url wrapped in quotes
+ * @returns {string} normalized url
+ */
+const normalizeUrl = (str, isString) => {
+	// Remove extra spaces and newlines:
+	// `url("im\
+	// g.png")`
+	if (isString) {
+		str = str.replace(STRING_MULTILINE, "");
+	}
+
+	str = str
+		// Remove unnecessary spaces from `url("   img.png	 ")`
+		.replace(TRIM_WHITE_SPACES, "")
+		// Unescape
+		.replace(UNESCAPE, (match) => {
+			if (match.length > 2) {
+				return String.fromCharCode(Number.parseInt(match.slice(1).trim(), 16));
+			}
+			return match[1];
+		});
+
+	if (/^data:/i.test(str)) {
+		return str;
+	}
+
+	if (str.includes("%")) {
+		// Convert `url('%2E/img.png')` -> `url('./img.png')`
+		try {
+			str = decodeURIComponent(str);
+		} catch (_err) {
+			// Ignore
+		}
+	}
+
+	return str;
+};
+
+const { escapeIdentifier, unescapeIdentifier } = walkCssTokens;
+
+/**
+ * A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
+ * The <custom-property-name> production corresponds to this:
+ * it’s defined as any <dashed-ident> (a valid identifier that starts with two dashes),
+ * except -- itself, which is reserved for future use by CSS.
+ * @param {string} identifier identifier
+ * @returns {boolean} true when identifier is dashed, otherwise false
+ */
+const isDashedIdentifier = (identifier) =>
+	identifier.startsWith("--") && identifier.length >= 3;
+
+/** @type {Record<string, number>} */
+const PREDEFINED_COUNTER_STYLES = {
+	decimal: 1,
+	"decimal-leading-zero": 1,
+	"arabic-indic": 1,
+	armenian: 1,
+	"upper-armenian": 1,
+	"lower-armenian": 1,
+	bengali: 1,
+	cambodian: 1,
+	khmer: 1,
+	"cjk-decimal": 1,
+	devanagari: 1,
+	georgian: 1,
+	gujarati: 1,
+	/* cspell:disable-next-line */
+	gurmukhi: 1,
+	hebrew: 1,
+	kannada: 1,
+	lao: 1,
+	malayalam: 1,
+	mongolian: 1,
+	myanmar: 1,
+	oriya: 1,
+	persian: 1,
+	"lower-roman": 1,
+	"upper-roman": 1,
+	tamil: 1,
+	telugu: 1,
+	thai: 1,
+	tibetan: 1,
+
+	"lower-alpha": 1,
+	"lower-latin": 1,
+	"upper-alpha": 1,
+	"upper-latin": 1,
+	"lower-greek": 1,
+	hiragana: 1,
+	/* cspell:disable-next-line */
+	"hiragana-iroha": 1,
+	katakana: 1,
+	/* cspell:disable-next-line */
+	"katakana-iroha": 1,
+
+	disc: 1,
+	circle: 1,
+	square: 1,
+	"disclosure-open": 1,
+	"disclosure-closed": 1,
+
+	"cjk-earthly-branch": 1,
+	"cjk-heavenly-stem": 1,
+
+	"japanese-informal": 1,
+	"japanese-formal": 1,
+
+	"korean-hangul-formal": 1,
+	/* cspell:disable-next-line */
+	"korean-hanja-informal": 1,
+	/* cspell:disable-next-line */
+	"korean-hanja-formal": 1,
+
+	"simp-chinese-informal": 1,
+	"simp-chinese-formal": 1,
+	"trad-chinese-informal": 1,
+	"trad-chinese-formal": 1,
+	"cjk-ideographic": 1,
+
+	"ethiopic-numeric": 1
+};
+
+/** @type {Record<string, number>} */
+const GLOBAL_VALUES = {
+	// Global values
+	initial: Infinity,
+	inherit: Infinity,
+	unset: Infinity,
+	revert: Infinity,
+	"revert-layer": Infinity
+};
+
+/** @type {Record<string, number>} */
+const GRID_AREA_OR_COLUMN_OR_ROW = {
+	auto: Infinity,
+	span: Infinity,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_AUTO_COLUMNS_OR_ROW = {
+	"min-content": Infinity,
+	"max-content": Infinity,
+	auto: Infinity,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_AUTO_FLOW = {
+	row: 1,
+	column: 1,
+	dense: 1,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_TEMPLATE_AREAS = {
+	// Special
+	none: 1,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_TEMPLATE_COLUMNS_OR_ROWS = {
+	none: 1,
+	subgrid: 1,
+	masonry: 1,
+	"max-content": Infinity,
+	"min-content": Infinity,
+	auto: Infinity,
+	...GLOBAL_VALUES
+};
+
+/** @type {Record<string, number>} */
+const GRID_TEMPLATE = {
+	...GRID_TEMPLATE_AREAS,
+	...GRID_TEMPLATE_COLUMNS_OR_ROWS
+};
+
+/** @type {Record<string, number>} */
+const GRID = {
+	"auto-flow": 1,
+	dense: 1,
+	...GRID_AUTO_COLUMNS_OR_ROW,
+	...GRID_AUTO_FLOW,
+	...GRID_TEMPLATE_AREAS,
+	...GRID_TEMPLATE_COLUMNS_OR_ROWS
+};
+
+/**
+ * Gets known properties.
+ * @param {{ animation?: boolean, container?: boolean, customIdents?: boolean, grid?: boolean }=} options options
+ * @returns {Map<string, Record<string, number>>} list of known properties
+ */
+const getKnownProperties = (options = {}) => {
+	/** @type {Map<string, Record<string, number>>} */
+	const knownProperties = new Map();
+
+	if (options.animation) {
+		knownProperties.set("animation", {
+			// animation-direction
+			normal: 1,
+			reverse: 1,
+			alternate: 1,
+			"alternate-reverse": 1,
+			// animation-fill-mode
+			forwards: 1,
+			backwards: 1,
+			both: 1,
+			// animation-iteration-count
+			infinite: 1,
+			// animation-play-state
+			paused: 1,
+			running: 1,
+			// animation-timing-function
+			ease: 1,
+			"ease-in": 1,
+			"ease-out": 1,
+			"ease-in-out": 1,
+			linear: 1,
+			"step-end": 1,
+			"step-start": 1,
+			// Special
+			none: Infinity, // No matter how many times you write none, it will never be an animation name
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("animation-name", {
+			// Special
+			none: Infinity, // No matter how many times you write none, it will never be an animation name
+			...GLOBAL_VALUES
+		});
+	}
+
+	if (options.container) {
+		knownProperties.set("container", {
+			// container-type
+			normal: 1,
+			size: 1,
+			"inline-size": 1,
+			"scroll-state": 1,
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("container-name", {
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+	}
+
+	if (options.customIdents) {
+		knownProperties.set("list-style", {
+			// list-style-position
+			inside: 1,
+			outside: 1,
+			// list-style-type
+			...PREDEFINED_COUNTER_STYLES,
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("list-style-type", {
+			// list-style-type
+			...PREDEFINED_COUNTER_STYLES,
+			// Special
+			none: Infinity,
+			...GLOBAL_VALUES
+		});
+		knownProperties.set("system", {
+			cyclic: 1,
+			numeric: 1,
+			alphabetic: 1,
+			symbolic: 1,
+			additive: 1,
+			fixed: 1,
+			extends: 1,
+			...PREDEFINED_COUNTER_STYLES
+		});
+		knownProperties.set("fallback", {
+			...PREDEFINED_COUNTER_STYLES
+		});
+		knownProperties.set("speak-as", {
+			auto: 1,
+			bullets: 1,
+			numbers: 1,
+			words: 1,
+			"spell-out": 1,
+			...PREDEFINED_COUNTER_STYLES
+		});
+	}
+
+	if (options.grid) {
+		knownProperties.set("grid", GRID);
+		knownProperties.set("grid-area", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-column", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-column-end", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-column-start", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-row", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-row-end", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-row-start", GRID_AREA_OR_COLUMN_OR_ROW);
+		knownProperties.set("grid-template", GRID_TEMPLATE);
+		knownProperties.set("grid-template-areas", GRID_TEMPLATE_AREAS);
+		knownProperties.set("grid-template-columns", GRID_TEMPLATE_COLUMNS_OR_ROWS);
+		knownProperties.set("grid-template-rows", GRID_TEMPLATE_COLUMNS_OR_ROWS);
+	}
+
+	return knownProperties;
+};
+
+const EMPTY_COMMENT_OPTIONS = {
+	options: null,
+	errors: null
+};
+
+const CSS_MODE_TOP_LEVEL = 0;
+const CSS_MODE_IN_BLOCK = 1;
+
+const LOCAL_MODE = 0;
+const GLOBAL_MODE = 1;
+
+const eatUntilSemi = walkCssTokens.eatUntil(";");
+const eatUntilLeftCurly = walkCssTokens.eatUntil("{");
+
+/**
+ * Defines the css parser own options type used by this module.
+ * @typedef {object} CssParserOwnOptions
+ * @property {("pure" | "global" | "local" | "auto")=} defaultMode default mode
+ */
+
+/** @typedef {CssAutoOrModuleParserOptions & CssParserOwnOptions} CssParserOptions */
+
+class CssParser extends Parser {
+	/**
+	 * Creates an instance of CssParser.
+	 * @param {CssParserOptions=} options options
+	 */
+	constructor(options = {}) {
+		super();
+		this.defaultMode =
+			typeof options.defaultMode !== "undefined" ? options.defaultMode : "pure";
+		this.options = {
+			url: true,
+			import: true,
+			namedExports: true,
+			animation: true,
+			container: true,
+			customIdents: true,
+			dashedIdents: true,
+			function: true,
+			grid: true,
+			...options
+		};
+		/** @type {Comment[] | undefined} */
+		this.comments = undefined;
+		this.magicCommentContext = createMagicCommentContext();
+	}
+
+	/**
+	 * Processes the provided state.
+	 * @param {ParserState} state parser state
+	 * @param {string} message warning message
+	 * @param {LocConverter} locConverter location converter
+	 * @param {number} start start offset
+	 * @param {number} end end offset
+	 */
+	_emitWarning(state, message, locConverter, start, end) {
+		const { line: sl, column: sc } = locConverter.get(start);
+		const { line: el, column: ec } = locConverter.get(end);
+
+		state.current.addWarning(
+			new ModuleDependencyWarning(state.module, new WebpackError(message), {
+				start: { line: sl, column: sc },
+				end: { line: el, column: ec }
+			})
+		);
+	}
+
+	/**
+	 * Emits a build error for the provided range.
+	 * @param {ParserState} state parser state
+	 * @param {string} message error message
+	 * @param {LocConverter} locConverter location converter
+	 * @param {number} start start offset
+	 * @param {number} end end offset
+	 */
+	_emitError(state, message, locConverter, start, end) {
+		const { line: sl, column: sc } = locConverter.get(start);
+		const { line: el, column: ec } = locConverter.get(end);
+
+		const err = new WebpackError(message);
+		err.module = state.module;
+		err.loc = {
+			start: { line: sl, column: sc },
+			end: { line: el, column: ec }
+		};
+		state.module.addError(err);
+	}
+
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (Buffer.isBuffer(source)) {
+			source = source.toString("utf8");
+		} else if (typeof source === "object") {
+			throw new Error("webpackAst is unexpected for the CssParser");
+		}
+		if (source[0] === "\uFEFF") {
+			source = source.slice(1);
+		}
+
+		const unescapeIdentifierCached = unescapeIdentifier.bindCache(
+			state.compilation.compiler.root
+		);
+
+		let mode = this.defaultMode;
+
+		const module = state.module;
+
+		if (
+			mode === "auto" &&
+			module.type === CSS_MODULE_TYPE_AUTO &&
+			IS_MODULES.test(
+				parseResource(/** @type {string} */ (module.getResource())).path
+			)
+		) {
+			mode = "local";
+		}
+
+		const isModules = mode === "global" || mode === "local";
+
+		const parsedModuleResource = parseResource(
+			/** @type {string} */ (module.getResource())
+		);
+
+		/**
+		 * Check whether a request points back to the current module
+		 * (e.g. `composes: foo from "./self.module.css"` inside `self.module.css`).
+		 * Only relative requests are checked — aliases / package / absolute requests
+		 * fall through to the normal import path. Requests with a `?query` or
+		 * `#fragment` are only treated as self when the parent module's resource
+		 * has the same query/fragment, since `NormalModuleFactory` keys modules
+		 * on the full resource string.
+		 * @param {string} request request string from `from "<request>"`
+		 * @returns {boolean} true if request resolves to the current module
+		 */
+		const isSelfReferenceRequest = (request) => {
+			if (!/^\.{1,2}\//.test(request)) return false;
+			if (!module.context) return false;
+			const parsedRequest = parseResource(request);
+			if (parsedRequest.query !== parsedModuleResource.query) return false;
+			if (parsedRequest.fragment !== parsedModuleResource.fragment) {
+				return false;
+			}
+			try {
+				return (
+					path.resolve(module.context, parsedRequest.path) ===
+					parsedModuleResource.path
+				);
+			} catch (_err) {
+				return false;
+			}
+		};
+
+		const knownProperties = getKnownProperties({
+			animation: this.options.animation,
+			container: this.options.container,
+			customIdents: this.options.customIdents,
+			grid: this.options.grid
+		});
+
+		/** @type {BuildMeta} */
+		(module.buildMeta).isCssModule = isModules;
+		if (/** @type {CssModule} */ (module).exportType === "style") {
+			/** @type {BuildMeta} */
+			(module.buildMeta).needIdInConcatenation = true;
+		}
+
+		const locConverter = new LocConverter(source);
+
+		/** @type {number} */
+		let scope = CSS_MODE_TOP_LEVEL;
+		/** @type {boolean} */
+		let allowImportAtRule = true;
+		/** @type {[string, number, number, boolean?][]} */
+		const balanced = [];
+		let lastTokenEndForComments = 0;
+
+		/** @type {boolean} */
+		let isNextRulePrelude = isModules;
+		/** @type {number} */
+		let blockNestingLevel = 0;
+		/** @type {0 | 1 | undefined} */
+		let modeData;
+		/** @type {number} */
+		let counter = 0;
+
+		/** @type {string[]} */
+		let lastLocalIdentifiers = [];
+
+		const pureMode = isModules && Boolean(this.options.pure);
+		/** @type {boolean} */
+		let currentSelectorHasLocal = false;
+		/** Whether any comma-separated selector in the current rule's prelude was impure. */
+		let currentRuleHasImpureSelector = false;
+		/** Offset just after the previous `}` (or 0) — used as the prelude start. */
+		let currentRulePreludeStart = 0;
+		/** Pure-mode flags (only meaningful when `pureMode` is true). */
+		let pureNoCheck = false;
+		let pureIgnorePending = false;
+		let nextBlockChildrenSkip = false;
+		let nextBlockTreatAsLeaf = false;
+		let seenTopLevelRule = false;
+		// True after an at-rule keyword and before the next `{` or `;`. Used so
+		// identifiers inside the at-rule prelude (e.g. `min-width` inside
+		// `@media (min-width: 768px)`) don't get counted as declarations.
+		let inAtRulePrelude = false;
+		/**
+		 * One entry per open block. `skipOwn` skips this rule's own check (set
+		 * when the parent passed down `skipChildren`, e.g. `from`/`to` inside
+		 * `@keyframes`). `skipChildren` is propagated to descendants. `ignored`
+		 * is per-rule only (PCSL semantics for `cssmodules-pure-ignore`).
+		 * `ancestorHadLocal` lets nested rules inherit purity from a
+		 * local-bearing ancestor.
+		 * @type {{
+		 * ignored: boolean,
+		 * skipOwn: boolean,
+		 * skipChildren: boolean,
+		 * treatAsLeaf: boolean,
+		 * ancestorHadLocal: boolean,
+		 * impure: boolean,
+		 * hasDirectDecl: boolean,
+		 * hasNestedBlock: boolean,
+		 * isRulePrelude: boolean,
+		 * preludeStart: number,
+		 * preludeEnd: number,
+		 * }[]}
+		 */
+		const pureBlockStack = [];
+
+		const PURE_IGNORE_RE = /^\s*cssmodules-pure-ignore(?:\s|$)/;
+		const PURE_NO_CHECK_RE = /^\s*cssmodules-pure-no-check(?:\s|$)/;
+
+		/**
+		 * @returns {(typeof pureBlockStack)[number] | undefined} top of stack
+		 */
+		const pureTop = () => pureBlockStack[pureBlockStack.length - 1];
+
+		/**
+		 * Was the parent rule pure overall (its own selectors pure or any
+		 * ancestor pure)? Used both for ancestor-inheritance and `&`-resolution.
+		 * @returns {boolean} true if any ancestor (self inclusive) provided a local
+		 */
+		const parentEffectivePure = () => {
+			const top = pureTop();
+			return top ? top.ancestorHadLocal : false;
+		};
+
+		/**
+		 * Marks the just-finished comma-separated selector (or whole prelude
+		 * at `{`) as impure if it lacks a local and no ancestor compensates.
+		 */
+		const finalizeSelector = () => {
+			if (!currentSelectorHasLocal && !parentEffectivePure()) {
+				currentRuleHasImpureSelector = true;
+			}
+			currentSelectorHasLocal = false;
+		};
+
+		/**
+		 * Reports a pure-mode violation covering the entire rule prelude.
+		 * @param {number} start prelude start offset
+		 * @param {number} end prelude end offset (`{` position)
+		 */
+		const reportPureRule = (start, end) => {
+			const slice = source.slice(start, end);
+			const lead = /** @type {RegExpExecArray} */ (
+				/^(?:\s|\/\*[\s\S]*?\*\/)*/.exec(slice)
+			)[0].length;
+			const trail = /** @type {RegExpExecArray} */ (/\s*$/.exec(slice))[0]
+				.length;
+			const from = start + lead;
+			const to = end - trail;
+			if (to <= from) return;
+			this._emitError(
+				state,
+				`Selector "${source.slice(from, to)}" is not pure (pure selectors must contain at least one local class or id)`,
+				locConverter,
+				from,
+				to
+			);
+		};
+
+		/** @typedef {{ value?: string, importName?: string, localName?: string, request?: string }} IcssDefinition */
+		/** @type {Map<string, IcssDefinition>} */
+		const icssDefinitions = new Map();
+
+		// Tracks `composes: <name> from "<file>"` declarations to enforce a
+		// predictable file load order across rules (port of
+		// postcss-modules-extract-imports#138). Each rule's composes order
+		// is a partial ordering: if `.x` composes `b from "./b"` before
+		// `c from "./c"`, then `b.css` must load before `c.css` so `c` can
+		// override `b` in the cascade. Edges are added inline as the rule
+		// is parsed; at end-of-parse the first composes-import dep of each
+		// file is tagged with `sourceOrder` according to a topological
+		// sort (`NormalModule#build` reorders by `sourceOrder` for us).
+		/** @type {Map<string, Set<string>>} */
+		const composesGraph = new Map();
+		/** @type {Map<string, CssIcssImportDependency>} */
+		const composesFirstFileImport = new Map();
+		/** @type {string | undefined} */
+		let currentRulePrevComposesFile;
+		/** @type {Set<string>} */
+		const currentRuleComposesFiles = new Set();
+
+		/**
+		 * Checks whether this css parser is next nested syntax.
+		 * @param {string} input input
+		 * @param {number} pos position
+		 * @returns {boolean} true, when next is nested syntax
+		 */
+		const isNextNestedSyntax = (input, pos) => {
+			pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+
+			if (
+				input.charCodeAt(pos) === CC_RIGHT_CURLY ||
+				(input.charCodeAt(pos) === CC_HYPHEN_MINUS &&
+					input.charCodeAt(pos + 1) === CC_HYPHEN_MINUS)
+			) {
+				return false;
+			}
+
+			const identifier = walkCssTokens.eatIdentSequence(input, pos);
+
+			if (!identifier) {
+				return true;
+			}
+
+			const leftCurly = eatUntilLeftCurly(input, pos);
+			const content = input.slice(identifier[0], leftCurly);
+
+			if (content.includes(";") || content.includes("}")) {
+				return false;
+			}
+
+			return true;
+		};
+		/**
+		 * Checks whether this css parser is local mode.
+		 * @returns {boolean} true, when in local scope
+		 */
+		const isLocalMode = () =>
+			modeData === LOCAL_MODE || (mode === "local" && modeData === undefined);
+
+		/**
+		 * Returns end.
+		 * @param {string} input input
+		 * @param {number} start start
+		 * @param {number} end end
+		 * @returns {number} end
+		 */
+		const comment = (input, start, end) => {
+			if (!this.comments) this.comments = [];
+			const { line: sl, column: sc } = locConverter.get(start);
+			const { line: el, column: ec } = locConverter.get(end);
+
+			const value = input.slice(start + 2, end - 2);
+
+			/** @type {Comment} */
+			const comment = {
+				value,
+				range: [start, end],
+				loc: {
+					start: { line: sl, column: sc },
+					end: { line: el, column: ec }
+				}
+			};
+			this.comments.push(comment);
+
+			if (pureMode) {
+				if (PURE_IGNORE_RE.test(value)) {
+					pureIgnorePending = true;
+				} else if (
+					PURE_NO_CHECK_RE.test(value) &&
+					scope === CSS_MODE_TOP_LEVEL &&
+					!seenTopLevelRule
+				) {
+					pureNoCheck = true;
+				}
+			}
+
+			return end;
+		};
+
+		// Vanilla CSS stuff
+
+		/**
+		 * Processes the provided input.
+		 * @param {string} input input
+		 * @param {number} start name start position
+		 * @param {number} end name end position
+		 * @returns {number} position after handling
+		 */
+		const processAtImport = (input, start, end) => {
+			const tokens = walkCssTokens.eatImportTokens(input, end, {
+				comment
+			});
+			if (!tokens[3]) return end;
+			const semi = tokens[3][1];
+			if (!tokens[0] || (tokens[0][4] && !isModules)) {
+				this._emitWarning(
+					state,
+					`Expected URL in '${input.slice(start, semi)}'`,
+					locConverter,
+					start,
+					semi
+				);
+				return end;
+			}
+
+			const urlToken = tokens[0];
+			/** @type {string} */
+			let url;
+			if (urlToken[4]) {
+				// URL given as identifier — resolve via CSS Modules @value.
+				const name = input.slice(urlToken[2], urlToken[3]);
+				const def = icssDefinitions.get(name);
+				if (!def) {
+					this._emitWarning(
+						state,
+						`Unknown '@value' identifier '${name}' in '${input.slice(start, semi)}'`,
+						locConverter,
+						start,
+						semi
+					);
+					// Consume the whole at-rule so the unresolved identifier
+					// doesn't get re-tokenized and accidentally substituted
+					// into a malformed `@import` in the output.
+					const dep = new ConstDependency("", [start, semi]);
+					module.addPresentationalDependency(dep);
+					return semi;
+				}
+				if (def.value === undefined) {
+					this._emitWarning(
+						state,
+						`'@value' identifier '${name}' was imported from another module and cannot be used as the URL of '@import' — only locally defined values are supported here`,
+						locConverter,
+						start,
+						semi
+					);
+					const dep = new ConstDependency("", [start, semi]);
+					module.addPresentationalDependency(dep);
+					return semi;
+				}
+				const raw = def.value.trim();
+				url =
+					(raw.startsWith('"') && raw.endsWith('"')) ||
+					(raw.startsWith("'") && raw.endsWith("'"))
+						? normalizeUrl(raw.slice(1, -1), true)
+						: normalizeUrl(raw, false);
+			} else {
+				url = normalizeUrl(input.slice(urlToken[2], urlToken[3]), true);
+			}
+			const newline = walkCssTokens.eatWhiteLine(input, semi);
+			const { options, errors: commentErrors } = this.parseCommentOptions([
+				end,
+				urlToken[1]
+			]);
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							comment.loc
+						)
+					);
+				}
+			}
+			if (options && options.webpackIgnore !== undefined) {
+				if (typeof options.webpackIgnore !== "boolean") {
+					const { line: sl, column: sc } = locConverter.get(start);
+					const { line: el, column: ec } = locConverter.get(newline);
+
+					state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
+							{
+								start: { line: sl, column: sc },
+								end: { line: el, column: ec }
+							}
+						)
+					);
+				} else if (options.webpackIgnore) {
+					return newline;
+				}
+			}
+			if (url.length === 0) {
+				const { line: sl, column: sc } = locConverter.get(start);
+				const { line: el, column: ec } = locConverter.get(newline);
+				const dep = new ConstDependency("", [start, newline]);
+				module.addPresentationalDependency(dep);
+				dep.setLoc(sl, sc, el, ec);
+
+				return newline;
+			}
+
+			/** @type {undefined | string} */
+			let layer;
+
+			if (tokens[1]) {
+				layer = input.slice(tokens[1][0] + 6, tokens[1][1] - 1).trim();
+			}
+
+			/** @type {undefined | string} */
+			let supports;
+
+			if (tokens[2]) {
+				supports = input.slice(tokens[2][0] + 9, tokens[2][1] - 1).trim();
+			}
+
+			const last = tokens[2] || tokens[1] || tokens[0];
+			const mediaStart = walkCssTokens.eatWhitespaceAndComments(
+				input,
+				last[1]
+			)[0];
+
+			/** @type {undefined | string} */
+			let media;
+
+			if (mediaStart !== semi - 1) {
+				media = input.slice(mediaStart, semi - 1).trim();
+			}
+
+			const { line: sl, column: sc } = locConverter.get(start);
+			const { line: el, column: ec } = locConverter.get(newline);
+			const dep = new CssImportDependency(
+				url,
+				[start, newline],
+				mode === "local" || mode === "global" ? mode : undefined,
+				layer,
+				supports && supports.length > 0 ? supports : undefined,
+				media && media.length > 0 ? media : undefined
+			);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			// `text` and `css-style-sheet` parents inline the imported
+			// module's rendered CSS at build time, which means we read the
+			// imported module's `codeGenerationResults` (and through it the
+			// results of any assets the import references). Registering this
+			// as a code-generation dependency tells the compilation scheduler
+			// to generate the imported subtree before us.
+			const exportType = /** @type {import("./CssModule")} */ (module)
+				.exportType;
+			if (exportType === "text" || exportType === "css-style-sheet") {
+				module.addCodeGenerationDependency(dep);
+			}
+
+			return newline;
+		};
+
+		/**
+		 * Process url function.
+		 * @param {string} input input
+		 * @param {number} end end position
+		 * @param {string} name the name of function
+		 * @returns {number} position after handling
+		 */
+		const processURLFunction = (input, end, name) => {
+			const string = walkCssTokens.eatString(input, end);
+			if (!string) return end;
+			const { options, errors: commentErrors } = this.parseCommentOptions([
+				lastTokenEndForComments,
+				end
+			]);
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							comment.loc
+						)
+					);
+				}
+			}
+			if (options && options.webpackIgnore !== undefined) {
+				if (typeof options.webpackIgnore !== "boolean") {
+					const { line: sl, column: sc } = locConverter.get(string[0]);
+					const { line: el, column: ec } = locConverter.get(string[1]);
+
+					state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
+							{
+								start: { line: sl, column: sc },
+								end: { line: el, column: ec }
+							}
+						)
+					);
+				} else if (options.webpackIgnore) {
+					return end;
+				}
+			}
+			const value = normalizeUrl(
+				input.slice(string[0] + 1, string[1] - 1),
+				true
+			);
+			// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
+			if (value.length === 0) return end;
+			const isUrl = name === "url" || name === "src";
+			const dep = new CssUrlDependency(
+				value,
+				[string[0], string[1]],
+				isUrl ? "string" : "url"
+			);
+			const { line: sl, column: sc } = locConverter.get(string[0]);
+			const { line: el, column: ec } = locConverter.get(string[1]);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			module.addCodeGenerationDependency(dep);
+			return string[1];
+		};
+
+		/**
+		 * Process old url function.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @param {number} contentStart start position
+		 * @param {number} contentEnd end position
+		 * @returns {number} position after handling
+		 */
+		const processOldURLFunction = (
+			input,
+			start,
+			end,
+			contentStart,
+			contentEnd
+		) => {
+			const { options, errors: commentErrors } = this.parseCommentOptions([
+				lastTokenEndForComments,
+				end
+			]);
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							comment.loc
+						)
+					);
+				}
+			}
+			if (options && options.webpackIgnore !== undefined) {
+				if (typeof options.webpackIgnore !== "boolean") {
+					const { line: sl, column: sc } = locConverter.get(
+						lastTokenEndForComments
+					);
+					const { line: el, column: ec } = locConverter.get(end);
+
+					state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
+							{
+								start: { line: sl, column: sc },
+								end: { line: el, column: ec }
+							}
+						)
+					);
+				} else if (options.webpackIgnore) {
+					return end;
+				}
+			}
+			let value = normalizeUrl(input.slice(contentStart, contentEnd), false);
+			// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
+			if (value.length === 0) return end;
+			if (isModules) {
+				const def = icssDefinitions.get(value);
+				if (def) {
+					if (def.value !== undefined) {
+						const raw = def.value.trim();
+						value =
+							(raw.startsWith('"') && raw.endsWith('"')) ||
+							(raw.startsWith("'") && raw.endsWith("'"))
+								? normalizeUrl(raw.slice(1, -1), true)
+								: normalizeUrl(raw, false);
+						if (value.length === 0) return end;
+					} else {
+						this._emitWarning(
+							state,
+							`'@value' identifier '${value}' was imported from another module and cannot be used inside 'url()' — only locally defined values are supported here`,
+							locConverter,
+							start,
+							end
+						);
+						return end;
+					}
+				}
+			}
+			const dep = new CssUrlDependency(value, [start, end], "url");
+			const { line: sl, column: sc } = locConverter.get(start);
+			const { line: el, column: ec } = locConverter.get(end);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			module.addCodeGenerationDependency(dep);
+			return end;
+		};
+
+		/**
+		 * Process image set function.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processImageSetFunction = (input, start, end) => {
+			lastTokenEndForComments = end;
+			const values = walkCssTokens.eatImageSetStrings(input, end, {
+				comment
+			});
+			if (values.length === 0) return end;
+			for (const [index, string] of values.entries()) {
+				const value = normalizeUrl(
+					input.slice(string[0] + 1, string[1] - 1),
+					true
+				);
+				if (value.length === 0) return end;
+				const { options, errors: commentErrors } = this.parseCommentOptions([
+					index === 0 ? start : values[index - 1][1],
+					string[1]
+				]);
+				if (commentErrors) {
+					for (const e of commentErrors) {
+						const { comment } = e;
+						state.module.addWarning(
+							new CommentCompilationWarning(
+								`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+								comment.loc
+							)
+						);
+					}
+				}
+				if (options && options.webpackIgnore !== undefined) {
+					if (typeof options.webpackIgnore !== "boolean") {
+						const { line: sl, column: sc } = locConverter.get(string[0]);
+						const { line: el, column: ec } = locConverter.get(string[1]);
+
+						state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
+								{
+									start: { line: sl, column: sc },
+									end: { line: el, column: ec }
+								}
+							)
+						);
+					} else if (options.webpackIgnore) {
+						continue;
+					}
+				}
+				const dep = new CssUrlDependency(value, [string[0], string[1]], "url");
+				const { line: sl, column: sc } = locConverter.get(string[0]);
+				const { line: el, column: ec } = locConverter.get(string[1]);
+				dep.setLoc(sl, sc, el, ec);
+				module.addDependency(dep);
+				module.addCodeGenerationDependency(dep);
+			}
+			// Can contain `url()` inside, so let's return end to allow parse them
+			return end;
+		};
+
+		// CSS modules stuff
+
+		/**
+		 * Returns resolved reexport (localName and importName).
+		 * @param {string} value value to resolve
+		 * @param {string=} localName override local name
+		 * @param {boolean=} isCustomProperty true when it is custom property, otherwise false
+		 * @returns {string | [string, string] | [string, string, string]} resolved reexport (`localName`, `importName` and optional `request` of the active `@value` import)
+		 */
+		const getReexport = (value, localName, isCustomProperty) => {
+			const reexport = icssDefinitions.get(
+				isCustomProperty ? `--${value}` : value
+			);
+
+			if (reexport) {
+				if (reexport.importName) {
+					const resolvedLocalName =
+						reexport.localName || (isCustomProperty ? `--${value}` : value);
+					return reexport.request
+						? [resolvedLocalName, reexport.importName, reexport.request]
+						: [resolvedLocalName, reexport.importName];
+				}
+
+				if (isCustomProperty) {
+					return /** @type {string} */ (reexport.value).slice(2);
+				}
+
+				return /** @type {string} */ (reexport.value);
+			}
+
+			if (localName) {
+				return [localName, value];
+			}
+
+			return value;
+		};
+
+		/**
+		 * Process import or export.
+		 * @param {0 | 1} type import or export
+		 * @param {string} input input
+		 * @param {number} pos start position
+		 * @returns {number} position after parse
+		 */
+		const processImportOrExport = (type, input, pos) => {
+			pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+			/** @type {string | undefined} */
+			let request;
+			if (type === 0) {
+				let cc = input.charCodeAt(pos);
+				if (cc !== CC_LEFT_PARENTHESIS) {
+					this._emitWarning(
+						state,
+						`Unexpected '${input[pos]}' at ${pos} during parsing of ':import' (expected '(')`,
+						locConverter,
+						pos,
+						pos
+					);
+					return pos;
+				}
+				pos++;
+				const stringStart = pos;
+				const str = walkCssTokens.eatString(input, pos);
+				if (!str) {
+					this._emitWarning(
+						state,
+						`Unexpected '${input[pos]}' at ${pos} during parsing of '${type === 0 ? ":import" : ":export"}' (expected string)`,
+						locConverter,
+						stringStart,
+						pos
+					);
+					return pos;
+				}
+				request = input.slice(str[0] + 1, str[1] - 1);
+				pos = str[1];
+				pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+				cc = input.charCodeAt(pos);
+				if (cc !== CC_RIGHT_PARENTHESIS) {
+					this._emitWarning(
+						state,
+						`Unexpected '${input[pos]}' at ${pos} during parsing of ':import' (expected ')')`,
+						locConverter,
+						pos,
+						pos
+					);
+					return pos;
+				}
+				pos++;
+				pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+			}
+
+			/**
+			 * Creates a dep from the provided name.
+			 * @param {string} name name
+			 * @param {string} value value
+			 * @param {number} start start of position
+			 * @param {number} end end of position
+			 */
+			const createDep = (name, value, start, end) => {
+				if (type === 0) {
+					const dep = new CssIcssImportDependency(
+						/** @type {string} */
+						(request),
+						[0, 0],
+						/** @type {"local" | "global"} */
+						(mode),
+						value,
+						name
+					);
+					const { line: sl, column: sc } = locConverter.get(start);
+					const { line: el, column: ec } = locConverter.get(end);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
+
+					icssDefinitions.set(name, {
+						importName: value,
+						request: /** @type {string} */ (request)
+					});
+				} else if (type === 1) {
+					const dep = new CssIcssExportDependency(name, getReexport(value));
+					const { line: sl, column: sc } = locConverter.get(start);
+					const { line: el, column: ec } = locConverter.get(end);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
+				}
+			};
+
+			let needTerminate = false;
+			let balanced = 0;
+			/** @type {undefined | 0 | 1 | 2} */
+			let scope;
+
+			/** @typedef {[number, number]} Name */
+
+			/** @type {Name | undefined} */
+			let name;
+			/** @type {number | undefined} */
+			let value;
+
+			/** @type {CssTokenCallbacks} */
+			const callbacks = {
+				leftCurlyBracket: (_input, _start, end) => {
+					balanced++;
+
+					if (scope === undefined) {
+						scope = 0;
+					}
+
+					return end;
+				},
+				rightCurlyBracket: (_input, _start, end) => {
+					balanced--;
+
+					if (scope === 2) {
+						const [nameStart, nameEnd] = /** @type {Name} */ (name);
+						createDep(
+							input.slice(nameStart, nameEnd),
+							input.slice(value, end - 1).trim(),
+							nameEnd,
+							end - 1
+						);
+						scope = 0;
+					}
+
+					if (balanced === 0 && scope === 0) {
+						needTerminate = true;
+					}
+
+					return end;
+				},
+				identifier: (_input, start, end) => {
+					if (scope === 0) {
+						name = [start, end];
+						scope = 1;
+					}
+
+					return end;
+				},
+				colon: (_input, _start, end) => {
+					if (scope === 1) {
+						scope = 2;
+						value = walkCssTokens.eatWhitespace(input, end);
+						return value;
+					}
+
+					return end;
+				},
+				semicolon: (input, _start, end) => {
+					if (scope === 2) {
+						const [nameStart, nameEnd] = /** @type {Name} */ (name);
+						createDep(
+							input.slice(nameStart, nameEnd),
+							input.slice(value, end - 1),
+							nameEnd,
+							end - 1
+						);
+						scope = 0;
+					}
+
+					return end;
+				},
+				needTerminate: () => needTerminate
+			};
+
+			pos = walkCssTokens(input, pos, callbacks);
+			pos = walkCssTokens.eatWhiteLine(input, pos);
+
+			return pos;
+		};
+
+		/** @typedef {{ from: string, items: ({ localName: string, importName: string })[] }} ValueAtRuleImport */
+		/** @typedef {{ localName: string, value: string }} ValueAtRuleValue */
+		/**
+		 * Parses value at rule params.
+		 * @param {string} str value at-rule params
+		 * @returns {ValueAtRuleImport | ValueAtRuleValue} parsed result
+		 */
+		const parseValueAtRuleParams = (str) => {
+			if (/from(\/\*|\s)(?:[\s\S]+)$/i.test(str)) {
+				str = str.replace(CSS_COMMENT, " ").trim().replace(/;$/, "");
+				const fromIdx = str.lastIndexOf("from");
+				const path = str
+					.slice(fromIdx + 5)
+					.trim()
+					.replace(/['"]/g, "");
+				let content = str.slice(0, fromIdx).trim();
+
+				if (content.startsWith("(") && content.endsWith(")")) {
+					content = content.slice(1, -1);
+				}
+
+				return {
+					from: path,
+					items: content.split(",").map((item) => {
+						item = item.trim();
+
+						if (item.includes(":")) {
+							const [local, remote] = item.split(":");
+
+							return { localName: local.trim(), importName: remote.trim() };
+						}
+
+						const asParts = item.split(/\s+as\s+/);
+
+						if (asParts.length === 2) {
+							return {
+								localName: asParts[1].trim(),
+								importName: asParts[0].trim()
+							};
+						}
+
+						return { localName: item, importName: item };
+					})
+				};
+			}
+
+			/** @type {string} */
+			let localName;
+			/** @type {string} */
+			let value;
+
+			const idx = str.indexOf(":");
+
+			if (idx !== -1) {
+				localName = str.slice(0, idx).replace(CSS_COMMENT, "").trim();
+				value = str.slice(idx + 1);
+			} else {
+				const mask = str.replace(CSS_COMMENT, (m) => " ".repeat(m.length));
+				const idx = mask.search(/\S\s/) + 1;
+
+				localName = str.slice(0, idx).replace(CSS_COMMENT, "").trim();
+				value = str.slice(idx + (str[idx] === " " ? 1 : 0));
+			}
+
+			if (value.length > 0 && !/^\s+$/.test(value.replace(CSS_COMMENT, ""))) {
+				value = value.trim();
+			}
+
+			return { localName, value };
+		};
+
+		/**
+		 * Processes the provided input.
+		 * @param {string} input input
+		 * @param {number} start name start position
+		 * @param {number} end name end position
+		 * @returns {number} position after handling
+		 */
+		const processAtValue = (input, start, end) => {
+			const semi = eatUntilSemi(input, end);
+			const atRuleEnd = semi + 1;
+			const params = input.slice(end, semi);
+			const parsed = parseValueAtRuleParams(params);
+
+			if (
+				typeof (/** @type {ValueAtRuleImport} */ (parsed).from) !== "undefined"
+			) {
+				if (/** @type {ValueAtRuleImport} */ (parsed).from.length === 0) {
+					this._emitWarning(
+						state,
+						`Broken '@value' at-rule: ${input.slice(start, atRuleEnd)}'`,
+						locConverter,
+						start,
+						atRuleEnd
+					);
+
+					const dep = new ConstDependency("", [start, atRuleEnd]);
+					module.addPresentationalDependency(dep);
+					return atRuleEnd;
+				}
+
+				let { from, items } = /** @type {ValueAtRuleImport} */ (parsed);
+
+				for (const { importName, localName } of items) {
+					{
+						const reexport = icssDefinitions.get(from);
+
+						if (reexport && reexport.value) {
+							from = reexport.value.slice(1, -1);
+						}
+
+						const dep = new CssIcssImportDependency(
+							from,
+							[0, 0],
+							/** @type {"local" | "global"} */
+							(mode),
+							importName,
+							localName
+						);
+						const { line: sl, column: sc } = locConverter.get(start);
+						const { line: el, column: ec } = locConverter.get(end);
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+
+						icssDefinitions.set(localName, { importName, request: from });
+					}
+
+					{
+						const dep = new CssIcssExportDependency(
+							localName,
+							getReexport(localName),
+							undefined,
+							false,
+							CssIcssExportDependency.EXPORT_MODE.REPLACE
+						);
+						const { line: sl, column: sc } = locConverter.get(start);
+						const { line: el, column: ec } = locConverter.get(end);
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
+				}
+			} else {
+				if (/** @type {ValueAtRuleValue} */ (parsed).localName.length === 0) {
+					this._emitWarning(
+						state,
+						`Broken '@value' at-rule: ${input.slice(start, atRuleEnd)}'`,
+						locConverter,
+						start,
+						atRuleEnd
+					);
+
+					const dep = new ConstDependency("", [start, atRuleEnd]);
+					module.addPresentationalDependency(dep);
+					return atRuleEnd;
+				}
+
+				const { localName, value } = /** @type {ValueAtRuleValue} */ (parsed);
+				const { line: sl, column: sc } = locConverter.get(start);
+				const { line: el, column: ec } = locConverter.get(end);
+
+				if (icssDefinitions.has(value)) {
+					const def =
+						/** @type {IcssDefinition} */
+						(icssDefinitions.get(value));
+
+					def.localName = value;
+
+					icssDefinitions.set(localName, def);
+
+					const dep = new CssIcssExportDependency(
+						localName,
+						getReexport(value)
+					);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
+				} else {
+					icssDefinitions.set(localName, { value });
+
+					const dep = new CssIcssExportDependency(localName, value);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
+				}
+			}
+
+			const dep = new ConstDependency("", [start, atRuleEnd]);
+			module.addPresentationalDependency(dep);
+			return atRuleEnd;
+		};
+
+		/**
+		 * Process icss symbol.
+		 * @param {string} name ICSS symbol name
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processICSSSymbol = (name, start, end) => {
+			const def =
+				/** @type {IcssDefinition} */
+				(icssDefinitions.get(name));
+			const { line: sl, column: sc } = locConverter.get(start);
+			const { line: el, column: ec } = locConverter.get(end);
+			const dep = new CssIcssSymbolDependency(
+				def.localName || name,
+				[start, end],
+				def.value,
+				def.importName,
+				def.request
+			);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			return end;
+		};
+
+		/**
+		 * Process local or global function.
+		 * @param {string} input input
+		 * @param {1 | 2} type type of function
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processLocalOrGlobalFunction = (input, type, start, end) => {
+			// Replace `local(`/` or `global(` (handle legacy `:local(` or `:global(` too)
+			{
+				const isColon = input.charCodeAt(start - 1) === CC_COLON;
+				const dep = new ConstDependency("", [isColon ? start - 1 : start, end]);
+				module.addPresentationalDependency(dep);
+			}
+
+			end = walkCssTokens.consumeUntil(
+				input,
+				start,
+				{
+					identifier(input, start, end) {
+						if (type === 1) {
+							let identifier = unescapeIdentifierCached(
+								input.slice(start, end)
+							);
+							const { line: sl, column: sc } = locConverter.get(start);
+							const { line: el, column: ec } = locConverter.get(end);
+							const isDashedIdent = isDashedIdentifier(identifier);
+
+							if (isDashedIdent) {
+								identifier = identifier.slice(2);
+							}
+
+							const dep = new CssIcssExportDependency(
+								identifier,
+								getReexport(identifier),
+								[start, end],
+								true,
+								CssIcssExportDependency.EXPORT_MODE.ONCE,
+								isDashedIdent
+									? CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
+									: CssIcssExportDependency.EXPORT_TYPE.NORMAL
+							);
+
+							dep.setLoc(sl, sc, el, ec);
+							module.addDependency(dep);
+						}
+
+						return end;
+					}
+				},
+				{},
+				{ onlyTopLevel: true, functionValue: true }
+			);
+
+			{
+				// Replace the last `)`
+				const dep = new ConstDependency("", [end, end + 1]);
+				module.addPresentationalDependency(dep);
+			}
+
+			return end;
+		};
+
+		/**
+		 * Process local at rule.
+		 * @param {string} input input
+		 * @param {number} end name end position
+		 * @param {{ string?: boolean, identifier?: boolean | RegExp }} options types which allowed to handle
+		 * @returns {number} position after handling
+		 */
+		const processLocalAtRule = (input, end, options) => {
+			let found = false;
+
+			return walkCssTokens.consumeUntil(
+				input,
+				end,
+				{
+					string(_input, start, end) {
+						if (!found && options.string) {
+							const value = unescapeIdentifierCached(
+								input.slice(start + 1, end - 1)
+							);
+							const { line: sl, column: sc } = locConverter.get(start);
+							const { line: el, column: ec } = locConverter.get(end);
+							const dep = new CssIcssExportDependency(
+								value,
+								value,
+								[start, end],
+								true,
+								CssIcssExportDependency.EXPORT_MODE.ONCE
+							);
+							dep.setLoc(sl, sc, el, ec);
+							module.addDependency(dep);
+							found = true;
+							if (pureMode) currentSelectorHasLocal = true;
+						}
+						return end;
+					},
+					identifier(input, start, end) {
+						if (!found) {
+							const value = input.slice(start, end);
+
+							if (options.identifier) {
+								const identifier = unescapeIdentifierCached(value);
+
+								if (
+									options.identifier instanceof RegExp &&
+									options.identifier.test(identifier)
+								) {
+									return end;
+								}
+
+								const { line: sl, column: sc } = locConverter.get(start);
+								const { line: el, column: ec } = locConverter.get(end);
+
+								const dep = new CssIcssExportDependency(
+									identifier,
+									getReexport(identifier),
+									[start, end],
+									true,
+									CssIcssExportDependency.EXPORT_MODE.ONCE,
+									CssIcssExportDependency.EXPORT_TYPE.NORMAL
+								);
+								dep.setLoc(sl, sc, el, ec);
+								module.addDependency(dep);
+								found = true;
+								if (pureMode) currentSelectorHasLocal = true;
+							}
+						}
+						return end;
+					}
+				},
+				{
+					function: (input, start, end) => {
+						// No need to handle `:` (COLON), because it's always a function
+						const name = input
+							.slice(start, end - 1)
+							.replace(/\\/g, "")
+							.toLowerCase();
+
+						const type =
+							name === "local" ? 1 : name === "global" ? 2 : undefined;
+
+						if (!found && type) {
+							found = true;
+							if (type === 1 && pureMode) currentSelectorHasLocal = true;
+							return processLocalOrGlobalFunction(input, type, start, end);
+						}
+
+						if (
+							this.options.dashedIdents &&
+							isLocalMode() &&
+							(name === "var" || name === "style")
+						) {
+							return processDashedIdent(input, end, end);
+						}
+
+						return end;
+					}
+				},
+				{ onlyTopLevel: true, atRulePrelude: true }
+			);
+		};
+		/**
+		 * Process dashed ident.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processDashedIdent = (input, start, end) => {
+			const customIdent = walkCssTokens.eatIdentSequence(input, start);
+			if (!customIdent) return end;
+			const identifier = unescapeIdentifierCached(
+				input.slice(customIdent[0] + 2, customIdent[1])
+			);
+			const afterCustomIdent = walkCssTokens.eatWhitespaceAndComments(
+				input,
+				customIdent[1]
+			)[0];
+			if (
+				input.charCodeAt(afterCustomIdent) === CC_LOWER_F ||
+				input.charCodeAt(afterCustomIdent) === CC_UPPER_F
+			) {
+				const fromWord = walkCssTokens.eatIdentSequence(
+					input,
+					afterCustomIdent
+				);
+				if (
+					!fromWord ||
+					input.slice(fromWord[0], fromWord[1]).toLowerCase() !== "from"
+				) {
+					return end;
+				}
+				const from = walkCssTokens.eatIdentSequenceOrString(
+					input,
+					walkCssTokens.eatWhitespaceAndComments(input, fromWord[1])[0]
+				);
+				if (!from) {
+					return end;
+				}
+				const path = input.slice(from[0], from[1]);
+				if (from[2] === true && path === "global") {
+					const dep = new ConstDependency("", [customIdent[1], from[1]]);
+					module.addPresentationalDependency(dep);
+					return end;
+				} else if (from[2] === false) {
+					const { line: sl, column: sc } = locConverter.get(customIdent[0]);
+					const { line: el, column: ec } = locConverter.get(from[1] - 1);
+					const localName = `__ICSS_IMPORT_${counter++}__`;
+
+					{
+						const dep = new CssIcssImportDependency(
+							path.slice(1, -1),
+							[customIdent[0], from[1] - 1],
+							/** @type {"local" | "global"} */
+							(mode),
+							identifier,
+							localName
+						);
+
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
+
+					{
+						const dep = new CssIcssExportDependency(
+							identifier,
+							getReexport(identifier, localName, true),
+							[customIdent[0], from[1] - 1],
+							true,
+							CssIcssExportDependency.EXPORT_MODE.ONCE,
+							CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
+						);
+
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
+
+					{
+						const dep = new ConstDependency("", [fromWord[0], from[1]]);
+						module.addPresentationalDependency(dep);
+						return end;
+					}
+				}
+			} else {
+				const { line: sl, column: sc } = locConverter.get(customIdent[0]);
+				const { line: el, column: ec } = locConverter.get(customIdent[1]);
+				const dep = new CssIcssExportDependency(
+					identifier,
+					getReexport(identifier, undefined, true),
+					[customIdent[0], customIdent[1]],
+					true,
+					CssIcssExportDependency.EXPORT_MODE.ONCE,
+					CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
+				);
+				dep.setLoc(sl, sc, el, ec);
+				module.addDependency(dep);
+				return end;
+			}
+
+			return end;
+		};
+		/**
+		 * Process local declaration.
+		 * @param {string} input input
+		 * @param {number} pos name start position
+		 * @param {number} end name end position
+		 * @returns {number} position after handling
+		 */
+		const processLocalDeclaration = (input, pos, end) => {
+			pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+			const identifier = walkCssTokens.eatIdentSequence(input, pos);
+
+			if (!identifier) {
+				return end;
+			}
+
+			const propertyNameStart = identifier[0];
+
+			pos = walkCssTokens.eatWhitespaceAndComments(input, identifier[1])[0];
+
+			if (input.charCodeAt(pos) !== CC_COLON) {
+				return end;
+			}
+
+			pos += 1;
+
+			// Remove prefix and lowercase
+			const propertyName = input
+				.slice(identifier[0], identifier[1])
+				.replace(/^(-\w+-)/, "")
+				.toLowerCase();
+
+			if (isLocalMode() && knownProperties.has(propertyName)) {
+				/** @type {[number, number, boolean?][]} */
+				const values = [];
+				/** @type {Record<string, number>} */
+				let parsedKeywords = Object.create(null);
+
+				const isGridProperty = Boolean(propertyName.startsWith("grid"));
+				const isGridTemplate = isGridProperty
+					? Boolean(
+							propertyName === "grid" ||
+							propertyName === "grid-template" ||
+							propertyName === "grid-template-columns" ||
+							propertyName === "grid-template-rows"
+						)
+					: false;
+
+				let afterExclamation = false;
+
+				const end = walkCssTokens.consumeUntil(
+					input,
+					pos,
+					{
+						delim(input, start, end) {
+							afterExclamation = input.charCodeAt(start) === CC_EXCLAMATION;
+							return end;
+						},
+						leftSquareBracket(input, start, end) {
+							let i = end;
+
+							while (true) {
+								i = walkCssTokens.eatWhitespaceAndComments(input, i)[0];
+								const name = walkCssTokens.eatIdentSequence(input, i);
+
+								if (!name) {
+									break;
+								}
+
+								values.push(name);
+								i = name[1];
+							}
+
+							return end;
+						},
+						string(_input, start, end) {
+							if (
+								propertyName === "animation" ||
+								propertyName === "animation-name"
+							) {
+								values.push([start, end, true]);
+							}
+
+							if (
+								propertyName === "grid" ||
+								propertyName === "grid-template" ||
+								propertyName === "grid-template-areas"
+							) {
+								const areas = unescapeIdentifierCached(
+									input.slice(start + 1, end - 1)
+								);
+								const matches = matchAll(/\b\w+\b/g, areas);
+
+								for (const match of matches) {
+									const areaStart = start + 1 + match.index;
+									values.push([areaStart, areaStart + match[0].length, false]);
+								}
+							}
+
+							return end;
+						},
+						identifier(input, start, end) {
+							if (isGridTemplate) {
+								return end;
+							}
+
+							if (afterExclamation) {
+								afterExclamation = false;
+								return end;
+							}
+
+							const identifier = input.slice(start, end);
+							const keyword = identifier.toLowerCase();
+
+							parsedKeywords[keyword] =
+								typeof parsedKeywords[keyword] !== "undefined"
+									? parsedKeywords[keyword] + 1
+									: 0;
+							const keywords =
+								/** @type {Record<string, number>} */
+								(knownProperties.get(propertyName));
+
+							if (
+								keywords[keyword] &&
+								parsedKeywords[keyword] < keywords[keyword]
+							) {
+								return end;
+							}
+
+							values.push([start, end]);
+							return end;
+						},
+						comma(_input, _start, end) {
+							parsedKeywords = {};
+
+							return end;
+						}
+					},
+					{
+						function: (input, start, end) => {
+							const name = input
+								.slice(start, end - 1)
+								.replace(/\\/g, "")
+								.toLowerCase();
+
+							const type =
+								name === "local" ? 1 : name === "global" ? 2 : undefined;
+
+							if (type) {
+								return processLocalOrGlobalFunction(input, type, start, end);
+							}
+
+							if (
+								this.options.dashedIdents &&
+								isLocalMode() &&
+								name === "var"
+							) {
+								return processDashedIdent(input, end, end);
+							}
+
+							if (this.options.url) {
+								if (name === "src" || name === "url") {
+									return processURLFunction(input, end, name);
+								} else if (IMAGE_SET_FUNCTION.test(name)) {
+									return processImageSetFunction(input, start, end);
+								}
+							}
+
+							return end;
+						}
+					},
+					{
+						onlyTopLevel: !isGridTemplate,
+						declarationValue: true
+					}
+				);
+
+				if (values.length > 0) {
+					for (const value of values) {
+						const { line: sl, column: sc } = locConverter.get(value[0]);
+						const { line: el, column: ec } = locConverter.get(value[1]);
+						const [start, end, isString] = value;
+						const name = unescapeIdentifierCached(
+							isString
+								? input.slice(start + 1, end - 1)
+								: input.slice(start, end)
+						);
+						const dep = new CssIcssExportDependency(
+							name,
+							getReexport(name),
+							[start, end],
+							true,
+							CssIcssExportDependency.EXPORT_MODE.ONCE,
+							isGridProperty
+								? CssIcssExportDependency.EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER
+								: CssIcssExportDependency.EXPORT_TYPE.NORMAL
+						);
+						dep.setLoc(sl, sc, el, ec);
+						module.addDependency(dep);
+					}
+				}
+
+				return end;
+			} else if (COMPOSES_PROPERTY.test(propertyName)) {
+				if (lastLocalIdentifiers.length > 1) {
+					const end = eatUntilSemi(input, pos);
+					this._emitWarning(
+						state,
+						`Composition is only allowed when selector is single local class name not in "${lastLocalIdentifiers.join('", "')}"`,
+						locConverter,
+						pos,
+						end
+					);
+
+					return end;
+				}
+
+				if (lastLocalIdentifiers.length !== 1) return pos;
+
+				const lastLocalIdentifier = lastLocalIdentifiers[0];
+				let end = pos;
+
+				/** @type {Set<[number, number, boolean]>} */
+				const classNames = new Set();
+
+				while (true) {
+					pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
+
+					let className = walkCssTokens.eatIdentSequence(input, pos);
+
+					const ifFunction =
+						className && input.charCodeAt(className[1]) === CC_LEFT_PARENTHESIS;
+					let isGlobalFunction = false;
+
+					if (className && ifFunction) {
+						const name = input
+							.slice(className[0], className[1])
+							.replace(/\\/g, "")
+							.toLowerCase();
+
+						isGlobalFunction = name === "global";
+						pos = walkCssTokens.eatWhitespaceAndComments(
+							input,
+							className[1] + 1
+						)[0];
+						className = walkCssTokens.eatIdentSequence(input, pos);
+						if (className) {
+							pos = walkCssTokens.eatWhitespaceAndComments(
+								input,
+								className[1]
+							)[0];
+							pos += 1;
+						}
+					} else if (className) {
+						pos = walkCssTokens.eatWhitespaceAndComments(
+							input,
+							className[1]
+						)[0];
+						pos = className[1];
+					}
+
+					// True when we have multiple values
+					const isComma = input.charCodeAt(pos) === CC_COMMA;
+					const isSemicolon = input.charCodeAt(pos) === CC_SEMICOLON;
+					const isRightCurly = input.charCodeAt(pos) === CC_RIGHT_CURLY;
+
+					if (isComma || isSemicolon || isRightCurly) {
+						if (className) {
+							classNames.add([className[0], className[1], isGlobalFunction]);
+						}
+
+						for (const entry of classNames) {
+							const [start, end, isGlobal] = entry;
+							const identifier = unescapeIdentifierCached(
+								input.slice(start, end)
+							);
+							const dep = new CssIcssExportDependency(
+								lastLocalIdentifier,
+								getReexport(identifier),
+								[start, end],
+								!isGlobal,
+								isGlobal
+									? CssIcssExportDependency.EXPORT_MODE.APPEND
+									: CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE,
+								CssIcssExportDependency.EXPORT_TYPE.COMPOSES
+							);
+							const { line: sl, column: sc } = locConverter.get(start);
+							const { line: el, column: ec } = locConverter.get(end);
+							dep.setLoc(sl, sc, el, ec);
+							module.addDependency(dep);
+						}
+
+						classNames.clear();
+
+						if (isSemicolon || isRightCurly) {
+							end = isSemicolon
+								? walkCssTokens.eatWhitespace(input, pos + 1)
+								: pos;
+							break;
+						}
+
+						pos += 1;
+					} else if (
+						classNames.size > 0 &&
+						className &&
+						input.slice(className[0], className[1]).toLowerCase() === "from"
+					) {
+						let from = walkCssTokens.eatString(input, pos);
+
+						if (from) {
+							const request = input.slice(from[0] + 1, from[1] - 1);
+							const selfReference = isSelfReferenceRequest(request);
+
+							if (!selfReference && !currentRuleComposesFiles.has(request)) {
+								currentRuleComposesFiles.add(request);
+								if (
+									currentRulePrevComposesFile !== undefined &&
+									currentRulePrevComposesFile !== request
+								) {
+									let successors = composesGraph.get(
+										currentRulePrevComposesFile
+									);
+									if (!successors) {
+										successors = new Set();
+										composesGraph.set(currentRulePrevComposesFile, successors);
+									}
+									successors.add(request);
+								}
+								currentRulePrevComposesFile = request;
+							}
+
+							for (const entry of classNames) {
+								const [start, end] = entry;
+								const identifier = unescapeIdentifierCached(
+									input.slice(start, end)
+								);
+								const { line: sl, column: sc } = locConverter.get(start);
+								const { line: el, column: ec } = locConverter.get(end);
+
+								if (selfReference) {
+									// `composes: foo from "./self.module.css"` from inside
+									// `self.module.css` — collapse to a self-reference, like
+									// `composes: foo` without `from`. When the composed name
+									// equals the local class name, it's a true no-op.
+									if (identifier === lastLocalIdentifier) continue;
+									const dep = new CssIcssExportDependency(
+										lastLocalIdentifier,
+										getReexport(identifier),
+										[start, end],
+										true,
+										CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE,
+										CssIcssExportDependency.EXPORT_TYPE.COMPOSES
+									);
+									dep.setLoc(sl, sc, el, ec);
+									module.addDependency(dep);
+									continue;
+								}
+
+								const localName = `__ICSS_IMPORT_${counter++}__`;
+
+								{
+									const dep = new CssIcssImportDependency(
+										request,
+										[start, end],
+										/** @type {"local" | "global"} */
+										(mode),
+										identifier,
+										localName
+									);
+									dep.setLoc(sl, sc, el, ec);
+									module.addDependency(dep);
+									if (!composesFirstFileImport.has(request)) {
+										composesFirstFileImport.set(request, dep);
+									}
+								}
+
+								{
+									const dep = new CssIcssExportDependency(
+										lastLocalIdentifier,
+										getReexport(identifier, localName),
+										[start, end],
+										true,
+										CssIcssExportDependency.EXPORT_MODE.APPEND,
+										CssIcssExportDependency.EXPORT_TYPE.COMPOSES
+									);
+									dep.setLoc(sl, sc, el, ec);
+									module.addDependency(dep);
+								}
+							}
+
+							classNames.clear();
+							pos = from[1];
+						} else {
+							from = walkCssTokens.eatIdentSequence(input, pos);
+
+							if (from && input.slice(from[0], from[1]) === "global") {
+								for (const entry of classNames) {
+									const [start, end] = entry;
+									const identifier = unescapeIdentifierCached(
+										input.slice(start, end)
+									);
+									const dep = new CssIcssExportDependency(
+										/** @type {string} */
+										(lastLocalIdentifier),
+										getReexport(identifier),
+										[start, end],
+										false,
+										CssIcssExportDependency.EXPORT_MODE.APPEND,
+										CssIcssExportDependency.EXPORT_TYPE.COMPOSES
+									);
+									const { line: sl, column: sc } = locConverter.get(start);
+									const { line: el, column: ec } = locConverter.get(end);
+									dep.setLoc(sl, sc, el, ec);
+									module.addDependency(dep);
+								}
+
+								classNames.clear();
+								pos = from[1];
+							} else {
+								const end = eatUntilSemi(input, pos);
+								this._emitWarning(
+									state,
+									"Incorrect composition, expected global keyword or string value",
+									locConverter,
+									pos,
+									end
+								);
+								return end;
+							}
+						}
+					} else if (className) {
+						classNames.add([className[0], className[1], isGlobalFunction]);
+					} else {
+						const end = eatUntilSemi(input, pos);
+						this._emitWarning(
+							state,
+							"Incorrect composition, expected class named",
+							locConverter,
+							pos,
+							end
+						);
+						return end;
+					}
+				}
+
+				// Remove `composes` from source code
+				const dep = new ConstDependency("", [propertyNameStart, end]);
+				module.addPresentationalDependency(dep);
+			}
+
+			return pos;
+		};
+
+		/**
+		 * Process id selector.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processIdSelector = (input, start, end) => {
+			const valueStart = start + 1;
+			const name = unescapeIdentifierCached(input.slice(valueStart, end));
+			const dep = new CssIcssExportDependency(
+				name,
+				getReexport(name),
+				[valueStart, end],
+				true,
+				CssIcssExportDependency.EXPORT_MODE.ONCE
+			);
+			const { line: sl, column: sc } = locConverter.get(start);
+			const { line: el, column: ec } = locConverter.get(end);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			if (pureMode) currentSelectorHasLocal = true;
+			return end;
+		};
+
+		/**
+		 * Process class selector.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processClassSelector = (input, start, end) => {
+			const ident = walkCssTokens.skipCommentsAndEatIdentSequence(input, end);
+			if (!ident) return end;
+			const name = unescapeIdentifierCached(input.slice(ident[0], ident[1]));
+			lastLocalIdentifiers.push(name);
+			const dep = new CssIcssExportDependency(
+				name,
+				getReexport(name),
+				[ident[0], ident[1]],
+				true,
+				CssIcssExportDependency.EXPORT_MODE.ONCE
+			);
+			const { line: sl, column: sc } = locConverter.get(ident[0]);
+			const { line: el, column: ec } = locConverter.get(ident[1]);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			if (pureMode) currentSelectorHasLocal = true;
+			return ident[1];
+		};
+
+		/**
+		 * Process attribute selector.
+		 * @param {string} input input
+		 * @param {number} start start position
+		 * @param {number} end end position
+		 * @returns {number} position after handling
+		 */
+		const processAttributeSelector = (input, start, end) => {
+			end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
+			const identifier = walkCssTokens.eatIdentSequence(input, end);
+			if (!identifier) return end;
+			const name = unescapeIdentifierCached(
+				input.slice(identifier[0], identifier[1])
+			);
+			if (name.toLowerCase() !== "class") {
+				return end;
+			}
+			end = walkCssTokens.eatWhitespaceAndComments(input, identifier[1])[0];
+
+			const isTilde = input.charCodeAt(end) === CC_TILDE;
+
+			if (
+				input.charCodeAt(end) !== CC_EQUAL &&
+				input.charCodeAt(end) !== CC_TILDE
+			) {
+				return end;
+			}
+
+			end += 1;
+
+			if (isTilde) {
+				if (input.charCodeAt(end) !== CC_EQUAL) {
+					return end;
+				}
+
+				end += 1;
+			}
+
+			end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
+			const value = walkCssTokens.eatIdentSequenceOrString(input, end);
+
+			if (!value) {
+				return end;
+			}
+
+			const classNameStart = value[2] ? value[0] : value[0] + 1;
+			const classNameEnd = value[2] ? value[1] : value[1] - 1;
+			const className = unescapeIdentifierCached(
+				input.slice(classNameStart, classNameEnd)
+			);
+			const dep = new CssIcssExportDependency(
+				className,
+				getReexport(className),
+				[classNameStart, classNameEnd],
+				true,
+				CssIcssExportDependency.EXPORT_MODE.NONE
+			);
+			const { line: sl, column: sc } = locConverter.get(classNameStart);
+			const { line: el, column: ec } = locConverter.get(classNameEnd);
+			dep.setLoc(sl, sc, el, ec);
+			module.addDependency(dep);
+			return value[2] ? classNameEnd : classNameEnd + 1;
+		};
+
+		walkCssTokens(source, 0, {
+			comment,
+			leftCurlyBracket: (input, start, end) => {
+				const wasTopLevel = scope === CSS_MODE_TOP_LEVEL;
+				if (wasTopLevel) {
+					allowImportAtRule = false;
+					scope = CSS_MODE_IN_BLOCK;
+				} else if (scope !== CSS_MODE_IN_BLOCK) {
+					return end;
+				}
+				if (!isModules) return end;
+				if (pureMode) {
+					inAtRulePrelude = false;
+					if (wasTopLevel) seenTopLevelRule = true;
+					const isRulePrelude = isNextRulePrelude;
+					if (isRulePrelude) finalizeSelector();
+					const top = pureTop();
+					if (top) top.hasNestedBlock = true;
+					const inheritedSkip = top ? top.skipChildren : false;
+					pureBlockStack.push({
+						ignored: pureIgnorePending,
+						skipOwn: inheritedSkip,
+						skipChildren: nextBlockChildrenSkip || inheritedSkip,
+						treatAsLeaf: nextBlockTreatAsLeaf,
+						// "this rule is fully pure" (no impure comma-segment) OR any
+						// ancestor pure. Matches PCSL's `[isPureSelectorSymbol]`.
+						ancestorHadLocal:
+							parentEffectivePure() ||
+							(isRulePrelude && !currentRuleHasImpureSelector),
+						impure: isRulePrelude && currentRuleHasImpureSelector,
+						hasDirectDecl: false,
+						hasNestedBlock: false,
+						isRulePrelude,
+						preludeStart: currentRulePreludeStart,
+						preludeEnd: start
+					});
+					pureIgnorePending = false;
+					nextBlockChildrenSkip = false;
+					nextBlockTreatAsLeaf = false;
+					currentRuleHasImpureSelector = false;
+					currentSelectorHasLocal = false;
+					currentRulePreludeStart = end;
+				}
+				blockNestingLevel = wasTopLevel ? 1 : blockNestingLevel + 1;
+				isNextRulePrelude = isNextNestedSyntax(input, end);
+				return end;
+			},
+			rightCurlyBracket: (input, start, end) => {
+				if (scope !== CSS_MODE_IN_BLOCK) return end;
+				const closing = blockNestingLevel === 1;
+				if (closing) {
+					scope = CSS_MODE_TOP_LEVEL;
+					blockNestingLevel = 0;
+					if (!isModules) return end;
+					isNextRulePrelude = true;
+					modeData = undefined;
+					lastLocalIdentifiers = [];
+					currentRulePrevComposesFile = undefined;
+					currentRuleComposesFiles.clear();
+				} else {
+					blockNestingLevel--;
+					if (!isModules) return end;
+					isNextRulePrelude = isNextNestedSyntax(input, end);
+				}
+				if (pureMode) {
+					const frame = pureBlockStack.pop();
+					if (frame) {
+						// PCSL throws on impure rules whose body has any non-rule
+						// content (declaration, empty body). Rules whose body is
+						// only nested rules are skipped — child rules carry the
+						// check themselves.
+						if (
+							!pureNoCheck &&
+							!frame.ignored &&
+							!frame.skipOwn &&
+							frame.isRulePrelude &&
+							frame.impure &&
+							(frame.hasDirectDecl ||
+								!frame.hasNestedBlock ||
+								frame.treatAsLeaf)
+						) {
+							reportPureRule(frame.preludeStart, frame.preludeEnd);
+						}
+						// Propagate "has direct declaration" through at-rule frames
+						// so a parent rule containing only e.g. `@media { decl }` is
+						// still treated as "rule with declarations".
+						if (!frame.isRulePrelude && frame.hasDirectDecl) {
+							const parent = pureTop();
+							if (parent) parent.hasDirectDecl = true;
+						}
+					}
+					currentRuleHasImpureSelector = false;
+					currentSelectorHasLocal = false;
+					currentRulePreludeStart = end;
+				}
+				return end;
+			},
+			url: (input, start, end, contentStart, contentEnd) => {
+				if (!this.options.url) {
+					return end;
+				}
+
+				return processOldURLFunction(
+					input,
+					start,
+					end,
+					contentStart,
+					contentEnd
+				);
+			},
+			atKeyword: (input, start, end) => {
+				const name = input.slice(start, end).toLowerCase();
+				const wasTopLevel = scope === CSS_MODE_TOP_LEVEL;
+				if (pureMode) {
+					inAtRulePrelude = true;
+					// Match PCSL's `isPureCheckDisabled`: any non-comment top-level
+					// node (including `;`-terminated at-rules like `@import`) seals
+					// the leading-comments window.
+					if (wasTopLevel) seenTopLevelRule = true;
+				}
+
+				let pos = end;
+				switch (name) {
+					case "@namespace": {
+						this._emitWarning(
+							state,
+							"'@namespace' is not supported in bundled CSS",
+							locConverter,
+							start,
+							end
+						);
+
+						pos = eatUntilSemi(input, start);
+						break;
+					}
+					case "@charset": {
+						const atRuleEnd = eatUntilSemi(input, start);
+
+						if (/** @type {CssModule} */ (module).exportType === "style") {
+							pos = atRuleEnd;
+							break;
+						}
+
+						const dep = new ConstDependency("", [start, atRuleEnd + 1]);
+						module.addPresentationalDependency(dep);
+
+						const value = walkCssTokens.eatString(input, end);
+
+						if (!value) {
+							pos = atRuleEnd;
+							break;
+						}
+
+						/** @type {BuildInfo} */
+						(module.buildInfo).charset = input
+							.slice(value[0] + 1, value[1] - 1)
+							.toUpperCase();
+
+						pos = atRuleEnd;
+						break;
+					}
+					case "@import": {
+						if (!this.options.import) {
+							pos = eatUntilSemi(input, end);
+							break;
+						}
+
+						if (!allowImportAtRule) {
+							this._emitWarning(
+								state,
+								"Any '@import' rules must precede all other rules",
+								locConverter,
+								start,
+								end
+							);
+							pos = eatUntilSemi(input, end);
+							break;
+						}
+
+						pos = processAtImport(input, start, end);
+						break;
+					}
+					default: {
+						if (isModules) {
+							if (name === "@value") {
+								pos = processAtValue(input, start, end);
+								break;
+							} else if (
+								this.options.animation &&
+								OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name) &&
+								isLocalMode()
+							) {
+								if (pureMode) {
+									nextBlockChildrenSkip = true;
+									nextBlockTreatAsLeaf = true;
+								}
+								pos = processLocalAtRule(input, end, {
+									string: true,
+									identifier: true
+								});
+								break;
+							} else if (
+								this.options.customIdents &&
+								name === "@counter-style" &&
+								isLocalMode()
+							) {
+								if (pureMode) {
+									nextBlockChildrenSkip = true;
+									nextBlockTreatAsLeaf = true;
+								}
+								pos = processLocalAtRule(input, end, {
+									identifier: true
+								});
+								break;
+							} else if (
+								this.options.container &&
+								name === "@container" &&
+								isLocalMode()
+							) {
+								pos = processLocalAtRule(input, end, {
+									identifier: /^(none|and|or|not)$/
+								});
+								break;
+							} else if (name === "@scope") {
+								isNextRulePrelude = true;
+								break;
+							}
+
+							isNextRulePrelude = false;
+						}
+					}
+				}
+
+				// If the at-rule consumed its own `;` (for `@import`/`@value`/
+				// `@charset`/`@namespace`), advance the prelude pointer so a
+				// later impure rule's reported selector doesn't include this
+				// at-rule's text. Body-bearing at-rules return at `{` — let
+				// `leftCurlyBracket` handle those.
+				if (pureMode && wasTopLevel && pos > end) {
+					let probe = pos - 1;
+					while (
+						probe > end &&
+						walkCssTokens.isWhiteSpace(input.charCodeAt(probe))
+					) {
+						probe--;
+					}
+					if (input.charCodeAt(probe) === CC_SEMICOLON) {
+						currentRulePreludeStart = pos;
+					}
+				}
+
+				return pos;
+			},
+			semicolon: (input, start, end) => {
+				if (isModules && scope === CSS_MODE_IN_BLOCK) {
+					isNextRulePrelude = isNextNestedSyntax(input, end);
+				}
+				if (pureMode) {
+					if (scope === CSS_MODE_IN_BLOCK) {
+						if (
+							balanced.length === 0 &&
+							!isNextRulePrelude &&
+							!inAtRulePrelude
+						) {
+							const top = pureTop();
+							if (top) top.hasDirectDecl = true;
+						}
+					} else if (scope === CSS_MODE_TOP_LEVEL && balanced.length === 0) {
+						// Top-level `;` ends a statement (e.g. `@import "x";`).
+						// Advance the prelude pointer so a later impure rule's
+						// reported selector doesn't include the preceding text.
+						currentRulePreludeStart = end;
+					}
+					inAtRulePrelude = false;
+				}
+				return end;
+			},
+			identifier: (input, start, end) => {
+				if (isModules) {
+					const identifier = input.slice(start, end);
+
+					if (
+						this.options.dashedIdents &&
+						isLocalMode() &&
+						isDashedIdentifier(identifier)
+					) {
+						return processDashedIdent(input, start, end);
+					}
+
+					if (icssDefinitions.has(identifier)) {
+						return processICSSSymbol(identifier, start, end);
+					}
+
+					switch (scope) {
+						case CSS_MODE_IN_BLOCK: {
+							if (isModules && !isNextRulePrelude) {
+								if (balanced.length === 0 && !inAtRulePrelude) {
+									const top = pureTop();
+									if (top) top.hasDirectDecl = true;
+								}
+								// Handle only top level values and not inside functions
+								return processLocalDeclaration(input, start, end);
+							}
+							break;
+						}
+					}
+				}
+
+				return end;
+			},
+			delim: (input, start, end) => {
+				const ch = input.charCodeAt(start);
+				if (ch === CC_FULL_STOP && isNextRulePrelude && isLocalMode()) {
+					return processClassSelector(input, start, end);
+				}
+				if (
+					ch === CC_AMPERSAND &&
+					isNextRulePrelude &&
+					parentEffectivePure() &&
+					pureMode
+				) {
+					currentSelectorHasLocal = true;
+				}
+
+				return end;
+			},
+			hash: (input, start, end, isID) => {
+				if (isNextRulePrelude && isLocalMode() && isID) {
+					return processIdSelector(input, start, end);
+				}
+
+				return end;
+			},
+			colon: (input, start, end) => {
+				if (isModules) {
+					const ident = walkCssTokens.skipCommentsAndEatIdentSequence(
+						input,
+						end
+					);
+					if (!ident) return end;
+					const name = input.slice(ident[0], ident[1]).toLowerCase();
+
+					switch (scope) {
+						case CSS_MODE_TOP_LEVEL: {
+							if (name === "import") {
+								const pos = processImportOrExport(0, input, ident[1]);
+								const dep = new ConstDependency("", [start, pos]);
+								module.addPresentationalDependency(dep);
+								return pos;
+							} else if (name === "export") {
+								const pos = processImportOrExport(1, input, ident[1]);
+								const dep = new ConstDependency("", [start, pos]);
+								module.addPresentationalDependency(dep);
+								return pos;
+							}
+						}
+						// falls through
+						default: {
+							if (isNextRulePrelude) {
+								const isFn = input.charCodeAt(ident[1]) === CC_LEFT_PARENTHESIS;
+
+								if (isFn && name === "local") {
+									// Eat extra whitespace
+									const end = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1] + 1
+									)[0];
+									modeData = LOCAL_MODE;
+									const dep = new ConstDependency("", [start, end]);
+									module.addPresentationalDependency(dep);
+									balanced.push([":local", start, end, true]);
+									return end;
+								} else if (name === "local") {
+									modeData = LOCAL_MODE;
+									const found = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1]
+									);
+
+									if (!found[1]) {
+										this._emitWarning(
+											state,
+											`Missing whitespace after ':local' in '${input.slice(
+												start,
+												eatUntilLeftCurly(input, end) + 1
+											)}'`,
+											locConverter,
+											start,
+											end
+										);
+									}
+
+									end = walkCssTokens.eatWhitespace(input, ident[1]);
+									const dep = new ConstDependency("", [start, end]);
+									module.addPresentationalDependency(dep);
+									return end;
+								} else if (isFn && name === "global") {
+									// Eat extra whitespace
+									const end = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1] + 1
+									)[0];
+									modeData = GLOBAL_MODE;
+									const dep = new ConstDependency("", [start, end]);
+									module.addPresentationalDependency(dep);
+									balanced.push([":global", start, end, true]);
+									return end;
+								} else if (name === "global") {
+									modeData = GLOBAL_MODE;
+									// Eat extra whitespace
+									const found = walkCssTokens.eatWhitespaceAndComments(
+										input,
+										ident[1]
+									);
+
+									if (!found[1]) {
+										this._emitWarning(
+											state,
+											`Missing whitespace after ':global' in '${input.slice(
+												start,
+												eatUntilLeftCurly(input, end) + 1
+											)}'`,
+											locConverter,
+											start,
+											end
+										);
+									}
+
+									end = walkCssTokens.eatWhitespace(input, ident[1]);
+									const dep = new ConstDependency("", [start, end]);
+									module.addPresentationalDependency(dep);
+									return end;
+								}
+							}
+						}
+					}
+				}
+
+				lastTokenEndForComments = end;
+
+				return end;
+			},
+			function: (input, start, end) => {
+				const name = input
+					.slice(start, end - 1)
+					.replace(/\\/g, "")
+					.toLowerCase();
+
+				balanced.push([name, start, end]);
+
+				switch (name) {
+					case "src":
+					case "url": {
+						if (!this.options.url) {
+							return end;
+						}
+
+						return processURLFunction(input, end, name);
+					}
+					default: {
+						if (this.options.url && IMAGE_SET_FUNCTION.test(name)) {
+							return processImageSetFunction(input, start, end);
+						}
+
+						if (isModules) {
+							if (
+								this.options.function &&
+								isLocalMode() &&
+								isDashedIdentifier(name)
+							) {
+								return processDashedIdent(input, start, end);
+							}
+
+							const type =
+								name === "local" ? 1 : name === "global" ? 2 : undefined;
+
+							if (type && !isNextRulePrelude) {
+								return processLocalOrGlobalFunction(input, type, start, end);
+							}
+						}
+					}
+				}
+
+				return end;
+			},
+			leftSquareBracket: (input, start, end) => {
+				if (isNextRulePrelude && isLocalMode()) {
+					return processAttributeSelector(input, start, end);
+				}
+				return end;
+			},
+			leftParenthesis: (input, start, end) => {
+				balanced.push(["(", start, end]);
+
+				return end;
+			},
+			rightParenthesis: (input, start, end) => {
+				const popped = balanced.pop();
+
+				if (isModules && popped) {
+					const isLocal = popped[0] === ":local";
+					const isGlobal = popped[0] === ":global";
+					if (isLocal || isGlobal) {
+						modeData = balanced[balanced.length - 1]
+							? balanced[balanced.length - 1][0] === ":local"
+								? LOCAL_MODE
+								: balanced[balanced.length - 1][0] === ":global"
+									? GLOBAL_MODE
+									: undefined
+							: undefined;
+						if (popped[3] && isLocal) {
+							while (walkCssTokens.isWhiteSpace(input.charCodeAt(start - 1))) {
+								start -= 1;
+							}
+						}
+						const dep = new ConstDependency("", [start, end]);
+						module.addPresentationalDependency(dep);
+					} else if (isNextRulePrelude) {
+						modeData = undefined;
+					}
+				}
+
+				return end;
+			},
+			comma: (input, start, end) => {
+				if (isModules && balanced.length === 0) {
+					// Reset stack for `:global .class :local .class-other` selector after
+					modeData = undefined;
+					if (pureMode && isNextRulePrelude) finalizeSelector();
+				}
+
+				lastTokenEndForComments = start;
+
+				return end;
+			}
+		});
+
+		/** @type {BuildInfo} */
+		(module.buildInfo).strict = true;
+
+		// Topologically sort the files referenced by `composes ... from`
+		// declarations and tag each file's first import dep with the
+		// resulting `sourceOrder`. `NormalModule#build` then reorders the
+		// deps via `sortWithSourceOrder` so the bundle loads them in
+		// cascade-correct order. Files stuck in a cycle are not visited
+		// and keep their natural loc-based position.
+		if (composesFirstFileImport.size > 1) {
+			topologicalSort(
+				composesGraph,
+				[...composesFirstFileImport.keys()],
+				(file, i) => {
+					/** @type {CssIcssImportDependency} */
+					(composesFirstFileImport.get(file)).sourceOrder = i;
+				}
+			);
+		}
+
+		const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
+
+		buildMeta.exportsType = this.options.namedExports ? "namespace" : "default";
+		buildMeta.defaultObject = this.options.namedExports
+			? false
+			: "redirect-warn";
+
+		if (
+			/** @type {CssModule} */ (module).exportType === "text" ||
+			/** @type {CssModule} */ (module).exportType === "css-style-sheet"
+		) {
+			module.addDependency(new StaticExportsDependency(["default"], true));
+		} else {
+			module.addDependency(new StaticExportsDependency([], true));
+		}
+
+		return state;
+	}
+
+	/**
+	 * Returns comments in the range.
+	 * @param {Range} range range
+	 * @returns {Comment[]} comments in the range
+	 */
+	getComments(range) {
+		if (!this.comments) return [];
+		const [rangeStart, rangeEnd] = range;
+		/**
+		 * Returns compared.
+		 * @param {Comment} comment comment
+		 * @param {number} needle needle
+		 * @returns {number} compared
+		 */
+		const compare = (comment, needle) =>
+			/** @type {Range} */ (comment.range)[0] - needle;
+		const comments = /** @type {Comment[]} */ (this.comments);
+		let idx = binarySearchBounds.ge(comments, rangeStart, compare);
+		/** @type {Comment[]} */
+		const commentsInRange = [];
+		while (
+			comments[idx] &&
+			/** @type {Range} */ (comments[idx].range)[1] <= rangeEnd
+		) {
+			commentsInRange.push(comments[idx]);
+			idx++;
+		}
+
+		return commentsInRange;
+	}
+
+	/**
+	 * Parses comment options.
+	 * @param {Range} range range of the comment
+	 * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
+	 */
+	parseCommentOptions(range) {
+		const comments = this.getComments(range);
+		if (comments.length === 0) {
+			return EMPTY_COMMENT_OPTIONS;
+		}
+		/** @type {Record<string, EXPECTED_ANY>} */
+		const options = {};
+		/** @type {(Error & { comment: Comment })[]} */
+		const errors = [];
+		for (const comment of comments) {
+			const { value } = comment;
+			if (value && webpackCommentRegExp.test(value)) {
+				// try compile only if webpack options comment is present
+				try {
+					for (let [key, val] of Object.entries(
+						vm.runInContext(
+							`(function(){return {${value}};})()`,
+							this.magicCommentContext
+						)
+					)) {
+						if (typeof val === "object" && val !== null) {
+							val =
+								val.constructor.name === "RegExp"
+									? new RegExp(val)
+									: JSON.parse(JSON.stringify(val));
+						}
+						options[key] = val;
+					}
+				} catch (err) {
+					const newErr = new Error(String(/** @type {Error} */ (err).message));
+					newErr.stack = String(/** @type {Error} */ (err).stack);
+					Object.assign(newErr, { comment });
+					errors.push(/** @type {(Error & { comment: Comment })} */ (newErr));
+				}
+			}
+		}
+		return { options, errors };
+	}
+}
+
+module.exports = CssParser;
+module.exports.escapeIdentifier = escapeIdentifier;
+module.exports.unescapeIdentifier = unescapeIdentifier;
Index: frontend/node_modules/webpack/lib/css/walkCssTokens.js
===================================================================
--- frontend/node_modules/webpack/lib/css/walkCssTokens.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/css/walkCssTokens.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2020 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { makeCacheable } = require("../util/identifier");
+
+/**
+ * Defines the css token callbacks type used by this module.
+ * @typedef {object} CssTokenCallbacks
+ * @property {((input: string, start: number, end: number) => number)=} comment
+ * @property {((input: string, start: number, end: number) => number)=} whitespace
+ * @property {((input: string, start: number, end: number) => number)=} string
+ * @property {((input: string, start: number, end: number) => number)=} leftCurlyBracket
+ * @property {((input: string, start: number, end: number) => number)=} rightCurlyBracket
+ * @property {((input: string, start: number, end: number) => number)=} leftParenthesis
+ * @property {((input: string, start: number, end: number) => number)=} rightParenthesis
+ * @property {((input: string, start: number, end: number) => number)=} leftSquareBracket
+ * @property {((input: string, start: number, end: number) => number)=} rightSquareBracket
+ * @property {((input: string, start: number, end: number) => number)=} function
+ * @property {((input: string, start: number, end: number, innerStart: number, innerEnd: number) => number)=} url
+ * @property {((input: string, start: number, end: number) => number)=} colon
+ * @property {((input: string, start: number, end: number) => number)=} atKeyword
+ * @property {((input: string, start: number, end: number) => number)=} delim
+ * @property {((input: string, start: number, end: number) => number)=} identifier
+ * @property {((input: string, start: number, end: number) => number)=} percentage
+ * @property {((input: string, start: number, end: number) => number)=} number
+ * @property {((input: string, start: number, end: number) => number)=} dimension
+ * @property {((input: string, start: number, end: number, isId: boolean) => number)=} hash
+ * @property {((input: string, start: number, end: number) => number)=} semicolon
+ * @property {((input: string, start: number, end: number) => number)=} comma
+ * @property {((input: string, start: number, end: number) => number)=} cdo
+ * @property {((input: string, start: number, end: number) => number)=} cdc
+ * @property {((input: string, start: number, end: number) => number)=} badStringToken
+ * @property {((input: string, start: number, end: number) => number)=} badUrlToken
+ * @property {(() => boolean)=} needTerminate
+ */
+
+/** @typedef {(input: string, pos: number, callbacks: CssTokenCallbacks) => number} CharHandler */
+
+// spec: https://drafts.csswg.org/css-syntax/
+
+const CC_LINE_FEED = "\n".charCodeAt(0);
+const CC_CARRIAGE_RETURN = "\r".charCodeAt(0);
+const CC_FORM_FEED = "\f".charCodeAt(0);
+
+const CC_TAB = "\t".charCodeAt(0);
+const CC_SPACE = " ".charCodeAt(0);
+
+const CC_SOLIDUS = "/".charCodeAt(0);
+const CC_REVERSE_SOLIDUS = "\\".charCodeAt(0);
+const CC_ASTERISK = "*".charCodeAt(0);
+
+const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
+const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
+const CC_LEFT_CURLY = "{".charCodeAt(0);
+const CC_RIGHT_CURLY = "}".charCodeAt(0);
+const CC_LEFT_SQUARE = "[".charCodeAt(0);
+const CC_RIGHT_SQUARE = "]".charCodeAt(0);
+
+const CC_QUOTATION_MARK = '"'.charCodeAt(0);
+const CC_APOSTROPHE = "'".charCodeAt(0);
+
+const CC_FULL_STOP = ".".charCodeAt(0);
+const CC_COLON = ":".charCodeAt(0);
+const CC_SEMICOLON = ";".charCodeAt(0);
+const CC_COMMA = ",".charCodeAt(0);
+const CC_PERCENTAGE = "%".charCodeAt(0);
+const CC_AT_SIGN = "@".charCodeAt(0);
+
+const CC_LOW_LINE = "_".charCodeAt(0);
+const CC_LOWER_A = "a".charCodeAt(0);
+const CC_LOWER_F = "f".charCodeAt(0);
+const CC_LOWER_E = "e".charCodeAt(0);
+const CC_LOWER_U = "u".charCodeAt(0);
+const CC_LOWER_Z = "z".charCodeAt(0);
+const CC_UPPER_A = "A".charCodeAt(0);
+const CC_UPPER_F = "F".charCodeAt(0);
+const CC_UPPER_E = "E".charCodeAt(0);
+const CC_UPPER_U = "U".charCodeAt(0);
+const CC_UPPER_Z = "Z".charCodeAt(0);
+const CC_0 = "0".charCodeAt(0);
+const CC_9 = "9".charCodeAt(0);
+
+const CC_NUMBER_SIGN = "#".charCodeAt(0);
+const CC_PLUS_SIGN = "+".charCodeAt(0);
+const CC_HYPHEN_MINUS = "-".charCodeAt(0);
+
+const CC_LESS_THAN_SIGN = "<".charCodeAt(0);
+const CC_GREATER_THAN_SIGN = ">".charCodeAt(0);
+
+/** @type {CharHandler} */
+const consumeSpace = (input, pos, callbacks) => {
+	const start = pos - 1;
+
+	// Consume as much whitespace as possible.
+	while (_isWhiteSpace(input.charCodeAt(pos))) {
+		pos++;
+	}
+
+	// Return a <whitespace-token>.
+	if (callbacks.whitespace !== undefined) {
+		return callbacks.whitespace(input, start, pos);
+	}
+
+	return pos;
+};
+
+// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
+// as they are converted to U+000A LINE FEED during preprocessing.
+//
+// Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point.
+
+/**
+ * Checks whether newline true, if cc is a newline.
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a newline
+ */
+const _isNewline = (cc) =>
+	cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED;
+
+/**
+ * Consume extra newline.
+ * @param {number} cc char code
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position
+ */
+const consumeExtraNewline = (cc, input, pos) => {
+	if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos) === CC_LINE_FEED) {
+		pos++;
+	}
+
+	return pos;
+};
+
+/**
+ * Checks whether space true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE).
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE)
+ */
+const _isSpace = (cc) => cc === CC_TAB || cc === CC_SPACE;
+
+/**
+ * Checks whether white space true, if cc is a whitespace.
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a whitespace
+ */
+const _isWhiteSpace = (cc) => _isNewline(cc) || _isSpace(cc);
+
+/**
+ * ident-start code point
+ *
+ * A letter, a non-ASCII code point, or U+005F LOW LINE (_).
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a start code point of an identifier
+ */
+const isIdentStartCodePoint = (cc) =>
+	(cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
+	(cc >= CC_UPPER_A && cc <= CC_UPPER_Z) ||
+	cc === CC_LOW_LINE ||
+	cc >= 0x80;
+
+const REGEX_SINGLE_ESCAPE = /[ -,./:-@[\]^`{-~]/;
+const REGEX_EXCESSIVE_SPACES = /(^|\\+)?(\\[A-F0-9]{1,6}) (?![a-fA-F0-9 ])/g;
+const REGEX_CTRL_WHITESPACE = /[\t\n\f\r\v]/;
+const REGEX_LEADING_HYPHEN_DIGIT = /^-[-\d]/;
+const REGEX_DIGIT = /\d/;
+const CONTAINS_ESCAPE = /\\/;
+
+/**
+ * Returns escaped identifier.
+ * @param {string} str string
+ * @returns {string} escaped identifier
+ */
+const _escapeIdentifier = (str) => {
+	let output = "";
+	let counter = 0;
+
+	while (counter < str.length) {
+		const character = str.charAt(counter++);
+
+		/** @type {string} */
+		let value;
+
+		if (REGEX_CTRL_WHITESPACE.test(character)) {
+			const codePoint = character.charCodeAt(0);
+
+			value = `\\${codePoint.toString(16).toUpperCase()} `;
+		} else if (character === "\\" || REGEX_SINGLE_ESCAPE.test(character)) {
+			value = `\\${character}`;
+		} else {
+			value = character;
+		}
+
+		output += value;
+	}
+
+	const firstChar = str.charAt(0);
+
+	if (REGEX_LEADING_HYPHEN_DIGIT.test(output)) {
+		output = `\\-${output.slice(1)}`;
+	} else if (REGEX_DIGIT.test(firstChar)) {
+		output = `\\3${firstChar} ${output.slice(1)}`;
+	}
+
+	// Remove spaces after `\HEX` escapes that are not followed by a hex digit,
+	// since they’re redundant. Note that this is only possible if the escape
+	// sequence isn’t preceded by an odd number of backslashes.
+	output = output.replace(REGEX_EXCESSIVE_SPACES, ($0, $1, $2) => {
+		if ($1 && $1.length % 2) {
+			// It’s not safe to remove the space, so don’t.
+			return $0;
+		}
+
+		// Strip the space.
+		return ($1 || "") + $2;
+	});
+
+	return output;
+};
+
+/**
+ * Returns hex.
+ * @param {string} str string
+ * @returns {[string, number] | undefined} hex
+ */
+const gobbleHex = (str) => {
+	const lower = str.toLowerCase();
+	let hex = "";
+	let spaceTerminated = false;
+
+	for (let i = 0; i < 6 && lower[i] !== undefined; i++) {
+		const code = lower.charCodeAt(i);
+		// check to see if we are dealing with a valid hex char [a-f|0-9]
+		const valid = (code >= 97 && code <= 102) || (code >= 48 && code <= 57);
+		// https://drafts.csswg.org/css-syntax/#consume-escaped-code-point
+		spaceTerminated = code === 32;
+		if (!valid) break;
+		hex += lower[i];
+	}
+
+	if (hex.length === 0) return undefined;
+
+	const codePoint = Number.parseInt(hex, 16);
+	const isSurrogate = codePoint >= 0xd800 && codePoint <= 0xdfff;
+
+	// Add special case for
+	// "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point"
+	// https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point
+	if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10ffff) {
+		return ["�", hex.length + (spaceTerminated ? 1 : 0)];
+	}
+
+	return [
+		String.fromCodePoint(codePoint),
+		hex.length + (spaceTerminated ? 1 : 0)
+	];
+};
+
+/**
+ * Unescape identifier.
+ * @param {string} str string
+ * @returns {string} unescaped string
+ */
+const _unescapeIdentifier = (str) => {
+	const needToProcess = CONTAINS_ESCAPE.test(str);
+	if (!needToProcess) return str;
+	let ret = "";
+	for (let i = 0; i < str.length; i++) {
+		if (str[i] === "\\") {
+			const gobbled = gobbleHex(str.slice(i + 1, i + 7));
+			if (gobbled !== undefined) {
+				ret += gobbled[0];
+				i += gobbled[1];
+				continue;
+			}
+			// Retain a pair of \\ if double escaped `\\\\`
+			// https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e
+			if (str[i + 1] === "\\") {
+				ret += "\\";
+				i += 1;
+				continue;
+			}
+			// if \\ is at the end of the string retain it
+			// https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb
+			if (str.length === i + 1) {
+				ret += str[i];
+			}
+			continue;
+		}
+		ret += str[i];
+	}
+
+	return ret;
+};
+
+const escapeIdentifier = makeCacheable(_escapeIdentifier);
+const unescapeIdentifier = makeCacheable(_unescapeIdentifier);
+
+/** @type {CharHandler} */
+const consumeDelimToken = (input, pos, callbacks) => {
+	// Return a <delim-token> with its value set to the current input code point.
+	if (callbacks.delim) {
+		pos = callbacks.delim(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeComments = (input, pos, callbacks) => {
+	// This section describes how to consume comments from a stream of code points. It returns nothing.
+	// If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
+	// consume them and all following code points up to and including the first U+002A ASTERISK (*)
+	// followed by a U+002F SOLIDUS (/), or up to an EOF code point.
+	// Return to the start of this step.
+	while (
+		input.charCodeAt(pos) === CC_SOLIDUS &&
+		input.charCodeAt(pos + 1) === CC_ASTERISK
+	) {
+		const start = pos;
+		pos += 2;
+
+		for (;;) {
+			if (pos === input.length) {
+				// If the preceding paragraph ended by consuming an EOF code point, this is a parse error.
+				return pos;
+			}
+
+			if (
+				input.charCodeAt(pos) === CC_ASTERISK &&
+				input.charCodeAt(pos + 1) === CC_SOLIDUS
+			) {
+				pos += 2;
+
+				if (callbacks.comment) {
+					pos = callbacks.comment(input, start, pos);
+				}
+
+				break;
+			}
+
+			pos++;
+		}
+	}
+
+	return pos;
+};
+
+/**
+ * Checks whether hex digit true, if cc is a hex digit.
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a hex digit
+ */
+const _isHexDigit = (cc) =>
+	_isDigit(cc) ||
+	(cc >= CC_UPPER_A && cc <= CC_UPPER_F) ||
+	(cc >= CC_LOWER_A && cc <= CC_LOWER_F);
+
+/**
+ * Consume an escaped code point.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position
+ */
+const _consumeAnEscapedCodePoint = (input, pos) => {
+	// This section describes how to consume an escaped code point.
+	// It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and that the next input code point has already been verified to be part of a valid escape.
+	// It will return a code point.
+
+	// Consume the next input code point.
+	const cc = input.charCodeAt(pos);
+	pos++;
+
+	// EOF
+	// This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�).
+	if (pos === input.length) {
+		return pos;
+	}
+
+	// hex digit
+	// Consume as many hex digits as possible, but no more than 5.
+	// Note that this means 1-6 hex digits have been consumed in total.
+	// If the next input code point is whitespace, consume it as well.
+	// Interpret the hex digits as a hexadecimal number.
+	// If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point, return U+FFFD REPLACEMENT CHARACTER (�).
+	// Otherwise, return the code point with that value.
+	if (_isHexDigit(cc)) {
+		for (let i = 0; i < 5; i++) {
+			if (_isHexDigit(input.charCodeAt(pos))) {
+				pos++;
+			}
+		}
+
+		const cc = input.charCodeAt(pos);
+
+		if (_isWhiteSpace(cc)) {
+			pos++;
+			pos = consumeExtraNewline(cc, input, pos);
+		}
+
+		return pos;
+	}
+
+	// anything else
+	// Return the current input code point.
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeAStringToken = (input, pos, callbacks) => {
+	// This section describes how to consume a string token from a stream of code points.
+	// It returns either a <string-token> or <bad-string-token>.
+	//
+	// This algorithm may be called with an ending code point, which denotes the code point that ends the string.
+	// If an ending code point is not specified, the current input code point is used.
+	const start = pos - 1;
+	const endingCodePoint = input.charCodeAt(pos - 1);
+
+	// Initially create a <string-token> with its value set to the empty string.
+
+	// Repeatedly consume the next input code point from the stream:
+	for (;;) {
+		// EOF
+		// This is a parse error. Return the <string-token>.
+		if (pos === input.length) {
+			if (callbacks.string !== undefined) {
+				return callbacks.string(input, start, pos);
+			}
+
+			return pos;
+		}
+
+		const cc = input.charCodeAt(pos);
+		pos++;
+
+		// ending code point
+		// Return the <string-token>.
+		if (cc === endingCodePoint) {
+			if (callbacks.string !== undefined) {
+				return callbacks.string(input, start, pos);
+			}
+
+			return pos;
+		}
+		// newline
+		// This is a parse error.
+		// Reconsume the current input code point, create a <bad-string-token>, and return it.
+		else if (_isNewline(cc)) {
+			pos--;
+
+			if (callbacks.badStringToken !== undefined) {
+				return callbacks.badStringToken(input, start, pos);
+			}
+
+			// bad string
+			return pos;
+		}
+		// U+005C REVERSE SOLIDUS (\)
+		else if (cc === CC_REVERSE_SOLIDUS) {
+			// If the next input code point is EOF, do nothing.
+			if (pos === input.length) {
+				return pos;
+			}
+			// Otherwise, if the next input code point is a newline, consume it.
+			else if (_isNewline(input.charCodeAt(pos))) {
+				const cc = input.charCodeAt(pos);
+				pos++;
+				pos = consumeExtraNewline(cc, input, pos);
+			}
+			// Otherwise, (the stream starts with a valid escape) consume an escaped code point and append the returned code point to the <string-token>’s value.
+			else if (_ifTwoCodePointsAreValidEscape(input, pos)) {
+				pos = _consumeAnEscapedCodePoint(input, pos);
+			}
+		}
+		// anything else
+		// Append the current input code point to the <string-token>’s value.
+		else {
+			// Append
+		}
+	}
+};
+
+/**
+ * Checks whether this object is non ascii code point.
+ * @param {number} cc char code
+ * @param {number} q char code
+ * @returns {boolean} is non-ASCII code point
+ */
+const isNonASCIICodePoint = (cc, q) =>
+	// Simplify
+	cc > 0x80;
+
+/**
+ * Checks whether this object is letter.
+ * @param {number} cc char code
+ * @returns {boolean} is letter
+ */
+const isLetter = (cc) =>
+	(cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
+	(cc >= CC_UPPER_A && cc <= CC_UPPER_Z);
+
+/**
+ * Is ident start code point.
+ * @param {number} cc char code
+ * @param {number} q char code
+ * @returns {boolean} is identifier start code
+ */
+const _isIdentStartCodePoint = (cc, q) =>
+	isLetter(cc) || isNonASCIICodePoint(cc, q) || cc === CC_LOW_LINE;
+
+/**
+ * Is ident code point.
+ * @param {number} cc char code
+ * @param {number} q char code
+ * @returns {boolean} is identifier code
+ */
+const _isIdentCodePoint = (cc, q) =>
+	_isIdentStartCodePoint(cc, q) || _isDigit(cc) || cc === CC_HYPHEN_MINUS;
+/**
+ * Checks whether digit is digit.
+ * @param {number} cc char code
+ * @returns {boolean} is digit
+ */
+const _isDigit = (cc) => cc >= CC_0 && cc <= CC_9;
+
+/**
+ * If two code points are valid escape.
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {number=} f first code point
+ * @param {number=} s second code point
+ * @returns {boolean} true if two code points are a valid escape
+ */
+const _ifTwoCodePointsAreValidEscape = (input, pos, f, s) => {
+	// This section describes how to check if two code points are a valid escape.
+	// The algorithm described here can be called explicitly with two code points, or can be called with the input stream itself.
+	// In the latter case, the two code points in question are the current input code point and the next input code point, in that order.
+
+	// Note: This algorithm will not consume any additional code point.
+	const first = f || input.charCodeAt(pos - 1);
+	const second = s || input.charCodeAt(pos);
+
+	// If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
+	if (first !== CC_REVERSE_SOLIDUS) return false;
+	// Otherwise, if the second code point is a newline, return false.
+	if (_isNewline(second)) return false;
+	// Otherwise, return true.
+	return true;
+};
+
+/**
+ * If three code points would start an ident sequence.
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {number=} f first
+ * @param {number=} s second
+ * @param {number=} t third
+ * @returns {boolean} true, if input at pos starts an identifier
+ */
+const _ifThreeCodePointsWouldStartAnIdentSequence = (input, pos, f, s, t) => {
+	// This section describes how to check if three code points would start an ident sequence.
+	// The algorithm described here can be called explicitly with three code points, or can be called with the input stream itself.
+	// In the latter case, the three code points in question are the current input code point and the next two input code points, in that order.
+
+	// Note: This algorithm will not consume any additional code points.
+
+	const first = f || input.charCodeAt(pos - 1);
+	const second = s || input.charCodeAt(pos);
+	const third = t || input.charCodeAt(pos + 1);
+
+	// Look at the first code point:
+
+	// U+002D HYPHEN-MINUS
+	if (first === CC_HYPHEN_MINUS) {
+		// If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS
+		// or a U+002D HYPHEN-MINUS, or the second and third code points are a valid escape, return true.
+		if (
+			_isIdentStartCodePoint(second, pos) ||
+			second === CC_HYPHEN_MINUS ||
+			_ifTwoCodePointsAreValidEscape(input, pos, second, third)
+		) {
+			return true;
+		}
+		return false;
+	}
+	// ident-start code point
+	else if (_isIdentStartCodePoint(first, pos - 1)) {
+		return true;
+	}
+	// U+005C REVERSE SOLIDUS (\)
+	// If the first and second code points are a valid escape, return true. Otherwise, return false.
+	else if (first === CC_REVERSE_SOLIDUS) {
+		if (_ifTwoCodePointsAreValidEscape(input, pos, first, second)) {
+			return true;
+		}
+
+		return false;
+	}
+	// anything else
+	// Return false.
+	return false;
+};
+
+/**
+ * If three code points would start a number.
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {number=} f first
+ * @param {number=} s second
+ * @param {number=} t third
+ * @returns {boolean} true, if input at pos starts an identifier
+ */
+const _ifThreeCodePointsWouldStartANumber = (input, pos, f, s, t) => {
+	// This section describes how to check if three code points would start a number.
+	// The algorithm described here can be called explicitly with three code points, or can be called with the input stream itself.
+	// In the latter case, the three code points in question are the current input code point and the next two input code points, in that order.
+
+	// Note: This algorithm will not consume any additional code points.
+
+	const first = f || input.charCodeAt(pos - 1);
+	const second = s || input.charCodeAt(pos);
+	const third = t || input.charCodeAt(pos + 1);
+
+	// Look at the first code point:
+
+	// U+002B PLUS SIGN (+)
+	// U+002D HYPHEN-MINUS (-)
+	//
+	// If the second code point is a digit, return true.
+	// Otherwise, if the second code point is a U+002E FULL STOP (.) and the third code point is a digit, return true.
+	// Otherwise, return false.
+	if (first === CC_PLUS_SIGN || first === CC_HYPHEN_MINUS) {
+		if (_isDigit(second)) {
+			return true;
+		} else if (second === CC_FULL_STOP && _isDigit(third)) {
+			return true;
+		}
+
+		return false;
+	}
+	// U+002E FULL STOP (.)
+	// If the second code point is a digit, return true. Otherwise, return false.
+	else if (first === CC_FULL_STOP) {
+		if (_isDigit(second)) {
+			return true;
+		}
+
+		return false;
+	}
+	// digit
+	// Return true.
+	else if (_isDigit(first)) {
+		return true;
+	}
+
+	// anything else
+	// Return false.
+	return false;
+};
+
+/** @type {CharHandler} */
+const consumeNumberSign = (input, pos, callbacks) => {
+	// If the next input code point is an ident code point or the next two input code points are a valid escape, then:
+	// - Create a <hash-token>.
+	// - If the next 3 input code points would start an ident sequence, set the <hash-token>’s type flag to "id".
+	// - Consume an ident sequence, and set the <hash-token>’s value to the returned string.
+	// - Return the <hash-token>.
+	const start = pos - 1;
+	const first = input.charCodeAt(pos);
+	const second = input.charCodeAt(pos + 1);
+
+	if (
+		_isIdentCodePoint(first, pos - 1) ||
+		_ifTwoCodePointsAreValidEscape(input, pos, first, second)
+	) {
+		const third = input.charCodeAt(pos + 2);
+		let isId = false;
+
+		if (
+			_ifThreeCodePointsWouldStartAnIdentSequence(
+				input,
+				pos,
+				first,
+				second,
+				third
+			)
+		) {
+			isId = true;
+		}
+
+		pos = _consumeAnIdentSequence(input, pos, callbacks);
+
+		if (callbacks.hash !== undefined) {
+			return callbacks.hash(input, start, pos, isId);
+		}
+
+		return pos;
+	}
+
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, start, pos);
+	}
+
+	// Otherwise, return a <delim-token> with its value set to the current input code point.
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeHyphenMinus = (input, pos, callbacks) => {
+	// If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
+	if (_ifThreeCodePointsWouldStartANumber(input, pos)) {
+		pos--;
+		return consumeANumericToken(input, pos, callbacks);
+	}
+	// Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
+	else if (
+		input.charCodeAt(pos) === CC_HYPHEN_MINUS &&
+		input.charCodeAt(pos + 1) === CC_GREATER_THAN_SIGN
+	) {
+		if (callbacks.cdc !== undefined) {
+			return callbacks.cdc(input, pos - 1, pos + 2);
+		}
+
+		return pos + 2;
+	}
+	// Otherwise, if the input stream starts with an ident sequence, reconsume the current input code point, consume an ident-like token, and return it.
+	else if (_ifThreeCodePointsWouldStartAnIdentSequence(input, pos)) {
+		pos--;
+		return consumeAnIdentLikeToken(input, pos, callbacks);
+	}
+
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, pos - 1, pos);
+	}
+
+	// Otherwise, return a <delim-token> with its value set to the current input code point.
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeFullStop = (input, pos, callbacks) => {
+	const start = pos - 1;
+
+	// If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
+	if (_ifThreeCodePointsWouldStartANumber(input, pos)) {
+		pos--;
+		return consumeANumericToken(input, pos, callbacks);
+	}
+
+	// Otherwise, return a <delim-token> with its value set to the current input code point.
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, start, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumePlusSign = (input, pos, callbacks) => {
+	const start = pos - 1;
+
+	// If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
+	if (_ifThreeCodePointsWouldStartANumber(input, pos)) {
+		pos--;
+		return consumeANumericToken(input, pos, callbacks);
+	}
+
+	// Otherwise, return a <delim-token> with its value set to the current input code point.
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, start, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const _consumeANumber = (input, pos) => {
+	// This section describes how to consume a number from a stream of code points.
+	// It returns a numeric value, and a type which is either "integer" or "number".
+
+	// Execute the following steps in order:
+	// Initially set type to "integer". Let repr be the empty string.
+
+	// If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-), consume it and append it to repr.
+	if (
+		input.charCodeAt(pos) === CC_HYPHEN_MINUS ||
+		input.charCodeAt(pos) === CC_PLUS_SIGN
+	) {
+		pos++;
+	}
+
+	// While the next input code point is a digit, consume it and append it to repr.
+	while (_isDigit(input.charCodeAt(pos))) {
+		pos++;
+	}
+
+	// If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
+	// 1. Consume the next input code point and append it to number part.
+	// 2. While the next input code point is a digit, consume it and append it to number part.
+	// 3. Set type to "number".
+	if (
+		input.charCodeAt(pos) === CC_FULL_STOP &&
+		_isDigit(input.charCodeAt(pos + 1))
+	) {
+		pos++;
+
+		while (_isDigit(input.charCodeAt(pos))) {
+			pos++;
+		}
+	}
+
+	// If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E (e), optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+), followed by a digit, then:
+	// 1. Consume the next input code point.
+	// 2. If the next input code point is "+" or "-", consume it and append it to exponent part.
+	// 3. While the next input code point is a digit, consume it and append it to exponent part.
+	// 4. Set type to "number".
+	if (
+		(input.charCodeAt(pos) === CC_LOWER_E ||
+			input.charCodeAt(pos) === CC_UPPER_E) &&
+		(((input.charCodeAt(pos + 1) === CC_HYPHEN_MINUS ||
+			input.charCodeAt(pos + 1) === CC_PLUS_SIGN) &&
+			_isDigit(input.charCodeAt(pos + 2))) ||
+			_isDigit(input.charCodeAt(pos + 1)))
+	) {
+		pos++;
+
+		if (
+			input.charCodeAt(pos) === CC_PLUS_SIGN ||
+			input.charCodeAt(pos) === CC_HYPHEN_MINUS
+		) {
+			pos++;
+		}
+
+		while (_isDigit(input.charCodeAt(pos))) {
+			pos++;
+		}
+	}
+
+	// Let value be the result of interpreting number part as a base-10 number.
+
+	// If exponent part is non-empty, interpret it as a base-10 integer, then raise 10 to the power of the result, multiply it by value, and set value to that result.
+
+	// Return value and type.
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeANumericToken = (input, pos, callbacks) => {
+	// This section describes how to consume a numeric token from a stream of code points.
+	// It returns either a <number-token>, <percentage-token>, or <dimension-token>.
+
+	const start = pos;
+
+	// Consume a number and let number be the result.
+	pos = _consumeANumber(input, pos, callbacks);
+
+	// If the next 3 input code points would start an ident sequence, then:
+	//
+	// - Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
+	// - Consume an ident sequence. Set the <dimension-token>’s unit to the returned value.
+	// - Return the <dimension-token>.
+
+	const first = input.charCodeAt(pos);
+	const second = input.charCodeAt(pos + 1);
+	const third = input.charCodeAt(pos + 2);
+
+	if (
+		_ifThreeCodePointsWouldStartAnIdentSequence(
+			input,
+			pos,
+			first,
+			second,
+			third
+		)
+	) {
+		pos = _consumeAnIdentSequence(input, pos, callbacks);
+
+		if (callbacks.dimension !== undefined) {
+			return callbacks.dimension(input, start, pos);
+		}
+
+		return pos;
+	}
+	// Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
+	// Create a <percentage-token> with the same value as number, and return it.
+	else if (first === CC_PERCENTAGE) {
+		if (callbacks.percentage !== undefined) {
+			return callbacks.percentage(input, start, pos + 1);
+		}
+
+		return pos + 1;
+	}
+
+	// Otherwise, create a <number-token> with the same value and type flag as number, and return it.
+	if (callbacks.number !== undefined) {
+		return callbacks.number(input, start, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeColon = (input, pos, callbacks) => {
+	// Return a <colon-token>.
+	if (callbacks.colon !== undefined) {
+		return callbacks.colon(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLeftParenthesis = (input, pos, callbacks) => {
+	// Return a <(-token>.
+	if (callbacks.leftParenthesis !== undefined) {
+		return callbacks.leftParenthesis(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeRightParenthesis = (input, pos, callbacks) => {
+	// Return a <)-token>.
+	if (callbacks.rightParenthesis !== undefined) {
+		return callbacks.rightParenthesis(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLeftSquareBracket = (input, pos, callbacks) => {
+	// Return a <]-token>.
+	if (callbacks.leftSquareBracket !== undefined) {
+		return callbacks.leftSquareBracket(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeRightSquareBracket = (input, pos, callbacks) => {
+	// Return a <]-token>.
+	if (callbacks.rightSquareBracket !== undefined) {
+		return callbacks.rightSquareBracket(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLeftCurlyBracket = (input, pos, callbacks) => {
+	// Return a <{-token>.
+	if (callbacks.leftCurlyBracket !== undefined) {
+		return callbacks.leftCurlyBracket(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeRightCurlyBracket = (input, pos, callbacks) => {
+	// Return a <}-token>.
+	if (callbacks.rightCurlyBracket !== undefined) {
+		return callbacks.rightCurlyBracket(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeSemicolon = (input, pos, callbacks) => {
+	// Return a <semicolon-token>.
+	if (callbacks.semicolon !== undefined) {
+		return callbacks.semicolon(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeComma = (input, pos, callbacks) => {
+	// Return a <comma-token>.
+	if (callbacks.comma !== undefined) {
+		return callbacks.comma(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const _consumeAnIdentSequence = (input, pos) => {
+	// This section describes how to consume an ident sequence from a stream of code points.
+	// It returns a string containing the largest name that can be formed from adjacent code points in the stream, starting from the first.
+
+	// Note: This algorithm does not do the verification of the first few code points that are necessary to ensure the returned code points would constitute an <ident-token>.
+	// If that is the intended use, ensure that the stream starts with an ident sequence before calling this algorithm.
+
+	// Let result initially be an empty string.
+
+	// Repeatedly consume the next input code point from the stream:
+	for (;;) {
+		const cc = input.charCodeAt(pos);
+		pos++;
+
+		// ident code point
+		// Append the code point to result.
+		if (_isIdentCodePoint(cc, pos - 1)) {
+			// Nothing
+		}
+		// the stream starts with a valid escape
+		// Consume an escaped code point. Append the returned code point to result.
+		else if (_ifTwoCodePointsAreValidEscape(input, pos)) {
+			pos = _consumeAnEscapedCodePoint(input, pos);
+		}
+		// anything else
+		// Reconsume the current input code point. Return result.
+		else {
+			return pos - 1;
+		}
+	}
+};
+
+/**
+ * Is non printable code point.
+ * @param {number} cc char code
+ * @returns {boolean} true, when cc is the non-printable code point, otherwise false
+ */
+const _isNonPrintableCodePoint = (cc) =>
+	(cc >= 0x00 && cc <= 0x08) ||
+	cc === 0x0b ||
+	(cc >= 0x0e && cc <= 0x1f) ||
+	cc === 0x7f;
+
+/**
+ * Consume the remnants of a bad url.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position
+ */
+const consumeTheRemnantsOfABadUrl = (input, pos) => {
+	// This section describes how to consume the remnants of a bad url from a stream of code points,
+	// "cleaning up" after the tokenizer realizes that it’s in the middle of a <bad-url-token> rather than a <url-token>.
+	// It returns nothing; its sole use is to consume enough of the input stream to reach a recovery point where normal tokenizing can resume.
+
+	// Repeatedly consume the next input code point from the stream:
+	for (;;) {
+		// EOF
+		// Return.
+		if (pos === input.length) {
+			return pos;
+		}
+
+		const cc = input.charCodeAt(pos);
+		pos++;
+
+		// U+0029 RIGHT PARENTHESIS ())
+		// Return.
+		if (cc === CC_RIGHT_PARENTHESIS) {
+			return pos;
+		}
+		// the input stream starts with a valid escape
+		// Consume an escaped code point.
+		// This allows an escaped right parenthesis ("\)") to be encountered without ending the <bad-url-token>.
+		// This is otherwise identical to the "anything else" clause.
+		else if (_ifTwoCodePointsAreValidEscape(input, pos)) {
+			pos = _consumeAnEscapedCodePoint(input, pos);
+		}
+		// anything else
+		// Do nothing.
+		else {
+			// Do nothing.
+		}
+	}
+};
+
+/**
+ * Consume a url token.
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {number} fnStart start
+ * @param {CssTokenCallbacks} callbacks callbacks
+ * @returns {pos} pos
+ */
+const consumeAUrlToken = (input, pos, fnStart, callbacks) => {
+	// This section describes how to consume a url token from a stream of code points.
+	// It returns either a <url-token> or a <bad-url-token>.
+
+	// Note: This algorithm assumes that the initial "url(" has already been consumed.
+	// This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
+	// A quoted value, like url("foo"), is parsed as a <function-token>.
+	// Consume an ident-like token automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
+
+	// Initially create a <url-token> with its value set to the empty string.
+
+	// Consume as much whitespace as possible.
+	while (_isWhiteSpace(input.charCodeAt(pos))) {
+		pos++;
+	}
+
+	const contentStart = pos;
+
+	// Repeatedly consume the next input code point from the stream:
+	for (;;) {
+		// EOF
+		// This is a parse error. Return the <url-token>.
+		if (pos === input.length) {
+			if (callbacks.url !== undefined) {
+				return callbacks.url(input, fnStart, pos, contentStart, pos - 1);
+			}
+
+			return pos;
+		}
+
+		const cc = input.charCodeAt(pos);
+		pos++;
+
+		// U+0029 RIGHT PARENTHESIS ())
+		// Return the <url-token>.
+		if (cc === CC_RIGHT_PARENTHESIS) {
+			if (callbacks.url !== undefined) {
+				return callbacks.url(input, fnStart, pos, contentStart, pos - 1);
+			}
+
+			return pos;
+		}
+		// whitespace
+		// Consume as much whitespace as possible.
+		// If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF, consume it and return the <url-token>
+		// (if EOF was encountered, this is a parse error); otherwise, consume the remnants of a bad url, create a <bad-url-token>, and return it.
+		else if (_isWhiteSpace(cc)) {
+			const end = pos - 1;
+
+			while (_isWhiteSpace(input.charCodeAt(pos))) {
+				pos++;
+			}
+
+			if (pos === input.length) {
+				if (callbacks.url !== undefined) {
+					return callbacks.url(input, fnStart, pos, contentStart, end);
+				}
+
+				return pos;
+			}
+
+			if (input.charCodeAt(pos) === CC_RIGHT_PARENTHESIS) {
+				pos++;
+
+				if (callbacks.url !== undefined) {
+					return callbacks.url(input, fnStart, pos, contentStart, end);
+				}
+
+				return pos;
+			}
+
+			// Don't handle bad urls
+			pos = consumeTheRemnantsOfABadUrl(input, pos);
+
+			if (callbacks.badUrlToken !== undefined) {
+				return callbacks.badUrlToken(input, fnStart, pos);
+			}
+
+			return pos;
+		}
+		// U+0022 QUOTATION MARK (")
+		// U+0027 APOSTROPHE (')
+		// U+0028 LEFT PARENTHESIS (()
+		// non-printable code point
+		// This is a parse error. Consume the remnants of a bad url, create a <bad-url-token>, and return it.
+		else if (
+			cc === CC_QUOTATION_MARK ||
+			cc === CC_APOSTROPHE ||
+			cc === CC_LEFT_PARENTHESIS ||
+			_isNonPrintableCodePoint(cc)
+		) {
+			// Don't handle bad urls
+			pos = consumeTheRemnantsOfABadUrl(input, pos);
+
+			if (callbacks.badUrlToken !== undefined) {
+				return callbacks.badUrlToken(input, fnStart, pos);
+			}
+
+			return pos;
+		}
+		// // U+005C REVERSE SOLIDUS (\)
+		// // If the stream starts with a valid escape, consume an escaped code point and append the returned code point to the <url-token>’s value.
+		// // Otherwise, this is a parse error. Consume the remnants of a bad url, create a <bad-url-token>, and return it.
+		else if (cc === CC_REVERSE_SOLIDUS) {
+			if (_ifTwoCodePointsAreValidEscape(input, pos)) {
+				pos = _consumeAnEscapedCodePoint(input, pos);
+			} else {
+				// Don't handle bad urls
+				pos = consumeTheRemnantsOfABadUrl(input, pos);
+
+				if (callbacks.badUrlToken !== undefined) {
+					return callbacks.badUrlToken(input, fnStart, pos);
+				}
+
+				return pos;
+			}
+		}
+		// anything else
+		// Append the current input code point to the <url-token>’s value.
+		else {
+			// Nothing
+		}
+	}
+};
+
+/** @type {CharHandler} */
+const consumeAnIdentLikeToken = (input, pos, callbacks) => {
+	const start = pos;
+	// This section describes how to consume an ident-like token from a stream of code points.
+	// It returns an <ident-token>, <function-token>, <url-token>, or <bad-url-token>.
+	pos = _consumeAnIdentSequence(input, pos, callbacks);
+
+	// If string’s value is an ASCII case-insensitive match for "url", and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
+	// While the next two input code points are whitespace, consume the next input code point.
+	// If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('), or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('), then create a <function-token> with its value set to string and return it.
+	// Otherwise, consume a url token, and return it.
+	if (
+		input.slice(start, pos).toLowerCase() === "url" &&
+		input.charCodeAt(pos) === CC_LEFT_PARENTHESIS
+	) {
+		pos++;
+		const end = pos;
+
+		while (
+			_isWhiteSpace(input.charCodeAt(pos)) &&
+			_isWhiteSpace(input.charCodeAt(pos + 1))
+		) {
+			pos++;
+		}
+
+		if (
+			input.charCodeAt(pos) === CC_QUOTATION_MARK ||
+			input.charCodeAt(pos) === CC_APOSTROPHE ||
+			(_isWhiteSpace(input.charCodeAt(pos)) &&
+				(input.charCodeAt(pos + 1) === CC_QUOTATION_MARK ||
+					input.charCodeAt(pos + 1) === CC_APOSTROPHE))
+		) {
+			if (callbacks.function !== undefined) {
+				return callbacks.function(input, start, end);
+			}
+
+			return pos;
+		}
+
+		return consumeAUrlToken(input, pos, start, callbacks);
+	}
+
+	// Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
+	// Create a <function-token> with its value set to string and return it.
+	if (input.charCodeAt(pos) === CC_LEFT_PARENTHESIS) {
+		pos++;
+
+		if (callbacks.function !== undefined) {
+			return callbacks.function(input, start, pos);
+		}
+
+		return pos;
+	}
+
+	// Otherwise, create an <ident-token> with its value set to string and return it.
+	if (callbacks.identifier !== undefined) {
+		return callbacks.identifier(input, start, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLessThan = (input, pos, callbacks) => {
+	// If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), consume them and return a <CDO-token>.
+	if (input.slice(pos, pos + 3) === "!--") {
+		if (callbacks.cdo !== undefined) {
+			return callbacks.cdo(input, pos - 1, pos + 3);
+		}
+
+		return pos + 3;
+	}
+
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, pos - 1, pos);
+	}
+
+	// Otherwise, return a <delim-token> with its value set to the current input code point.
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeCommercialAt = (input, pos, callbacks) => {
+	const start = pos - 1;
+
+	// If the next 3 input code points would start an ident sequence, consume an ident sequence, create an <at-keyword-token> with its value set to the returned value, and return it.
+	if (
+		_ifThreeCodePointsWouldStartAnIdentSequence(
+			input,
+			pos,
+			input.charCodeAt(pos),
+			input.charCodeAt(pos + 1),
+			input.charCodeAt(pos + 2)
+		)
+	) {
+		pos = _consumeAnIdentSequence(input, pos, callbacks);
+
+		if (callbacks.atKeyword !== undefined) {
+			pos = callbacks.atKeyword(input, start, pos);
+		}
+
+		return pos;
+	}
+
+	// Otherwise, return a <delim-token> with its value set to the current input code point.
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, start, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeReverseSolidus = (input, pos, callbacks) => {
+	// If the input stream starts with a valid escape, reconsume the current input code point, consume an ident-like token, and return it.
+	if (_ifTwoCodePointsAreValidEscape(input, pos)) {
+		pos--;
+		return consumeAnIdentLikeToken(input, pos, callbacks);
+	}
+
+	// Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
+	if (callbacks.delim !== undefined) {
+		return callbacks.delim(input, pos - 1, pos);
+	}
+
+	return pos;
+};
+
+/** @type {CharHandler} */
+const consumeAToken = (input, pos, callbacks) => {
+	const cc = input.charCodeAt(pos - 1);
+
+	// https://drafts.csswg.org/css-syntax/#consume-token
+	switch (cc) {
+		// whitespace
+		case CC_LINE_FEED:
+		case CC_CARRIAGE_RETURN:
+		case CC_FORM_FEED:
+		case CC_TAB:
+		case CC_SPACE:
+			return consumeSpace(input, pos, callbacks);
+		// U+0022 QUOTATION MARK (")
+		case CC_QUOTATION_MARK:
+			return consumeAStringToken(input, pos, callbacks);
+		// U+0023 NUMBER SIGN (#)
+		case CC_NUMBER_SIGN:
+			return consumeNumberSign(input, pos, callbacks);
+		// U+0027 APOSTROPHE (')
+		case CC_APOSTROPHE:
+			return consumeAStringToken(input, pos, callbacks);
+		// U+0028 LEFT PARENTHESIS (()
+		case CC_LEFT_PARENTHESIS:
+			return consumeLeftParenthesis(input, pos, callbacks);
+		// U+0029 RIGHT PARENTHESIS ())
+		case CC_RIGHT_PARENTHESIS:
+			return consumeRightParenthesis(input, pos, callbacks);
+		// U+002B PLUS SIGN (+)
+		case CC_PLUS_SIGN:
+			return consumePlusSign(input, pos, callbacks);
+		// U+002C COMMA (,)
+		case CC_COMMA:
+			return consumeComma(input, pos, callbacks);
+		// U+002D HYPHEN-MINUS (-)
+		case CC_HYPHEN_MINUS:
+			return consumeHyphenMinus(input, pos, callbacks);
+		// U+002E FULL STOP (.)
+		case CC_FULL_STOP:
+			return consumeFullStop(input, pos, callbacks);
+		// U+003A COLON (:)
+		case CC_COLON:
+			return consumeColon(input, pos, callbacks);
+		// U+003B SEMICOLON (;)
+		case CC_SEMICOLON:
+			return consumeSemicolon(input, pos, callbacks);
+		// U+003C LESS-THAN SIGN (<)
+		case CC_LESS_THAN_SIGN:
+			return consumeLessThan(input, pos, callbacks);
+		// U+0040 COMMERCIAL AT (@)
+		case CC_AT_SIGN:
+			return consumeCommercialAt(input, pos, callbacks);
+		// U+005B LEFT SQUARE BRACKET ([)
+		case CC_LEFT_SQUARE:
+			return consumeLeftSquareBracket(input, pos, callbacks);
+		// U+005C REVERSE SOLIDUS (\)
+		case CC_REVERSE_SOLIDUS:
+			return consumeReverseSolidus(input, pos, callbacks);
+		// U+005D RIGHT SQUARE BRACKET (])
+		case CC_RIGHT_SQUARE:
+			return consumeRightSquareBracket(input, pos, callbacks);
+		// U+007B LEFT CURLY BRACKET ({)
+		case CC_LEFT_CURLY:
+			return consumeLeftCurlyBracket(input, pos, callbacks);
+		// U+007D RIGHT CURLY BRACKET (})
+		case CC_RIGHT_CURLY:
+			return consumeRightCurlyBracket(input, pos, callbacks);
+		default:
+			// digit
+			// Reconsume the current input code point, consume a numeric token, and return it.
+			if (_isDigit(cc)) {
+				pos--;
+				return consumeANumericToken(input, pos, callbacks);
+			} else if (cc === CC_LOWER_U || cc === CC_UPPER_U) {
+				// If unicode ranges allowed is true and the input stream would start a unicode-range,
+				// reconsume the current input code point, consume a unicode-range token, and return it.
+				// Skip now
+				// if (_ifThreeCodePointsWouldStartAUnicodeRange(input, pos)) {
+				// 	pos--;
+				// 	return consumeAUnicodeRangeToken(input, pos, callbacks);
+				// }
+
+				// Otherwise, reconsume the current input code point, consume an ident-like token, and return it.
+				pos--;
+				return consumeAnIdentLikeToken(input, pos, callbacks);
+			}
+			// ident-start code point
+			// Reconsume the current input code point, consume an ident-like token, and return it.
+			else if (isIdentStartCodePoint(cc)) {
+				pos--;
+				return consumeAnIdentLikeToken(input, pos, callbacks);
+			}
+
+			// EOF, but we don't have it
+
+			// anything else
+			// Return a <delim-token> with its value set to the current input code point.
+			return consumeDelimToken(input, pos, callbacks);
+	}
+};
+
+/**
+ * Returns pos.
+ * @param {string} input input css
+ * @param {number=} pos pos
+ * @param {CssTokenCallbacks=} callbacks callbacks
+ * @returns {number} pos
+ */
+module.exports = (input, pos = 0, callbacks = {}) => {
+	// This section describes how to consume a token from a stream of code points. It will return a single token of any type.
+	while (pos < input.length) {
+		// Consume comments.
+		pos = consumeComments(input, pos, callbacks);
+
+		// Consume the next input code point.
+		pos++;
+		pos = consumeAToken(input, pos, callbacks);
+
+		if (callbacks.needTerminate && callbacks.needTerminate()) {
+			break;
+		}
+	}
+
+	return pos;
+};
+
+/**
+ * Returns pos.
+ * @param {string} input input css
+ * @param {number} pos pos
+ * @param {CssTokenCallbacks} callbacks callbacks
+ * @param {CssTokenCallbacks=} additional additional callbacks
+ * @param {{ onlyTopLevel?: boolean, declarationValue?: boolean, atRulePrelude?: boolean, functionValue?: boolean }=} options options
+ * @returns {number} pos
+ */
+const consumeUntil = (input, pos, callbacks, additional, options = {}) => {
+	let needHandle = true;
+	let needTerminate = false;
+
+	/** @type {CssTokenCallbacks} */
+	const servicedCallbacks = {};
+
+	let balanced = 0;
+
+	if (options.onlyTopLevel) {
+		servicedCallbacks.function = (input, start, end) => {
+			balanced++;
+			if (!options.functionValue) {
+				needHandle = false;
+			}
+
+			if (additional && additional.function !== undefined) {
+				return additional.function(input, start, end);
+			}
+
+			return end;
+		};
+
+		servicedCallbacks.leftParenthesis = (_input, _start, end) => {
+			balanced++;
+			needHandle = false;
+			return end;
+		};
+		servicedCallbacks.rightParenthesis = (_input, _start, end) => {
+			balanced--;
+			if (balanced === 0) {
+				needHandle = true;
+			}
+			return end;
+		};
+	}
+
+	if (options.declarationValue) {
+		servicedCallbacks.semicolon = (_input, _start, end) => {
+			needTerminate = true;
+			return end;
+		};
+
+		servicedCallbacks.rightCurlyBracket = (_input, _start, end) => {
+			needTerminate = true;
+			return end;
+		};
+	} else if (options.functionValue) {
+		servicedCallbacks.rightParenthesis = (_input, _start, end) => {
+			balanced--;
+			if (balanced === 0) {
+				needTerminate = true;
+			}
+			return end;
+		};
+	} else if (options.atRulePrelude) {
+		servicedCallbacks.leftCurlyBracket = (_input, _start, end) => {
+			needTerminate = true;
+			return end;
+		};
+		servicedCallbacks.semicolon = (_input, _start, end) => {
+			needTerminate = true;
+			return end;
+		};
+	}
+
+	const mergedCallbacks = { ...servicedCallbacks, ...callbacks };
+
+	while (pos < input.length) {
+		// Consume comments.
+		pos = consumeComments(
+			input,
+			pos,
+			needHandle ? mergedCallbacks : servicedCallbacks
+		);
+
+		const start = pos;
+
+		// Consume the next input code point.
+		pos++;
+		pos = consumeAToken(
+			input,
+			pos,
+			needHandle ? mergedCallbacks : servicedCallbacks
+		);
+
+		if (needTerminate) {
+			return start;
+		}
+	}
+
+	return pos;
+};
+
+/**
+ * Returns position after comments.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after comments
+ */
+const eatComments = (input, pos) => {
+	for (;;) {
+		const originalPos = pos;
+		pos = consumeComments(input, pos, {});
+		if (originalPos === pos) {
+			break;
+		}
+	}
+
+	return pos;
+};
+
+/**
+ * Returns position after whitespace.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after whitespace
+ */
+const eatWhitespace = (input, pos) => {
+	while (_isWhiteSpace(input.charCodeAt(pos))) {
+		pos++;
+	}
+
+	return pos;
+};
+
+/**
+ * Eat whitespace and comments.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {[number, boolean]} position after whitespace and comments
+ */
+const eatWhitespaceAndComments = (input, pos) => {
+	let foundWhitespace = false;
+
+	for (;;) {
+		const originalPos = pos;
+		pos = consumeComments(input, pos, {});
+		while (_isWhiteSpace(input.charCodeAt(pos))) {
+			if (!foundWhitespace) {
+				foundWhitespace = true;
+			}
+			pos++;
+		}
+		if (originalPos === pos) {
+			break;
+		}
+	}
+
+	return [pos, foundWhitespace];
+};
+
+/**
+ * Returns position after whitespace.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after whitespace
+ */
+const eatWhiteLine = (input, pos) => {
+	for (;;) {
+		const cc = input.charCodeAt(pos);
+		if (_isSpace(cc)) {
+			pos++;
+			continue;
+		}
+		if (_isNewline(cc)) pos++;
+		pos = consumeExtraNewline(cc, input, pos);
+		break;
+	}
+
+	return pos;
+};
+
+/**
+ * Skip comments and eat ident sequence.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {[number, number] | undefined} positions of ident sequence
+ */
+const skipCommentsAndEatIdentSequence = (input, pos) => {
+	pos = eatComments(input, pos);
+
+	const start = pos;
+
+	if (
+		_ifThreeCodePointsWouldStartAnIdentSequence(
+			input,
+			pos,
+			input.charCodeAt(pos),
+			input.charCodeAt(pos + 1),
+			input.charCodeAt(pos + 2)
+		)
+	) {
+		return [start, _consumeAnIdentSequence(input, pos, {})];
+	}
+
+	return undefined;
+};
+
+/**
+ * Returns positions of ident sequence.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {[number, number] | undefined} positions of ident sequence
+ */
+const eatString = (input, pos) => {
+	pos = eatWhitespaceAndComments(input, pos)[0];
+
+	const start = pos;
+
+	if (
+		input.charCodeAt(pos) === CC_QUOTATION_MARK ||
+		input.charCodeAt(pos) === CC_APOSTROPHE
+	) {
+		return [start, consumeAStringToken(input, pos + 1, {})];
+	}
+
+	return undefined;
+};
+
+/**
+ * Eat image set strings.
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {CssTokenCallbacks} cbs callbacks
+ * @returns {[number, number][]} positions of ident sequence
+ */
+const eatImageSetStrings = (input, pos, cbs) => {
+	/** @type {[number, number][]} */
+	const result = [];
+
+	let isFirst = true;
+	let needStop = false;
+	// We already in `func(` token
+	let balanced = 1;
+
+	/** @type {CssTokenCallbacks} */
+	const callbacks = {
+		...cbs,
+		string: (_input, start, end) => {
+			if (isFirst && balanced === 1) {
+				result.push([start, end]);
+				isFirst = false;
+			}
+
+			return end;
+		},
+		comma: (_input, _start, end) => {
+			if (balanced === 1) {
+				isFirst = true;
+			}
+
+			return end;
+		},
+		leftParenthesis: (input, start, end) => {
+			balanced++;
+
+			return end;
+		},
+		function: (_input, start, end) => {
+			balanced++;
+
+			return end;
+		},
+		rightParenthesis: (_input, _start, end) => {
+			balanced--;
+
+			if (balanced === 0) {
+				needStop = true;
+			}
+
+			return end;
+		}
+	};
+
+	while (pos < input.length) {
+		// Consume comments.
+		pos = consumeComments(input, pos, callbacks);
+
+		// Consume the next input code point.
+		pos++;
+		pos = consumeAToken(input, pos, callbacks);
+
+		if (needStop) {
+			break;
+		}
+	}
+
+	return result;
+};
+
+/**
+ * Returns positions of top level tokens.
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {CssTokenCallbacks} cbs callbacks
+ * @returns {[[number, number, number, number, boolean?] | undefined, [number, number] | undefined, [number, number] | undefined, [number, number] | undefined]} positions of top level tokens — the URL tuple's optional 5th element is `true` when the URL was given as an identifier (CSS Modules `@value` reference)
+ */
+const eatImportTokens = (input, pos, cbs) => {
+	const result =
+		/** @type {[[number, number, number, number, boolean?] | undefined, [number, number] | undefined, [number, number] | undefined, [number, number] | undefined]} */
+		(Array.from({ length: 4 }));
+
+	/** @type {0 | 1 | 2 | undefined} */
+	let scope;
+	let needStop = false;
+	let balanced = 0;
+
+	/** @type {CssTokenCallbacks} */
+	const callbacks = {
+		...cbs,
+		url: (_input, start, end, contentStart, contentEnd) => {
+			if (
+				result[0] === undefined &&
+				balanced === 0 &&
+				result[1] === undefined &&
+				result[2] === undefined &&
+				result[3] === undefined
+			) {
+				result[0] = [start, end, contentStart, contentEnd];
+				scope = undefined;
+			}
+
+			return end;
+		},
+		string: (_input, start, end) => {
+			if (
+				balanced === 0 &&
+				result[0] === undefined &&
+				result[1] === undefined &&
+				result[2] === undefined &&
+				result[3] === undefined
+			) {
+				result[0] = [start, end, start + 1, end - 1];
+				scope = undefined;
+			} else if (result[0] !== undefined && scope === 0) {
+				result[0][2] = start + 1;
+				result[0][3] = end - 1;
+			}
+
+			return end;
+		},
+		leftParenthesis: (_input, _start, end) => {
+			balanced++;
+
+			return end;
+		},
+		rightParenthesis: (_input, _start, end) => {
+			balanced--;
+
+			if (balanced === 0 && scope !== undefined) {
+				/** @type {[number, number]} */
+				(result[scope])[1] = end;
+				scope = undefined;
+			}
+
+			return end;
+		},
+		function: (input, start, end) => {
+			if (balanced === 0) {
+				const name = input
+					.slice(start, end - 1)
+					.replace(/\\/g, "")
+					.toLowerCase();
+
+				if (
+					name === "url" &&
+					result[0] === undefined &&
+					result[1] === undefined &&
+					result[2] === undefined &&
+					result[3] === undefined
+				) {
+					scope = 0;
+					result[scope] = [start, end + 1, end + 1, end + 1];
+				} else if (
+					name === "layer" &&
+					result[1] === undefined &&
+					result[2] === undefined
+				) {
+					scope = 1;
+					result[scope] = [start, end];
+				} else if (name === "supports" && result[2] === undefined) {
+					scope = 2;
+					result[scope] = [start, end];
+				} else {
+					scope = undefined;
+				}
+			}
+
+			balanced++;
+
+			return end;
+		},
+		identifier: (input, start, end) => {
+			if (
+				balanced === 0 &&
+				result[1] === undefined &&
+				result[2] === undefined
+			) {
+				const name = input.slice(start, end).replace(/\\/g, "").toLowerCase();
+
+				if (name === "layer") {
+					result[1] = [start, end];
+					scope = undefined;
+				} else if (result[0] === undefined) {
+					// Capture as URL identifier (e.g. `@import myValue;` where
+					// `myValue` is a CSS Modules `@value` definition).
+					result[0] = [start, end, start, end, true];
+					scope = undefined;
+				}
+			}
+
+			return end;
+		},
+		semicolon: (_input, start, end) => {
+			if (balanced === 0) {
+				needStop = true;
+				result[3] = [start, end];
+			}
+
+			return end;
+		}
+	};
+
+	while (pos < input.length) {
+		// Consume comments.
+		pos = consumeComments(input, pos, callbacks);
+
+		// Consume the next input code point.
+		pos++;
+		pos = consumeAToken(input, pos, callbacks);
+
+		if (needStop) {
+			break;
+		}
+	}
+
+	return result;
+};
+
+/**
+ * Eat ident sequence.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {[number, number] | undefined} positions of ident sequence
+ */
+const eatIdentSequence = (input, pos) => {
+	pos = eatWhitespaceAndComments(input, pos)[0];
+
+	const start = pos;
+
+	if (
+		_ifThreeCodePointsWouldStartAnIdentSequence(
+			input,
+			pos,
+			input.charCodeAt(pos),
+			input.charCodeAt(pos + 1),
+			input.charCodeAt(pos + 2)
+		)
+	) {
+		return [start, _consumeAnIdentSequence(input, pos, {})];
+	}
+
+	return undefined;
+};
+
+/**
+ * Eat ident sequence or string.
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {[number, number, boolean] | undefined} positions of ident sequence or string
+ */
+const eatIdentSequenceOrString = (input, pos) => {
+	pos = eatWhitespaceAndComments(input, pos)[0];
+
+	const start = pos;
+
+	if (
+		input.charCodeAt(pos) === CC_QUOTATION_MARK ||
+		input.charCodeAt(pos) === CC_APOSTROPHE
+	) {
+		return [start, consumeAStringToken(input, pos + 1, {}), false];
+	} else if (
+		_ifThreeCodePointsWouldStartAnIdentSequence(
+			input,
+			pos,
+			input.charCodeAt(pos),
+			input.charCodeAt(pos + 1),
+			input.charCodeAt(pos + 2)
+		)
+	) {
+		return [start, _consumeAnIdentSequence(input, pos, {}), true];
+	}
+
+	return undefined;
+};
+
+/**
+ * Returns function to eat characters.
+ * @param {string} chars characters
+ * @returns {(input: string, pos: number) => number} function to eat characters
+ */
+const eatUntil = (chars) => {
+	const charCodes = Array.from({ length: chars.length }, (_, i) =>
+		chars.charCodeAt(i)
+	);
+	const arr = Array.from(
+		{ length: Math.max(...charCodes, 0) + 1 },
+		() => false
+	);
+	for (const cc of charCodes) {
+		arr[cc] = true;
+	}
+
+	return (input, pos) => {
+		for (;;) {
+			const cc = input.charCodeAt(pos);
+			if (cc < arr.length && arr[cc]) {
+				return pos;
+			}
+			pos++;
+			if (pos === input.length) return pos;
+		}
+	};
+};
+
+module.exports.consumeUntil = consumeUntil;
+module.exports.eatComments = eatComments;
+module.exports.eatIdentSequence = eatIdentSequence;
+module.exports.eatIdentSequenceOrString = eatIdentSequenceOrString;
+module.exports.eatImageSetStrings = eatImageSetStrings;
+module.exports.eatImportTokens = eatImportTokens;
+module.exports.eatString = eatString;
+module.exports.eatUntil = eatUntil;
+module.exports.eatWhiteLine = eatWhiteLine;
+module.exports.eatWhitespace = eatWhitespace;
+module.exports.eatWhitespaceAndComments = eatWhitespaceAndComments;
+module.exports.escapeIdentifier = escapeIdentifier;
+module.exports.isIdentStartCodePoint = isIdentStartCodePoint;
+module.exports.isWhiteSpace = _isWhiteSpace;
+module.exports.skipCommentsAndEatIdentSequence =
+	skipCommentsAndEatIdentSequence;
+module.exports.unescapeIdentifier = unescapeIdentifier;
Index: frontend/node_modules/webpack/lib/debug/ProfilingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/debug/ProfilingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/debug/ProfilingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,610 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { Tracer } = require("chrome-trace-event");
+const {
+	CSS_MODULES,
+	JAVASCRIPT_MODULES,
+	JSON_MODULE_TYPE,
+	WEBASSEMBLY_MODULES
+} = require("../ModuleTypeConstants");
+const { dirname, mkdirpSync } = require("../util/fs");
+
+/** @typedef {import("inspector").Session} Session */
+/** @typedef {import("tapable").FullTap} FullTap */
+/** @typedef {import("../../declarations/plugins/debug/ProfilingPlugin").ProfilingPluginOptions} ProfilingPluginOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../NormalModuleFactory")} NormalModuleFactory */
+/** @typedef {import("../ResolverFactory")} ResolverFactory */
+/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
+
+/**
+ * Defines the hook type used by this module.
+ * @template T, R
+ * @typedef {import("tapable").Hook<T, R>} Hook
+ */
+
+/**
+ * Defines the fake hook type used by this module.
+ * @template T
+ * @typedef {import("../util/deprecation").FakeHook<T>} FakeHook
+ */
+
+/**
+ * Defines the hook map type used by this module.
+ * @template T
+ * @typedef {import("tapable").HookMap<T>} HookMap
+ */
+
+/**
+ * Defines the hook interceptor type used by this module.
+ * @template T, R
+ * @typedef {import("tapable").HookInterceptor<T, R>} HookInterceptor
+ */
+
+/** @typedef {{ Session: typeof import("inspector").Session }} Inspector */
+
+/** @type {Inspector | undefined} */
+let inspector;
+
+try {
+	// eslint-disable-next-line n/no-unsupported-features/node-builtins
+	inspector = require("inspector");
+} catch (_err) {
+	// eslint-disable-next-line no-console
+	console.log("Unable to CPU profile in < node 8.0");
+}
+
+class Profiler {
+	/**
+	 * Creates an instance of Profiler.
+	 * @param {Inspector} inspector inspector
+	 */
+	constructor(inspector) {
+		/** @type {undefined | Session} */
+		this.session = undefined;
+		this.inspector = inspector;
+		this._startTime = 0;
+	}
+
+	hasSession() {
+		return this.session !== undefined;
+	}
+
+	startProfiling() {
+		if (this.inspector === undefined) {
+			return Promise.resolve();
+		}
+
+		try {
+			this.session = new /** @type {Inspector} */ (inspector).Session();
+			/** @type {Session} */
+			(this.session).connect();
+		} catch (_) {
+			this.session = undefined;
+			return Promise.resolve();
+		}
+
+		const hrtime = process.hrtime();
+		this._startTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000);
+
+		return Promise.all([
+			this.sendCommand("Profiler.setSamplingInterval", {
+				interval: 100
+			}),
+			this.sendCommand("Profiler.enable"),
+			this.sendCommand("Profiler.start")
+		]);
+	}
+
+	/**
+	 * Returns promise for the result.
+	 * @param {string} method method name
+	 * @param {EXPECTED_OBJECT=} params params
+	 * @returns {Promise<EXPECTED_ANY | void>} Promise for the result
+	 */
+	sendCommand(method, params) {
+		if (this.hasSession()) {
+			return new Promise((res, rej) => {
+				/** @type {Session} */
+				(this.session).post(method, params, (err, params) => {
+					if (err !== null) {
+						rej(err);
+					} else {
+						res(params);
+					}
+				});
+			});
+		}
+		return Promise.resolve();
+	}
+
+	destroy() {
+		if (this.hasSession()) {
+			/** @type {Session} */
+			(this.session).disconnect();
+		}
+
+		return Promise.resolve();
+	}
+
+	/**
+	 * Returns }>} profile result.
+	 * @returns {Promise<{ profile: { startTime: number, endTime: number } }>} profile result
+	 */
+	stopProfiling() {
+		return this.sendCommand("Profiler.stop").then(({ profile }) => {
+			const hrtime = process.hrtime();
+			const endTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000);
+			// Avoid coverage problems due indirect changes
+			/* istanbul ignore next */
+			if (profile.startTime < this._startTime || profile.endTime > endTime) {
+				// In some cases timestamps mismatch and we need to adjust them
+				// Both process.hrtime and the inspector timestamps claim to be relative
+				// to a unknown point in time. But they do not guarantee that this is the
+				// same point in time.
+				const duration = profile.endTime - profile.startTime;
+				const ownDuration = endTime - this._startTime;
+				const untracked = Math.max(0, ownDuration - duration);
+				profile.startTime = this._startTime + untracked / 2;
+				profile.endTime = endTime - untracked / 2;
+			}
+			return { profile };
+		});
+	}
+}
+
+/**
+ * an object that wraps Tracer and Profiler with a counter
+ * @typedef {object} Trace
+ * @property {Tracer} trace instance of Tracer
+ * @property {number} counter Counter
+ * @property {Profiler} profiler instance of Profiler
+ * @property {(callback: (err?: null | Error) => void) => void} end the end function
+ */
+
+/**
+ * Creates a trace from the provided f.
+ * @param {IntermediateFileSystem} fs filesystem used for output
+ * @param {string} outputPath The location where to write the log.
+ * @returns {Trace} The trace object
+ */
+const createTrace = (fs, outputPath) => {
+	const trace = new Tracer();
+	const profiler = new Profiler(/** @type {Inspector} */ (inspector));
+	if (/\/|\\/.test(outputPath)) {
+		const dirPath = dirname(fs, outputPath);
+		mkdirpSync(fs, dirPath);
+	}
+	const fsStream = fs.createWriteStream(outputPath);
+
+	let counter = 0;
+
+	trace.pipe(fsStream);
+	// These are critical events that need to be inserted so that tools like
+	// chrome dev tools can load the profile.
+	trace.instantEvent({
+		name: "TracingStartedInPage",
+		id: ++counter,
+		cat: ["disabled-by-default-devtools.timeline"],
+		args: {
+			data: {
+				sessionId: "-1",
+				page: "0xfff",
+				frames: [
+					{
+						frame: "0xfff",
+						url: "webpack",
+						name: ""
+					}
+				]
+			}
+		}
+	});
+
+	trace.instantEvent({
+		name: "TracingStartedInBrowser",
+		id: ++counter,
+		cat: ["disabled-by-default-devtools.timeline"],
+		args: {
+			data: {
+				sessionId: "-1"
+			}
+		}
+	});
+
+	return {
+		trace,
+		counter,
+		profiler,
+		end: (callback) => {
+			trace.push("]");
+			// Wait until the write stream finishes.
+			fsStream.on("close", () => {
+				callback();
+			});
+			// Tear down the readable trace stream.
+			trace.push(null);
+		}
+	};
+};
+
+const PLUGIN_NAME = "ProfilingPlugin";
+
+class ProfilingPlugin {
+	/**
+	 * Creates an instance of ProfilingPlugin.
+	 * @param {ProfilingPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {ProfilingPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/debug/ProfilingPlugin.json"),
+				this.options,
+				{
+					name: "Profiling Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/debug/ProfilingPlugin.check")(options)
+			);
+		});
+
+		const tracer = createTrace(
+			/** @type {IntermediateFileSystem} */
+			(compiler.intermediateFileSystem),
+			this.options.outputPath || "events.json"
+		);
+		tracer.profiler.startProfiling();
+
+		// Compiler Hooks
+		for (const hookName of Object.keys(compiler.hooks)) {
+			const hook =
+				compiler.hooks[/** @type {keyof Compiler["hooks"]} */ (hookName)];
+			if (hook) {
+				hook.intercept(makeInterceptorFor("Compiler", tracer)(hookName));
+			}
+		}
+
+		for (const hookName of Object.keys(compiler.resolverFactory.hooks)) {
+			const hook =
+				compiler.resolverFactory.hooks[
+					/** @type {keyof ResolverFactory["hooks"]} */
+					(hookName)
+				];
+			if (hook) {
+				hook.intercept(
+					/** @type {EXPECTED_ANY} */
+					(makeInterceptorFor("Resolver", tracer)(hookName))
+				);
+			}
+		}
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory, contextModuleFactory }) => {
+				interceptAllHooksFor(compilation, tracer, "Compilation");
+				interceptAllHooksFor(
+					normalModuleFactory,
+					tracer,
+					"Normal Module Factory"
+				);
+				interceptAllHooksFor(
+					contextModuleFactory,
+					tracer,
+					"Context Module Factory"
+				);
+				interceptAllParserHooks(normalModuleFactory, tracer);
+				interceptAllGeneratorHooks(normalModuleFactory, tracer);
+				interceptAllJavascriptModulesPluginHooks(compilation, tracer);
+				interceptAllCssModulesPluginHooks(compilation, tracer);
+			}
+		);
+
+		// We need to write out the CPU profile when we are all done.
+		compiler.hooks.done.tapAsync(
+			{
+				name: PLUGIN_NAME,
+				stage: Infinity
+			},
+			(stats, callback) => {
+				if (compiler.watchMode) return callback();
+				tracer.profiler.stopProfiling().then((parsedResults) => {
+					if (parsedResults === undefined) {
+						tracer.profiler.destroy();
+						tracer.end(callback);
+						return;
+					}
+
+					const cpuStartTime = parsedResults.profile.startTime;
+					const cpuEndTime = parsedResults.profile.endTime;
+
+					tracer.trace.completeEvent({
+						name: "TaskQueueManager::ProcessTaskFromWorkQueue",
+						id: ++tracer.counter,
+						cat: ["toplevel"],
+						ts: cpuStartTime,
+						args: {
+							// eslint-disable-next-line camelcase
+							src_file: "../../ipc/ipc_moji_bootstrap.cc",
+							// eslint-disable-next-line camelcase
+							src_func: "Accept"
+						}
+					});
+
+					tracer.trace.completeEvent({
+						name: "EvaluateScript",
+						id: ++tracer.counter,
+						cat: ["devtools.timeline"],
+						ts: cpuStartTime,
+						dur: cpuEndTime - cpuStartTime,
+						args: {
+							data: {
+								url: "webpack",
+								lineNumber: 1,
+								columnNumber: 1,
+								frame: "0xFFF"
+							}
+						}
+					});
+
+					tracer.trace.instantEvent({
+						name: "CpuProfile",
+						id: ++tracer.counter,
+						cat: ["disabled-by-default-devtools.timeline"],
+						ts: cpuEndTime,
+						args: {
+							data: {
+								cpuProfile: parsedResults.profile
+							}
+						}
+					});
+
+					tracer.profiler.destroy();
+					tracer.end(callback);
+				});
+			}
+		);
+	}
+}
+
+/** @typedef {Record<string, Hook<EXPECTED_ANY, EXPECTED_ANY> | FakeHook<EXPECTED_ANY> | HookMap<EXPECTED_ANY>>} Hooks */
+
+/**
+ * Intercept all hooks for.
+ * @param {EXPECTED_OBJECT & { hooks?: Hooks }} instance instance
+ * @param {Trace} tracer tracer
+ * @param {string} logLabel log label
+ */
+const interceptAllHooksFor = (instance, tracer, logLabel) => {
+	if (Reflect.has(instance, "hooks")) {
+		const hooks = /** @type {Hooks} */ (instance.hooks);
+		for (const hookName of Object.keys(hooks)) {
+			const hook = hooks[hookName];
+			if (hook && !hook._fakeHook) {
+				hook.intercept(makeInterceptorFor(logLabel, tracer)(hookName));
+			}
+		}
+	}
+};
+
+/**
+ * Intercept all parser hooks.
+ * @param {NormalModuleFactory} moduleFactory normal module factory
+ * @param {Trace} tracer tracer
+ */
+const interceptAllParserHooks = (moduleFactory, tracer) => {
+	const moduleTypes = [
+		...JAVASCRIPT_MODULES,
+		JSON_MODULE_TYPE,
+		...WEBASSEMBLY_MODULES,
+		...CSS_MODULES
+	];
+
+	for (const moduleType of moduleTypes) {
+		moduleFactory.hooks.parser
+			.for(moduleType)
+			.tap(PLUGIN_NAME, (parser, _parserOpts) => {
+				interceptAllHooksFor(parser, tracer, "Parser");
+			});
+	}
+};
+
+/**
+ * Intercept all generator hooks.
+ * @param {NormalModuleFactory} moduleFactory normal module factory
+ * @param {Trace} tracer tracer
+ */
+const interceptAllGeneratorHooks = (moduleFactory, tracer) => {
+	const moduleTypes = [
+		...JAVASCRIPT_MODULES,
+		JSON_MODULE_TYPE,
+		...WEBASSEMBLY_MODULES,
+		...CSS_MODULES
+	];
+
+	for (const moduleType of moduleTypes) {
+		moduleFactory.hooks.generator
+			.for(moduleType)
+			.tap(PLUGIN_NAME, (parser, _parserOpts) => {
+				interceptAllHooksFor(parser, tracer, "Generator");
+			});
+	}
+};
+
+/**
+ * Intercept all javascript modules plugin hooks.
+ * @param {Compilation} compilation compilation
+ * @param {Trace} tracer tracer
+ */
+const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => {
+	interceptAllHooksFor(
+		{
+			hooks:
+				require("../javascript/JavascriptModulesPlugin").getCompilationHooks(
+					compilation
+				)
+		},
+		tracer,
+		"JavascriptModulesPlugin"
+	);
+};
+
+/**
+ * Intercept all css modules plugin hooks.
+ * @param {Compilation} compilation compilation
+ * @param {Trace} tracer tracer
+ */
+const interceptAllCssModulesPluginHooks = (compilation, tracer) => {
+	interceptAllHooksFor(
+		{
+			hooks: require("../css/CssModulesPlugin").getCompilationHooks(compilation)
+		},
+		tracer,
+		"CssModulesPlugin"
+	);
+};
+
+/** @typedef {(...args: EXPECTED_ANY[]) => EXPECTED_ANY | Promise<(...args: EXPECTED_ANY[]) => EXPECTED_ANY>} PluginFunction */
+
+/**
+ * Creates interceptor for.
+ * @template T
+ * @param {string} instance instance
+ * @param {Trace} tracer tracer
+ * @returns {(hookName: string) => HookInterceptor<EXPECTED_ANY, EXPECTED_ANY>} interceptor
+ */
+const makeInterceptorFor = (instance, tracer) => (hookName) => ({
+	/**
+	 * Returns modified full tap.
+	 * @param {FullTap} tapInfo tap info
+	 * @returns {FullTap} modified full tap
+	 */
+	register: (tapInfo) => {
+		const { name, type, fn: internalFn } = tapInfo;
+		const newFn =
+			// Don't tap our own hooks to ensure stream can close cleanly
+			name === PLUGIN_NAME
+				? internalFn
+				: makeNewProfiledTapFn(hookName, tracer, {
+						name,
+						type,
+						fn: /** @type {PluginFunction} */ (internalFn)
+					});
+		return { ...tapInfo, fn: newFn };
+	}
+});
+
+/**
+ * Creates new profiled tap fn.
+ * @param {string} hookName Name of the hook to profile.
+ * @param {Trace} tracer The trace object.
+ * @param {object} options Options for the profiled fn.
+ * @param {string} options.name Plugin name
+ * @param {"sync" | "async" | "promise"} options.type Plugin type (sync | async | promise)
+ * @param {PluginFunction} options.fn Plugin function
+ * @returns {PluginFunction} Chainable hooked function.
+ */
+const makeNewProfiledTapFn = (hookName, tracer, { name, type, fn }) => {
+	const defaultCategory = ["blink.user_timing"];
+
+	switch (type) {
+		case "promise":
+			return (...args) => {
+				const id = ++tracer.counter;
+				tracer.trace.begin({
+					name,
+					id,
+					cat: defaultCategory
+				});
+				const promise =
+					/** @type {Promise<(...args: EXPECTED_ANY[]) => EXPECTED_ANY>} */
+					(fn(...args));
+				return promise.then((r) => {
+					tracer.trace.end({
+						name,
+						id,
+						cat: defaultCategory
+					});
+					return r;
+				});
+			};
+		case "async":
+			return (...args) => {
+				const id = ++tracer.counter;
+				tracer.trace.begin({
+					name,
+					id,
+					cat: defaultCategory
+				});
+				const callback = args.pop();
+				fn(
+					...args,
+					/**
+					 * Handles the cat callback for this hook.
+					 * @param {...EXPECTED_ANY[]} r result
+					 */
+					(...r) => {
+						tracer.trace.end({
+							name,
+							id,
+							cat: defaultCategory
+						});
+						callback(...r);
+					}
+				);
+			};
+		case "sync":
+			return (...args) => {
+				const id = ++tracer.counter;
+				// Do not instrument ourself due to the CPU
+				// profile needing to be the last event in the trace.
+				if (name === PLUGIN_NAME) {
+					return fn(...args);
+				}
+
+				tracer.trace.begin({
+					name,
+					id,
+					cat: defaultCategory
+				});
+				/** @type {PluginFunction} */
+				let r;
+				try {
+					r = fn(...args);
+				} catch (err) {
+					tracer.trace.end({
+						name,
+						id,
+						cat: defaultCategory
+					});
+					throw err;
+				}
+				tracer.trace.end({
+					name,
+					id,
+					cat: defaultCategory
+				});
+				return r;
+			};
+		default:
+			return fn;
+	}
+};
+
+module.exports = ProfilingPlugin;
+module.exports.Profiler = Profiler;
Index: frontend/node_modules/webpack/lib/dependencies/AMDDefineDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDDefineDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDDefineDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,274 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("./LocalModule")} LocalModule */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @type {Record<string, { definition: string, content: string, requests: string[] }>} */
+const DEFINITIONS = {
+	f: {
+		definition: "var __WEBPACK_AMD_DEFINE_RESULT__;",
+		content: `!(__WEBPACK_AMD_DEFINE_RESULT__ = (#).call(exports, ${RuntimeGlobals.require}, exports, module),
+		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
+		requests: [
+			RuntimeGlobals.require,
+			RuntimeGlobals.exports,
+			RuntimeGlobals.module
+		]
+	},
+	o: {
+		definition: "",
+		content: "!(module.exports = #)",
+		requests: [RuntimeGlobals.module]
+	},
+	of: {
+		definition:
+			"var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;",
+		content: `!(__WEBPACK_AMD_DEFINE_FACTORY__ = (#),
+		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+		(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, ${RuntimeGlobals.require}, exports, module)) :
+		__WEBPACK_AMD_DEFINE_FACTORY__),
+		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
+		requests: [
+			RuntimeGlobals.require,
+			RuntimeGlobals.exports,
+			RuntimeGlobals.module
+		]
+	},
+	af: {
+		definition:
+			"var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;",
+		content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_RESULT__ = (#).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
+		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
+		requests: [RuntimeGlobals.exports, RuntimeGlobals.module]
+	},
+	ao: {
+		definition: "",
+		content: "!(#, module.exports = #)",
+		requests: [RuntimeGlobals.module]
+	},
+	aof: {
+		definition:
+			"var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;",
+		content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_FACTORY__ = (#),
+		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+		(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
+		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
+		requests: [RuntimeGlobals.exports, RuntimeGlobals.module]
+	},
+	lf: {
+		definition: "var XXX, XXXmodule;",
+		content: `!(XXXmodule = { id: YYY, exports: {}, loaded: false }, XXX = (#).call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule), XXXmodule.loaded = true, XXX === undefined && (XXX = XXXmodule.exports))`,
+		requests: [RuntimeGlobals.require, RuntimeGlobals.module]
+	},
+	lo: {
+		definition: "var XXX;",
+		content: "!(XXX = #)",
+		requests: []
+	},
+	lof: {
+		definition: "var XXX, XXXfactory, XXXmodule;",
+		content: `!(XXXfactory = (#), (typeof XXXfactory === 'function' ? ((XXXmodule = { id: YYY, exports: {}, loaded: false }), (XXX = XXXfactory.call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule)), (XXXmodule.loaded = true), XXX === undefined && (XXX = XXXmodule.exports)) : XXX = XXXfactory))`,
+		requests: [RuntimeGlobals.require, RuntimeGlobals.module]
+	},
+	laf: {
+		definition: "var __WEBPACK_AMD_DEFINE_ARRAY__, XXX, XXXexports;",
+		content:
+			"!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, XXX = (#).apply(XXXexports = {}, __WEBPACK_AMD_DEFINE_ARRAY__), XXX === undefined && (XXX = XXXexports))",
+		requests: []
+	},
+	lao: {
+		definition: "var XXX;",
+		content: "!(#, XXX = #)",
+		requests: []
+	},
+	laof: {
+		definition: "var XXXarray, XXXfactory, XXXexports, XXX;",
+		content: `!(XXXarray = #, XXXfactory = (#),
+		(typeof XXXfactory === 'function' ?
+			((XXX = XXXfactory.apply(XXXexports = {}, XXXarray)), XXX === undefined && (XXX = XXXexports)) :
+			(XXX = XXXfactory)
+		))`,
+		requests: []
+	}
+};
+
+class AMDDefineDependency extends NullDependency {
+	/**
+	 * Creates an instance of AMDDefineDependency.
+	 * @param {Range} range range
+	 * @param {Range | null} arrayRange array range
+	 * @param {Range | null} functionRange function range
+	 * @param {Range | null} objectRange object range
+	 * @param {string | null} namedModule true, when define is called with a name
+	 */
+	constructor(range, arrayRange, functionRange, objectRange, namedModule) {
+		super();
+		this.range = range;
+		this.arrayRange = arrayRange;
+		this.functionRange = functionRange;
+		this.objectRange = objectRange;
+		this.namedModule = namedModule;
+		/** @type {LocalModule | null} */
+		this.localModule = null;
+	}
+
+	get type() {
+		return "amd define";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.arrayRange);
+		write(this.functionRange);
+		write(this.objectRange);
+		write(this.namedModule);
+		write(this.localModule);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.arrayRange = read();
+		this.functionRange = read();
+		this.objectRange = read();
+		this.namedModule = read();
+		this.localModule = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	AMDDefineDependency,
+	"webpack/lib/dependencies/AMDDefineDependency"
+);
+
+AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeRequirements }) {
+		const dep = /** @type {AMDDefineDependency} */ (dependency);
+		const branch = this.branch(dep);
+		const { definition, content, requests } = DEFINITIONS[branch];
+		for (const req of requests) {
+			runtimeRequirements.add(req);
+		}
+		this.replace(dep, source, definition, content);
+	}
+
+	/**
+	 * Returns variable name.
+	 * @param {AMDDefineDependency} dependency dependency
+	 * @returns {string | false | null} variable name
+	 */
+	localModuleVar(dependency) {
+		return (
+			dependency.localModule &&
+			dependency.localModule.used &&
+			dependency.localModule.variableName()
+		);
+	}
+
+	/**
+	 * Returns branch.
+	 * @param {AMDDefineDependency} dependency dependency
+	 * @returns {string} branch
+	 */
+	branch(dependency) {
+		const localModuleVar = this.localModuleVar(dependency) ? "l" : "";
+		const arrayRange = dependency.arrayRange ? "a" : "";
+		const objectRange = dependency.objectRange ? "o" : "";
+		const functionRange = dependency.functionRange ? "f" : "";
+		return localModuleVar + arrayRange + objectRange + functionRange;
+	}
+
+	/**
+	 * Processes the provided dependency.
+	 * @param {AMDDefineDependency} dependency dependency
+	 * @param {ReplaceSource} source source
+	 * @param {string} definition definition
+	 * @param {string} text text
+	 */
+	replace(dependency, source, definition, text) {
+		const localModuleVar = this.localModuleVar(dependency);
+		if (localModuleVar) {
+			text = text.replace(/XXX/g, localModuleVar.replace(/\$/g, "$$$$"));
+			definition = definition.replace(
+				/XXX/g,
+				localModuleVar.replace(/\$/g, "$$$$")
+			);
+		}
+
+		if (dependency.namedModule) {
+			text = text.replace(/YYY/g, JSON.stringify(dependency.namedModule));
+		}
+
+		const texts = text.split("#");
+
+		if (definition) source.insert(0, definition);
+
+		let current = dependency.range[0];
+		if (dependency.arrayRange) {
+			source.replace(
+				current,
+				dependency.arrayRange[0] - 1,
+				/** @type {string} */ (texts.shift())
+			);
+			current = dependency.arrayRange[1];
+		}
+
+		if (dependency.objectRange) {
+			source.replace(
+				current,
+				dependency.objectRange[0] - 1,
+				/** @type {string} */ (texts.shift())
+			);
+			current = dependency.objectRange[1];
+		} else if (dependency.functionRange) {
+			source.replace(
+				current,
+				dependency.functionRange[0] - 1,
+				/** @type {string} */ (texts.shift())
+			);
+			current = dependency.functionRange[1];
+		}
+		source.replace(
+			current,
+			dependency.range[1] - 1,
+			/** @type {string} */ (texts.shift())
+		);
+		if (texts.length > 0) throw new Error("Implementation error");
+	}
+};
+
+module.exports = AMDDefineDependency;
Index: frontend/node_modules/webpack/lib/dependencies/AMDDefineDependencyParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDDefineDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDDefineDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,521 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const AMDDefineDependency = require("./AMDDefineDependency");
+const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
+const AMDRequireContextDependency = require("./AMDRequireContextDependency");
+const AMDRequireItemDependency = require("./AMDRequireItemDependency");
+const ConstDependency = require("./ConstDependency");
+const ContextDependencyHelpers = require("./ContextDependencyHelpers");
+const DynamicExports = require("./DynamicExports");
+const LocalModuleDependency = require("./LocalModuleDependency");
+const { addLocalModule, getLocalModule } = require("./LocalModulesHelpers");
+
+/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").FunctionExpression} FunctionExpression */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("estree").Literal} Literal */
+/** @typedef {import("estree").MemberExpression} MemberExpression */
+/** @typedef {import("estree").ObjectExpression} ObjectExpression */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").ExportedVariableInfo} ExportedVariableInfo */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./LocalModule")} LocalModule */
+
+/**
+ * Checks whether this object is bound function expression.
+ * @param {Expression | SpreadElement} expr expression
+ * @returns {expr is CallExpression} true if it's a bound function expression
+ */
+const isBoundFunctionExpression = (expr) => {
+	if (expr.type !== "CallExpression") return false;
+	if (expr.callee.type !== "MemberExpression") return false;
+	if (expr.callee.computed) return false;
+	if (expr.callee.object.type !== "FunctionExpression") return false;
+	if (expr.callee.property.type !== "Identifier") return false;
+	if (expr.callee.property.name !== "bind") return false;
+	return true;
+};
+
+/** @typedef {FunctionExpression | ArrowFunctionExpression} UnboundFunctionExpression */
+
+/**
+ * Checks whether this object is unbound function expression.
+ * @param {Expression | SpreadElement} expr expression
+ * @returns {expr is FunctionExpression | ArrowFunctionExpression} true when unbound function expression
+ */
+const isUnboundFunctionExpression = (expr) => {
+	if (expr.type === "FunctionExpression") return true;
+	if (expr.type === "ArrowFunctionExpression") return true;
+	return false;
+};
+
+/**
+ * Checks whether this object is callable.
+ * @param {Expression | SpreadElement} expr expression
+ * @returns {expr is FunctionExpression | ArrowFunctionExpression | CallExpression} true when callable
+ */
+const isCallable = (expr) => {
+	if (isUnboundFunctionExpression(expr)) return true;
+	if (isBoundFunctionExpression(expr)) return true;
+	return false;
+};
+
+/** @typedef {Record<number, string>} Identifiers */
+
+const PLUGIN_NAME = "AMDDefineDependencyParserPlugin";
+
+class AMDDefineDependencyParserPlugin {
+	/**
+	 * Creates an instance of AMDDefineDependencyParserPlugin.
+	 * @param {JavascriptParserOptions} options parserOptions
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.call
+			.for("define")
+			.tap(PLUGIN_NAME, this.processCallDefine.bind(this, parser));
+	}
+
+	/**
+	 * Processes the provided parser.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @param {Identifiers} identifiers identifiers
+	 * @param {string=} namedModule named module
+	 * @returns {boolean | undefined} result
+	 */
+	processArray(parser, expr, param, identifiers, namedModule) {
+		if (param.isArray()) {
+			const items = /** @type {BasicEvaluatedExpression[]} */ (param.items);
+			for (const [idx, item] of items.entries()) {
+				if (
+					item.isString() &&
+					["require", "module", "exports"].includes(
+						/** @type {string} */ (item.string)
+					)
+				) {
+					identifiers[idx] =
+						/** @type {string} */
+						(item.string);
+				}
+				const result = this.processItem(parser, expr, item, namedModule);
+				if (result === undefined) {
+					this.processContext(parser, expr, item);
+				}
+			}
+			return true;
+		} else if (param.isConstArray()) {
+			/** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */
+			const deps = [];
+			const array = /** @type {string[]} */ (param.array);
+			for (const [idx, request] of array.entries()) {
+				/** @type {string | LocalModuleDependency | AMDRequireItemDependency} */
+				let dep;
+				/** @type {undefined | null | LocalModule} */
+				let localModule;
+				if (request === "require") {
+					identifiers[idx] = request;
+					dep = RuntimeGlobals.require;
+				} else if (["exports", "module"].includes(request)) {
+					identifiers[idx] = request;
+					dep = request;
+				} else if ((localModule = getLocalModule(parser.state, request))) {
+					localModule.flagUsed();
+					dep = new LocalModuleDependency(localModule, undefined, false);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					parser.state.module.addPresentationalDependency(dep);
+				} else {
+					dep = this.newRequireItemDependency(request);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					dep.optional = Boolean(parser.scope.inTry);
+					parser.state.current.addDependency(dep);
+				}
+				deps.push(dep);
+			}
+			const dep = this.newRequireArrayDependency(
+				deps,
+				/** @type {Range} */ (param.range)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			dep.optional = Boolean(parser.scope.inTry);
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		}
+	}
+
+	/**
+	 * Processes the provided parser.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @param {string=} namedModule named module
+	 * @returns {boolean | undefined} result
+	 */
+	processItem(parser, expr, param, namedModule) {
+		if (param.isConditional()) {
+			const options = /** @type {BasicEvaluatedExpression[]} */ (param.options);
+			for (const item of options) {
+				const result = this.processItem(parser, expr, item);
+				if (result === undefined) {
+					this.processContext(parser, expr, item);
+				}
+			}
+
+			return true;
+		} else if (param.isString()) {
+			/** @type {Dependency} */
+			let dep;
+			/** @type {undefined | null | LocalModule} */
+			let localModule;
+
+			if (param.string === "require") {
+				dep = new ConstDependency(
+					RuntimeGlobals.require,
+					/** @type {Range} */ (param.range),
+					[RuntimeGlobals.require]
+				);
+			} else if (param.string === "exports") {
+				dep = new ConstDependency(
+					"exports",
+					/** @type {Range} */ (param.range),
+					[RuntimeGlobals.exports]
+				);
+			} else if (param.string === "module") {
+				dep = new ConstDependency(
+					"module",
+					/** @type {Range} */ (param.range),
+					[RuntimeGlobals.module]
+				);
+			} else if (
+				(localModule = getLocalModule(
+					parser.state,
+					/** @type {string} */ (param.string),
+					namedModule
+				))
+			) {
+				localModule.flagUsed();
+				dep = new LocalModuleDependency(localModule, param.range, false);
+			} else {
+				dep = this.newRequireItemDependency(
+					/** @type {string} */ (param.string),
+					param.range
+				);
+				dep.optional = Boolean(parser.scope.inTry);
+				parser.state.current.addDependency(dep);
+				return true;
+			}
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		}
+	}
+
+	/**
+	 * Processes the provided parser.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {boolean | undefined} result
+	 */
+	processContext(parser, expr, param) {
+		const dep = ContextDependencyHelpers.create(
+			AMDRequireContextDependency,
+			/** @type {Range} */ (param.range),
+			param,
+			expr,
+			this.options,
+			{
+				category: "amd"
+			},
+			parser
+		);
+		if (!dep) return;
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		dep.optional = Boolean(parser.scope.inTry);
+		parser.state.current.addDependency(dep);
+		return true;
+	}
+
+	/**
+	 * Process call define.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @returns {boolean | undefined} result
+	 */
+	processCallDefine(parser, expr) {
+		/** @type {Expression | SpreadElement | undefined} */
+		let array;
+		/** @type {FunctionExpression | ArrowFunctionExpression | CallExpression | Identifier | undefined} */
+		let fn;
+		/** @type {ObjectExpression | Identifier | undefined} */
+		let obj;
+		/** @type {string | undefined} */
+		let namedModule;
+		switch (expr.arguments.length) {
+			case 1:
+				if (isCallable(expr.arguments[0])) {
+					// define(f() {…})
+					fn = expr.arguments[0];
+				} else if (expr.arguments[0].type === "ObjectExpression") {
+					// define({…})
+					obj = expr.arguments[0];
+				} else {
+					// define(expr)
+					// unclear if function or object
+					obj = fn = /** @type {Identifier} */ (expr.arguments[0]);
+				}
+				break;
+			case 2:
+				if (expr.arguments[0].type === "Literal") {
+					namedModule = /** @type {string} */ (expr.arguments[0].value);
+					// define("…", …)
+					if (isCallable(expr.arguments[1])) {
+						// define("…", f() {…})
+						fn = expr.arguments[1];
+					} else if (expr.arguments[1].type === "ObjectExpression") {
+						// define("…", {…})
+						obj = expr.arguments[1];
+					} else {
+						// define("…", expr)
+						// unclear if function or object
+						obj = fn = /** @type {Identifier} */ (expr.arguments[1]);
+					}
+				} else {
+					array = expr.arguments[0];
+					if (isCallable(expr.arguments[1])) {
+						// define([…], f() {})
+						fn = expr.arguments[1];
+					} else if (expr.arguments[1].type === "ObjectExpression") {
+						// define([…], {…})
+						obj = expr.arguments[1];
+					} else {
+						// define([…], expr)
+						// unclear if function or object
+						obj = fn = /** @type {Identifier} */ (expr.arguments[1]);
+					}
+				}
+				break;
+			case 3:
+				// define("…", […], f() {…})
+				namedModule =
+					/** @type {string} */
+					(
+						/** @type {Literal} */
+						(expr.arguments[0]).value
+					);
+				array = expr.arguments[1];
+				if (isCallable(expr.arguments[2])) {
+					// define("…", […], f() {})
+					fn = expr.arguments[2];
+				} else if (expr.arguments[2].type === "ObjectExpression") {
+					// define("…", […], {…})
+					obj = expr.arguments[2];
+				} else {
+					// define("…", […], expr)
+					// unclear if function or object
+					obj = fn = /** @type {Identifier} */ (expr.arguments[2]);
+				}
+				break;
+			default:
+				return;
+		}
+		DynamicExports.bailout(parser.state);
+		/** @type {Identifier[] | null} */
+		let fnParams = null;
+		let fnParamsOffset = 0;
+		if (fn) {
+			if (isUnboundFunctionExpression(fn)) {
+				fnParams =
+					/** @type {Identifier[]} */
+					(fn.params);
+			} else if (isBoundFunctionExpression(fn)) {
+				const object =
+					/** @type {FunctionExpression} */
+					(/** @type {MemberExpression} */ (fn.callee).object);
+
+				fnParams =
+					/** @type {Identifier[]} */
+					(object.params);
+				fnParamsOffset = fn.arguments.length - 1;
+				if (fnParamsOffset < 0) {
+					fnParamsOffset = 0;
+				}
+			}
+		}
+		/** @type {Map<string, ExportedVariableInfo>} */
+		const fnRenames = new Map();
+		if (array) {
+			/** @type {Identifiers} */
+			const identifiers = {};
+			const param = parser.evaluateExpression(array);
+			const result = this.processArray(
+				parser,
+				expr,
+				param,
+				identifiers,
+				namedModule
+			);
+			if (!result) return;
+			if (fnParams) {
+				fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
+					if (identifiers[idx]) {
+						fnRenames.set(param.name, parser.getVariableInfo(identifiers[idx]));
+						return false;
+					}
+					return true;
+				});
+			}
+		} else {
+			const identifiers = ["require", "exports", "module"];
+			if (fnParams) {
+				fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
+					if (identifiers[idx]) {
+						fnRenames.set(param.name, parser.getVariableInfo(identifiers[idx]));
+						return false;
+					}
+					return true;
+				});
+			}
+		}
+		/** @type {boolean | undefined} */
+		let inTry;
+		if (fn && isUnboundFunctionExpression(fn)) {
+			inTry = parser.scope.inTry;
+			parser.inFunctionScope(
+				true,
+				/** @type {Identifier[]} */ (fnParams),
+				() => {
+					for (const [name, varInfo] of fnRenames) {
+						parser.setVariable(name, varInfo);
+					}
+					parser.scope.inTry = /** @type {boolean} */ (inTry);
+					if (fn.body.type === "BlockStatement") {
+						parser.detectMode(fn.body.body);
+						const prev = parser.prevStatement;
+						parser.preWalkStatement(fn.body);
+						parser.prevStatement = prev;
+						parser.walkStatement(fn.body);
+					} else {
+						parser.walkExpression(fn.body);
+					}
+				}
+			);
+		} else if (fn && isBoundFunctionExpression(fn)) {
+			inTry = parser.scope.inTry;
+
+			const object =
+				/** @type {FunctionExpression} */
+				(/** @type {MemberExpression} */ (fn.callee).object);
+
+			parser.inFunctionScope(
+				true,
+				/** @type {Identifier[]} */
+				(object.params).filter(
+					(i) => !["require", "module", "exports"].includes(i.name)
+				),
+				() => {
+					for (const [name, varInfo] of fnRenames) {
+						parser.setVariable(name, varInfo);
+					}
+					parser.scope.inTry = /** @type {boolean} */ (inTry);
+					parser.detectMode(object.body.body);
+					const prev = parser.prevStatement;
+					parser.preWalkStatement(object.body);
+					parser.prevStatement = prev;
+					parser.walkStatement(object.body);
+				}
+			);
+			if (fn.arguments) {
+				parser.walkExpressions(fn.arguments);
+			}
+		} else if (fn || obj) {
+			parser.walkExpression(
+				/** @type {FunctionExpression | ArrowFunctionExpression | CallExpression | ObjectExpression | Identifier} */
+				(fn || obj)
+			);
+		}
+
+		const dep = this.newDefineDependency(
+			/** @type {Range} */ (expr.range),
+			array ? /** @type {Range} */ (array.range) : null,
+			fn ? /** @type {Range} */ (fn.range) : null,
+			obj ? /** @type {Range} */ (obj.range) : null,
+			namedModule || null
+		);
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		if (namedModule) {
+			dep.localModule = addLocalModule(parser.state, namedModule);
+		}
+		parser.state.module.addPresentationalDependency(dep);
+		return true;
+	}
+
+	/**
+	 * New define dependency.
+	 * @param {Range} range range
+	 * @param {Range | null} arrayRange array range
+	 * @param {Range | null} functionRange function range
+	 * @param {Range | null} objectRange object range
+	 * @param {string | null} namedModule true, when define is called with a name
+	 * @returns {AMDDefineDependency} AMDDefineDependency
+	 */
+	newDefineDependency(
+		range,
+		arrayRange,
+		functionRange,
+		objectRange,
+		namedModule
+	) {
+		return new AMDDefineDependency(
+			range,
+			arrayRange,
+			functionRange,
+			objectRange,
+			namedModule
+		);
+	}
+
+	/**
+	 * New require array dependency.
+	 * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
+	 * @param {Range} range range
+	 * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency
+	 */
+	newRequireArrayDependency(depsArray, range) {
+		return new AMDRequireArrayDependency(depsArray, range);
+	}
+
+	/**
+	 * New require item dependency.
+	 * @param {string} request request
+	 * @param {Range=} range range
+	 * @returns {AMDRequireItemDependency} AMDRequireItemDependency
+	 */
+	newRequireItemDependency(request, range) {
+		return new AMDRequireItemDependency(request, range);
+	}
+}
+
+module.exports = AMDDefineDependencyParserPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/AMDPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,246 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const {
+	approve,
+	evaluateToIdentifier,
+	evaluateToString,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+
+const AMDDefineDependency = require("./AMDDefineDependency");
+const AMDDefineDependencyParserPlugin = require("./AMDDefineDependencyParserPlugin");
+const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
+const AMDRequireContextDependency = require("./AMDRequireContextDependency");
+const AMDRequireDependenciesBlockParserPlugin = require("./AMDRequireDependenciesBlockParserPlugin");
+const AMDRequireDependency = require("./AMDRequireDependency");
+const AMDRequireItemDependency = require("./AMDRequireItemDependency");
+const {
+	AMDDefineRuntimeModule,
+	AMDOptionsRuntimeModule
+} = require("./AMDRuntimeModules");
+const ConstDependency = require("./ConstDependency");
+const LocalModuleDependency = require("./LocalModuleDependency");
+const UnsupportedDependency = require("./UnsupportedDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").Amd} Amd */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../javascript/BasicEvaluatedExpression").GetMembers} GetMembers */
+
+const PLUGIN_NAME = "AMDPlugin";
+
+/** @typedef {Exclude<Amd, false>} AmdOptions */
+
+class AMDPlugin {
+	/**
+	 * Creates an instance of AMDPlugin.
+	 * @param {AmdOptions} amdOptions the AMD options
+	 */
+	constructor(amdOptions) {
+		this.amdOptions = amdOptions;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { amdOptions } = this;
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { contextModuleFactory, normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					AMDRequireDependency,
+					new AMDRequireDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					AMDRequireItemDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					AMDRequireItemDependency,
+					new AMDRequireItemDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					AMDRequireArrayDependency,
+					new AMDRequireArrayDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					AMDRequireContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					AMDRequireContextDependency,
+					new AMDRequireContextDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					AMDDefineDependency,
+					new AMDDefineDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					UnsupportedDependency,
+					new UnsupportedDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					LocalModuleDependency,
+					new LocalModuleDependency.Template()
+				);
+
+				compilation.hooks.runtimeRequirementInModule
+					.for(RuntimeGlobals.amdDefine)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.require);
+					});
+
+				compilation.hooks.runtimeRequirementInModule
+					.for(RuntimeGlobals.amdOptions)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.requireScope);
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.amdDefine)
+					.tap(PLUGIN_NAME, (chunk, _set) => {
+						compilation.addRuntimeModule(chunk, new AMDDefineRuntimeModule());
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.amdOptions)
+					.tap(PLUGIN_NAME, (chunk, _set) => {
+						compilation.addRuntimeModule(
+							chunk,
+							new AMDOptionsRuntimeModule(amdOptions)
+						);
+					});
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (parserOptions.amd !== undefined && !parserOptions.amd) return;
+
+					/**
+					 * Processes the provided option expr.
+					 * @param {string} optionExpr option expression
+					 * @param {string} rootName root name
+					 * @param {GetMembers} getMembers callback
+					 */
+					const tapOptionsHooks = (optionExpr, rootName, getMembers) => {
+						parser.hooks.expression
+							.for(optionExpr)
+							.tap(
+								PLUGIN_NAME,
+								toConstantDependency(parser, RuntimeGlobals.amdOptions, [
+									RuntimeGlobals.amdOptions
+								])
+							);
+						parser.hooks.evaluateIdentifier
+							.for(optionExpr)
+							.tap(PLUGIN_NAME, (expr) =>
+								evaluateToIdentifier(
+									optionExpr,
+									rootName,
+									getMembers,
+									true
+								)(expr)
+							);
+						parser.hooks.evaluateTypeof
+							.for(optionExpr)
+							.tap(PLUGIN_NAME, evaluateToString("object"));
+						parser.hooks.typeof
+							.for(optionExpr)
+							.tap(
+								PLUGIN_NAME,
+								toConstantDependency(parser, JSON.stringify("object"))
+							);
+					};
+
+					new AMDRequireDependenciesBlockParserPlugin(parserOptions).apply(
+						parser
+					);
+					new AMDDefineDependencyParserPlugin(parserOptions).apply(parser);
+
+					tapOptionsHooks("define.amd", "define", () => ["amd"]);
+					tapOptionsHooks("require.amd", "require", () => ["amd"]);
+					tapOptionsHooks(
+						"__webpack_amd_options__",
+						"__webpack_amd_options__",
+						() => []
+					);
+
+					parser.hooks.expression.for("define").tap(PLUGIN_NAME, (expr) => {
+						const dep = new ConstDependency(
+							RuntimeGlobals.amdDefine,
+							/** @type {Range} */ (expr.range),
+							[RuntimeGlobals.amdDefine]
+						);
+						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+						parser.state.module.addPresentationalDependency(dep);
+						return true;
+					});
+					parser.hooks.typeof
+						.for("define")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("function"))
+						);
+					parser.hooks.evaluateTypeof
+						.for("define")
+						.tap(PLUGIN_NAME, evaluateToString("function"));
+					parser.hooks.canRename.for("define").tap(PLUGIN_NAME, approve);
+					parser.hooks.rename.for("define").tap(PLUGIN_NAME, (expr) => {
+						const dep = new ConstDependency(
+							RuntimeGlobals.amdDefine,
+							/** @type {Range} */ (expr.range),
+							[RuntimeGlobals.amdDefine]
+						);
+						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+						parser.state.module.addPresentationalDependency(dep);
+						return false;
+					});
+					parser.hooks.typeof
+						.for("require")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("function"))
+						);
+					parser.hooks.evaluateTypeof
+						.for("require")
+						.tap(PLUGIN_NAME, evaluateToString("function"));
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+module.exports = AMDPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRequireArrayDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRequireArrayDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRequireArrayDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,130 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DependencyTemplate = require("../DependencyTemplate");
+const makeSerializable = require("../util/makeSerializable");
+const LocalModuleDependency = require("./LocalModuleDependency");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./AMDRequireItemDependency")} AMDRequireItemDependency */
+
+class AMDRequireArrayDependency extends NullDependency {
+	/**
+	 * Creates an instance of AMDRequireArrayDependency.
+	 * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
+	 * @param {Range} range range
+	 */
+	constructor(depsArray, range) {
+		super();
+
+		this.depsArray = depsArray;
+		this.range = range;
+	}
+
+	get type() {
+		return "amd require array";
+	}
+
+	get category() {
+		return "amd";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.depsArray);
+		write(this.range);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.depsArray = read();
+		this.range = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	AMDRequireArrayDependency,
+	"webpack/lib/dependencies/AMDRequireArrayDependency"
+);
+
+AMDRequireArrayDependency.Template = class AMDRequireArrayDependencyTemplate extends (
+	DependencyTemplate
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {AMDRequireArrayDependency} */ (dependency);
+		const content = this.getContent(dep, templateContext);
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+	}
+
+	/**
+	 * Returns content.
+	 * @param {AMDRequireArrayDependency} dep the dependency for which the template should be applied
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {string} content
+	 */
+	getContent(dep, templateContext) {
+		const requires = dep.depsArray.map((dependency) =>
+			this.contentForDependency(dependency, templateContext)
+		);
+		return `[${requires.join(", ")}]`;
+	}
+
+	/**
+	 * Content for dependency.
+	 * @param {string | LocalModuleDependency | AMDRequireItemDependency} dep the dependency for which the template should be applied
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {string} content
+	 */
+	contentForDependency(
+		dep,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		if (typeof dep === "string") {
+			return dep;
+		}
+
+		if (dep instanceof LocalModuleDependency) {
+			return dep.localModule.variableName();
+		}
+
+		return runtimeTemplate.moduleExports({
+			module: moduleGraph.getModule(dep),
+			chunkGraph,
+			request: dep.request,
+			runtimeRequirements
+		});
+	}
+};
+
+module.exports = AMDRequireArrayDependency;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRequireContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRequireContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRequireContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,72 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+
+class AMDRequireContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of AMDRequireContextDependency.
+	 * @param {ContextDependencyOptions} options options
+	 * @param {Range} range range
+	 * @param {Range} valueRange value range
+	 */
+	constructor(options, range, valueRange) {
+		super(options);
+
+		this.range = range;
+		this.valueRange = valueRange;
+	}
+
+	get type() {
+		return "amd require context";
+	}
+
+	get category() {
+		return "amd";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.range);
+		write(this.valueRange);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.range = read();
+		this.valueRange = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	AMDRequireContextDependency,
+	"webpack/lib/dependencies/AMDRequireContextDependency"
+);
+
+AMDRequireContextDependency.Template = require("./ContextDependencyTemplateAsRequireCall");
+
+module.exports = AMDRequireContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlock.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,29 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+
+class AMDRequireDependenciesBlock extends AsyncDependenciesBlock {
+	/**
+	 * Creates an instance of AMDRequireDependenciesBlock.
+	 * @param {DependencyLocation} loc location info
+	 * @param {string=} request request
+	 */
+	constructor(loc, request) {
+		super(null, loc, request);
+	}
+}
+
+makeSerializable(
+	AMDRequireDependenciesBlock,
+	"webpack/lib/dependencies/AMDRequireDependenciesBlock"
+);
+
+module.exports = AMDRequireDependenciesBlock;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,439 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
+const AMDRequireContextDependency = require("./AMDRequireContextDependency");
+const AMDRequireDependenciesBlock = require("./AMDRequireDependenciesBlock");
+const AMDRequireDependency = require("./AMDRequireDependency");
+const AMDRequireItemDependency = require("./AMDRequireItemDependency");
+const ConstDependency = require("./ConstDependency");
+const ContextDependencyHelpers = require("./ContextDependencyHelpers");
+const LocalModuleDependency = require("./LocalModuleDependency");
+const { getLocalModule } = require("./LocalModulesHelpers");
+const UnsupportedDependency = require("./UnsupportedDependency");
+const getFunctionExpression = require("./getFunctionExpression");
+
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("estree").SourceLocation} SourceLocation */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./LocalModule")} LocalModule */
+
+const PLUGIN_NAME = "AMDRequireDependenciesBlockParserPlugin";
+
+class AMDRequireDependenciesBlockParserPlugin {
+	/**
+	 * Creates an instance of AMDRequireDependenciesBlockParserPlugin.
+	 * @param {JavascriptParserOptions} options parserOptions
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Process function argument.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {Expression | SpreadElement} expression expression
+	 * @returns {boolean} need bind this
+	 */
+	processFunctionArgument(parser, expression) {
+		let bindThis = true;
+		const fnData = getFunctionExpression(expression);
+		if (fnData) {
+			parser.inFunctionScope(
+				true,
+				fnData.fn.params.filter(
+					(i) =>
+						!["require", "module", "exports"].includes(
+							/** @type {Identifier} */ (i).name
+						)
+				),
+				() => {
+					if (fnData.fn.body.type === "BlockStatement") {
+						parser.walkStatement(fnData.fn.body);
+					} else {
+						parser.walkExpression(fnData.fn.body);
+					}
+				}
+			);
+			parser.walkExpressions(fnData.expressions);
+			if (fnData.needThis === false) {
+				bindThis = false;
+			}
+		} else {
+			parser.walkExpression(expression);
+		}
+		return bindThis;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.call
+			.for("require")
+			.tap(PLUGIN_NAME, this.processCallRequire.bind(this, parser));
+	}
+
+	/**
+	 * Processes the provided parser.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {boolean | undefined} result
+	 */
+	processArray(parser, expr, param) {
+		if (param.isArray()) {
+			for (const p of /** @type {BasicEvaluatedExpression[]} */ (param.items)) {
+				const result = this.processItem(parser, expr, p);
+				if (result === undefined) {
+					this.processContext(parser, expr, p);
+				}
+			}
+			return true;
+		} else if (param.isConstArray()) {
+			/** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */
+			const deps = [];
+			for (const request of /** @type {string[]} */ (param.array)) {
+				/** @type {string | LocalModuleDependency | AMDRequireItemDependency} */
+				let dep;
+				/** @type {undefined | null | LocalModule} */
+				let localModule;
+				if (request === "require") {
+					dep = RuntimeGlobals.require;
+				} else if (["exports", "module"].includes(request)) {
+					dep = request;
+				} else if ((localModule = getLocalModule(parser.state, request))) {
+					localModule.flagUsed();
+					dep = new LocalModuleDependency(localModule, undefined, false);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					parser.state.module.addPresentationalDependency(dep);
+				} else {
+					dep = this.newRequireItemDependency(request);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					dep.optional = Boolean(parser.scope.inTry);
+					parser.state.current.addDependency(dep);
+				}
+				deps.push(dep);
+			}
+			const dep = this.newRequireArrayDependency(
+				deps,
+				/** @type {Range} */
+				(param.range)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			dep.optional = Boolean(parser.scope.inTry);
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		}
+	}
+
+	/**
+	 * Processes the provided parser.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {boolean | undefined} result
+	 */
+	processItem(parser, expr, param) {
+		if (param.isConditional()) {
+			for (const p of /** @type {BasicEvaluatedExpression[]} */ (
+				param.options
+			)) {
+				const result = this.processItem(parser, expr, p);
+				if (result === undefined) {
+					this.processContext(parser, expr, p);
+				}
+			}
+			return true;
+		} else if (param.isString()) {
+			/** @type {Dependency} */
+			let dep;
+			/** @type {LocalModule | null | undefined} */
+			let localModule;
+			if (param.string === "require") {
+				dep = new ConstDependency(
+					RuntimeGlobals.require,
+					/** @type {Range} */
+					(param.range),
+					[RuntimeGlobals.require]
+				);
+			} else if (param.string === "module") {
+				dep = new ConstDependency(
+					parser.state.module.moduleArgument,
+					/** @type {Range} */
+					(param.range),
+					[RuntimeGlobals.module]
+				);
+			} else if (param.string === "exports") {
+				dep = new ConstDependency(
+					parser.state.module.exportsArgument,
+					/** @type {Range} */
+					(param.range),
+					[RuntimeGlobals.exports]
+				);
+			} else if (
+				(localModule = getLocalModule(
+					parser.state,
+					/** @type {string} */
+					(param.string)
+				))
+			) {
+				localModule.flagUsed();
+				dep = new LocalModuleDependency(localModule, param.range, false);
+			} else {
+				dep = this.newRequireItemDependency(
+					/** @type {string} */
+					(param.string),
+					param.range
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				dep.optional = Boolean(parser.scope.inTry);
+				parser.state.current.addDependency(dep);
+				return true;
+			}
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		}
+	}
+
+	/**
+	 * Processes the provided parser.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {boolean | undefined} result
+	 */
+	processContext(parser, expr, param) {
+		const dep = ContextDependencyHelpers.create(
+			AMDRequireContextDependency,
+			/** @type {Range} */
+			(param.range),
+			param,
+			expr,
+			this.options,
+			{
+				category: "amd"
+			},
+			parser
+		);
+		if (!dep) return;
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		dep.optional = Boolean(parser.scope.inTry);
+		parser.state.current.addDependency(dep);
+		return true;
+	}
+
+	/**
+	 * Process array for request string.
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {string | undefined} result
+	 */
+	processArrayForRequestString(param) {
+		if (param.isArray()) {
+			const result =
+				/** @type {BasicEvaluatedExpression[]} */
+				(param.items).map((item) => this.processItemForRequestString(item));
+			if (result.every(Boolean)) return result.join(" ");
+		} else if (param.isConstArray()) {
+			return /** @type {string[]} */ (param.array).join(" ");
+		}
+	}
+
+	/**
+	 * Process item for request string.
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {string | undefined} result
+	 */
+	processItemForRequestString(param) {
+		if (param.isConditional()) {
+			const result =
+				/** @type {BasicEvaluatedExpression[]} */
+				(param.options).map((item) => this.processItemForRequestString(item));
+			if (result.every(Boolean)) return result.join("|");
+		} else if (param.isString()) {
+			return param.string;
+		}
+	}
+
+	/**
+	 * Process call require.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {CallExpression} expr call expression
+	 * @returns {boolean | undefined} result
+	 */
+	processCallRequire(parser, expr) {
+		/** @type {BasicEvaluatedExpression | undefined} */
+		let param;
+		/** @type {AMDRequireDependenciesBlock | undefined | null} */
+		let depBlock;
+		/** @type {AMDRequireDependency | undefined} */
+		let dep;
+		/** @type {boolean | undefined} */
+		let result;
+
+		const old = parser.state.current;
+
+		if (expr.arguments.length >= 1) {
+			param = parser.evaluateExpression(
+				/** @type {Expression} */ (expr.arguments[0])
+			);
+			depBlock = this.newRequireDependenciesBlock(
+				/** @type {DependencyLocation} */ (expr.loc),
+				this.processArrayForRequestString(param)
+			);
+			dep = this.newRequireDependency(
+				/** @type {Range} */ (expr.range),
+				/** @type {Range} */ (param.range),
+				expr.arguments.length > 1
+					? /** @type {Range} */ (expr.arguments[1].range)
+					: null,
+				expr.arguments.length > 2
+					? /** @type {Range} */ (expr.arguments[2].range)
+					: null
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			depBlock.addDependency(dep);
+
+			parser.state.current = /** @type {EXPECTED_ANY} */ (depBlock);
+		}
+
+		if (expr.arguments.length === 1) {
+			parser.inFunctionScope(true, [], () => {
+				result = this.processArray(
+					parser,
+					expr,
+					/** @type {BasicEvaluatedExpression} */
+					(param)
+				);
+			});
+			parser.state.current = old;
+			if (!result) return;
+			parser.state.current.addBlock(
+				/** @type {AMDRequireDependenciesBlock} */
+				(depBlock)
+			);
+			return true;
+		}
+
+		if (expr.arguments.length === 2 || expr.arguments.length === 3) {
+			try {
+				parser.inFunctionScope(true, [], () => {
+					result = this.processArray(
+						parser,
+						expr,
+						/** @type {BasicEvaluatedExpression} */
+						(param)
+					);
+				});
+				if (!result) {
+					const dep = new UnsupportedDependency(
+						"unsupported",
+						/** @type {Range} */
+						(expr.range)
+					);
+					old.addPresentationalDependency(dep);
+					if (parser.state.module) {
+						parser.state.module.addError(
+							new UnsupportedFeatureWarning(
+								`Cannot statically analyse 'require(…, …)' in line ${
+									/** @type {SourceLocation} */ (expr.loc).start.line
+								}`,
+								/** @type {DependencyLocation} */
+								(expr.loc)
+							)
+						);
+					}
+					depBlock = null;
+					return true;
+				}
+				/** @type {AMDRequireDependency} */
+				(dep).functionBindThis = this.processFunctionArgument(
+					parser,
+					expr.arguments[1]
+				);
+				if (expr.arguments.length === 3) {
+					/** @type {AMDRequireDependency} */
+					(dep).errorCallbackBindThis = this.processFunctionArgument(
+						parser,
+						expr.arguments[2]
+					);
+				}
+			} finally {
+				parser.state.current = old;
+				if (depBlock) parser.state.current.addBlock(depBlock);
+			}
+			return true;
+		}
+	}
+
+	/**
+	 * New require dependencies block.
+	 * @param {DependencyLocation} loc location
+	 * @param {string=} request request
+	 * @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock
+	 */
+	newRequireDependenciesBlock(loc, request) {
+		return new AMDRequireDependenciesBlock(loc, request);
+	}
+
+	/**
+	 * New require dependency.
+	 * @param {Range} outerRange outer range
+	 * @param {Range} arrayRange array range
+	 * @param {Range | null} functionRange function range
+	 * @param {Range | null} errorCallbackRange error callback range
+	 * @returns {AMDRequireDependency} dependency
+	 */
+	newRequireDependency(
+		outerRange,
+		arrayRange,
+		functionRange,
+		errorCallbackRange
+	) {
+		return new AMDRequireDependency(
+			outerRange,
+			arrayRange,
+			functionRange,
+			errorCallbackRange
+		);
+	}
+
+	/**
+	 * New require item dependency.
+	 * @param {string} request request
+	 * @param {Range=} range range
+	 * @returns {AMDRequireItemDependency} AMDRequireItemDependency
+	 */
+	newRequireItemDependency(request, range) {
+		return new AMDRequireItemDependency(request, range);
+	}
+
+	/**
+	 * New require array dependency.
+	 * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
+	 * @param {Range} range range
+	 * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency
+	 */
+	newRequireArrayDependency(depsArray, range) {
+		return new AMDRequireArrayDependency(depsArray, range);
+	}
+}
+
+module.exports = AMDRequireDependenciesBlockParserPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRequireDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,193 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class AMDRequireDependency extends NullDependency {
+	/**
+	 * Creates an instance of AMDRequireDependency.
+	 * @param {Range} outerRange outer range
+	 * @param {Range} arrayRange array range
+	 * @param {Range | null} functionRange function range
+	 * @param {Range | null} errorCallbackRange error callback range
+	 */
+	constructor(outerRange, arrayRange, functionRange, errorCallbackRange) {
+		super();
+
+		this.outerRange = outerRange;
+		this.arrayRange = arrayRange;
+		this.functionRange = functionRange;
+		this.errorCallbackRange = errorCallbackRange;
+		this.functionBindThis = false;
+		this.errorCallbackBindThis = false;
+	}
+
+	get category() {
+		return "amd";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.outerRange);
+		write(this.arrayRange);
+		write(this.functionRange);
+		write(this.errorCallbackRange);
+		write(this.functionBindThis);
+		write(this.errorCallbackBindThis);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.outerRange = read();
+		this.arrayRange = read();
+		this.functionRange = read();
+		this.errorCallbackRange = read();
+		this.functionBindThis = read();
+		this.errorCallbackBindThis = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	AMDRequireDependency,
+	"webpack/lib/dependencies/AMDRequireDependency"
+);
+
+AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {AMDRequireDependency} */ (dependency);
+		const depBlock = /** @type {AsyncDependenciesBlock} */ (
+			moduleGraph.getParentBlock(dep)
+		);
+		const promise = runtimeTemplate.blockPromise({
+			chunkGraph,
+			block: depBlock,
+			message: "AMD require",
+			runtimeRequirements
+		});
+
+		// has array range but no function range
+		if (dep.arrayRange && !dep.functionRange) {
+			const startBlock = `${promise}.then(function() {`;
+			const endBlock = `;})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
+			runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);
+
+			source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);
+
+			source.replace(dep.arrayRange[1], dep.outerRange[1] - 1, endBlock);
+
+			return;
+		}
+
+		// has function range but no array range
+		if (dep.functionRange && !dep.arrayRange) {
+			const startBlock = `${promise}.then((`;
+			const endBlock = `).bind(exports, ${RuntimeGlobals.require}, exports, module))['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
+			runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);
+
+			source.replace(dep.outerRange[0], dep.functionRange[0] - 1, startBlock);
+
+			source.replace(dep.functionRange[1], dep.outerRange[1] - 1, endBlock);
+
+			return;
+		}
+
+		// has array range, function range, and errorCallbackRange
+		if (dep.arrayRange && dep.functionRange && dep.errorCallbackRange) {
+			const startBlock = `${promise}.then(function() { `;
+			const errorRangeBlock = `}${
+				dep.functionBindThis ? ".bind(this)" : ""
+			})['catch'](`;
+			const endBlock = `${dep.errorCallbackBindThis ? ".bind(this)" : ""})`;
+
+			source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);
+
+			source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = ");
+
+			source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; (");
+
+			source.insert(
+				dep.functionRange[1],
+				").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);"
+			);
+
+			source.replace(
+				dep.functionRange[1],
+				dep.errorCallbackRange[0] - 1,
+				errorRangeBlock
+			);
+
+			source.replace(
+				dep.errorCallbackRange[1],
+				dep.outerRange[1] - 1,
+				endBlock
+			);
+
+			return;
+		}
+
+		// has array range, function range, but no errorCallbackRange
+		if (dep.arrayRange && dep.functionRange) {
+			const startBlock = `${promise}.then(function() { `;
+			const endBlock = `}${
+				dep.functionBindThis ? ".bind(this)" : ""
+			})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
+			runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);
+
+			source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);
+
+			source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = ");
+
+			source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; (");
+
+			source.insert(
+				dep.functionRange[1],
+				").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);"
+			);
+
+			source.replace(dep.functionRange[1], dep.outerRange[1] - 1, endBlock);
+		}
+	}
+};
+
+module.exports = AMDRequireDependency;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRequireItemDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRequireItemDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRequireItemDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+class AMDRequireItemDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of AMDRequireItemDependency.
+	 * @param {string} request the request string
+	 * @param {Range=} range location in source code
+	 */
+	constructor(request, range) {
+		super(request);
+
+		this.range = range;
+	}
+
+	get type() {
+		return "amd require";
+	}
+
+	get category() {
+		return "amd";
+	}
+}
+
+makeSerializable(
+	AMDRequireItemDependency,
+	"webpack/lib/dependencies/AMDRequireItemDependency"
+);
+
+AMDRequireItemDependency.Template = ModuleDependencyTemplateAsRequireId;
+
+module.exports = AMDRequireItemDependency;
Index: frontend/node_modules/webpack/lib/dependencies/AMDRuntimeModules.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/AMDRuntimeModules.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/AMDRuntimeModules.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,53 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("./AMDPlugin").AmdOptions} AmdOptions */
+
+class AMDDefineRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("amd define");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return Template.asString([
+			`${RuntimeGlobals.amdDefine} = function () {`,
+			Template.indent("throw new Error('define cannot be used indirect');"),
+			"};"
+		]);
+	}
+}
+
+class AMDOptionsRuntimeModule extends RuntimeModule {
+	/**
+	 * Creates an instance of AMDOptionsRuntimeModule.
+	 * @param {AmdOptions} options the AMD options
+	 */
+	constructor(options) {
+		super("amd options");
+		this.options = options;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return Template.asString([
+			`${RuntimeGlobals.amdOptions} = ${JSON.stringify(this.options)};`
+		]);
+	}
+}
+
+module.exports.AMDDefineRuntimeModule = AMDDefineRuntimeModule;
+module.exports.AMDOptionsRuntimeModule = AMDOptionsRuntimeModule;
Index: frontend/node_modules/webpack/lib/dependencies/CachedConstDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CachedConstDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CachedConstDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,140 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const DependencyTemplate = require("../DependencyTemplate");
+const InitFragment = require("../InitFragment");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+class CachedConstDependency extends NullDependency {
+	/**
+	 * Creates an instance of CachedConstDependency.
+	 * @param {string} expression expression
+	 * @param {Range | null} range range
+	 * @param {string} identifier identifier
+	 * @param {number=} place place where we inject the expression
+	 */
+	constructor(
+		expression,
+		range,
+		identifier,
+		place = CachedConstDependency.PLACE_MODULE
+	) {
+		super();
+
+		this.expression = expression;
+		this.range = range;
+		this.identifier = identifier;
+		this.place = place;
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	/**
+	 * Create hash update.
+	 * @returns {string} hash update
+	 */
+	_createHashUpdate() {
+		return `${this.place}${this.identifier}${this.range}${this.expression}`;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			this._hashUpdate = this._createHashUpdate();
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.expression);
+		write(this.range);
+		write(this.identifier);
+		write(this.place);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.expression = read();
+		this.range = read();
+		this.identifier = read();
+		this.place = read();
+
+		super.deserialize(context);
+	}
+}
+
+CachedConstDependency.PLACE_MODULE = 10;
+CachedConstDependency.PLACE_CHUNK = 20;
+
+makeSerializable(
+	CachedConstDependency,
+	"webpack/lib/dependencies/CachedConstDependency"
+);
+
+CachedConstDependency.Template = class CachedConstDependencyTemplate extends (
+	DependencyTemplate
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { initFragments, chunkInitFragments }) {
+		const dep = /** @type {CachedConstDependency} */ (dependency);
+
+		(dep.place === CachedConstDependency.PLACE_MODULE
+			? initFragments
+			: chunkInitFragments
+		).push(
+			new InitFragment(
+				`var ${dep.identifier} = ${dep.expression};\n`,
+				InitFragment.STAGE_CONSTANTS,
+				// For a chunk we inject expression after imports
+				dep.place === CachedConstDependency.PLACE_MODULE ? 0 : 10,
+				`const ${dep.identifier}`
+			)
+		);
+
+		if (typeof dep.range === "number") {
+			source.insert(dep.range, dep.identifier);
+		} else if (dep.range !== null) {
+			source.replace(dep.range[0], dep.range[1] - 1, dep.identifier);
+		}
+	}
+};
+
+module.exports = CachedConstDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsDependencyHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsDependencyHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsDependencyHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,129 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const { propertyAccess } = require("../util/property");
+
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {"exports" | "module.exports" | "this" | "Object.defineProperty(exports)" | "Object.defineProperty(module.exports)" | "Object.defineProperty(this)"} CommonJSDependencyBaseKeywords */
+
+/**
+ * The well-known name of the ESM named export that, when present, is unwrapped
+ * by CommonJS `require()` to match Node.js v23+ `require(esm)` semantics:
+ * https://nodejs.org/docs/latest/api/modules.html#loading-ecmascript-modules-using-require
+ */
+const ESM_MODULE_EXPORTS_NAME = "module.exports";
+
+/**
+ * Whether `require()` of `importedModule` would trigger Node.js's
+ * `require(esm)` `"module.exports"` named-export unwrap. This is the
+ * usage-independent eligibility check: it only looks at module type and
+ * whether the export is declared, so it can be safely used from
+ * `getReferencedExports` before usage info is finalized (otherwise the
+ * check would be circular — we'd need `"module.exports"` to already be
+ * marked used in order to ask whether to mark it used).
+ * @param {Module} importedModule the imported module
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @returns {boolean} true if `require()` should unwrap `"module.exports"`
+ */
+const isRequireEsmModuleExportsModule = (importedModule, moduleGraph) => {
+	if (importedModule.getExportsType(moduleGraph, false) !== "namespace") {
+		return false;
+	}
+	const exportsInfo = moduleGraph.getExportsInfo(importedModule);
+	const exportInfo = exportsInfo.getReadOnlyExportInfo(ESM_MODULE_EXPORTS_NAME);
+	return exportInfo.provided === true;
+};
+
+/**
+ * When CommonJS `require()` resolves to an ES module that has a named export
+ * with the literal string name `"module.exports"`, Node.js returns the value of
+ * that export instead of the namespace object. Returns the property-access
+ * expression to apply to the require result for that unwrapping, or `null` if
+ * the imported module is not eligible (not strictly ESM, or no such export,
+ * or the export was tree-shaken away).
+ * @param {Module} importedModule the imported module
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+ * @returns {string | null} property-access expression (e.g. `["module.exports"]`), or `null`
+ */
+const getRequireEsmModuleExportsAccess = (
+	importedModule,
+	moduleGraph,
+	runtime
+) => {
+	if (!isRequireEsmModuleExportsModule(importedModule, moduleGraph)) {
+		return null;
+	}
+	const exportsInfo = moduleGraph.getExportsInfo(importedModule);
+	const usedName = exportsInfo.getUsedName([ESM_MODULE_EXPORTS_NAME], runtime);
+	if (usedName === false) return null;
+	return propertyAccess(/** @type {readonly string[]} */ (usedName));
+};
+
+module.exports.ESM_MODULE_EXPORTS_NAME = ESM_MODULE_EXPORTS_NAME;
+module.exports.getRequireEsmModuleExportsAccess =
+	getRequireEsmModuleExportsAccess;
+
+/**
+ * Returns type and base.
+ * @param {CommonJSDependencyBaseKeywords} depBase commonjs dependency base
+ * @param {Module} module module
+ * @param {RuntimeRequirements} runtimeRequirements runtime requirements
+ * @returns {[string, string]} type and base
+ */
+module.exports.handleDependencyBase = (
+	depBase,
+	module,
+	runtimeRequirements
+) => {
+	/** @type {string} */
+	let base;
+	/** @type {string} */
+	let type;
+	switch (depBase) {
+		case "exports":
+			runtimeRequirements.add(RuntimeGlobals.exports);
+			base = module.exportsArgument;
+			type = "expression";
+			break;
+		case "module.exports":
+			runtimeRequirements.add(RuntimeGlobals.module);
+			base = `${module.moduleArgument}.exports`;
+			type = "expression";
+			break;
+		case "this":
+			runtimeRequirements.add(RuntimeGlobals.thisAsExports);
+			base = "this";
+			type = "expression";
+			break;
+		case "Object.defineProperty(exports)":
+			runtimeRequirements.add(RuntimeGlobals.exports);
+			base = module.exportsArgument;
+			type = "Object.defineProperty";
+			break;
+		case "Object.defineProperty(module.exports)":
+			runtimeRequirements.add(RuntimeGlobals.module);
+			base = `${module.moduleArgument}.exports`;
+			type = "Object.defineProperty";
+			break;
+		case "Object.defineProperty(this)":
+			runtimeRequirements.add(RuntimeGlobals.thisAsExports);
+			base = "this";
+			type = "Object.defineProperty";
+			break;
+		default:
+			throw new Error(`Unsupported base ${depBase}`);
+	}
+
+	return [type, base];
+};
+module.exports.isRequireEsmModuleExportsModule =
+	isRequireEsmModuleExportsModule;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,470 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const { UsageState } = require("../ExportsInfo");
+const Template = require("../Template");
+const { equals } = require("../util/ArrayHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess } = require("../util/property");
+const {
+	ESM_MODULE_EXPORTS_NAME,
+	getRequireEsmModuleExportsAccess,
+	handleDependencyBase,
+	isRequireEsmModuleExportsModule
+} = require("./CommonJsDependencyHelpers");
+const ModuleDependency = require("./ModuleDependency");
+const processExportInfo = require("./processExportInfo");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ExportsInfo")} ExportsInfo */
+/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */
+
+const idsSymbol = /** @type {symbol} */ (
+	Symbol("CommonJsExportRequireDependency.ids")
+);
+
+const EMPTY_OBJECT = {};
+
+/** @typedef {Set<string>} Exports */
+/** @typedef {Set<string>} Checked */
+
+class CommonJsExportRequireDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of CommonJsExportRequireDependency.
+	 * @param {Range} range range
+	 * @param {Range | null} valueRange value range
+	 * @param {CommonJSDependencyBaseKeywords} base base
+	 * @param {ExportInfoName[]} names names
+	 * @param {string} request request
+	 * @param {ExportInfoName[]} ids ids
+	 * @param {boolean} resultUsed true, when the result is used
+	 */
+	constructor(range, valueRange, base, names, request, ids, resultUsed) {
+		super(request);
+		this.range = range;
+		this.valueRange = valueRange;
+		this.base = base;
+		this.names = names;
+		this.ids = ids;
+		this.resultUsed = resultUsed;
+		/** @type {undefined | boolean} */
+		this.asiSafe = undefined;
+	}
+
+	get type() {
+		return "cjs export require";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return Dependency.TRANSITIVE;
+	}
+
+	/**
+	 * Returns the imported id.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ExportInfoName[]} the imported id
+	 */
+	getIds(moduleGraph) {
+		return moduleGraph.getMeta(this)[idsSymbol] || this.ids;
+	}
+
+	/**
+	 * Updates ids using the provided module graph.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ExportInfoName[]} ids the imported ids
+	 * @returns {void}
+	 */
+	setIds(moduleGraph, ids) {
+		moduleGraph.getMeta(this)[idsSymbol] = ids;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		const ids = this.getIds(moduleGraph);
+		const importedModule = moduleGraph.getModule(this);
+		if (
+			importedModule &&
+			isRequireEsmModuleExportsModule(importedModule, moduleGraph)
+		) {
+			// `require(esm)` unwraps the "module.exports" named export; any
+			// further property access lands on that value (which webpack does
+			// not model), so only the "module.exports" export is observable.
+			return [[ESM_MODULE_EXPORTS_NAME]];
+		}
+		const getFullResult = () => {
+			if (ids.length === 0) {
+				return Dependency.EXPORTS_OBJECT_REFERENCED;
+			}
+			return [
+				{
+					name: ids,
+					canMangle: false
+				}
+			];
+		};
+		if (this.resultUsed) return getFullResult();
+		/** @type {ExportsInfo | undefined} */
+		let exportsInfo = moduleGraph.getExportsInfo(
+			/** @type {Module} */ (moduleGraph.getParentModule(this))
+		);
+		for (const name of this.names) {
+			const exportInfo =
+				/** @type {ExportInfo} */
+				(exportsInfo.getReadOnlyExportInfo(name));
+			const used = exportInfo.getUsed(runtime);
+			if (used === UsageState.Unused) return Dependency.NO_EXPORTS_REFERENCED;
+			if (used !== UsageState.OnlyPropertiesUsed) return getFullResult();
+			exportsInfo = exportInfo.exportsInfo;
+			if (!exportsInfo) return getFullResult();
+		}
+		if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
+			return getFullResult();
+		}
+		/** @type {RawReferencedExports} */
+		const referencedExports = [];
+		for (const exportInfo of exportsInfo.orderedExports) {
+			processExportInfo(
+				runtime,
+				referencedExports,
+				[...ids, exportInfo.name],
+				exportInfo,
+				false
+			);
+		}
+		return referencedExports.map((name) => ({
+			name,
+			canMangle: false
+		}));
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		const importedModule = moduleGraph.getModule(this);
+		const esmUnwrap =
+			importedModule &&
+			isRequireEsmModuleExportsModule(importedModule, moduleGraph);
+		if (this.names.length === 1) {
+			const ids = this.getIds(moduleGraph);
+			const name = this.names[0];
+			const from = moduleGraph.getConnection(this);
+			if (!from) return;
+			const exportChain = esmUnwrap
+				? [ESM_MODULE_EXPORTS_NAME, ...ids]
+				: ids.length === 0
+					? null
+					: ids;
+			return {
+				exports: [
+					{
+						name,
+						from,
+						export: exportChain,
+						// we can't mangle names that are in an empty object
+						// because one could access the prototype property
+						// when export isn't set yet
+						canMangle: !(name in EMPTY_OBJECT) && false
+					}
+				],
+				dependencies: [from.module]
+			};
+		} else if (this.names.length > 0) {
+			const name = this.names[0];
+			return {
+				exports: [
+					{
+						name,
+						// we can't mangle names that are in an empty object
+						// because one could access the prototype property
+						// when export isn't set yet
+						canMangle: !(name in EMPTY_OBJECT) && false
+					}
+				],
+				dependencies: undefined
+			};
+		}
+		const from = moduleGraph.getConnection(this);
+		if (!from) return;
+		if (esmUnwrap) {
+			// Full re-export `module.exports = require("./esm")` of a module
+			// with a `"module.exports"` named export: the wrapping module's
+			// `module.exports` becomes the unwrapped value, whose own
+			// properties webpack cannot enumerate statically.
+			return {
+				exports: true,
+				canMangle: false,
+				dependencies: [from.module]
+			};
+		}
+		const reexportInfo = this.getStarReexports(
+			moduleGraph,
+			undefined,
+			from.module
+		);
+		const ids = this.getIds(moduleGraph);
+		if (reexportInfo) {
+			return {
+				exports: Array.from(
+					/** @type {Exports} */
+					(reexportInfo.exports),
+					(name) => ({
+						name,
+						from,
+						export: [...ids, name],
+						canMangle: !(name in EMPTY_OBJECT) && false
+					})
+				),
+				// TODO handle deep reexports
+				dependencies: [from.module]
+			};
+		}
+		return {
+			exports: true,
+			from: ids.length === 0 ? from : undefined,
+			canMangle: false,
+			dependencies: [from.module]
+		};
+	}
+
+	/**
+	 * Gets star reexports.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {Module} importedModule the imported module (optional)
+	 * @returns {{ exports?: Exports, checked?: Checked } | undefined} information
+	 */
+	getStarReexports(
+		moduleGraph,
+		runtime,
+		importedModule = /** @type {Module} */ (moduleGraph.getModule(this))
+	) {
+		/** @type {ExportsInfo | undefined} */
+		let importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
+		const ids = this.getIds(moduleGraph);
+		if (ids.length > 0) {
+			importedExportsInfo = importedExportsInfo.getNestedExportsInfo(ids);
+		}
+		/** @type {ExportsInfo | undefined} */
+		let exportsInfo = moduleGraph.getExportsInfo(
+			/** @type {Module} */ (moduleGraph.getParentModule(this))
+		);
+		if (this.names.length > 0) {
+			exportsInfo = exportsInfo.getNestedExportsInfo(this.names);
+		}
+
+		const noExtraExports =
+			importedExportsInfo &&
+			importedExportsInfo.otherExportsInfo.provided === false;
+		const noExtraImports =
+			exportsInfo &&
+			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused;
+
+		if (!noExtraExports && !noExtraImports) {
+			return;
+		}
+
+		const isNamespaceImport =
+			importedModule.getExportsType(moduleGraph, false) === "namespace";
+
+		/** @type {Exports} */
+		const exports = new Set();
+		/** @type {Checked} */
+		const checked = new Set();
+
+		if (noExtraImports) {
+			for (const exportInfo of /** @type {ExportsInfo} */ (exportsInfo)
+				.orderedExports) {
+				const name = exportInfo.name;
+				if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
+				if (name === "__esModule" && isNamespaceImport) {
+					exports.add(name);
+				} else if (importedExportsInfo) {
+					const importedExportInfo =
+						importedExportsInfo.getReadOnlyExportInfo(name);
+					if (importedExportInfo.provided === false) continue;
+					exports.add(name);
+					if (importedExportInfo.provided === true) continue;
+					checked.add(name);
+				} else {
+					exports.add(name);
+					checked.add(name);
+				}
+			}
+		} else if (noExtraExports) {
+			for (const importedExportInfo of /** @type {ExportsInfo} */ (
+				importedExportsInfo
+			).orderedExports) {
+				const name = importedExportInfo.name;
+				if (importedExportInfo.provided === false) continue;
+				if (exportsInfo) {
+					const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
+					if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
+				}
+				exports.add(name);
+				if (importedExportInfo.provided === true) continue;
+				checked.add(name);
+			}
+			if (isNamespaceImport) {
+				exports.add("__esModule");
+				checked.delete("__esModule");
+			}
+		}
+
+		return { exports, checked };
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.asiSafe);
+		write(this.range);
+		write(this.valueRange);
+		write(this.base);
+		write(this.names);
+		write(this.ids);
+		write(this.resultUsed);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.asiSafe = read();
+		this.range = read();
+		this.valueRange = read();
+		this.base = read();
+		this.names = read();
+		this.ids = read();
+		this.resultUsed = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	CommonJsExportRequireDependency,
+	"webpack/lib/dependencies/CommonJsExportRequireDependency"
+);
+
+CommonJsExportRequireDependency.Template = class CommonJsExportRequireDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{
+			module,
+			runtimeTemplate,
+			chunkGraph,
+			moduleGraph,
+			runtimeRequirements,
+			runtime
+		}
+	) {
+		const dep = /** @type {CommonJsExportRequireDependency} */ (dependency);
+		const used = moduleGraph
+			.getExportsInfo(module)
+			.getUsedName(dep.names, runtime);
+
+		const [type, base] = handleDependencyBase(
+			dep.base,
+			module,
+			runtimeRequirements
+		);
+
+		const importedModule = moduleGraph.getModule(dep);
+		let requireExpr = runtimeTemplate.moduleExports({
+			module: importedModule,
+			chunkGraph,
+			request: dep.request,
+			weak: dep.weak,
+			runtimeRequirements
+		});
+		if (importedModule) {
+			const ids = dep.getIds(moduleGraph);
+			const esmRequireAccess = getRequireEsmModuleExportsAccess(
+				importedModule,
+				moduleGraph,
+				runtime
+			);
+			if (esmRequireAccess !== null) {
+				requireExpr += `${esmRequireAccess}${propertyAccess(ids)}`;
+			} else {
+				const usedImported = moduleGraph
+					.getExportsInfo(importedModule)
+					.getUsedName(ids, runtime);
+				if (usedImported) {
+					const comment = equals(usedImported, ids)
+						? ""
+						: `${Template.toNormalComment(propertyAccess(ids))} `;
+					requireExpr += `${comment}${propertyAccess(usedImported)}`;
+				}
+			}
+		}
+
+		switch (type) {
+			case "expression":
+				source.replace(
+					dep.range[0],
+					dep.range[1] - 1,
+					used
+						? `${base}${propertyAccess(used)} = ${requireExpr}`
+						: `/* unused reexport */ ${requireExpr}`
+				);
+				return;
+			case "Object.defineProperty":
+				throw new Error("TODO");
+			default:
+				throw new Error("Unexpected type");
+		}
+	}
+};
+
+module.exports = CommonJsExportRequireDependency;
+module.exports.idsSymbol = idsSymbol;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsExportsDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsExportsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsExportsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,188 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const InitFragment = require("../InitFragment");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess } = require("../util/property");
+const { handleDependencyBase } = require("./CommonJsDependencyHelpers");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */
+
+const EMPTY_OBJECT = {};
+
+class CommonJsExportsDependency extends NullDependency {
+	/**
+	 * Creates an instance of CommonJsExportsDependency.
+	 * @param {Range} range range
+	 * @param {Range | null} valueRange value range
+	 * @param {CommonJSDependencyBaseKeywords} base base
+	 * @param {ExportInfoName[]} names names
+	 */
+	constructor(range, valueRange, base, names) {
+		super();
+		this.range = range;
+		this.valueRange = valueRange;
+		this.base = base;
+		this.names = names;
+	}
+
+	get type() {
+		return "cjs exports";
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		const name = this.names[0];
+		return {
+			exports: [
+				{
+					name,
+					// we can't mangle names that are in an empty object
+					// because one could access the prototype property
+					// when export isn't set yet
+					canMangle: !(name in EMPTY_OBJECT)
+				}
+			],
+			dependencies: undefined
+		};
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.valueRange);
+		write(this.base);
+		write(this.names);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.valueRange = read();
+		this.base = read();
+		this.names = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	CommonJsExportsDependency,
+	"webpack/lib/dependencies/CommonJsExportsDependency"
+);
+
+CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ module, moduleGraph, initFragments, runtimeRequirements, runtime }
+	) {
+		const dep = /** @type {CommonJsExportsDependency} */ (dependency);
+		const used = moduleGraph
+			.getExportsInfo(module)
+			.getUsedName(dep.names, runtime);
+
+		const [type, base] = handleDependencyBase(
+			dep.base,
+			module,
+			runtimeRequirements
+		);
+
+		switch (type) {
+			case "expression":
+				if (!used) {
+					initFragments.push(
+						new InitFragment(
+							"var __webpack_unused_export__;\n",
+							InitFragment.STAGE_CONSTANTS,
+							0,
+							"__webpack_unused_export__"
+						)
+					);
+					source.replace(
+						dep.range[0],
+						dep.range[1] - 1,
+						"__webpack_unused_export__"
+					);
+					return;
+				}
+				source.replace(
+					dep.range[0],
+					dep.range[1] - 1,
+					`${base}${propertyAccess(used)}`
+				);
+				return;
+			case "Object.defineProperty":
+				if (!used) {
+					initFragments.push(
+						new InitFragment(
+							"var __webpack_unused_export__;\n",
+							InitFragment.STAGE_CONSTANTS,
+							0,
+							"__webpack_unused_export__"
+						)
+					);
+					source.replace(
+						dep.range[0],
+						/** @type {Range} */ (dep.valueRange)[0] - 1,
+						"__webpack_unused_export__ = ("
+					);
+					source.replace(
+						/** @type {Range} */ (dep.valueRange)[1],
+						dep.range[1] - 1,
+						")"
+					);
+					return;
+				}
+				source.replace(
+					dep.range[0],
+					/** @type {Range} */ (dep.valueRange)[0] - 1,
+					`Object.defineProperty(${base}${propertyAccess(
+						used.slice(0, -1)
+					)}, ${JSON.stringify(used[used.length - 1])}, (`
+				);
+				source.replace(
+					/** @type {Range} */ (dep.valueRange)[1],
+					dep.range[1] - 1,
+					"))"
+				);
+		}
+	}
+};
+
+module.exports = CommonJsExportsDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,433 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const { evaluateToString } = require("../javascript/JavascriptParserHelpers");
+const formatLocation = require("../util/formatLocation");
+const { propertyAccess } = require("../util/property");
+const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
+const CommonJsExportsDependency = require("./CommonJsExportsDependency");
+const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
+const DynamicExports = require("./DynamicExports");
+const HarmonyExports = require("./HarmonyExports");
+const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
+
+/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").Super} Super */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../javascript/JavascriptParser").Members} Members */
+/** @typedef {import("../javascript/JavascriptParser").StatementPath} StatementPath */
+/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+
+/**
+ * This function takes a generic expression and detects whether it is an ObjectExpression.
+ * This is used in the context of parsing CommonJS exports to get the value of the property descriptor
+ * when the `exports` object is assigned to `Object.defineProperty`.
+ *
+ * In CommonJS modules, the `exports` object can be assigned to `Object.defineProperty` and therefore
+ * webpack has to detect this case and get the value key of the property descriptor. See the following example
+ * for more information: https://astexplorer.net/#/gist/83ce51a4e96e59d777df315a6d111da6/8058ead48a1bb53c097738225db0967ef7f70e57
+ *
+ * This would be an example of a CommonJS module that exports an object with a property descriptor:
+ * ```js
+ * Object.defineProperty(exports, "__esModule", { value: true });
+ * exports.foo = void 0;
+ * exports.foo = "bar";
+ * ```
+ * @param {Expression} expr expression
+ * @returns {Expression | undefined} returns the value of property descriptor
+ */
+const getValueOfPropertyDescription = (expr) => {
+	if (expr.type !== "ObjectExpression") return;
+	for (const property of expr.properties) {
+		if (property.type === "SpreadElement" || property.computed) continue;
+		const key = property.key;
+		if (key.type !== "Identifier" || key.name !== "value") continue;
+		return /** @type {Expression} */ (property.value);
+	}
+};
+
+/**
+ * The purpose of this function is to check whether an expression is a truthy literal or not. This is
+ * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy
+ * values like `null` and `false`. However, exports should only be created if the exported value is truthy.
+ * @param {Expression} expr expression being checked
+ * @returns {boolean} true, when the expression is a truthy literal
+ */
+const isTruthyLiteral = (expr) => {
+	switch (expr.type) {
+		case "Literal":
+			return Boolean(expr.value);
+		case "UnaryExpression":
+			if (expr.operator === "!") return isFalsyLiteral(expr.argument);
+	}
+	return false;
+};
+
+/**
+ * The purpose of this function is to check whether an expression is a falsy literal or not. This is
+ * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy
+ * values like `null` and `false`. However, exports should only be created if the exported value is truthy.
+ * @param {Expression} expr expression being checked
+ * @returns {boolean} true, when the expression is a falsy literal
+ */
+const isFalsyLiteral = (expr) => {
+	switch (expr.type) {
+		case "Literal":
+			return !expr.value;
+		case "UnaryExpression":
+			if (expr.operator === "!") return isTruthyLiteral(expr.argument);
+	}
+	return false;
+};
+
+/**
+ * Parses require call.
+ * @param {JavascriptParser} parser the parser
+ * @param {Expression} expr expression
+ * @returns {{ argument: BasicEvaluatedExpression, ids: ExportInfoName[] } | undefined} parsed call
+ */
+const parseRequireCall = (parser, expr) => {
+	/** @type {ExportInfoName[]} */
+	const ids = [];
+	while (expr.type === "MemberExpression") {
+		if (expr.object.type === "Super") return;
+		if (!expr.property) return;
+		const prop = expr.property;
+		if (expr.computed) {
+			if (prop.type !== "Literal") return;
+			ids.push(`${prop.value}`);
+		} else {
+			if (prop.type !== "Identifier") return;
+			ids.push(prop.name);
+		}
+		expr = expr.object;
+	}
+	if (expr.type !== "CallExpression" || expr.arguments.length !== 1) return;
+	const callee = expr.callee;
+	if (
+		callee.type !== "Identifier" ||
+		parser.getVariableInfo(callee.name) !== "require"
+	) {
+		return;
+	}
+	const arg = expr.arguments[0];
+	if (arg.type === "SpreadElement") return;
+	const argValue = parser.evaluateExpression(arg);
+	return { argument: argValue, ids: ids.reverse() };
+};
+
+const PLUGIN_NAME = "CommonJsExportsParserPlugin";
+
+class CommonJsExportsParserPlugin {
+	/**
+	 * Creates an instance of CommonJsExportsParserPlugin.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 */
+	constructor(moduleGraph) {
+		this.moduleGraph = moduleGraph;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const enableStructuredExports = () => {
+			DynamicExports.enable(parser.state);
+		};
+
+		/**
+		 * Checks namespace.
+		 * @param {boolean} topLevel true, when the export is on top level
+		 * @param {Members} members members of the export
+		 * @param {Expression | undefined} valueExpr expression for the value
+		 * @returns {void}
+		 */
+		const checkNamespace = (topLevel, members, valueExpr) => {
+			if (!DynamicExports.isEnabled(parser.state)) return;
+			if (members.length > 0 && members[0] === "__esModule") {
+				if (valueExpr && isTruthyLiteral(valueExpr) && topLevel) {
+					DynamicExports.setFlagged(parser.state);
+				} else {
+					DynamicExports.setDynamic(parser.state);
+				}
+			}
+		};
+		/**
+		 * Processes the provided reason.
+		 * @param {string=} reason reason
+		 */
+		const bailout = (reason) => {
+			DynamicExports.bailout(parser.state);
+			if (reason) bailoutHint(reason);
+		};
+		/**
+		 * Processes the provided reason.
+		 * @param {string} reason reason
+		 */
+		const bailoutHint = (reason) => {
+			this.moduleGraph
+				.getOptimizationBailout(parser.state.module)
+				.push(`CommonJS bailout: ${reason}`);
+		};
+
+		// metadata //
+		parser.hooks.evaluateTypeof
+			.for("module")
+			.tap(PLUGIN_NAME, evaluateToString("object"));
+		parser.hooks.evaluateTypeof
+			.for("exports")
+			.tap(PLUGIN_NAME, evaluateToString("object"));
+
+		// exporting //
+
+		/**
+		 * Handle assign export.
+		 * @param {AssignmentExpression} expr expression
+		 * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords
+		 * @param {Members} members members of the export
+		 * @returns {boolean | undefined} true, when the expression was handled
+		 */
+		const handleAssignExport = (expr, base, members) => {
+			if (HarmonyExports.isEnabled(parser.state)) return;
+			// Handle reexporting
+			const requireCall = parseRequireCall(parser, expr.right);
+			if (
+				requireCall &&
+				requireCall.argument.isString() &&
+				(members.length === 0 || members[0] !== "__esModule")
+			) {
+				enableStructuredExports();
+				// It's possible to reexport __esModule, so we must convert to a dynamic module
+				if (members.length === 0) DynamicExports.setDynamic(parser.state);
+				const dep = new CommonJsExportRequireDependency(
+					/** @type {Range} */ (expr.range),
+					null,
+					base,
+					members,
+					/** @type {string} */ (requireCall.argument.string),
+					requireCall.ids,
+					!parser.isStatementLevelExpression(expr)
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				dep.optional = Boolean(parser.scope.inTry);
+				parser.state.module.addDependency(dep);
+				/** @type {BuildMeta} */ (
+					parser.state.module.buildMeta
+				).treatAsCommonJs = true;
+
+				return true;
+			}
+			if (members.length === 0) return;
+			enableStructuredExports();
+			const remainingMembers = members;
+			checkNamespace(
+				/** @type {StatementPath} */
+				(parser.statementPath).length === 1 &&
+					parser.isStatementLevelExpression(expr),
+				remainingMembers,
+				expr.right
+			);
+			const dep = new CommonJsExportsDependency(
+				/** @type {Range} */ (expr.left.range),
+				null,
+				base,
+				remainingMembers
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addDependency(dep);
+			/** @type {BuildMeta} */ (parser.state.module.buildMeta).treatAsCommonJs =
+				true;
+			parser.walkExpression(expr.right);
+			return true;
+		};
+		parser.hooks.assignMemberChain
+			.for("exports")
+			.tap(PLUGIN_NAME, (expr, members) =>
+				handleAssignExport(expr, "exports", members)
+			);
+		parser.hooks.assignMemberChain
+			.for("this")
+			.tap(PLUGIN_NAME, (expr, members) => {
+				if (!parser.scope.topLevelScope) return;
+				return handleAssignExport(expr, "this", members);
+			});
+		parser.hooks.assignMemberChain
+			.for("module")
+			.tap(PLUGIN_NAME, (expr, members) => {
+				if (members[0] !== "exports") return;
+				return handleAssignExport(expr, "module.exports", members.slice(1));
+			});
+		parser.hooks.call
+			.for("Object.defineProperty")
+			.tap(PLUGIN_NAME, (expression) => {
+				const expr = /** @type {CallExpression} */ (expression);
+				if (!parser.isStatementLevelExpression(expr)) return;
+				if (expr.arguments.length !== 3) return;
+				if (expr.arguments[0].type === "SpreadElement") return;
+				if (expr.arguments[1].type === "SpreadElement") return;
+				if (expr.arguments[2].type === "SpreadElement") return;
+				const exportsArg = parser.evaluateExpression(expr.arguments[0]);
+				if (!exportsArg.isIdentifier()) return;
+				if (
+					exportsArg.identifier !== "exports" &&
+					exportsArg.identifier !== "module.exports" &&
+					(exportsArg.identifier !== "this" || !parser.scope.topLevelScope)
+				) {
+					return;
+				}
+				const propertyArg = parser.evaluateExpression(expr.arguments[1]);
+				const property = propertyArg.asString();
+				if (typeof property !== "string") return;
+				enableStructuredExports();
+				const descArg = expr.arguments[2];
+				checkNamespace(
+					/** @type {StatementPath} */
+					(parser.statementPath).length === 1,
+					[property],
+					getValueOfPropertyDescription(descArg)
+				);
+				const dep = new CommonJsExportsDependency(
+					/** @type {Range} */ (expr.range),
+					/** @type {Range} */ (expr.arguments[2].range),
+					`Object.defineProperty(${exportsArg.identifier})`,
+					[property]
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addDependency(dep);
+				/** @type {BuildMeta} */ (
+					parser.state.module.buildMeta
+				).treatAsCommonJs = true;
+
+				parser.walkExpression(expr.arguments[2]);
+				return true;
+			});
+
+		// Self reference //
+
+		/**
+		 * Handle access export.
+		 * @param {Expression | Super} expr expression
+		 * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords
+		 * @param {Members} members members of the export
+		 * @param {CallExpression=} call call expression
+		 * @returns {boolean | void} true, when the expression was handled
+		 */
+		const handleAccessExport = (expr, base, members, call) => {
+			if (HarmonyExports.isEnabled(parser.state)) return;
+			if (members.length === 0) {
+				bailout(
+					`${base} is used directly at ${formatLocation(
+						/** @type {DependencyLocation} */ (expr.loc)
+					)}`
+				);
+			}
+			if (call && members.length === 1) {
+				bailoutHint(
+					`${base}${propertyAccess(
+						members
+					)}(...) prevents optimization as ${base} is passed as call context at ${formatLocation(
+						/** @type {DependencyLocation} */ (expr.loc)
+					)}`
+				);
+			}
+			const dep = new CommonJsSelfReferenceDependency(
+				/** @type {Range} */ (expr.range),
+				base,
+				members,
+				Boolean(call)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addDependency(dep);
+			/** @type {BuildMeta} */ (parser.state.module.buildMeta).treatAsCommonJs =
+				true;
+
+			if (call) {
+				parser.walkExpressions(call.arguments);
+			}
+			return true;
+		};
+		parser.hooks.callMemberChain
+			.for("exports")
+			.tap(PLUGIN_NAME, (expr, members) =>
+				handleAccessExport(expr.callee, "exports", members, expr)
+			);
+		parser.hooks.expressionMemberChain
+			.for("exports")
+			.tap(PLUGIN_NAME, (expr, members) =>
+				handleAccessExport(expr, "exports", members)
+			);
+		parser.hooks.expression
+			.for("exports")
+			.tap(PLUGIN_NAME, (expr) => handleAccessExport(expr, "exports", []));
+		parser.hooks.callMemberChain
+			.for("module")
+			.tap(PLUGIN_NAME, (expr, members) => {
+				if (members[0] !== "exports") return;
+				return handleAccessExport(
+					expr.callee,
+					"module.exports",
+					members.slice(1),
+					expr
+				);
+			});
+		parser.hooks.expressionMemberChain
+			.for("module")
+			.tap(PLUGIN_NAME, (expr, members) => {
+				if (members[0] !== "exports") return;
+				return handleAccessExport(expr, "module.exports", members.slice(1));
+			});
+		parser.hooks.expression
+			.for("module.exports")
+			.tap(PLUGIN_NAME, (expr) =>
+				handleAccessExport(expr, "module.exports", [])
+			);
+		parser.hooks.callMemberChain
+			.for("this")
+			.tap(PLUGIN_NAME, (expr, members) => {
+				if (!parser.scope.topLevelScope) return;
+				return handleAccessExport(expr.callee, "this", members, expr);
+			});
+		parser.hooks.expressionMemberChain
+			.for("this")
+			.tap(PLUGIN_NAME, (expr, members) => {
+				if (!parser.scope.topLevelScope) return;
+				return handleAccessExport(expr, "this", members);
+			});
+		parser.hooks.expression.for("this").tap(PLUGIN_NAME, (expr) => {
+			if (!parser.scope.topLevelScope) return;
+			return handleAccessExport(expr, "this", []);
+		});
+
+		// Bailouts //
+		parser.hooks.expression.for("module").tap(PLUGIN_NAME, (expr) => {
+			bailout();
+			const isHarmony = HarmonyExports.isEnabled(parser.state);
+			const dep = new ModuleDecoratorDependency(
+				isHarmony
+					? RuntimeGlobals.harmonyModuleDecorator
+					: RuntimeGlobals.nodeModuleDecorator,
+				!isHarmony
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addDependency(dep);
+			return true;
+		});
+	}
+}
+
+module.exports = CommonJsExportsParserPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsFullRequireDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsFullRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsFullRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,189 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Template = require("../Template");
+const { equals } = require("../util/ArrayHelpers");
+const { getTrimmedIdsAndRange } = require("../util/chainedImports");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess } = require("../util/property");
+const {
+	ESM_MODULE_EXPORTS_NAME,
+	getRequireEsmModuleExportsAccess,
+	isRequireEsmModuleExportsModule
+} = require("./CommonJsDependencyHelpers");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../util/chainedImports").IdRanges} IdRanges */
+
+class CommonJsFullRequireDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of CommonJsFullRequireDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 * @param {ExportInfoName[]} names accessed properties on module
+	 * @param {IdRanges=} idRanges ranges for members of ids; the two arrays are right-aligned
+	 */
+	constructor(
+		request,
+		range,
+		names,
+		idRanges /* TODO webpack 6 make this non-optional. It must always be set to properly trim ids. */
+	) {
+		super(request);
+		this.range = range;
+		this.names = names;
+		this.idRanges = idRanges;
+		/** @type {boolean} */
+		this.call = false;
+		/** @type {undefined | boolean} */
+		this.asiSafe = undefined;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		const importedModule = moduleGraph.getModule(this);
+		if (
+			importedModule &&
+			isRequireEsmModuleExportsModule(importedModule, moduleGraph)
+		) {
+			// When `require(esm)` unwraps a `"module.exports"` named export, the
+			// user's property access lands on that value (which webpack does not
+			// model), so only the "module.exports" export itself is referenced.
+			return [[ESM_MODULE_EXPORTS_NAME]];
+		}
+		if (
+			this.call &&
+			(!importedModule ||
+				importedModule.getExportsType(moduleGraph, false) !== "namespace")
+		) {
+			return [this.names.slice(0, -1)];
+		}
+		return [this.names];
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.names);
+		write(this.idRanges);
+		write(this.call);
+		write(this.asiSafe);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.names = read();
+		this.idRanges = read();
+		this.call = read();
+		this.asiSafe = read();
+		super.deserialize(context);
+	}
+
+	get type() {
+		return "cjs full require";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+}
+
+CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements, runtime }
+	) {
+		const dep = /** @type {CommonJsFullRequireDependency} */ (dependency);
+		if (!dep.range) return;
+		const importedModule = moduleGraph.getModule(dep);
+		let requireExpr = runtimeTemplate.moduleExports({
+			module: importedModule,
+			chunkGraph,
+			request: dep.request,
+			weak: dep.weak,
+			runtimeRequirements
+		});
+
+		const esmRequireAccess = importedModule
+			? getRequireEsmModuleExportsAccess(importedModule, moduleGraph, runtime)
+			: null;
+
+		const {
+			trimmedRange: [trimmedRangeStart, trimmedRangeEnd],
+			trimmedIds
+		} = getTrimmedIdsAndRange(
+			dep.names,
+			dep.range,
+			dep.idRanges,
+			moduleGraph,
+			dep
+		);
+
+		if (esmRequireAccess !== null) {
+			const access = `${esmRequireAccess}${propertyAccess(trimmedIds)}`;
+			requireExpr =
+				dep.asiSafe === true
+					? `(${requireExpr}${access})`
+					: `${requireExpr}${access}`;
+		} else if (importedModule) {
+			const usedImported = moduleGraph
+				.getExportsInfo(importedModule)
+				.getUsedName(trimmedIds, runtime);
+			if (usedImported) {
+				const comment = equals(usedImported, trimmedIds)
+					? ""
+					: `${Template.toNormalComment(propertyAccess(trimmedIds))} `;
+				const access = `${comment}${propertyAccess(usedImported)}`;
+				requireExpr =
+					dep.asiSafe === true
+						? `(${requireExpr}${access})`
+						: `${requireExpr}${access}`;
+			}
+		}
+		source.replace(trimmedRangeStart, trimmedRangeEnd - 1, requireExpr);
+	}
+};
+
+makeSerializable(
+	CommonJsFullRequireDependency,
+	"webpack/lib/dependencies/CommonJsFullRequireDependency"
+);
+
+module.exports = CommonJsFullRequireDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,800 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const {
+	evaluateToIdentifier,
+	evaluateToString,
+	expressionIsUnsupported,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
+const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
+const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
+const CommonJsRequireDependency = require("./CommonJsRequireDependency");
+const ConstDependency = require("./ConstDependency");
+const ContextDependencyHelpers = require("./ContextDependencyHelpers");
+const LocalModuleDependency = require("./LocalModuleDependency");
+const { getLocalModule } = require("./LocalModulesHelpers");
+const RequireHeaderDependency = require("./RequireHeaderDependency");
+const RequireResolveContextDependency = require("./RequireResolveContextDependency");
+const RequireResolveDependency = require("./RequireResolveDependency");
+const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
+
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").NewExpression} NewExpression */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../javascript/JavascriptParser").Members} Members */
+/** @typedef {import("../javascript/JavascriptParser").CalleeMembers} CalleeMembers */
+/** @typedef {import("./LocalModule")} LocalModule */
+
+/**
+ * Defines the common js import settings type used by this module.
+ * @typedef {object} CommonJsImportSettings
+ * @property {string=} name
+ * @property {string} context
+ */
+
+/**
+ * Per-`const NAME = require(LITERAL)` binding state used to forward
+ * member-access references on `NAME` to the `CommonJsRequireDependency`
+ * created for the `require()` call.
+ * @typedef {object} RequireBindingData
+ * @property {RawReferencedExports} referencedExports mutable list shared with the dependency; pushed to as `NAME.x.y` accesses are walked
+ * @property {InstanceType<typeof import("./CommonJsRequireDependency")> | null} dep dependency for the `require()` call (assigned during walk)
+ */
+
+/** @type {WeakMap<CallExpression, RequireBindingData>} */
+const requireBindingData = new WeakMap();
+
+const REQUIRE_BINDING_TAG = Symbol(
+	"CommonJsImportsParserPlugin require binding"
+);
+
+const PLUGIN_NAME = "CommonJsImportsParserPlugin";
+
+/**
+ * Checks whether this object is require call expression.
+ * @param {Expression} expression expression
+ * @returns {boolean} true, when expression is `require(...)` or `module.require(...)`
+ */
+const isRequireCallExpression = (expression) => {
+	if (expression.type !== "CallExpression") return false;
+	const { callee } = expression;
+	if (callee.type === "Identifier") {
+		return callee.name === "require";
+	}
+	if (callee.type === "MemberExpression" && !callee.computed) {
+		const object = callee.object;
+		const property = callee.property;
+		return (
+			object.type === "Identifier" &&
+			object.name === "module" &&
+			property.type === "Identifier" &&
+			property.name === "require"
+		);
+	}
+	return false;
+};
+
+/**
+ * Gets require referenced exports from destructuring.
+ * @param {JavascriptParser} parser parser
+ * @param {CallExpression | NewExpression} expr expression
+ * @returns {RawReferencedExports | null} referenced exports from destructuring
+ */
+const getRequireReferencedExportsFromDestructuring = (parser, expr) => {
+	const referencedPropertiesInDestructuring =
+		parser.destructuringAssignmentPropertiesFor(expr);
+	if (!referencedPropertiesInDestructuring) return null;
+
+	/** @type {RawReferencedExports} */
+	const referencedExports = [];
+	traverseDestructuringAssignmentProperties(
+		referencedPropertiesInDestructuring,
+		(stack) => referencedExports.push(stack.map((p) => p.id))
+	);
+	return referencedExports;
+};
+
+/**
+ * Creates a require cache dependency.
+ * @param {JavascriptParser} parser parser
+ * @returns {(expr: Expression) => boolean} handler
+ */
+const createRequireCacheDependency = (parser) =>
+	toConstantDependency(parser, RuntimeGlobals.moduleCache, [
+		RuntimeGlobals.moduleCache,
+		RuntimeGlobals.moduleId,
+		RuntimeGlobals.moduleLoaded
+	]);
+
+/**
+ * Creates a require as expression handler.
+ * @param {JavascriptParser} parser parser
+ * @param {JavascriptParserOptions} options options
+ * @param {() => undefined | string} getContext context accessor
+ * @returns {(expr: Expression) => boolean} handler
+ */
+const createRequireAsExpressionHandler =
+	(parser, options, getContext) => (expr) => {
+		const dep = new CommonJsRequireContextDependency(
+			{
+				request: /** @type {string} */ (options.unknownContextRequest),
+				recursive: /** @type {boolean} */ (options.unknownContextRecursive),
+				regExp: /** @type {RegExp} */ (options.unknownContextRegExp),
+				mode: "sync"
+			},
+			/** @type {Range} */ (expr.range),
+			undefined,
+			parser.scope.inShorthand,
+			getContext()
+		);
+		dep.critical =
+			options.unknownContextCritical &&
+			"require function is used in a way in which dependencies cannot be statically extracted";
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		dep.optional = Boolean(parser.scope.inTry);
+		parser.state.current.addDependency(dep);
+		return true;
+	};
+
+/**
+ * Creates a require call handler.
+ * @param {JavascriptParser} parser parser
+ * @param {JavascriptParserOptions} options options
+ * @param {() => undefined | string} getContext context accessor
+ * @returns {(callNew: boolean) => (expr: CallExpression | NewExpression) => (boolean | void)} handler factory
+ */
+const createRequireCallHandler = (parser, options, getContext) => {
+	/**
+	 * Process require item.
+	 * @param {CallExpression | NewExpression} expr expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {boolean | void} true when handled
+	 */
+	const processRequireItem = (expr, param) => {
+		if (param.isString()) {
+			let referencedExports = getRequireReferencedExportsFromDestructuring(
+				parser,
+				expr
+			);
+			const binding = requireBindingData.get(
+				/** @type {CallExpression} */ (expr)
+			);
+			if (binding && !referencedExports) {
+				// `const NAME = require(LITERAL)` — let later member-access walks
+				// on `NAME` populate the dependency's referenced exports.
+				referencedExports = binding.referencedExports;
+			}
+			const dep = new CommonJsRequireDependency(
+				/** @type {string} */ (param.string),
+				/** @type {Range} */ (param.range),
+				getContext(),
+				referencedExports,
+				/** @type {Range} */ (expr.range)
+			);
+			if (binding) binding.dep = dep;
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			dep.optional = Boolean(parser.scope.inTry);
+			parser.state.current.addDependency(dep);
+			return true;
+		}
+	};
+	/**
+	 * Process require context.
+	 * @param {CallExpression | NewExpression} expr expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @returns {boolean | void} true when handled
+	 */
+	const processRequireContext = (expr, param) => {
+		const referencedExports = getRequireReferencedExportsFromDestructuring(
+			parser,
+			expr
+		);
+		const dep = ContextDependencyHelpers.create(
+			CommonJsRequireContextDependency,
+			/** @type {Range} */ (expr.range),
+			param,
+			expr,
+			options,
+			{
+				category: "commonjs",
+				referencedExports
+			},
+			parser,
+			undefined,
+			getContext()
+		);
+		if (!dep) return;
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		dep.optional = Boolean(parser.scope.inTry);
+		parser.state.current.addDependency(dep);
+		return true;
+	};
+
+	return (callNew) => (expr) => {
+		if (options.commonjsMagicComments) {
+			const { options: requireOptions, errors: commentErrors } =
+				parser.parseCommentOptions(/** @type {Range} */ (expr.range));
+
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					parser.state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							/** @type {DependencyLocation} */ (comment.loc)
+						)
+					);
+				}
+			}
+			if (requireOptions && requireOptions.webpackIgnore !== undefined) {
+				if (typeof requireOptions.webpackIgnore !== "boolean") {
+					parser.state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
+							/** @type {DependencyLocation} */ (expr.loc)
+						)
+					);
+				} else if (requireOptions.webpackIgnore) {
+					// Do not instrument `require()` if `webpackIgnore` is `true`
+					return true;
+				}
+			}
+		}
+
+		if (expr.arguments.length !== 1) return;
+		/** @type {null | LocalModule} */
+		let localModule;
+		const param = parser.evaluateExpression(expr.arguments[0]);
+		if (param.isConditional()) {
+			let isExpression = false;
+			for (const p of /** @type {BasicEvaluatedExpression[]} */ (
+				param.options
+			)) {
+				const result = processRequireItem(expr, p);
+				if (result === undefined) {
+					isExpression = true;
+				}
+			}
+			if (!isExpression) {
+				const dep = new RequireHeaderDependency(
+					/** @type {Range} */ (expr.callee.range)
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addPresentationalDependency(dep);
+				return true;
+			}
+		}
+		if (
+			param.isString() &&
+			(localModule = getLocalModule(
+				parser.state,
+				/** @type {string} */ (param.string)
+			))
+		) {
+			localModule.flagUsed();
+			const dep = new LocalModuleDependency(
+				localModule,
+				/** @type {Range} */ (expr.range),
+				callNew
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+		} else {
+			const result = processRequireItem(expr, param);
+			if (result === undefined) {
+				processRequireContext(expr, param);
+			} else {
+				const dep = new RequireHeaderDependency(
+					/** @type {Range} */ (expr.callee.range)
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addPresentationalDependency(dep);
+			}
+		}
+		return true;
+	};
+};
+
+/**
+ * Creates a process resolve handler.
+ * @param {JavascriptParser} parser parser
+ * @param {JavascriptParserOptions} options options
+ * @param {() => undefined | string} getContext context accessor
+ * @returns {(expr: CallExpression, weak: boolean) => (boolean | void)} resolver
+ */
+const createProcessResolveHandler = (parser, options, getContext) => {
+	/**
+	 * Process resolve item.
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @param {boolean} weak weak
+	 * @returns {boolean | void} true when handled
+	 */
+	const processResolveItem = (expr, param, weak) => {
+		if (param.isString()) {
+			const dep = new RequireResolveDependency(
+				/** @type {string} */ (param.string),
+				/** @type {Range} */ (param.range),
+				getContext()
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			dep.optional = Boolean(parser.scope.inTry);
+			dep.weak = weak;
+			parser.state.current.addDependency(dep);
+			return true;
+		}
+	};
+	/**
+	 * Process resolve context.
+	 * @param {CallExpression} expr call expression
+	 * @param {BasicEvaluatedExpression} param param
+	 * @param {boolean} weak weak
+	 * @returns {boolean | void} true when handled
+	 */
+	const processResolveContext = (expr, param, weak) => {
+		const dep = ContextDependencyHelpers.create(
+			RequireResolveContextDependency,
+			/** @type {Range} */ (param.range),
+			param,
+			expr,
+			options,
+			{
+				category: "commonjs",
+				mode: weak ? "weak" : "sync"
+			},
+			parser,
+			getContext()
+		);
+		if (!dep) return;
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		dep.optional = Boolean(parser.scope.inTry);
+		parser.state.current.addDependency(dep);
+		return true;
+	};
+
+	return (expr, weak) => {
+		if (!weak && options.commonjsMagicComments) {
+			const { options: requireOptions, errors: commentErrors } =
+				parser.parseCommentOptions(/** @type {Range} */ (expr.range));
+
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					parser.state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							/** @type {DependencyLocation} */ (comment.loc)
+						)
+					);
+				}
+			}
+			if (requireOptions && requireOptions.webpackIgnore !== undefined) {
+				if (typeof requireOptions.webpackIgnore !== "boolean") {
+					parser.state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
+							/** @type {DependencyLocation} */ (expr.loc)
+						)
+					);
+				} else if (requireOptions.webpackIgnore) {
+					// Do not instrument `require()` if `webpackIgnore` is `true`
+					return true;
+				}
+			}
+		}
+
+		if (expr.arguments.length !== 1) return;
+		const param = parser.evaluateExpression(expr.arguments[0]);
+		if (param.isConditional()) {
+			for (const option of /** @type {BasicEvaluatedExpression[]} */ (
+				param.options
+			)) {
+				const result = processResolveItem(expr, option, weak);
+				if (result === undefined) {
+					processResolveContext(expr, option, weak);
+				}
+			}
+			const dep = new RequireResolveHeaderDependency(
+				/** @type {Range} */ (expr.callee.range)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		}
+		const result = processResolveItem(expr, param, weak);
+		if (result === undefined) {
+			processResolveContext(expr, param, weak);
+		}
+		const dep = new RequireResolveHeaderDependency(
+			/** @type {Range} */ (expr.callee.range)
+		);
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		parser.state.module.addPresentationalDependency(dep);
+		return true;
+	};
+};
+
+class CommonJsImportsParserPlugin {
+	/**
+	 * Creates an instance of CommonJsImportsParserPlugin.
+	 * @param {JavascriptParserOptions} options parser options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const options = this.options;
+		parser.hooks.collectDestructuringAssignmentProperties.tap(
+			PLUGIN_NAME,
+			(expr) => {
+				if (isRequireCallExpression(expr)) return true;
+			}
+		);
+
+		const getContext = () => {
+			if (parser.currentTagData) {
+				const { context } =
+					/** @type {CommonJsImportSettings} */
+					(parser.currentTagData);
+				return context;
+			}
+		};
+
+		// #region metadata
+		/**
+		 * Tap require expression.
+		 * @param {string} expression expression
+		 * @param {() => Members} getMembers get members
+		 */
+		const tapRequireExpression = (expression, getMembers) => {
+			parser.hooks.typeof
+				.for(expression)
+				.tap(
+					PLUGIN_NAME,
+					toConstantDependency(parser, JSON.stringify("function"))
+				);
+			parser.hooks.evaluateTypeof
+				.for(expression)
+				.tap(PLUGIN_NAME, evaluateToString("function"));
+			parser.hooks.evaluateIdentifier
+				.for(expression)
+				.tap(
+					PLUGIN_NAME,
+					evaluateToIdentifier(expression, "require", getMembers, true)
+				);
+		};
+		tapRequireExpression("require", () => []);
+		tapRequireExpression("require.resolve", () => ["resolve"]);
+		tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
+		// #endregion
+
+		// Weird stuff //
+		parser.hooks.assign.for("require").tap(PLUGIN_NAME, (expr) => {
+			// to not leak to global "require", we need to define a local require here.
+			const dep = new ConstDependency("var require;", 0);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		});
+
+		// #region Unsupported
+		parser.hooks.call
+			.for("require.main.require")
+			.tap(
+				PLUGIN_NAME,
+				expressionIsUnsupported(
+					parser,
+					"require.main.require is not supported by webpack."
+				)
+			);
+		parser.hooks.expression
+			.for("module.parent.require")
+			.tap(
+				PLUGIN_NAME,
+				expressionIsUnsupported(
+					parser,
+					"module.parent.require is not supported by webpack."
+				)
+			);
+		parser.hooks.call
+			.for("module.parent.require")
+			.tap(
+				PLUGIN_NAME,
+				expressionIsUnsupported(
+					parser,
+					"module.parent.require is not supported by webpack."
+				)
+			);
+		// #endregion
+
+		// #region Renaming
+		/**
+		 * Returns true when set undefined.
+		 * @param {Expression} expr expression
+		 * @returns {boolean} true when set undefined
+		 */
+		const defineUndefined = (expr) => {
+			// To avoid "not defined" error, replace the value with undefined
+			const dep = new ConstDependency(
+				"undefined",
+				/** @type {Range} */ (expr.range)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+			return false;
+		};
+		parser.hooks.canRename.for("require").tap(PLUGIN_NAME, () => true);
+		parser.hooks.rename.for("require").tap(PLUGIN_NAME, defineUndefined);
+		// #endregion
+
+		// #region Inspection
+		const requireCache = createRequireCacheDependency(parser);
+
+		parser.hooks.expression.for("require.cache").tap(PLUGIN_NAME, requireCache);
+		// #endregion
+
+		// #region Require as expression
+		/**
+		 * Require as expression handler.
+		 * @param {Expression} expr expression
+		 * @returns {boolean} true when handled
+		 */
+		const requireAsExpressionHandler = createRequireAsExpressionHandler(
+			parser,
+			options,
+			getContext
+		);
+		parser.hooks.expression
+			.for("require")
+			.tap(PLUGIN_NAME, requireAsExpressionHandler);
+		// #endregion
+
+		// #region Require
+		/**
+		 * Creates a require handler.
+		 * @param {boolean} callNew true, when require is called with new
+		 * @returns {(expr: CallExpression | NewExpression) => (boolean | void)} handler
+		 */
+		const createRequireHandler = createRequireCallHandler(
+			parser,
+			options,
+			getContext
+		);
+		parser.hooks.call
+			.for("require")
+			.tap(PLUGIN_NAME, createRequireHandler(false));
+		parser.hooks.new
+			.for("require")
+			.tap(PLUGIN_NAME, createRequireHandler(true));
+		parser.hooks.call
+			.for("module.require")
+			.tap(PLUGIN_NAME, createRequireHandler(false));
+		parser.hooks.new
+			.for("module.require")
+			.tap(PLUGIN_NAME, createRequireHandler(true));
+		// #endregion
+
+		// #region Require with property access
+		/**
+		 * Returns true when handled.
+		 * @param {Expression} expr expression
+		 * @param {CalleeMembers} calleeMembers callee members
+		 * @param {CallExpression} callExpr call expression
+		 * @param {Members} members members
+		 * @param {Range[]} memberRanges member ranges
+		 * @returns {boolean | void} true when handled
+		 */
+		const chainHandler = (
+			expr,
+			calleeMembers,
+			callExpr,
+			members,
+			memberRanges
+		) => {
+			if (callExpr.arguments.length !== 1) return;
+			const param = parser.evaluateExpression(callExpr.arguments[0]);
+			if (
+				param.isString() &&
+				!getLocalModule(parser.state, /** @type {string} */ (param.string))
+			) {
+				const dep = new CommonJsFullRequireDependency(
+					/** @type {string} */ (param.string),
+					/** @type {Range} */ (expr.range),
+					members,
+					/** @type {Range[]} */ memberRanges
+				);
+				dep.asiSafe = !parser.isAsiPosition(
+					/** @type {Range} */ (expr.range)[0]
+				);
+				dep.optional = Boolean(parser.scope.inTry);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.current.addDependency(dep);
+				return true;
+			}
+		};
+		/**
+		 * Call chain handler.
+		 * @param {CallExpression} expr expression
+		 * @param {CalleeMembers} calleeMembers callee members
+		 * @param {CallExpression} callExpr call expression
+		 * @param {Members} members members
+		 * @param {Range[]} memberRanges member ranges
+		 * @returns {boolean | void} true when handled
+		 */
+		const callChainHandler = (
+			expr,
+			calleeMembers,
+			callExpr,
+			members,
+			memberRanges
+		) => {
+			if (callExpr.arguments.length !== 1) return;
+			const param = parser.evaluateExpression(callExpr.arguments[0]);
+			if (
+				param.isString() &&
+				!getLocalModule(parser.state, /** @type {string} */ (param.string))
+			) {
+				const dep = new CommonJsFullRequireDependency(
+					/** @type {string} */ (param.string),
+					/** @type {Range} */ (expr.callee.range),
+					members,
+					/** @type {Range[]} */ memberRanges
+				);
+				dep.call = true;
+				dep.asiSafe = !parser.isAsiPosition(
+					/** @type {Range} */ (expr.range)[0]
+				);
+				dep.optional = Boolean(parser.scope.inTry);
+				dep.loc = /** @type {DependencyLocation} */ (expr.callee.loc);
+				parser.state.current.addDependency(dep);
+				parser.walkExpressions(expr.arguments);
+				return true;
+			}
+		};
+		parser.hooks.memberChainOfCallMemberChain
+			.for("require")
+			.tap(PLUGIN_NAME, chainHandler);
+		parser.hooks.memberChainOfCallMemberChain
+			.for("module.require")
+			.tap(PLUGIN_NAME, chainHandler);
+		parser.hooks.callMemberChainOfCallMemberChain
+			.for("require")
+			.tap(PLUGIN_NAME, callChainHandler);
+		parser.hooks.callMemberChainOfCallMemberChain
+			.for("module.require")
+			.tap(PLUGIN_NAME, callChainHandler);
+		// #endregion
+
+		// #region Require bound to a const variable
+		// Track `const NAME = require(LITERAL)` so that static member accesses on
+		// `NAME` (e.g. `NAME.foo`, `NAME.foo()`) are forwarded to the same
+		// `CommonJsRequireDependency` as referenced exports — enabling tree
+		// shaking of CommonJS modules that are imported into a named binding
+		// rather than destructured.
+		parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator, statement) => {
+			if (statement.kind !== "const") return;
+			if (declarator.id.type !== "Identifier") return;
+			if (!declarator.init || declarator.init.type !== "CallExpression") {
+				return;
+			}
+			const init = declarator.init;
+			if (
+				init.callee.type !== "Identifier" ||
+				init.callee.name !== "require" ||
+				init.arguments.length !== 1
+			) {
+				return;
+			}
+			const arg = init.arguments[0];
+			if (arg.type !== "Literal" || typeof arg.value !== "string") return;
+			// Only attach binding state when `require` resolves to the free
+			// `require` (i.e. it isn't shadowed in the current scope).
+			const requireInfo = parser.getFreeInfoFromVariable("require");
+			if (!requireInfo || requireInfo.name !== "require") return;
+			/** @type {RequireBindingData} */
+			const binding = {
+				referencedExports: [],
+				dep: null
+			};
+			requireBindingData.set(init, binding);
+			parser.tagVariable(declarator.id.name, REQUIRE_BINDING_TAG, binding);
+			return true;
+		});
+
+		parser.hooks.expression.for(REQUIRE_BINDING_TAG).tap(PLUGIN_NAME, () => {
+			const binding =
+				/** @type {RequireBindingData} */
+				(parser.currentTagData);
+			if (binding && binding.dep) {
+				// `NAME` is read as a value (not as the object of a static member
+				// chain), so we have to assume the whole exports object is used.
+				binding.dep.referencedExports = null;
+			}
+		});
+
+		parser.hooks.expressionMemberChain
+			.for(REQUIRE_BINDING_TAG)
+			.tap(PLUGIN_NAME, (_expr, members) => {
+				const binding =
+					/** @type {RequireBindingData} */
+					(parser.currentTagData);
+				if (binding && binding.dep && binding.dep.referencedExports) {
+					binding.dep.referencedExports.push(members);
+				}
+				// Returning truthy suppresses the parser's fallback chain (which
+				// would otherwise walk `NAME` as a bare expression and trigger our
+				// `expression` hook above, marking the whole namespace as used).
+				return true;
+			});
+
+		parser.hooks.callMemberChain
+			.for(REQUIRE_BINDING_TAG)
+			.tap(PLUGIN_NAME, (expr, members) => {
+				const binding =
+					/** @type {RequireBindingData} */
+					(parser.currentTagData);
+				if (binding && binding.dep && binding.dep.referencedExports) {
+					if (members.length === 0) {
+						// `NAME(...)` — calling the require result directly; the
+						// whole exports object is observable.
+						binding.dep.referencedExports = null;
+					} else {
+						binding.dep.referencedExports.push(members);
+					}
+				}
+				if (expr.arguments) parser.walkExpressions(expr.arguments);
+				return true;
+			});
+		// #endregion
+
+		// #region Require.resolve
+		/**
+		 * Processes the provided expr.
+		 * @param {CallExpression} expr call expression
+		 * @param {boolean} weak weak
+		 * @returns {boolean | void} true when handled
+		 */
+		const processResolve = createProcessResolveHandler(
+			parser,
+			options,
+			getContext
+		);
+
+		parser.hooks.call
+			.for("require.resolve")
+			.tap(PLUGIN_NAME, (expr) => processResolve(expr, false));
+		parser.hooks.call
+			.for("require.resolveWeak")
+			.tap(PLUGIN_NAME, (expr) => processResolve(expr, true));
+		// #endregion
+	}
+}
+
+module.exports = CommonJsImportsParserPlugin;
+module.exports.createProcessResolveHandler = createProcessResolveHandler;
+module.exports.createRequireAsExpressionHandler =
+	createRequireAsExpressionHandler;
+module.exports.createRequireCacheDependency = createRequireCacheDependency;
+module.exports.createRequireHandler = createRequireCallHandler;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,319 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const SelfModuleFactory = require("../SelfModuleFactory");
+const Template = require("../Template");
+const {
+	evaluateToIdentifier,
+	expressionIsUnsupported,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
+const CommonJsExportsDependency = require("./CommonJsExportsDependency");
+const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin");
+const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
+const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
+const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
+const CommonJsRequireDependency = require("./CommonJsRequireDependency");
+const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
+const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
+const RequireHeaderDependency = require("./RequireHeaderDependency");
+const RequireResolveContextDependency = require("./RequireResolveContextDependency");
+const RequireResolveDependency = require("./RequireResolveDependency");
+const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
+const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+const PLUGIN_NAME = "CommonJsPlugin";
+
+class CommonJsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { contextModuleFactory, normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					CommonJsRequireDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CommonJsRequireDependency,
+					new CommonJsRequireDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					CommonJsFullRequireDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CommonJsFullRequireDependency,
+					new CommonJsFullRequireDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					CommonJsRequireContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CommonJsRequireContextDependency,
+					new CommonJsRequireContextDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					RequireResolveDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					RequireResolveDependency,
+					new RequireResolveDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					RequireResolveContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					RequireResolveContextDependency,
+					new RequireResolveContextDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					RequireResolveHeaderDependency,
+					new RequireResolveHeaderDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					RequireHeaderDependency,
+					new RequireHeaderDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					CommonJsExportsDependency,
+					new CommonJsExportsDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					CommonJsExportRequireDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					CommonJsExportRequireDependency,
+					new CommonJsExportRequireDependency.Template()
+				);
+
+				const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
+
+				compilation.dependencyFactories.set(
+					CommonJsSelfReferenceDependency,
+					selfFactory
+				);
+				compilation.dependencyTemplates.set(
+					CommonJsSelfReferenceDependency,
+					new CommonJsSelfReferenceDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					ModuleDecoratorDependency,
+					selfFactory
+				);
+				compilation.dependencyTemplates.set(
+					ModuleDecoratorDependency,
+					new ModuleDecoratorDependency.Template()
+				);
+
+				compilation.hooks.runtimeRequirementInModule
+					.for(RuntimeGlobals.harmonyModuleDecorator)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.module);
+						set.add(RuntimeGlobals.requireScope);
+					});
+
+				compilation.hooks.runtimeRequirementInModule
+					.for(RuntimeGlobals.nodeModuleDecorator)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.module);
+						set.add(RuntimeGlobals.requireScope);
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.harmonyModuleDecorator)
+					.tap(PLUGIN_NAME, (chunk, _set) => {
+						compilation.addRuntimeModule(
+							chunk,
+							new HarmonyModuleDecoratorRuntimeModule()
+						);
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.nodeModuleDecorator)
+					.tap(PLUGIN_NAME, (chunk, _set) => {
+						compilation.addRuntimeModule(
+							chunk,
+							new NodeModuleDecoratorRuntimeModule()
+						);
+					});
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (parserOptions.commonjs !== undefined && !parserOptions.commonjs) {
+						return;
+					}
+					parser.hooks.typeof
+						.for("module")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("object"))
+						);
+
+					parser.hooks.expression
+						.for("require.main")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(
+								parser,
+								`${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`,
+								[RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId]
+							)
+						);
+
+					parser.hooks.expression
+						.for("require.extensions")
+						.tap(
+							PLUGIN_NAME,
+							expressionIsUnsupported(
+								parser,
+								"require.extensions is not supported by webpack. Use a loader instead."
+							)
+						);
+
+					parser.hooks.expression
+						.for(RuntimeGlobals.moduleLoaded)
+						.tap(PLUGIN_NAME, (expr) => {
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).moduleConcatenationBailout =
+								RuntimeGlobals.moduleLoaded;
+							const dep = new RuntimeRequirementsDependency([
+								RuntimeGlobals.moduleLoaded
+							]);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+
+					parser.hooks.expression
+						.for(RuntimeGlobals.moduleId)
+						.tap(PLUGIN_NAME, (expr) => {
+							/** @type {BuildInfo} */
+							(parser.state.module.buildInfo).moduleConcatenationBailout =
+								RuntimeGlobals.moduleId;
+							const dep = new RuntimeRequirementsDependency([
+								RuntimeGlobals.moduleId
+							]);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+
+					parser.hooks.evaluateIdentifier.for("module.hot").tap(
+						PLUGIN_NAME,
+						evaluateToIdentifier("module.hot", "module", () => ["hot"], null)
+					);
+
+					new CommonJsImportsParserPlugin(parserOptions).apply(parser);
+					new CommonJsExportsParserPlugin(compilation.moduleGraph).apply(
+						parser
+					);
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("harmony module decorator");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation);
+		return Template.asString([
+			`${
+				RuntimeGlobals.harmonyModuleDecorator
+			} = ${runtimeTemplate.basicFunction("module", [
+				"module = Object.create(module);",
+				"if (!module.children) module.children = [];",
+				"Object.defineProperty(module, 'exports', {",
+				Template.indent([
+					"enumerable: true,",
+					`set: ${runtimeTemplate.basicFunction("", [
+						"throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);"
+					])}`
+				]),
+				"});",
+				"return module;"
+			])};`
+		]);
+	}
+}
+
+class NodeModuleDecoratorRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("node module decorator");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation);
+		return Template.asString([
+			`${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction(
+				"module",
+				[
+					"module.paths = [];",
+					"if (!module.children) module.children = [];",
+					"return module;"
+				]
+			)};`
+		]);
+	}
+}
+
+module.exports = CommonJsPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsRequireContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsRequireContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsRequireContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,97 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class CommonJsRequireContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of CommonJsRequireContextDependency.
+	 * @param {ContextDependencyOptions} options options for the context module
+	 * @param {Range} range location in source code
+	 * @param {Range=} valueRange location of the require call
+	 * @param {boolean | string=} inShorthand true or name
+	 * @param {string=} context context
+	 */
+	constructor(options, range, valueRange, inShorthand, context) {
+		super(options, context);
+
+		this.range = range;
+		this.valueRange = valueRange;
+		// inShorthand must be serialized by subclasses that use it
+		this.inShorthand = inShorthand;
+	}
+
+	get type() {
+		return "cjs require context";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		if (!this.options.referencedExports) {
+			return Dependency.EXPORTS_OBJECT_REFERENCED;
+		}
+		return this.options.referencedExports.map((name) => ({
+			name,
+			canMangle: false
+		}));
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.range);
+		write(this.valueRange);
+		write(this.inShorthand);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.range = read();
+		this.valueRange = read();
+		this.inShorthand = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	CommonJsRequireContextDependency,
+	"webpack/lib/dependencies/CommonJsRequireContextDependency"
+);
+
+CommonJsRequireContextDependency.Template =
+	ContextDependencyTemplateAsRequireCall;
+
+module.exports = CommonJsRequireContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsRequireDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsRequireDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,149 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+const {
+	ESM_MODULE_EXPORTS_NAME,
+	getRequireEsmModuleExportsAccess,
+	isRequireEsmModuleExportsModule
+} = require("./CommonJsDependencyHelpers");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class CommonJsRequireDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of CommonJsRequireDependency.
+	 * @param {string} request request
+	 * @param {Range=} range location in source code of the string-literal argument (gets replaced by the module id)
+	 * @param {string=} context request context
+	 * @param {RawReferencedExports | null=} referencedExports list of referenced exports
+	 * @param {Range=} valueRange location in source code of the whole `require(...)` call (for `require(esm)` interop)
+	 */
+	constructor(
+		request,
+		range,
+		context,
+		referencedExports = null,
+		valueRange = undefined
+	) {
+		super(request);
+		this.range = range;
+		this._context = context;
+		this.referencedExports = referencedExports;
+		this.valueRange = valueRange;
+	}
+
+	get type() {
+		return "cjs require";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		const importedModule = moduleGraph.getModule(this);
+		if (
+			importedModule &&
+			isRequireEsmModuleExportsModule(importedModule, moduleGraph)
+		) {
+			// `require(esm)` will unwrap the "module.exports" named export; only
+			// that export is observable through this `require()` call.
+			return [[ESM_MODULE_EXPORTS_NAME]];
+		}
+		if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
+		return this.referencedExports.map((name) => ({
+			name,
+			canMangle: false
+		}));
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.referencedExports);
+		write(this.valueRange);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.referencedExports = read();
+		this.valueRange = read();
+		super.deserialize(context);
+	}
+}
+
+CommonJsRequireDependency.Template = class CommonJsRequireDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtime }
+	) {
+		const dep = /** @type {CommonJsRequireDependency} */ (dependency);
+		if (!dep.range) return;
+		const importedModule = /** @type {Module} */ (moduleGraph.getModule(dep));
+		const content = runtimeTemplate.moduleId({
+			module: importedModule,
+			chunkGraph,
+			request: dep.request,
+			weak: dep.weak
+		});
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+
+		if (dep.valueRange && importedModule) {
+			const access = getRequireEsmModuleExportsAccess(
+				importedModule,
+				moduleGraph,
+				runtime
+			);
+			if (access !== null) {
+				source.insert(dep.valueRange[1], access);
+			}
+		}
+	}
+};
+
+makeSerializable(
+	CommonJsRequireDependency,
+	"webpack/lib/dependencies/CommonJsRequireDependency"
+);
+
+module.exports = CommonJsRequireDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CommonJsSelfReferenceDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CommonJsSelfReferenceDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CommonJsSelfReferenceDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,161 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const { equals } = require("../util/ArrayHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess } = require("../util/property");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */
+
+class CommonJsSelfReferenceDependency extends NullDependency {
+	/**
+	 * Creates an instance of CommonJsSelfReferenceDependency.
+	 * @param {Range} range range
+	 * @param {CommonJSDependencyBaseKeywords} base base
+	 * @param {ExportInfoName[]} names names
+	 * @param {boolean} call is a call
+	 */
+	constructor(range, base, names, call) {
+		super();
+		this.range = range;
+		this.base = base;
+		this.names = names;
+		this.call = call;
+	}
+
+	get type() {
+		return "cjs self exports reference";
+	}
+
+	get category() {
+		return "self";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return "self";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return [this.call ? this.names.slice(0, -1) : this.names];
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.base);
+		write(this.names);
+		write(this.call);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.base = read();
+		this.names = read();
+		this.call = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	CommonJsSelfReferenceDependency,
+	"webpack/lib/dependencies/CommonJsSelfReferenceDependency"
+);
+
+CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ module, moduleGraph, runtime, runtimeRequirements }
+	) {
+		const dep = /** @type {CommonJsSelfReferenceDependency} */ (dependency);
+		const used =
+			dep.names.length === 0
+				? dep.names
+				: moduleGraph.getExportsInfo(module).getUsedName(dep.names, runtime);
+		if (!used) {
+			throw new Error(
+				"Self-reference dependency has unused export name: This should not happen"
+			);
+		}
+
+		/** @type {string} */
+		let base;
+		switch (dep.base) {
+			case "exports":
+				runtimeRequirements.add(RuntimeGlobals.exports);
+				base = module.exportsArgument;
+				break;
+			case "module.exports":
+				runtimeRequirements.add(RuntimeGlobals.module);
+				base = `${module.moduleArgument}.exports`;
+				break;
+			case "this":
+				runtimeRequirements.add(RuntimeGlobals.thisAsExports);
+				base = "this";
+				break;
+			default:
+				throw new Error(`Unsupported base ${dep.base}`);
+		}
+
+		if (base === dep.base && equals(used, dep.names)) {
+			// Nothing has to be changed
+			// We don't use a replacement for compat reasons
+			// for plugins that update `module._source` which they
+			// shouldn't do!
+			return;
+		}
+
+		source.replace(
+			dep.range[0],
+			dep.range[1] - 1,
+			`${base}${propertyAccess(used)}`
+		);
+	}
+};
+
+module.exports = CommonJsSelfReferenceDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ConstDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ConstDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ConstDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,123 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("./NullDependency").RawRuntimeRequirements} RawRuntimeRequirements */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+class ConstDependency extends NullDependency {
+	/**
+	 * Creates an instance of ConstDependency.
+	 * @param {string} expression the expression
+	 * @param {number | Range} range the source range
+	 * @param {RawRuntimeRequirements | null=} runtimeRequirements runtime requirements
+	 */
+	constructor(expression, range, runtimeRequirements) {
+		super();
+		this.expression = expression;
+		this.range = range;
+		this.runtimeRequirements = runtimeRequirements
+			? new Set(runtimeRequirements)
+			: null;
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			let hashUpdate = `${this.range}|${this.expression}`;
+			if (this.runtimeRequirements) {
+				for (const item of this.runtimeRequirements) {
+					hashUpdate += "|";
+					hashUpdate += item;
+				}
+			}
+			this._hashUpdate = hashUpdate;
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		return false;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.expression);
+		write(this.range);
+		write(this.runtimeRequirements);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.expression = read();
+		this.range = read();
+		this.runtimeRequirements = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ConstDependency, "webpack/lib/dependencies/ConstDependency");
+
+ConstDependency.Template = class ConstDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {ConstDependency} */ (dependency);
+		if (dep.runtimeRequirements) {
+			for (const req of dep.runtimeRequirements) {
+				templateContext.runtimeRequirements.add(req);
+			}
+		}
+		if (typeof dep.range === "number") {
+			source.insert(dep.range, dep.expression);
+			return;
+		}
+
+		source.replace(dep.range[0], dep.range[1] - 1, dep.expression);
+	}
+};
+
+module.exports = ConstDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,190 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const DependencyTemplate = require("../DependencyTemplate");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../ContextModule").ContextOptions} ContextOptions */
+/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+const getCriticalDependencyWarning = memoize(() =>
+	require("./CriticalDependencyWarning")
+);
+
+/** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */
+
+/** @typedef {{ value: string, range: Range }[]} Replaces */
+
+/**
+ * Returns stringified regexp.
+ * @param {RegExp | false | null | undefined} r regexp
+ * @returns {string} stringified regexp
+ */
+const regExpToString = (r) => (r ? String(r) : "");
+
+class ContextDependency extends Dependency {
+	/**
+	 * Creates an instance of ContextDependency.
+	 * @param {ContextDependencyOptions} options options for the context module
+	 * @param {string=} context request context
+	 */
+	constructor(options, context) {
+		super();
+
+		this.options = options;
+		this.userRequest = this.options && this.options.request;
+		/** @type {false | undefined | string} */
+		this.critical = false;
+		this.hadGlobalOrStickyRegExp = false;
+
+		if (
+			this.options &&
+			this.options.regExp &&
+			(this.options.regExp.global || this.options.regExp.sticky)
+		) {
+			this.options = { ...this.options, regExp: null };
+			this.hadGlobalOrStickyRegExp = true;
+		}
+
+		/** @type {string | undefined} */
+		this.request = undefined;
+		/** @type {Range | undefined} */
+		this.range = undefined;
+		/** @type {Range | undefined} */
+		this.valueRange = undefined;
+		/** @type {boolean | string | undefined} */
+		this.inShorthand = undefined;
+		/** @type {Replaces | undefined} */
+		this.replaces = undefined;
+		this._requestContext = context;
+	}
+
+	/**
+	 * Returns a request context.
+	 * @returns {string | undefined} a request context
+	 */
+	getContext() {
+		return this._requestContext;
+	}
+
+	get category() {
+		return "commonjs";
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return true;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return (
+			`context${this._requestContext || ""}|ctx request${
+				this.options.request
+			} ${this.options.recursive} ` +
+			`${regExpToString(this.options.regExp)} ${regExpToString(
+				this.options.include
+			)} ${regExpToString(this.options.exclude)} ` +
+			`${this.options.mode} ${this.options.chunkName} ` +
+			`${JSON.stringify(this.options.groupOptions)}` +
+			`${
+				this.options.referencedExports
+					? ` ${JSON.stringify(this.options.referencedExports)}`
+					: ""
+			}`
+		);
+	}
+
+	/**
+	 * Returns warnings.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} warnings
+	 */
+	getWarnings(moduleGraph) {
+		let warnings = super.getWarnings(moduleGraph);
+
+		if (this.critical) {
+			if (!warnings) warnings = [];
+			const CriticalDependencyWarning = getCriticalDependencyWarning();
+			warnings.push(new CriticalDependencyWarning(this.critical));
+		}
+
+		if (this.hadGlobalOrStickyRegExp) {
+			if (!warnings) warnings = [];
+			const CriticalDependencyWarning = getCriticalDependencyWarning();
+			warnings.push(
+				new CriticalDependencyWarning(
+					"Contexts can't use RegExps with the 'g' or 'y' flags."
+				)
+			);
+		}
+
+		return warnings;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.options);
+		write(this.userRequest);
+		write(this.critical);
+		write(this.hadGlobalOrStickyRegExp);
+		write(this.request);
+		write(this._requestContext);
+		write(this.range);
+		write(this.valueRange);
+		write(this.replaces);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.options = read();
+		this.userRequest = read();
+		this.critical = read();
+		this.hadGlobalOrStickyRegExp = read();
+		this.request = read();
+		this._requestContext = read();
+		this.range = read();
+		this.valueRange = read();
+		this.replaces = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ContextDependency,
+	"webpack/lib/dependencies/ContextDependency"
+);
+
+ContextDependency.Template = DependencyTemplate;
+
+module.exports = ContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ContextDependencyHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ContextDependencyHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ContextDependencyHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,280 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { parseResource } = require("../util/identifier");
+
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./ContextDependency")} ContextDependency */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+/** @typedef {import("./ContextDependency").Replaces} Replaces */
+
+/**
+ * Escapes regular expression metacharacters
+ * @param {string} str String to quote
+ * @returns {string} Escaped string
+ */
+const quoteMeta = (str) => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
+
+/**
+ * Split context from prefix.
+ * @param {string} prefix prefix
+ * @returns {{ prefix: string, context: string }} result
+ */
+const splitContextFromPrefix = (prefix) => {
+	const idx = prefix.lastIndexOf("/");
+	let context = ".";
+	if (idx >= 0) {
+		context = prefix.slice(0, idx);
+		prefix = `.${prefix.slice(idx)}`;
+	}
+	return {
+		context,
+		prefix
+	};
+};
+
+/** @typedef {Partial<Omit<ContextDependencyOptions, "resource">>} PartialContextDependencyOptions */
+/** @typedef {{ new (options: ContextDependencyOptions, range: Range, valueRange: Range, ...args: EXPECTED_ANY[]): ContextDependency }} ContextDependencyConstructor */
+
+/**
+ * Defines the get additional dep args type used by this module.
+ * @template T
+ * @typedef {T extends new (options: ContextDependencyOptions, range: Range, valueRange: Range, ...remains: infer R) => ContextDependency ? R : []} GetAdditionalDepArgs
+ */
+
+/**
+ * Returns the created Dependency.
+ * @template {ContextDependencyConstructor} T
+ * @param {T} Dep the Dependency class
+ * @param {Range} range source range
+ * @param {BasicEvaluatedExpression} param context param
+ * @param {Expression} expr expr
+ * @param {Pick<JavascriptParserOptions, `${"expr" | "wrapped"}Context${"Critical" | "Recursive" | "RegExp"}` | "exprContextRequest">} options options for context creation
+ * @param {PartialContextDependencyOptions} contextOptions options for the ContextModule
+ * @param {JavascriptParser} parser the parser
+ * @param {GetAdditionalDepArgs<T>} depArgs depArgs
+ * @returns {ContextDependency} the created Dependency
+ */
+module.exports.create = (
+	Dep,
+	range,
+	param,
+	expr,
+	options,
+	contextOptions,
+	parser,
+	...depArgs
+) => {
+	if (param.isTemplateString()) {
+		const quasis = /** @type {BasicEvaluatedExpression[]} */ (param.quasis);
+		const prefixRaw = /** @type {string} */ (quasis[0].string);
+		const postfixRaw =
+			/** @type {string} */
+			(quasis.length > 1 ? quasis[quasis.length - 1].string : "");
+
+		const valueRange = /** @type {Range} */ (param.range);
+		const { context, prefix } = splitContextFromPrefix(prefixRaw);
+		const {
+			path: postfix,
+			query,
+			fragment
+		} = parseResource(postfixRaw, parser);
+
+		// When there are more than two quasis, the generated RegExp can be more precise
+		// We join the quasis with the expression regexp
+		const innerQuasis = quasis.slice(1, -1);
+		const innerRegExp =
+			/** @type {RegExp} */ (options.wrappedContextRegExp).source +
+			innerQuasis
+				.map(
+					(q) =>
+						quoteMeta(/** @type {string} */ (q.string)) +
+						/** @type {RegExp} */ (options.wrappedContextRegExp).source
+				)
+				.join("");
+
+		// Example: `./context/pre${e}inner${e}inner2${e}post?query#frag`
+		// context: "./context"
+		// prefix: "./pre"
+		// innerQuasis: [BEE("inner"), BEE("inner2")]
+		// (BEE = BasicEvaluatedExpression)
+		// postfix: "post"
+		// query: "?query"
+		// fragment: "#frag"
+		// regExp: /^\.\/pre.*inner.*inner2.*post$/
+		const regExp = new RegExp(
+			`^${quoteMeta(prefix)}${innerRegExp}${quoteMeta(postfix)}$`
+		);
+		const dep = new Dep(
+			{
+				request: context + query + fragment,
+				recursive: /** @type {boolean} */ (options.wrappedContextRecursive),
+				regExp,
+				mode: "sync",
+				...contextOptions
+			},
+			range,
+			valueRange,
+			...depArgs
+		);
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+
+		/** @type {Replaces} */
+		const replaces = [];
+		const parts = /** @type {BasicEvaluatedExpression[]} */ (param.parts);
+
+		for (const [i, part] of parts.entries()) {
+			if (i % 2 === 0) {
+				// Quasis or merged quasi
+				let range = /** @type {Range} */ (part.range);
+				let value = /** @type {string} */ (part.string);
+				if (param.templateStringKind === "cooked") {
+					value = JSON.stringify(value);
+					value = value.slice(1, -1);
+				}
+				if (i === 0) {
+					// prefix
+					value = prefix;
+					range = [
+						/** @type {Range} */ (param.range)[0],
+						/** @type {Range} */ (part.range)[1]
+					];
+					value =
+						(param.templateStringKind === "cooked" ? "`" : "String.raw`") +
+						value;
+				} else if (i === parts.length - 1) {
+					// postfix
+					value = postfix;
+					range = [
+						/** @type {Range} */ (part.range)[0],
+						/** @type {Range} */ (param.range)[1]
+					];
+					value = `${value}\``;
+				} else if (
+					part.expression &&
+					part.expression.type === "TemplateElement" &&
+					part.expression.value.raw === value
+				) {
+					// Shortcut when it's a single quasi and doesn't need to be replaced
+					continue;
+				}
+				replaces.push({
+					range,
+					value
+				});
+			} else {
+				// Expression
+				parser.walkExpression(
+					/** @type {Expression} */
+					(part.expression)
+				);
+			}
+		}
+
+		dep.replaces = replaces;
+		dep.critical =
+			options.wrappedContextCritical &&
+			"a part of the request of a dependency is an expression";
+		return dep;
+	} else if (
+		param.isWrapped() &&
+		((param.prefix && param.prefix.isString()) ||
+			(param.postfix && param.postfix.isString()))
+	) {
+		const prefixRaw =
+			/** @type {string} */
+			(param.prefix && param.prefix.isString() ? param.prefix.string : "");
+		const postfixRaw =
+			/** @type {string} */
+			(param.postfix && param.postfix.isString() ? param.postfix.string : "");
+		const prefixRange =
+			param.prefix && param.prefix.isString() ? param.prefix.range : null;
+		const postfixRange =
+			param.postfix && param.postfix.isString() ? param.postfix.range : null;
+		const valueRange = /** @type {Range} */ (param.range);
+		const { context, prefix } = splitContextFromPrefix(prefixRaw);
+		const {
+			path: postfix,
+			query,
+			fragment
+		} = parseResource(postfixRaw, parser);
+		const regExp = new RegExp(
+			`^${quoteMeta(prefix)}${
+				/** @type {RegExp} */ (options.wrappedContextRegExp).source
+			}${quoteMeta(postfix)}$`
+		);
+		const dep = new Dep(
+			{
+				request: context + query + fragment,
+				recursive: /** @type {boolean} */ (options.wrappedContextRecursive),
+				regExp,
+				mode: "sync",
+				...contextOptions
+			},
+			range,
+			valueRange,
+			...depArgs
+		);
+		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+		/** @type {Replaces} */
+		const replaces = [];
+		if (prefixRange) {
+			replaces.push({
+				range: prefixRange,
+				value: JSON.stringify(prefix)
+			});
+		}
+		if (postfixRange) {
+			replaces.push({
+				range: postfixRange,
+				value: JSON.stringify(postfix)
+			});
+		}
+		dep.replaces = replaces;
+		dep.critical =
+			options.wrappedContextCritical &&
+			"a part of the request of a dependency is an expression";
+
+		if (parser && param.wrappedInnerExpressions) {
+			for (const part of param.wrappedInnerExpressions) {
+				if (part.expression) {
+					parser.walkExpression(
+						/** @type {Expression} */
+						(part.expression)
+					);
+				}
+			}
+		}
+
+		return dep;
+	}
+	const dep = new Dep(
+		{
+			request: /** @type {string} */ (options.exprContextRequest),
+			recursive: /** @type {boolean} */ (options.exprContextRecursive),
+			regExp: /** @type {RegExp} */ (options.exprContextRegExp),
+			mode: "sync",
+			...contextOptions
+		},
+		range,
+		/** @type {Range} */ (param.range),
+		...depArgs
+	);
+	dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+	dep.critical =
+		options.exprContextCritical &&
+		"the request of a dependency is an expression";
+
+	parser.walkExpression(/** @type {Expression} */ (param.expression));
+
+	return dep;
+};
Index: frontend/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsId.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,64 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ContextDependency = require("./ContextDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+
+class ContextDependencyTemplateAsId extends ContextDependency.Template {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {ContextDependency} */ (dependency);
+		const module = moduleGraph.getModule(dep);
+		const moduleExports = runtimeTemplate.moduleExports({
+			module,
+			chunkGraph,
+			request: /** @type {string} */ (dep.request),
+			weak: dep.weak,
+			runtimeRequirements
+		});
+
+		const range = /** @type {Range} */ (dep.range);
+
+		if (module) {
+			if (dep.valueRange) {
+				if (Array.isArray(dep.replaces)) {
+					for (let i = 0; i < dep.replaces.length; i++) {
+						const rep = dep.replaces[i];
+						source.replace(rep.range[0], rep.range[1] - 1, rep.value);
+					}
+				}
+
+				source.replace(dep.valueRange[1], range[1] - 1, ")");
+				source.replace(
+					range[0],
+					dep.valueRange[0] - 1,
+					`${moduleExports}.resolve(`
+				);
+			} else {
+				source.replace(range[0], range[1] - 1, `${moduleExports}.resolve`);
+			}
+		} else {
+			source.replace(range[0], range[1] - 1, moduleExports);
+		}
+	}
+}
+
+module.exports = ContextDependencyTemplateAsId;
Index: frontend/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsRequireCall.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsRequireCall.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsRequireCall.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,63 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ContextDependency = require("./ContextDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+
+class ContextDependencyTemplateAsRequireCall
+	extends ContextDependency.Template
+{
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {ContextDependency} */ (dependency);
+		let moduleExports = runtimeTemplate.moduleExports({
+			module: moduleGraph.getModule(dep),
+			chunkGraph,
+			request: /** @type {string} */ (dep.request),
+			runtimeRequirements
+		});
+
+		if (dep.inShorthand) {
+			moduleExports = `${dep.inShorthand}: ${moduleExports}`;
+		}
+
+		const range = /** @type {Range} */ (dep.range);
+
+		if (moduleGraph.getModule(dep)) {
+			if (dep.valueRange) {
+				if (Array.isArray(dep.replaces)) {
+					for (let i = 0; i < dep.replaces.length; i++) {
+						const rep = dep.replaces[i];
+						source.replace(rep.range[0], rep.range[1] - 1, rep.value);
+					}
+				}
+				source.replace(dep.valueRange[1], range[1] - 1, ")");
+				source.replace(range[0], dep.valueRange[0] - 1, `${moduleExports}(`);
+			} else {
+				source.replace(range[0], range[1] - 1, moduleExports);
+			}
+		} else {
+			source.replace(range[0], range[1] - 1, moduleExports);
+		}
+	}
+}
+
+module.exports = ContextDependencyTemplateAsRequireCall;
Index: frontend/node_modules/webpack/lib/dependencies/ContextElementDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ContextElementDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ContextElementDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,151 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("../ContextModule")} ContextModule */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class ContextElementDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ContextElementDependency.
+	 * @param {string} request request
+	 * @param {string | undefined} userRequest user request
+	 * @param {string | undefined} typePrefix type prefix
+	 * @param {string} category category
+	 * @param {RawReferencedExports | null=} referencedExports referenced exports
+	 * @param {string=} context context
+	 * @param {ImportAttributes=} attributes import assertions
+	 */
+	constructor(
+		request,
+		userRequest,
+		typePrefix,
+		category,
+		referencedExports,
+		context,
+		attributes
+	) {
+		super(request);
+
+		if (userRequest) {
+			this.userRequest = userRequest;
+		}
+
+		this._typePrefix = typePrefix;
+		this._category = category;
+		this.referencedExports = referencedExports;
+		this._context = context || undefined;
+		this.attributes = attributes;
+	}
+
+	get type() {
+		if (this._typePrefix) {
+			return `${this._typePrefix} context element`;
+		}
+
+		return "context element";
+	}
+
+	get category() {
+		return this._category;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		let str = super.getResourceIdentifier();
+		if (this.attributes) {
+			str += `|attributes${JSON.stringify(this.attributes)}`;
+		}
+		return str;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
+		/** @type {ReferencedExports} */
+		const refs = [];
+		for (const referencedExport of this.referencedExports) {
+			if (
+				this._typePrefix === "import()" &&
+				referencedExport[0] === "default"
+			) {
+				const selfModule =
+					/** @type {ContextModule} */
+					(moduleGraph.getParentModule(this));
+				const importedModule =
+					/** @type {Module} */
+					(moduleGraph.getModule(this));
+				const exportsType = importedModule.getExportsType(
+					moduleGraph,
+					selfModule.options.namespaceObject === "strict"
+				);
+				if (
+					exportsType === "default-only" ||
+					exportsType === "default-with-named"
+				) {
+					return Dependency.EXPORTS_OBJECT_REFERENCED;
+				}
+			}
+			refs.push({
+				name: referencedExport,
+				canMangle: false
+			});
+		}
+		return refs;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this._typePrefix);
+		write(this._category);
+		write(this.referencedExports);
+		write(this.attributes);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this._typePrefix = read();
+		this._category = read();
+		this.referencedExports = read();
+		this.attributes = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ContextElementDependency,
+	"webpack/lib/dependencies/ContextElementDependency"
+);
+
+module.exports = ContextElementDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CreateRequireParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CreateRequireParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CreateRequireParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,362 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { fileURLToPath } = require("url");
+const WebpackError = require("../errors/WebpackError");
+const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
+const { VariableInfo } = require("../javascript/JavascriptParser");
+const {
+	evaluateToString,
+	expressionIsUnsupported,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
+const ConstDependency = require("./ConstDependency");
+
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+/**
+ * Defines the common js import settings type used by this module.
+ * @typedef {object} CommonJsImportSettings
+ * @property {string=} name
+ * @property {string} context
+ */
+
+const createRequireSpecifierTag = Symbol("createRequire");
+const createdRequireIdentifierTag = Symbol("createRequire()");
+
+const PLUGIN_NAME = "CreateRequireParserPlugin";
+
+const {
+	createProcessResolveHandler,
+	createRequireAsExpressionHandler,
+	createRequireCacheDependency,
+	createRequireHandler
+} = CommonJsImportsParserPlugin;
+
+class CreateRequireParserPlugin {
+	/**
+	 * Creates an instance of CreateRequireParserPlugin.
+	 * @param {JavascriptParserOptions} options parser options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const options = this.options;
+		if (!options.createRequire) return;
+
+		const getContext = () => {
+			if (parser.currentTagData) {
+				const { context } =
+					/** @type {CommonJsImportSettings} */
+					(parser.currentTagData);
+				return context;
+			}
+		};
+
+		/**
+		 * Tap require expression tag.
+		 * @param {string | symbol} tag tag
+		 */
+		const tapRequireExpressionTag = (tag) => {
+			parser.hooks.typeof
+				.for(tag)
+				.tap(
+					PLUGIN_NAME,
+					toConstantDependency(parser, JSON.stringify("function"))
+				);
+			parser.hooks.evaluateTypeof
+				.for(tag)
+				.tap(PLUGIN_NAME, evaluateToString("function"));
+		};
+
+		/**
+		 * Returns true when set undefined.
+		 * @param {Expression} expr expression
+		 * @returns {boolean} true when set undefined
+		 */
+		const defineUndefined = (expr) => {
+			const dep = new ConstDependency(
+				"undefined",
+				/** @type {Range} */ (expr.range)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.module.addPresentationalDependency(dep);
+			return false;
+		};
+
+		const requireCache = createRequireCacheDependency(parser);
+		const requireAsExpressionHandler = createRequireAsExpressionHandler(
+			parser,
+			options,
+			getContext
+		);
+		const createRequireCallHandler = createRequireHandler(
+			parser,
+			options,
+			getContext
+		);
+		const processResolve = createProcessResolveHandler(
+			parser,
+			options,
+			getContext
+		);
+
+		/** @type {ImportSource[]} */
+		let moduleNames = [];
+		/** @type {string | undefined} */
+		let specifierName;
+
+		if (options.createRequire === true) {
+			moduleNames = ["module", "node:module"];
+			specifierName = "createRequire";
+		} else if (typeof options.createRequire === "string") {
+			/** @type {undefined | string} */
+			let parsedModuleName;
+			const match = /^(.*) from (.*)$/.exec(options.createRequire);
+			if (match) {
+				[, specifierName, parsedModuleName] = match;
+			}
+			if (!specifierName || !parsedModuleName) {
+				const err = new WebpackError(
+					`Parsing javascript parser option "createRequire" failed, got ${JSON.stringify(
+						options.createRequire
+					)}`
+				);
+				err.details =
+					'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module';
+				throw err;
+			}
+			moduleNames = [parsedModuleName];
+		} else {
+			return;
+		}
+
+		/**
+		 * Parses create require arguments.
+		 * @param {CallExpression} expr call expression
+		 * @returns {string | void} context
+		 */
+		const parseCreateRequireArguments = (expr) => {
+			const args = expr.arguments;
+			if (args.length !== 1) {
+				const err = new WebpackError(
+					"module.createRequire supports only one argument."
+				);
+				err.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addWarning(err);
+				return;
+			}
+			const arg = args[0];
+			const evaluated = parser.evaluateExpression(arg);
+			if (!evaluated.isString()) {
+				const err = new WebpackError(
+					"module.createRequire failed parsing argument."
+				);
+				err.loc = /** @type {DependencyLocation} */ (arg.loc);
+				parser.state.module.addWarning(err);
+				return;
+			}
+			const ctx = /** @type {string} */ (evaluated.string).startsWith("file://")
+				? fileURLToPath(/** @type {string} */ (evaluated.string))
+				: /** @type {string} */ (evaluated.string);
+			// argument always should be a filename
+			return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
+		};
+
+		tapRequireExpressionTag(createdRequireIdentifierTag);
+		tapRequireExpressionTag(createRequireSpecifierTag);
+
+		parser.hooks.evaluateCallExpression
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, (expr) => {
+				const context = parseCreateRequireArguments(expr);
+				if (context === undefined) return;
+				const ident = parser.evaluatedVariable({
+					tag: createdRequireIdentifierTag,
+					data: { context },
+					next: undefined
+				});
+
+				return new BasicEvaluatedExpression()
+					.setIdentifier(ident, ident, () => [])
+					.setSideEffects(false)
+					.setRange(/** @type {Range} */ (expr.range));
+			});
+
+		parser.hooks.unhandledExpressionMemberChain
+			.for(createdRequireIdentifierTag)
+			.tap(PLUGIN_NAME, (expr, members) =>
+				expressionIsUnsupported(
+					parser,
+					`createRequire().${members.join(".")} is not supported by webpack.`
+				)(expr)
+			);
+		parser.hooks.canRename
+			.for(createdRequireIdentifierTag)
+			.tap(PLUGIN_NAME, () => true);
+		parser.hooks.canRename
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, () => true);
+		parser.hooks.rename
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, defineUndefined);
+		parser.hooks.expression
+			.for(createdRequireIdentifierTag)
+			.tap(PLUGIN_NAME, requireAsExpressionHandler);
+		parser.hooks.call
+			.for(createdRequireIdentifierTag)
+			.tap(PLUGIN_NAME, createRequireCallHandler(false));
+
+		parser.hooks.import.tap(
+			{
+				name: PLUGIN_NAME,
+				stage: -10
+			},
+			(statement, source) => {
+				if (
+					!moduleNames.includes(source) ||
+					statement.specifiers.length !== 1 ||
+					statement.specifiers[0].type !== "ImportSpecifier" ||
+					statement.specifiers[0].imported.type !== "Identifier" ||
+					statement.specifiers[0].imported.name !== specifierName
+				) {
+					return;
+				}
+				// clear for 'import { createRequire as x } from "module"'
+				// if any other specifier was used import module
+				const clearDep = new ConstDependency(
+					parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
+						? ";"
+						: "",
+					/** @type {Range} */ (statement.range)
+				);
+				clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
+				parser.state.module.addPresentationalDependency(clearDep);
+				parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
+				return true;
+			}
+		);
+		parser.hooks.importSpecifier.tap(
+			{
+				name: PLUGIN_NAME,
+				stage: -10
+			},
+			(statement, source, id, name) => {
+				if (!moduleNames.includes(source) || id !== specifierName) return;
+				parser.tagVariable(name, createRequireSpecifierTag);
+				return true;
+			}
+		);
+		parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
+			if (
+				declarator.id.type !== "Identifier" ||
+				!declarator.init ||
+				declarator.init.type !== "CallExpression" ||
+				declarator.init.callee.type !== "Identifier"
+			) {
+				return;
+			}
+			const variableInfo = parser.getVariableInfo(declarator.init.callee.name);
+			if (
+				variableInfo instanceof VariableInfo &&
+				variableInfo.tagInfo &&
+				variableInfo.tagInfo.tag === createRequireSpecifierTag
+			) {
+				const context = parseCreateRequireArguments(declarator.init);
+				if (context === undefined) return;
+				parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, {
+					name: declarator.id.name,
+					context
+				});
+				return true;
+			}
+		});
+
+		parser.hooks.memberChainOfCallMemberChain
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, (expr, calleeMembers, callExpr, members) => {
+				if (
+					calleeMembers.length !== 0 ||
+					members.length !== 1 ||
+					members[0] !== "cache"
+				) {
+					return;
+				}
+				// createRequire().cache
+				const context = parseCreateRequireArguments(callExpr);
+				if (context === undefined) return;
+				return requireCache(expr);
+			});
+		parser.hooks.callMemberChainOfCallMemberChain
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, (expr, calleeMembers, innerCallExpression, members) => {
+				if (
+					calleeMembers.length !== 0 ||
+					members.length !== 1 ||
+					members[0] !== "resolve"
+				) {
+					return;
+				}
+				// createRequire().resolve()
+				return processResolve(expr, false);
+			});
+		parser.hooks.expressionMemberChain
+			.for(createdRequireIdentifierTag)
+			.tap(PLUGIN_NAME, (expr, members) => {
+				// require.cache
+				if (members.length === 1 && members[0] === "cache") {
+					return requireCache(expr);
+				}
+			});
+		parser.hooks.callMemberChain
+			.for(createdRequireIdentifierTag)
+			.tap(PLUGIN_NAME, (expr, members) => {
+				// require.resolve()
+				if (members.length === 1 && members[0] === "resolve") {
+					return processResolve(expr, false);
+				}
+			});
+		parser.hooks.expression
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, (expr) => {
+				const clearDep = new ConstDependency(
+					"/* createRequire */ undefined",
+					/** @type {Range} */ (expr.range)
+				);
+				clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addPresentationalDependency(clearDep);
+				return true;
+			});
+		parser.hooks.call
+			.for(createRequireSpecifierTag)
+			.tap(PLUGIN_NAME, (expr) => {
+				const clearDep = new ConstDependency(
+					"/* createRequire() */ undefined",
+					/** @type {Range} */ (expr.range)
+				);
+				clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addPresentationalDependency(clearDep);
+				return true;
+			});
+	}
+}
+
+module.exports = CreateRequireParserPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/CreateScriptUrlDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CreateScriptUrlDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CreateScriptUrlDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,79 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class CreateScriptUrlDependency extends NullDependency {
+	/**
+	 * Creates an instance of CreateScriptUrlDependency.
+	 * @param {Range} range range
+	 */
+	constructor(range) {
+		super();
+		this.range = range;
+	}
+
+	get type() {
+		return "create script url";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		super.deserialize(context);
+	}
+}
+
+CreateScriptUrlDependency.Template = class CreateScriptUrlDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeRequirements }) {
+		const dep = /** @type {CreateScriptUrlDependency} */ (dependency);
+
+		runtimeRequirements.add(RuntimeGlobals.createScriptUrl);
+
+		source.insert(dep.range[0], `${RuntimeGlobals.createScriptUrl}(`);
+		source.insert(dep.range[1], ")");
+	}
+};
+
+makeSerializable(
+	CreateScriptUrlDependency,
+	"webpack/lib/dependencies/CreateScriptUrlDependency"
+);
+
+module.exports = CreateScriptUrlDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CriticalDependencyWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CriticalDependencyWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CriticalDependencyWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const makeSerializable = require("../util/makeSerializable");
+
+class CriticalDependencyWarning extends WebpackError {
+	/**
+	 * Creates an instance of CriticalDependencyWarning.
+	 * @param {string} message message
+	 */
+	constructor(message) {
+		super();
+
+		/** @type {string} */
+		this.name = "CriticalDependencyWarning";
+		this.message = `Critical dependency: ${message}`;
+	}
+}
+
+makeSerializable(
+	CriticalDependencyWarning,
+	"webpack/lib/dependencies/CriticalDependencyWarning"
+);
+
+module.exports = CriticalDependencyWarning;
Index: frontend/node_modules/webpack/lib/dependencies/CssIcssExportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CssIcssExportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CssIcssExportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,935 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const { CSS_TYPE, JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
+const { interpolate } = require("../TemplatedPathPlugin");
+const WebpackError = require("../errors/WebpackError");
+const { cssExportConvention } = require("../util/conventions");
+const createHash = require("../util/createHash");
+const { makePathsRelative } = require("../util/identifier");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
+const { updateHashFromSource } = require("../util/source");
+const CssIcssImportDependency = require("./CssIcssImportDependency");
+const NullDependency = require("./NullDependency");
+
+const getCssParser = memoize(() => require("../css/CssParser"));
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
+/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */
+/** @typedef {import("../css/CssModule")} CssModule */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../css/CssGenerator")} CssGenerator */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation").ModulePathData} ModulePathData */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../css/CssParser").Range} Range */
+
+/** @typedef {(name: string) => string | string[]} ExportsConventionFn */
+
+/**
+ * Returns local ident.
+ * @param {string} local css local
+ * @param {CssModule} module module
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
+ * @returns {string} local ident
+ */
+const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
+	const generator = /** @type {CssGenerator} */ (module.generator);
+	const localIdentName =
+		/** @type {CssGeneratorLocalIdentName} */
+		(generator.options.localIdentName);
+	const relativeResourcePath = makePathsRelative(
+		/** @type {string} */
+		(runtimeTemplate.compilation.compiler.context),
+		/** @type {string} */
+		(module.getResource()),
+		runtimeTemplate.compilation.compiler.root
+	);
+	const { uniqueName } = runtimeTemplate.outputOptions;
+
+	let localIdentHash = "";
+
+	if (
+		typeof localIdentName === "function" ||
+		/\[(?:fullhash|hash)\]/.test(localIdentName)
+	) {
+		const hashSalt = generator.options.localIdentHashSalt;
+		const hashDigest =
+			/** @type {string} */
+			(generator.options.localIdentHashDigest);
+		const hashDigestLength = generator.options.localIdentHashDigestLength;
+		const hashFunction =
+			/** @type {HashFunction} */
+			(generator.options.localIdentHashFunction);
+
+		const hash = createHash(hashFunction);
+
+		if (hashSalt) {
+			hash.update(hashSalt);
+		}
+
+		if (uniqueName) {
+			hash.update(uniqueName);
+		}
+
+		hash.update(relativeResourcePath);
+		hash.update(local);
+
+		localIdentHash = hash.digest(hashDigest).slice(0, hashDigestLength);
+	}
+
+	let contentHash = "";
+
+	if (
+		typeof localIdentName === "function" ||
+		/\[contenthash\]/.test(localIdentName)
+	) {
+		const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
+		const source = module.originalSource();
+
+		if (source) {
+			updateHashFromSource(hash, source);
+		}
+
+		if (module.error) {
+			hash.update(module.error.toString());
+		}
+
+		const fullContentHash = hash.digest(
+			runtimeTemplate.outputOptions.hashDigest
+		);
+
+		contentHash = nonNumericOnlyHash(
+			fullContentHash,
+			runtimeTemplate.outputOptions.hashDigestLength
+		);
+	}
+
+	let localIdent = interpolate(localIdentName, {
+		prepareId: (id) => {
+			if (typeof id !== "string") return id;
+
+			return (
+				id
+					.replace(/^([.-]|[^a-z0-9_-])+/i, "")
+					// We keep the `@` symbol because it can be used in the package name (e.g. `@company/package`), and if we replace it with `_`, a class conflict may occur.
+					// For example - `@import "@foo/package/style.module.css"` and `@import "foo/package/style.module.css"` (`foo` is a package, `package` is just a directory) will create a class conflict.
+					.replace(/[^a-z0-9@_-]+/gi, "_")
+			);
+		},
+		filename: relativeResourcePath,
+		hash: localIdentHash,
+		local,
+		contentHash,
+		chunkGraph,
+		module
+	});
+
+	// TODO move these things into interpolate
+	if (/\[local\]/.test(localIdent)) {
+		localIdent = localIdent.replace(/\[local\]/g, local);
+	}
+
+	if (/\[uniqueName\]/.test(localIdent)) {
+		localIdent = localIdent.replace(
+			/\[uniqueName\]/g,
+			/** @type {string} */ (uniqueName)
+		);
+	}
+
+	// Protect the first character from unsupported values
+	return localIdent.replace(/^((-?\d)|--)/, "_$1");
+};
+
+/** @typedef {string | [string, string] | [string, string, string]} Value */
+
+// 0 - replace, 1 - replace, 2 - append,  2 - once
+/** @typedef {0 | 1 | 2 | 3 | 4} ExportMode */
+// 0 - normal, 1 - custom css variable, 2 - grid custom ident, 3 - composes
+/** @typedef {0 | 1 | 2 | 3} ExportType */
+
+/**
+ * Computes the interpolated identifier for `(module, value, exportType)`.
+ * Module-level reference so `moduleGraph.cached` can use it as a stable
+ * computer key — repeated lookups during a build skip
+ * `cssExportConvention`, `getLocalIdent` (with its content / path hashing)
+ * and `escapeIdentifier`.
+ * @param {ModuleGraph} _moduleGraph module graph (unused, kept for `cached` signature)
+ * @param {CssModule} module css module the value resolves in
+ * @param {string} value raw value to interpolate
+ * @param {ExportType} exportType export type discriminator
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
+ * @returns {string} interpolated identifier
+ */
+const computeInterpolatedIdentifier = (
+	_moduleGraph,
+	module,
+	value,
+	exportType,
+	chunkGraph,
+	runtimeTemplate
+) => {
+	const generator = /** @type {CssGenerator} */ (module.generator);
+	const local = cssExportConvention(
+		value,
+		/** @type {CssGeneratorExportsConvention} */
+		(generator.options.exportsConvention)
+	)[0];
+	const prefix =
+		exportType === CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
+			? "--"
+			: "";
+	return (
+		prefix +
+		getCssParser().escapeIdentifier(
+			getLocalIdent(local, module, chunkGraph, runtimeTemplate),
+			runtimeTemplate.compilation.compiler.root
+		)
+	);
+};
+
+/**
+ * Top-level computer for `resolve`. Allocates a fresh `seen` set; recursive
+ * calls go through the un-cached inner path so cycle detection still works.
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {CssModule} module module to search
+ * @param {string} localName local name
+ * @param {string} importName imported export name
+ * @param {string | undefined} request request of the active `@value` import
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
+ * @returns {string | undefined} resolved value or undefined
+ */
+const computeResolve = (
+	moduleGraph,
+	module,
+	localName,
+	importName,
+	request,
+	chunkGraph,
+	runtimeTemplate
+) =>
+	CssIcssExportDependency.Template._doResolve(
+		localName,
+		importName,
+		/** @type {DependencyTemplateContext} */
+		(
+			/** @type {unknown} */
+			({ moduleGraph, module, chunkGraph, runtimeTemplate })
+		),
+		request,
+		new Set()
+	);
+
+/**
+ * Top-level computer for `resolveReferences`. See `computeResolve`.
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {CssIcssExportDependency} dep export dependency
+ * @param {CssModule} module module that hosts `dep`
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
+ * @returns {string[]} final references, deduplicated
+ */
+const computeResolveReferences = (
+	moduleGraph,
+	dep,
+	module,
+	chunkGraph,
+	runtimeTemplate
+) =>
+	CssIcssExportDependency.Template._doResolveReferences(
+		dep,
+		/** @type {DependencyTemplateContext} */
+		(
+			/** @type {unknown} */
+			({ moduleGraph, module, chunkGraph, runtimeTemplate })
+		),
+		new Set()
+	);
+
+class CssIcssExportDependency extends NullDependency {
+	/**
+	 * Example of dependency:
+	 *
+	 * :export { LOCAL_NAME: EXPORT_NAME }
+	 * @param {string} name export name
+	 * @param {Value} value value or local name and import name
+	 * @param {Range=} range range
+	 * @param {boolean=} interpolate true when value need to be interpolated, otherwise false
+	 * @param {ExportMode=} exportMode export mode
+	 * @param {ExportType=} exportType export type
+	 */
+	constructor(
+		name,
+		value,
+		range,
+		interpolate = false,
+		exportMode = CssIcssExportDependency.EXPORT_MODE.REPLACE,
+		exportType = CssIcssExportDependency.EXPORT_TYPE.NORMAL
+	) {
+		super();
+		this.name = name;
+		this.value = value;
+		this.range = range;
+		this.interpolate = interpolate;
+		this.exportMode = exportMode;
+		this.exportType = exportType;
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+		/** @type {undefined | string[]} */
+		this._conventionNames = undefined;
+		/** @type {undefined | string[]} */
+		this._valueConventionNames = undefined;
+	}
+
+	get type() {
+		return "css :export";
+	}
+
+	/**
+	 * Gets exports convention names.
+	 * @param {string} name export name
+	 * @param {CssGeneratorExportsConvention} convention convention of the export name
+	 * @returns {string[]} convention results
+	 */
+	getExportsConventionNames(name, convention) {
+		if (this._conventionNames) {
+			return this._conventionNames;
+		}
+		this._conventionNames = cssExportConvention(name, convention);
+		return this._conventionNames;
+	}
+
+	/**
+	 * Memoized `cssExportConvention(this.value, convention)`. Used by every
+	 * code path that needs the convention-derived aliases of the composed /
+	 * referenced class: `getReferencedExports`, `getWarnings`, and the template's
+	 * `getIdentifier`. Caller guarantees `typeof this.value === "string"` —
+	 * the array form (cross-module references) is resolved separately.
+	 * @param {CssGeneratorExportsConvention} convention convention of the export name
+	 * @returns {string[]} convention results
+	 */
+	getValueConventionNames(convention) {
+		if (this._valueConventionNames) {
+			return this._valueConventionNames;
+		}
+		this._valueConventionNames = cssExportConvention(
+			/** @type {string} */ (this.value),
+			convention
+		);
+		return this._valueConventionNames;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		if (
+			this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE &&
+			typeof this.value === "string"
+		) {
+			// `composes: foo;` — the composed class (`this.value`) is the one
+			// referenced, not the class doing the composing (`this.name`). Apply
+			// the generator's `exportsConvention` so the export names produced
+			// by the convention are what the optimizer sees.
+			const module =
+				/** @type {CssModule | undefined} */
+				(moduleGraph.getParentModule(this));
+			if (!module) return super.getReferencedExports(moduleGraph, runtime);
+			const generator = /** @type {CssGenerator} */ (module.generator);
+			const names = this.getValueConventionNames(
+				/** @type {CssGeneratorExportsConvention} */
+				(generator.options.exportsConvention)
+			);
+			return names.map((name) => ({
+				name: [name],
+				canMangle: true
+			}));
+		}
+
+		return super.getReferencedExports(moduleGraph, runtime);
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		if (
+			this.exportMode === CssIcssExportDependency.EXPORT_MODE.NONE ||
+			this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
+		) {
+			return;
+		}
+
+		const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this));
+		const generator = /** @type {CssGenerator} */ (module.generator);
+		const names = this.getExportsConventionNames(
+			this.name,
+			/** @type {CssGeneratorExportsConvention} */
+			(generator.options.exportsConvention)
+		);
+
+		return {
+			exports: [...names].map((name) => ({
+				name,
+				canMangle: true
+			})),
+			dependencies: undefined
+		};
+	}
+
+	/**
+	 * Returns warnings.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} warnings
+	 */
+	getWarnings(moduleGraph) {
+		if (
+			this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE &&
+			typeof this.value === "string"
+		) {
+			const module =
+				/** @type {CssModule | undefined} */
+				(moduleGraph.getParentModule(this));
+
+			if (!module) return null;
+
+			// `ExportsInfo` only stores names produced by `exportsConvention`,
+			// so a raw `isExportProvided(this.value)` check is a false-positive
+			// for `camel-case-only` / `dashes-only` (and any custom function
+			// that drops the original spelling). Treat the composed class as
+			// provided if *any* of its convention-produced aliases is provided.
+			const generator = /** @type {CssGenerator} */ (module.generator);
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+			const names = this.getValueConventionNames(
+				/** @type {CssGeneratorExportsConvention} */
+				(generator.options.exportsConvention)
+			);
+			const isProvided = names.some((name) =>
+				exportsInfo.isExportProvided(name)
+			);
+
+			if (!isProvided) {
+				const error = new WebpackError(
+					`Self-referencing name "${this.value}" not found`
+				);
+				error.module = module;
+
+				return [error];
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, { chunkGraph }) {
+		if (this._hashUpdate === undefined) {
+			const module =
+				/** @type {CssModule} */
+				(chunkGraph.moduleGraph.getParentModule(this));
+			const generator = /** @type {CssGenerator} */ (module.generator);
+			const names = this.getExportsConventionNames(
+				this.name,
+				/** @type {CssGeneratorExportsConvention} */
+				(generator.options.exportsConvention)
+			);
+			// Include all instance state that affects the emitted output —
+			// `name`, `value`, `range`, `interpolate`, `exportMode`,
+			// `exportType` — so changes like switching `composes: foo` →
+			// `composes: bar` or `ONCE` → `APPEND` invalidate caches.
+			this._hashUpdate = `exportsConvention|${JSON.stringify(names)}|localIdentName|${JSON.stringify(generator.options.localIdentName)}|value|${JSON.stringify(this.value)}|range|${JSON.stringify(this.range)}|interpolate|${this.interpolate}|exportMode|${this.exportMode}|exportType|${this.exportType}`;
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.name);
+		write(this.value);
+		write(this.range);
+		write(this.interpolate);
+		write(this.exportMode);
+		write(this.exportType);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.name = read();
+		this.value = read();
+		this.range = read();
+		this.interpolate = read();
+		this.exportMode = read();
+		this.exportType = read();
+		super.deserialize(context);
+	}
+}
+
+CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Returns found reference. The top-level call (no `seen` argument) is
+	 * memoized via `moduleGraph.cached` keyed by `(module, localName,
+	 * importName, request, chunkGraph, runtimeTemplate)`. Recursive callers
+	 * pass `seen` and skip the cache so the cycle guard is preserved — only
+	 * completed top-level resolutions land in the cache.
+	 * @param {string} localName local name
+	 * @param {string} importName import name
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @param {string | undefined} request user request of the `@value` import that was active when the reference was parsed — used to disambiguate when the same local name is imported from multiple modules
+	 * @param {Set<CssIcssExportDependency>=} seen seen to prevent cyclical problems
+	 * @returns {string | undefined} found reference
+	 */
+	static resolve(localName, importName, templateContext, request, seen) {
+		if (seen !== undefined) {
+			return CssIcssExportDependencyTemplate._doResolve(
+				localName,
+				importName,
+				templateContext,
+				request,
+				seen
+			);
+		}
+		const { moduleGraph, module, chunkGraph, runtimeTemplate } =
+			templateContext;
+		return moduleGraph.cached(
+			computeResolve,
+			/** @type {CssModule} */ (module),
+			localName,
+			importName,
+			request,
+			chunkGraph,
+			runtimeTemplate
+		);
+	}
+
+	/**
+	 * Inner recursive worker for `resolve`. Not memoized — see `resolve`.
+	 * @param {string} localName local name
+	 * @param {string} importName import name
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @param {string | undefined} request user request
+	 * @param {Set<CssIcssExportDependency>} seen seen to prevent cyclical problems
+	 * @returns {string | undefined} found reference
+	 */
+	static _doResolve(localName, importName, templateContext, request, seen) {
+		const { moduleGraph } = templateContext;
+		const importDep =
+			/** @type {CssIcssImportDependency | undefined} */
+			(
+				CssIcssExportDependencyTemplate.findImportDep(
+					templateContext.module.dependencies,
+					localName,
+					request
+				)
+			);
+		if (!importDep) return undefined;
+
+		const module = /** @type {CssModule} */ (moduleGraph.getModule(importDep));
+		if (!module) return undefined;
+
+		const exportDep =
+			/** @type {CssIcssExportDependency} */
+			(
+				module.dependencies.find(
+					(d) => d instanceof CssIcssExportDependency && d.name === importName
+				)
+			);
+
+		if (!exportDep) return undefined;
+
+		if (seen.has(exportDep)) return undefined;
+		seen.add(exportDep);
+
+		const { value, interpolate } = exportDep;
+
+		if (Array.isArray(value)) {
+			return CssIcssExportDependencyTemplate._doResolve(
+				value[0],
+				value[1],
+				{
+					...templateContext,
+					module
+				},
+				value[2],
+				seen
+			);
+		}
+
+		if (interpolate) {
+			return CssIcssExportDependency.Template.getIdentifier(value, exportDep, {
+				...templateContext,
+				module
+			});
+		}
+
+		return value;
+	}
+
+	/**
+	 * Finds the active `CssIcssImportDependency` for a given local name. When a
+	 * `request` is provided the lookup also requires the import dependency's
+	 * `request` to match — this lets references that appear between two
+	 * `@value foo from "..."` declarations resolve through the import that was
+	 * in scope at the reference site, rather than always picking the first.
+	 * @param {Iterable<Dependency>} dependencies module dependencies to search
+	 * @param {string} localName local name
+	 * @param {string=} request user request of the `@value` import to match
+	 * @returns {CssIcssImportDependency | undefined} matching import dep, if any
+	 */
+	static findImportDep(dependencies, localName, request) {
+		/** @type {CssIcssImportDependency | undefined} */
+		let firstMatch;
+		for (const d of dependencies) {
+			if (d instanceof CssIcssImportDependency && d.localName === localName) {
+				if (request === undefined) return d;
+				if (d.request === request) return d;
+				if (firstMatch === undefined) firstMatch = d;
+			}
+		}
+		return firstMatch;
+	}
+
+	/**
+	 * Resolves references. The top-level call (no `seen` argument) is
+	 * memoized via `moduleGraph.cached`; recursive callers pass `seen` and
+	 * bypass the cache to keep the cycle guard intact.
+	 * @param {CssIcssExportDependency} dep value
+	 * @param {DependencyTemplateContext} templateContext template context
+	 * @param {Set<CssIcssExportDependency>=} seen to prevent cyclical problems
+	 * @returns {string[]} final names
+	 */
+	static resolveReferences(dep, templateContext, seen) {
+		if (seen !== undefined) {
+			return CssIcssExportDependencyTemplate._doResolveReferences(
+				dep,
+				templateContext,
+				seen
+			);
+		}
+		const { moduleGraph, module, chunkGraph, runtimeTemplate } =
+			templateContext;
+		return moduleGraph.cached(
+			computeResolveReferences,
+			dep,
+			/** @type {CssModule} */ (module),
+			chunkGraph,
+			runtimeTemplate
+		);
+	}
+
+	/**
+	 * Inner recursive worker for `resolveReferences`. Not memoized.
+	 * @param {CssIcssExportDependency} dep value
+	 * @param {DependencyTemplateContext} templateContext template context
+	 * @param {Set<CssIcssExportDependency>} seen to prevent cyclical problems
+	 * @returns {string[]} final names
+	 */
+	static _doResolveReferences(dep, templateContext, seen) {
+		/** @type {string[]} */
+		const references = [];
+
+		if (seen.has(dep)) return references;
+		seen.add(dep);
+
+		if (Array.isArray(dep.value)) {
+			const importDep =
+				/** @type {CssIcssImportDependency | undefined} */
+				(
+					CssIcssExportDependencyTemplate.findImportDep(
+						templateContext.module.dependencies,
+						dep.value[0],
+						dep.value[2]
+					)
+				);
+			if (!importDep) return references;
+
+			const module =
+				/** @type {CssModule} */
+				(templateContext.moduleGraph.getModule(importDep));
+			if (!module) return references;
+
+			for (const d of module.dependencies) {
+				if (d instanceof CssIcssExportDependency && d.name === dep.value[1]) {
+					if (Array.isArray(d.value)) {
+						const deepReferences =
+							CssIcssExportDependencyTemplate._doResolveReferences(
+								d,
+								{
+									...templateContext,
+									module
+								},
+								seen
+							);
+
+						references.push(...deepReferences);
+					} else {
+						references.push(
+							CssIcssExportDependencyTemplate.getIdentifier(d.value, d, {
+								...templateContext,
+								module
+							})
+						);
+					}
+				}
+			}
+		} else {
+			// Adding basic class
+			references.push(
+				CssIcssExportDependencyTemplate.getIdentifier(
+					dep.value,
+					dep,
+					templateContext
+				)
+			);
+
+			for (const d of templateContext.module.dependencies) {
+				if (
+					d instanceof CssIcssExportDependency &&
+					d.exportType === CssIcssExportDependency.EXPORT_TYPE.COMPOSES &&
+					d.name === dep.value
+				) {
+					if (Array.isArray(d.value)) {
+						const deepReferences =
+							CssIcssExportDependencyTemplate._doResolveReferences(
+								d,
+								templateContext,
+								seen
+							);
+
+						references.push(...deepReferences);
+					} else {
+						references.push(
+							CssIcssExportDependencyTemplate.getIdentifier(
+								d.value,
+								d,
+								templateContext
+							)
+						);
+					}
+				}
+			}
+		}
+
+		return [...new Set(references)];
+	}
+
+	/**
+	 * Returns identifier. When the dep opts into interpolation the full
+	 * computation is memoized via `moduleGraph.cached` keyed by
+	 * `(module, value, exportType, chunkGraph, runtimeTemplate)` so
+	 * `cssExportConvention` / `getLocalIdent` / `escapeIdentifier` are not
+	 * re-run for the same identifier during code generation.
+	 * @param {string} value value to identifier
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {string} identifier
+	 */
+	static getIdentifier(value, dependency, templateContext) {
+		const dep = /** @type {CssIcssExportDependency} */ (dependency);
+		if (!dep.interpolate) return value;
+		const { moduleGraph, module, chunkGraph, runtimeTemplate } =
+			templateContext;
+		return moduleGraph.cached(
+			computeInterpolatedIdentifier,
+			/** @type {CssModule} */ (module),
+			value,
+			dep.exportType,
+			chunkGraph,
+			runtimeTemplate
+		);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {CssIcssExportDependency} */ (dependency);
+		if (!dep.range && templateContext.type !== JAVASCRIPT_TYPE) return;
+		const { module: m, moduleGraph, runtime, cssData } = templateContext;
+		const module = /** @type {CssModule} */ (m);
+		const generator = /** @type {CssGenerator} */ (module.generator);
+		const isReference = Array.isArray(dep.value);
+
+		/** @type {string} */
+		let value;
+
+		// The `composes` has more complex logic for collecting all the classes
+		if (
+			dep.exportType === CssIcssExportDependency.EXPORT_TYPE.COMPOSES &&
+			templateContext.type === JAVASCRIPT_TYPE
+		) {
+			value = CssIcssExportDependencyTemplate.resolveReferences(
+				dep,
+				templateContext
+			).join(" ");
+		} else if (isReference) {
+			const resolved = CssIcssExportDependencyTemplate.resolve(
+				dep.value[0],
+				dep.value[1],
+				templateContext,
+				dep.value[2]
+			);
+
+			// Fallback to the local name if not resolved
+			value = resolved || dep.value[0];
+		} else {
+			value = CssIcssExportDependencyTemplate.getIdentifier(
+				/** @type {string} */ (dep.value),
+				dep,
+				templateContext
+			);
+		}
+
+		if (
+			dep.exportType ===
+			CssIcssExportDependency.EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER
+		) {
+			value += `-${dep.name}`;
+		}
+
+		if (
+			templateContext.type === JAVASCRIPT_TYPE &&
+			dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.NONE
+		) {
+			const names = dep.getExportsConventionNames(
+				dep.name,
+				/** @type {CssGeneratorExportsConvention} */
+				(generator.options.exportsConvention)
+			);
+			const usedNames =
+				/** @type {string[]} */
+				(
+					names
+						.map((name) =>
+							moduleGraph.getExportInfo(module, name).getUsedName(name, runtime)
+						)
+						.filter(Boolean)
+				);
+			const allNames = new Set([...usedNames, ...names]);
+			const unescaped = getCssParser().unescapeIdentifier(
+				value,
+				templateContext.runtimeTemplate.compilation.compiler.root
+			);
+
+			const depLocStart =
+				dep.loc &&
+				/** @type {{ start?: { line: number, column: number } }} */ (dep.loc)
+					.start;
+			for (const used of allNames) {
+				if (dep.exportMode === CssIcssExportDependency.EXPORT_MODE.ONCE) {
+					if (cssData.exports.has(used)) return;
+					cssData.exports.set(used, unescaped);
+					if (
+						depLocStart &&
+						cssData.exportLocs &&
+						!cssData.exportLocs.has(used)
+					) {
+						cssData.exportLocs.set(used, {
+							line: depLocStart.line,
+							column: depLocStart.column
+						});
+					}
+				} else {
+					const originalValue =
+						dep.exportMode === CssIcssExportDependency.EXPORT_MODE.REPLACE
+							? undefined
+							: cssData.exports.get(used);
+
+					cssData.exports.set(
+						used,
+						`${originalValue ? `${originalValue}${unescaped ? " " : ""}` : ""}${unescaped}`
+					);
+					// Record the source location once per export (use the first
+					// occurrence — for APPEND/REPLACE this corresponds to the
+					// first selector seen, which is a reasonable anchor).
+					if (
+						depLocStart &&
+						cssData.exportLocs &&
+						!cssData.exportLocs.has(used)
+					) {
+						cssData.exportLocs.set(used, {
+							line: depLocStart.line,
+							column: depLocStart.column
+						});
+					}
+				}
+			}
+		} else if (
+			dep.range &&
+			templateContext.type === CSS_TYPE &&
+			dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.APPEND &&
+			dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
+		) {
+			source.replace(dep.range[0], dep.range[1] - 1, value);
+		}
+	}
+};
+
+/** @type {Record<"NONE" | "REPLACE" | "APPEND" | "ONCE" | "SELF_REFERENCE", ExportMode>} */
+CssIcssExportDependency.EXPORT_MODE = {
+	NONE: 0,
+	REPLACE: 1,
+	APPEND: 2,
+	ONCE: 3,
+	SELF_REFERENCE: 4
+};
+
+/** @type {Record<"NORMAL" | "CUSTOM_VARIABLE" | "GRID_CUSTOM_IDENTIFIER" | "COMPOSES", ExportType>} */
+CssIcssExportDependency.EXPORT_TYPE = {
+	NORMAL: 0,
+	CUSTOM_VARIABLE: 1,
+	GRID_CUSTOM_IDENTIFIER: 2,
+	COMPOSES: 3
+};
+
+makeSerializable(
+	CssIcssExportDependency,
+	"webpack/lib/dependencies/CssIcssExportDependency"
+);
+
+module.exports = CssIcssExportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CssIcssImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CssIcssImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CssIcssImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,171 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const { cssExportConvention } = require("../util/conventions");
+const makeSerializable = require("../util/makeSerializable");
+const CssImportDependency = require("./CssImportDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../css/CssGenerator")} CssGenerator */
+/** @typedef {import("../css/CssModule")} CssModule */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
+/** @typedef {import("./CssIcssExportDependency").ExportMode} ExportMode */
+/** @typedef {import("./CssIcssExportDependency").ExportType} ExportType */
+
+class CssIcssImportDependency extends CssImportDependency {
+	/**
+	 * Example of dependency:
+	 *
+	 * :import('./style.css') { value: name }
+	 * @param {string} request request request path which needs resolving
+	 * @param {Range} range the range of dependency
+	 * @param {"local" | "global"} mode mode of the parsed CSS
+	 * @param {string} importName import name (`name` from example)
+	 * @param {string} localName local name (`value` from example)
+	 */
+	constructor(request, range, mode, importName, localName) {
+		super(request, range, mode);
+		this.importName = importName;
+		this.localName = localName;
+		/** @type {undefined | string[]} */
+		this._importNameConventionNames = undefined;
+	}
+
+	/**
+	 * Memoized `cssExportConvention(this.importName, convention)`. The target
+	 * module is fixed for a given dep, so its `exportsConvention` is fixed,
+	 * so the convention-derived aliases of `importName` can be cached on the dep.
+	 * @param {CssGeneratorExportsConvention} convention convention from the target module's generator
+	 * @returns {string[]} convention results
+	 */
+	getImportNameConventionNames(convention) {
+		if (this._importNameConventionNames) {
+			return this._importNameConventionNames;
+		}
+		this._importNameConventionNames = cssExportConvention(
+			this.importName,
+			convention
+		);
+		return this._importNameConventionNames;
+	}
+
+	get type() {
+		return "css :import";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return [
+			{
+				name: [this.importName],
+				canMangle: true
+			}
+		];
+	}
+
+	/**
+	 * Returns warnings.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} warnings
+	 */
+	getWarnings(moduleGraph) {
+		const module = /** @type {CssModule | undefined} */ (
+			moduleGraph.getModule(this)
+		);
+
+		if (!module) return null;
+
+		// The target module stores exports under the names produced by its
+		// `exportsConvention`, so a raw `isExportProvided(this.importName)`
+		// would false-positive against `camel-case-only` / `dashes-only` (and
+		// any custom function that drops the original spelling). Expand
+		// `importName` through the *target* module's convention and accept
+		// if any alias is provided.
+		const generator =
+			/** @type {CssGenerator | undefined} */
+			(module.generator);
+		const convention =
+			generator &&
+			/** @type {CssGeneratorExportsConvention | undefined} */
+			(generator.options && generator.options.exportsConvention);
+		const exportsInfo = moduleGraph.getExportsInfo(module);
+		const names = convention
+			? this.getImportNameConventionNames(convention)
+			: [this.importName];
+		const isProvided = names.some((name) => exportsInfo.isExportProvided(name));
+
+		if (!isProvided) {
+			const error = new WebpackError(
+				`Referenced name "${this.importName}" in "${this.userRequest}" not found`
+			);
+			error.module = module;
+
+			return [error];
+		}
+
+		return null;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.importName);
+		write(this.localName);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.importName = read();
+		this.localName = read();
+		super.deserialize(context);
+	}
+}
+
+CssIcssImportDependency.Template = class CssIcssImportDependencyTemplate extends (
+	CssImportDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		// Nothing
+	}
+};
+
+makeSerializable(
+	CssIcssImportDependency,
+	"webpack/lib/dependencies/CssIcssImportDependency"
+);
+
+module.exports = CssIcssImportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CssIcssSymbolDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CssIcssSymbolDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CssIcssSymbolDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,132 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const { CSS_TYPE } = require("../ModuleSourceTypeConstants");
+const makeSerializable = require("../util/makeSerializable");
+const CssIcssExportDependency = require("./CssIcssExportDependency");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../css/CssParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class CssIcssSymbolDependency extends NullDependency {
+	/**
+	 * Creates an instance of CssIcssSymbolDependency.
+	 * @param {string} localName local name
+	 * @param {Range} range range
+	 * @param {string=} value value when it was defined in this module
+	 * @param {string=} importName import name when it was imported from other module
+	 * @param {string=} request request of the `@value` import that was active when this reference was parsed — used to disambiguate when the same local name is imported from multiple modules
+	 */
+	constructor(localName, range, value, importName, request) {
+		super();
+		this.localName = localName;
+		this.range = range;
+		this.value = value;
+		this.importName = importName;
+		this.request = request;
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	get type() {
+		return "css symbol identifier";
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			// Concatenate with explicit field separators so adjacent fields
+			// can't alias each other (e.g. range `[1,11]` + localName `"foo"`
+			// vs range `[1,1]` + localName `"1foo"`).
+			this._hashUpdate = `range|${JSON.stringify(this.range)}|localName|${this.localName}|value|${this.value || ""}|importName|${this.importName || ""}|request|${this.request || ""}`;
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.localName);
+		write(this.range);
+		write(this.value);
+		write(this.importName);
+		write(this.request);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.localName = read();
+		this.range = read();
+		this.value = read();
+		this.importName = read();
+		this.request = read();
+		super.deserialize(context);
+	}
+}
+
+CssIcssSymbolDependency.Template = class CssIcssSymbolDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		if (templateContext.type === CSS_TYPE) {
+			const dep = /** @type {CssIcssSymbolDependency} */ (dependency);
+			/** @type {string | undefined} */
+			const value = dep.importName
+				? CssIcssExportDependency.Template.resolve(
+						dep.localName,
+						dep.importName,
+						templateContext,
+						dep.request
+					)
+				: dep.value;
+
+			if (!value) {
+				return;
+			}
+
+			source.replace(dep.range[0], dep.range[1] - 1, value);
+		}
+	}
+};
+
+makeSerializable(
+	CssIcssSymbolDependency,
+	"webpack/lib/dependencies/CssIcssSymbolDependency"
+);
+
+module.exports = CssIcssSymbolDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CssImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CssImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CssImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,132 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../css/CssParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class CssImportDependency extends ModuleDependency {
+	/**
+	 * Example of dependency:
+	 * \@import url("landscape.css") layer(forms) screen and (orientation: landscape) screen and (orientation: landscape);
+	 * @param {string} request request
+	 * @param {Range} range range of the argument
+	 * @param {"local" | "global"=} mode mode of the parsed CSS
+	 * @param {string=} layer layer
+	 * @param {string=} supports list of supports conditions
+	 * @param {string=} media list of media conditions
+	 */
+	constructor(request, range, mode, layer, supports, media) {
+		super(request);
+		this.range = range;
+		this.mode = mode;
+		this.layer = layer;
+		this.supports = supports;
+		this.media = media;
+	}
+
+	get type() {
+		return "css @import";
+	}
+
+	get category() {
+		return `css-import${this.mode ? `-${this.mode}-module` : ""}`;
+	}
+
+	/**
+	 * Returns true if this dependency can be concatenated
+	 * @returns {boolean} true if this dependency can be concatenated
+	 */
+	canConcatenate() {
+		return true;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		let str = `context${this._context || ""}|module${this.request}`;
+
+		if (this.mode) {
+			str += `|mode${this.mode}`;
+		}
+
+		if (this.layer) {
+			str += `|layer${this.layer}`;
+		}
+
+		if (this.supports) {
+			str += `|supports${this.supports}`;
+		}
+
+		if (this.media) {
+			str += `|media${this.media}`;
+		}
+
+		return str;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.mode);
+		write(this.layer);
+		write(this.supports);
+		write(this.media);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.mode = read();
+		this.layer = read();
+		this.supports = read();
+		this.media = read();
+		super.deserialize(context);
+	}
+}
+
+CssImportDependency.Template = class CssImportDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		if (templateContext.type === "javascript") return;
+		const dep = /** @type {CssImportDependency} */ (dependency);
+
+		source.replace(dep.range[0], dep.range[1] - 1, "");
+	}
+};
+
+makeSerializable(
+	CssImportDependency,
+	"webpack/lib/dependencies/CssImportDependency"
+);
+
+module.exports = CssImportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/CssUrlDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/CssUrlDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/CssUrlDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,222 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const { ASSET_URL_TYPE } = require("../ModuleSourceTypeConstants");
+const RawDataUrlModule = require("../asset/RawDataUrlModule");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+const getIgnoredRawDataUrlModule = memoize(
+	() => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)")
+);
+
+class CssUrlDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of CssUrlDependency.
+	 * @param {string} request request
+	 * @param {Range} range range of the argument
+	 * @param {"string" | "url" | "src"} urlType dependency type e.g. url() or string
+	 */
+	constructor(request, range, urlType) {
+		super(request);
+		this.range = range;
+		this.urlType = urlType;
+	}
+
+	get type() {
+		return "css url()";
+	}
+
+	get category() {
+		return "url";
+	}
+
+	/**
+	 * Creates an ignored module.
+	 * @param {string} context context directory
+	 * @returns {Module} ignored module
+	 */
+	createIgnoredModule(context) {
+		return getIgnoredRawDataUrlModule();
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		// The dependency template substitutes the referenced asset's hashed
+		// filename into the rendered CSS at code-generation time. Folding the
+		// asset module's content hash into the dependency hash ensures the
+		// CSS module's hash invalidates — and the CSS chunk's contenthash
+		// updates — whenever the referenced asset's content changes.
+		const { chunkGraph } = context;
+		const module = chunkGraph.moduleGraph.getModule(this);
+		if (!module) return;
+		const buildInfo = /** @type {BuildInfo | undefined} */ (module.buildInfo);
+		if (buildInfo && buildInfo.hash) {
+			hash.update(/** @type {string} */ (buildInfo.hash));
+		}
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.urlType);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.urlType = read();
+		super.deserialize(context);
+	}
+}
+
+/**
+ * Returns string in quotes if needed.
+ * @param {string} str string
+ * @returns {string} string in quotes if needed
+ */
+const cssEscapeString = (str) => {
+	let countWhiteOrBracket = 0;
+	let countQuotation = 0;
+	let countApostrophe = 0;
+	for (let i = 0; i < str.length; i++) {
+		const cc = str.charCodeAt(i);
+		switch (cc) {
+			case 9: // tab
+			case 10: // nl
+			case 32: // space
+			case 40: // (
+			case 41: // )
+				countWhiteOrBracket++;
+				break;
+			case 34:
+				countQuotation++;
+				break;
+			case 39:
+				countApostrophe++;
+				break;
+		}
+	}
+	if (countWhiteOrBracket < 2) {
+		return str.replace(/[\n\t ()'"\\]/g, (m) => `\\${m}`);
+	} else if (countQuotation <= countApostrophe) {
+		return `"${str.replace(/[\n"\\]/g, (m) => `\\${m}`)}"`;
+	}
+	return `'${str.replace(/[\n'\\]/g, (m) => `\\${m}`)}'`;
+};
+
+CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ type, moduleGraph, runtimeTemplate, codeGenerationResults }
+	) {
+		if (type === "javascript") return;
+		const dep = /** @type {CssUrlDependency} */ (dependency);
+		const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+
+		/** @type {string | undefined} */
+		let newValue;
+
+		switch (dep.urlType) {
+			case "string":
+				newValue = cssEscapeString(
+					this.assetUrl({
+						module,
+						codeGenerationResults
+					})
+				);
+				break;
+			case "url":
+				newValue = `url(${cssEscapeString(
+					this.assetUrl({
+						module,
+						codeGenerationResults
+					})
+				)})`;
+				break;
+			case "src":
+				newValue = `src(${cssEscapeString(
+					this.assetUrl({
+						module,
+						codeGenerationResults
+					})
+				)})`;
+				break;
+		}
+
+		source.replace(
+			dep.range[0],
+			dep.range[1] - 1,
+			/** @type {string} */ (newValue)
+		);
+	}
+
+	/**
+	 * Returns the url of the asset.
+	 * @param {object} options options object
+	 * @param {Module} options.module the module
+	 * @param {RuntimeSpec=} options.runtime runtime
+	 * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
+	 * @returns {string} the url of the asset
+	 */
+	assetUrl({ runtime, module, codeGenerationResults }) {
+		if (!module) {
+			return "data:,";
+		}
+		const codeGen = codeGenerationResults.get(module, runtime);
+		const data = codeGen.data;
+		if (!data) return "data:,";
+		const url = data.get("url");
+		if (!url || !url[ASSET_URL_TYPE]) return "data:,";
+		return url[ASSET_URL_TYPE];
+	}
+};
+
+makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency");
+
+CssUrlDependency.PUBLIC_PATH_AUTO = "__WEBPACK_CSS_PUBLIC_PATH_AUTO__";
+CssUrlDependency.PUBLIC_PATH_FULL_HASH = "__WEBPACK_CSS_PUBLIC_PATH_FULL_HASH_";
+
+module.exports = CssUrlDependency;
Index: frontend/node_modules/webpack/lib/dependencies/DelegatedSourceDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/DelegatedSourceDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/DelegatedSourceDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+class DelegatedSourceDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of DelegatedSourceDependency.
+	 * @param {string} request the request string
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "delegated source";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	DelegatedSourceDependency,
+	"webpack/lib/dependencies/DelegatedSourceDependency"
+);
+
+module.exports = DelegatedSourceDependency;
Index: frontend/node_modules/webpack/lib/dependencies/DllEntryDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/DllEntryDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/DllEntryDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,64 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./EntryDependency")} EntryDependency */
+
+class DllEntryDependency extends Dependency {
+	/**
+	 * Creates an instance of DllEntryDependency.
+	 * @param {EntryDependency[]} dependencies dependencies
+	 * @param {string} name name
+	 */
+	constructor(dependencies, name) {
+		super();
+
+		this.dependencies = dependencies;
+		this.name = name;
+	}
+
+	get type() {
+		return "dll entry";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.dependencies);
+		write(this.name);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.dependencies = read();
+		this.name = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	DllEntryDependency,
+	"webpack/lib/dependencies/DllEntryDependency"
+);
+
+module.exports = DllEntryDependency;
Index: frontend/node_modules/webpack/lib/dependencies/DynamicExports.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/DynamicExports.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/DynamicExports.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,78 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
+
+/** @type {WeakMap<JavascriptParserState, boolean>} */
+const parserStateExportsState = new WeakMap();
+
+/**
+ * Processes the provided parser state.
+ * @param {JavascriptParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.bailout = (parserState) => {
+	const value = parserStateExportsState.get(parserState);
+	parserStateExportsState.set(parserState, false);
+	if (value === true) {
+		const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta);
+		buildMeta.exportsType = undefined;
+		buildMeta.defaultObject = false;
+	}
+};
+
+/**
+ * Processes the provided parser state.
+ * @param {JavascriptParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.enable = (parserState) => {
+	const value = parserStateExportsState.get(parserState);
+	if (value === false) return;
+	parserStateExportsState.set(parserState, true);
+	if (value !== true) {
+		const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta);
+		buildMeta.exportsType = "default";
+		buildMeta.defaultObject = "redirect";
+	}
+};
+
+/**
+ * Returns true, when enabled.
+ * @param {JavascriptParserState} parserState parser state
+ * @returns {boolean} true, when enabled
+ */
+module.exports.isEnabled = (parserState) => {
+	const value = parserStateExportsState.get(parserState);
+	return value === true;
+};
+
+/**
+ * Processes the provided parser state.
+ * @param {JavascriptParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.setDynamic = (parserState) => {
+	const value = parserStateExportsState.get(parserState);
+	if (value !== true) return;
+	/** @type {BuildMeta} */
+	(parserState.module.buildMeta).exportsType = "dynamic";
+};
+
+/**
+ * Processes the provided parser state.
+ * @param {JavascriptParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.setFlagged = (parserState) => {
+	const value = parserStateExportsState.get(parserState);
+	if (value !== true) return;
+	const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta);
+	if (buildMeta.exportsType === "dynamic") return;
+	buildMeta.exportsType = "flagged";
+};
Index: frontend/node_modules/webpack/lib/dependencies/EntryDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/EntryDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/EntryDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+class EntryDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of EntryDependency.
+	 * @param {string} request request path for entry
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "entry";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(EntryDependency, "webpack/lib/dependencies/EntryDependency");
+
+module.exports = EntryDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ExportsInfoDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ExportsInfoDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ExportsInfoDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,167 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Defines the sortable set type used by this module.
+ * @template T
+ * @typedef {import("../util/SortableSet")<T>} SortableSet
+ */
+
+/**
+ * Returns value of the property.
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {Module} module the module
+ * @param {ExportInfoName[] | null} exportName_ name of the export if any
+ * @param {string | null} property name of the requested property
+ * @param {RuntimeSpec} runtime for which runtime
+ * @returns {undefined | null | boolean | ExportInfoName[]} value of the property
+ */
+const getProperty = (moduleGraph, module, exportName_, property, runtime) => {
+	if (!exportName_) {
+		switch (property) {
+			case "usedExports": {
+				const usedExports = moduleGraph
+					.getExportsInfo(module)
+					.getUsedExports(runtime);
+				if (
+					typeof usedExports === "boolean" ||
+					usedExports === undefined ||
+					usedExports === null
+				) {
+					return usedExports;
+				}
+				return [...usedExports].sort();
+			}
+		}
+	}
+	const exportName = /** @type {ExportInfoName[]} */ (exportName_);
+	switch (property) {
+		case "canMangle": {
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+			const exportInfo = exportsInfo.getReadOnlyExportInfoRecursive(exportName);
+			if (exportInfo) return exportInfo.canMangle;
+			return exportsInfo.otherExportsInfo.canMangle;
+		}
+		case "used":
+			return (
+				moduleGraph.getExportsInfo(module).getUsed(exportName, runtime) !==
+				UsageState.Unused
+			);
+		case "useInfo": {
+			const state = moduleGraph
+				.getExportsInfo(module)
+				.getUsed(exportName, runtime);
+			switch (state) {
+				case UsageState.Used:
+				case UsageState.OnlyPropertiesUsed:
+					return true;
+				case UsageState.Unused:
+					return false;
+				case UsageState.NoInfo:
+					return;
+				case UsageState.Unknown:
+					return null;
+				default:
+					throw new Error(`Unexpected UsageState ${state}`);
+			}
+		}
+		case "provideInfo":
+			return moduleGraph.getExportsInfo(module).isExportProvided(exportName);
+	}
+};
+
+class ExportsInfoDependency extends NullDependency {
+	/**
+	 * Creates an instance of ExportsInfoDependency.
+	 * @param {Range} range range
+	 * @param {ExportInfoName[] | null} exportName export name
+	 * @param {string | null} property property
+	 */
+	constructor(range, exportName, property) {
+		super();
+		this.range = range;
+		this.exportName = exportName;
+		this.property = property;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.exportName);
+		write(this.property);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {ExportsInfoDependency} ExportsInfoDependency
+	 */
+	static deserialize(context) {
+		const obj = new ExportsInfoDependency(
+			context.read(),
+			context.read(),
+			context.read()
+		);
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	ExportsInfoDependency,
+	"webpack/lib/dependencies/ExportsInfoDependency"
+);
+
+ExportsInfoDependency.Template = class ExportsInfoDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { module, moduleGraph, runtime }) {
+		const dep = /** @type {ExportsInfoDependency} */ (dependency);
+
+		const value = getProperty(
+			moduleGraph,
+			module,
+			dep.exportName,
+			dep.property,
+			runtime
+		);
+		source.replace(
+			dep.range[0],
+			dep.range[1] - 1,
+			value === undefined ? "undefined" : JSON.stringify(value)
+		);
+	}
+};
+
+module.exports = ExportsInfoDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ExternalModuleDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ExternalModuleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ExternalModuleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,114 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const CachedConstDependency = require("./CachedConstDependency");
+const ExternalModuleInitFragment = require("./ExternalModuleInitFragment");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../dependencies/ExternalModuleInitFragment").ArrayImportSpecifiers} ArrayImportSpecifiers */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ExternalModuleDependency extends CachedConstDependency {
+	/**
+	 * Creates an instance of ExternalModuleDependency.
+	 * @param {string} module module
+	 * @param {ArrayImportSpecifiers} importSpecifiers import specifiers
+	 * @param {string | undefined} defaultImport default import
+	 * @param {string} expression expression
+	 * @param {Range | null} range range
+	 * @param {string} identifier identifier
+	 * @param {number=} place place where we inject the expression
+	 */
+	constructor(
+		module,
+		importSpecifiers,
+		defaultImport,
+		expression,
+		range,
+		identifier,
+		place = CachedConstDependency.PLACE_MODULE
+	) {
+		super(expression, range, identifier, place);
+
+		this.importedModule = module;
+		this.specifiers = importSpecifiers;
+		this.default = defaultImport;
+	}
+
+	/**
+	 * Create hash update.
+	 * @returns {string} hash update
+	 */
+	_createHashUpdate() {
+		return `${this.importedModule}${JSON.stringify(this.specifiers)}${
+			this.default || "null"
+		}${super._createHashUpdate()}`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		super.serialize(context);
+		const { write } = context;
+		write(this.importedModule);
+		write(this.specifiers);
+		write(this.default);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		super.deserialize(context);
+		const { read } = context;
+		this.importedModule = read();
+		this.specifiers = read();
+		this.default = read();
+	}
+}
+
+makeSerializable(
+	ExternalModuleDependency,
+	"webpack/lib/dependencies/ExternalModuleDependency"
+);
+
+ExternalModuleDependency.Template = class ExternalModuleDependencyTemplate extends (
+	CachedConstDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		super.apply(dependency, source, templateContext);
+		const dep = /** @type {ExternalModuleDependency} */ (dependency);
+		const { chunkInitFragments, runtimeTemplate } = templateContext;
+
+		chunkInitFragments.push(
+			new ExternalModuleInitFragment(
+				`${runtimeTemplate.supportNodePrefixForCoreModules() ? "node:" : ""}${
+					dep.importedModule
+				}`,
+				dep.specifiers,
+				dep.default
+			)
+		);
+	}
+};
+
+module.exports = ExternalModuleDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ExternalModuleInitFragment.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ExternalModuleInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ExternalModuleInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,140 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const InitFragment = require("../InitFragment");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {{ name: string, value?: string }[]} ArrayImportSpecifiers */
+/** @typedef {Set<string>} ImportSpecifier */
+/** @typedef {Map<string, ImportSpecifier>} ImportSpecifiers */
+
+/**
+ * @extends {InitFragment<GenerateContext>}
+ */
+class ExternalModuleInitFragment extends InitFragment {
+	/**
+	 * @param {string} importedModule imported module
+	 * @param {ArrayImportSpecifiers | ImportSpecifiers} specifiers import specifiers
+	 * @param {string=} defaultImport default import
+	 */
+	constructor(importedModule, specifiers, defaultImport) {
+		super(
+			undefined,
+			InitFragment.STAGE_CONSTANTS,
+			0,
+			`external module imports|${importedModule}|${defaultImport || "null"}`
+		);
+		this.importedModule = importedModule;
+		if (Array.isArray(specifiers)) {
+			/** @type {ImportSpecifiers} */
+			this.specifiers = new Map();
+			for (const { name, value } of specifiers) {
+				let specifiers = this.specifiers.get(name);
+				if (!specifiers) {
+					/** @type {ImportSpecifier} */
+					specifiers = new Set();
+					this.specifiers.set(name, specifiers);
+				}
+				specifiers.add(value || name);
+			}
+		} else {
+			this.specifiers = specifiers;
+		}
+		this.defaultImport = defaultImport;
+	}
+
+	/**
+	 * @param {ExternalModuleInitFragment} other other
+	 * @returns {ExternalModuleInitFragment} ExternalModuleInitFragment
+	 */
+	merge(other) {
+		const newSpecifiersMap = new Map(this.specifiers);
+		for (const [name, specifiers] of other.specifiers) {
+			if (newSpecifiersMap.has(name)) {
+				const currentSpecifiers =
+					/** @type {Set<string>} */
+					(newSpecifiersMap.get(name));
+				for (const spec of specifiers) currentSpecifiers.add(spec);
+			} else {
+				newSpecifiersMap.set(name, specifiers);
+			}
+		}
+		return new ExternalModuleInitFragment(
+			this.importedModule,
+			newSpecifiersMap,
+			this.defaultImport
+		);
+	}
+
+	/**
+	 * Returns the source code that will be included as initialization code.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included as initialization code
+	 */
+	getContent({ runtimeRequirements }) {
+		/** @type {string[]} */
+		const namedImports = [];
+
+		for (const [name, specifiers] of this.specifiers) {
+			for (const spec of specifiers) {
+				if (spec === name) {
+					namedImports.push(name);
+				} else {
+					namedImports.push(`${name} as ${spec}`);
+				}
+			}
+		}
+
+		let importsString =
+			namedImports.length > 0 ? `{${namedImports.join(",")}}` : "";
+
+		if (this.defaultImport) {
+			importsString = `${this.defaultImport}${
+				importsString ? `, ${importsString}` : ""
+			}`;
+		}
+
+		return `import ${importsString} from ${JSON.stringify(
+			this.importedModule
+		)};\n`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		super.serialize(context);
+		const { write } = context;
+		write(this.importedModule);
+		write(this.specifiers);
+		write(this.defaultImport);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		super.deserialize(context);
+		const { read } = context;
+		this.importedModule = read();
+		this.specifiers = read();
+		this.defaultImport = read();
+	}
+}
+
+makeSerializable(
+	ExternalModuleInitFragment,
+	"webpack/lib/dependencies/ExternalModuleInitFragment"
+);
+
+module.exports = ExternalModuleInitFragment;
Index: frontend/node_modules/webpack/lib/dependencies/ExternalModuleInitFragmentDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ExternalModuleInitFragmentDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ExternalModuleInitFragmentDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const DependencyTemplate = require("../DependencyTemplate");
+const makeSerializable = require("../util/makeSerializable");
+const ExternalModuleInitFragment = require("./ExternalModuleInitFragment");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../dependencies/ExternalModuleInitFragment").ArrayImportSpecifiers} ArrayImportSpecifiers */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ExternalModuleInitFragmentDependency extends NullDependency {
+	/**
+	 * Creates an instance of ExternalModuleInitFragmentDependency.
+	 * @param {string} module module
+	 * @param {ArrayImportSpecifiers} importSpecifiers import specifiers
+	 * @param {string | undefined} defaultImport default import
+	 */
+	constructor(module, importSpecifiers, defaultImport) {
+		super();
+		this.importedModule = module;
+		this.specifiers = importSpecifiers;
+		this.default = defaultImport;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.importedModule);
+		write(this.specifiers);
+		write(this.default);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.importedModule = read();
+		this.specifiers = read();
+		this.default = read();
+	}
+}
+
+makeSerializable(
+	ExternalModuleInitFragmentDependency,
+	"webpack/lib/dependencies/ExternalModuleConstDependency"
+);
+
+ExternalModuleInitFragmentDependency.Template = class ExternalModuleConstDependencyTemplate extends (
+	DependencyTemplate
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep =
+			/** @type {ExternalModuleInitFragmentDependency} */
+			(dependency);
+		const { chunkInitFragments, runtimeTemplate } = templateContext;
+
+		chunkInitFragments.push(
+			new ExternalModuleInitFragment(
+				`${runtimeTemplate.supportNodePrefixForCoreModules() ? "node:" : ""}${
+					dep.importedModule
+				}`,
+				dep.specifiers,
+				dep.default
+			)
+		);
+	}
+};
+
+module.exports = ExternalModuleInitFragmentDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyAcceptDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyAcceptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyAcceptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,243 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Template = require("../Template");
+const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment");
+const makeSerializable = require("../util/makeSerializable");
+const HarmonyImportDependency = require("./HarmonyImportDependency");
+const { ImportPhaseUtils } = require("./ImportPhase");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./HarmonyAcceptImportDependency")} HarmonyAcceptImportDependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").ModuleId} ModuleId */
+
+class HarmonyAcceptDependency extends NullDependency {
+	/**
+	 * Creates an instance of HarmonyAcceptDependency.
+	 * @param {Range} range expression range
+	 * @param {HarmonyAcceptImportDependency[]} dependencies import dependencies
+	 * @param {boolean} hasCallback true, if the range wraps an existing callback
+	 */
+	constructor(range, dependencies, hasCallback) {
+		super();
+		this.range = range;
+		this.dependencies = dependencies;
+		this.hasCallback = hasCallback;
+	}
+
+	get type() {
+		return "accepted harmony modules";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.dependencies);
+		write(this.hasCallback);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.dependencies = read();
+		this.hasCallback = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	HarmonyAcceptDependency,
+	"webpack/lib/dependencies/HarmonyAcceptDependency"
+);
+
+HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {HarmonyAcceptDependency} */ (dependency);
+		const {
+			module,
+			runtime,
+			runtimeRequirements,
+			runtimeTemplate,
+			moduleGraph,
+			chunkGraph
+		} = templateContext;
+
+		/**
+		 * Gets dependency module id.
+		 * @param {Dependency} dependency the dependency to get module id for
+		 * @returns {ModuleId | null} the module id or null if not found
+		 */
+		const getDependencyModuleId = (dependency) =>
+			chunkGraph.getModuleId(
+				/** @type {Module} */ (moduleGraph.getModule(dependency))
+			);
+
+		/**
+		 * Checks whether this harmony accept dependency is related harmony import dependency.
+		 * @param {Dependency} a the first dependency
+		 * @param {Dependency} b the second dependency
+		 * @returns {boolean} true if the dependencies are related
+		 */
+		const isRelatedHarmonyImportDependency = (a, b) =>
+			a !== b &&
+			b instanceof HarmonyImportDependency &&
+			getDependencyModuleId(a) === getDependencyModuleId(b);
+
+		/**
+		 * HarmonyAcceptImportDependency lacks a lot of information, such as the defer property.
+		 * One HarmonyAcceptImportDependency may need to generate multiple ImportStatements.
+		 * Therefore, we find its original HarmonyImportDependency for code generation.
+		 * @param {HarmonyAcceptImportDependency} dependency the dependency to get harmony import dependencies for
+		 * @returns {HarmonyImportDependency[]} array of related harmony import dependencies
+		 */
+		const getHarmonyImportDependencies = (dependency) => {
+			/** @type {HarmonyImportDependency[]} */
+			const result = [];
+			/** @type {HarmonyImportDependency | null} */
+			let deferDependency = null;
+			/** @type {HarmonyImportDependency | null} */
+			let noDeferredDependency = null;
+
+			for (const d of module.dependencies) {
+				if (deferDependency && noDeferredDependency) break;
+				if (isRelatedHarmonyImportDependency(dependency, d)) {
+					if (
+						ImportPhaseUtils.isDefer(
+							/** @type {HarmonyImportDependency} */ (d).phase
+						)
+					) {
+						deferDependency = /** @type {HarmonyImportDependency} */ (d);
+					} else {
+						noDeferredDependency = /** @type {HarmonyImportDependency} */ (d);
+					}
+				}
+			}
+			if (deferDependency) result.push(deferDependency);
+			if (noDeferredDependency) result.push(noDeferredDependency);
+			if (result.length === 0) {
+				// fallback to the original dependency
+				result.push(dependency);
+			}
+			return result;
+		};
+
+		/** @type {HarmonyImportDependency[]} */
+		const syncDeps = [];
+
+		/** @type {HarmonyAcceptImportDependency[]} */
+		const asyncDeps = [];
+
+		for (const dependency of dep.dependencies) {
+			const connection = moduleGraph.getConnection(dependency);
+
+			if (connection && moduleGraph.isAsync(connection.module)) {
+				asyncDeps.push(dependency);
+			} else {
+				syncDeps.push(...getHarmonyImportDependencies(dependency));
+			}
+		}
+
+		let content = syncDeps
+			.map((dependency) => {
+				const referencedModule = moduleGraph.getModule(dependency);
+				return {
+					dependency,
+					runtimeCondition: referencedModule
+						? HarmonyImportDependency.Template.getImportEmittedRuntime(
+								module,
+								referencedModule
+							)
+						: false
+				};
+			})
+			.filter(({ runtimeCondition }) => runtimeCondition !== false)
+			.map(({ dependency, runtimeCondition }) => {
+				const condition = runtimeTemplate.runtimeConditionExpression({
+					chunkGraph,
+					runtime,
+					runtimeCondition,
+					runtimeRequirements
+				});
+				const s = dependency.getImportStatement(true, templateContext);
+				const code = s[0] + s[1];
+				if (condition !== "true") {
+					return `if (${condition}) {\n${Template.indent(code)}\n}\n`;
+				}
+				return code;
+			})
+			.join("");
+
+		const promises = new Map(
+			asyncDeps.map((dependency) => [
+				dependency.getImportVar(moduleGraph),
+				dependency.getModuleExports(templateContext)
+			])
+		);
+
+		let optAsync = "";
+		if (promises.size !== 0) {
+			optAsync = "async ";
+			content += new AwaitDependenciesInitFragment(promises).getContent({
+				...templateContext,
+				type: "javascript"
+			});
+		}
+
+		if (dep.hasCallback) {
+			if (runtimeTemplate.supportsArrowFunction()) {
+				source.insert(
+					dep.range[0],
+					`${optAsync}__WEBPACK_OUTDATED_DEPENDENCIES__ => { ${content} return (`
+				);
+				source.insert(dep.range[1], ")(__WEBPACK_OUTDATED_DEPENDENCIES__); }");
+			} else {
+				source.insert(
+					dep.range[0],
+					`${optAsync}function(__WEBPACK_OUTDATED_DEPENDENCIES__) { ${content} return (`
+				);
+				source.insert(
+					dep.range[1],
+					")(__WEBPACK_OUTDATED_DEPENDENCIES__); }.bind(this)"
+				);
+			}
+			return;
+		}
+
+		const arrow = runtimeTemplate.supportsArrowFunction();
+		source.insert(
+			dep.range[1] - 0.5,
+			`, ${arrow ? `${optAsync}() =>` : `${optAsync}function()`} { ${content} }`
+		);
+	}
+};
+
+module.exports = HarmonyAcceptDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyAcceptImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyAcceptImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyAcceptImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const HarmonyImportDependency = require("./HarmonyImportDependency");
+const { ImportPhase } = require("./ImportPhase");
+const NullDependency = require("./NullDependency");
+
+class HarmonyAcceptImportDependency extends HarmonyImportDependency {
+	/**
+	 * Creates an instance of HarmonyAcceptImportDependency.
+	 * @param {string} request the request string
+	 */
+	constructor(request) {
+		super(request, Infinity, ImportPhase.Evaluation);
+		this.weak = true;
+	}
+
+	get type() {
+		return "harmony accept";
+	}
+}
+
+makeSerializable(
+	HarmonyAcceptImportDependency,
+	"webpack/lib/dependencies/HarmonyAcceptImportDependency"
+);
+
+HarmonyAcceptImportDependency.Template =
+	/** @type {typeof HarmonyImportDependency.Template} */ (
+		NullDependency.Template
+	);
+
+module.exports = HarmonyAcceptImportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,92 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+
+class HarmonyCompatibilityDependency extends NullDependency {
+	get type() {
+		return "harmony export header";
+	}
+}
+
+makeSerializable(
+	HarmonyCompatibilityDependency,
+	"webpack/lib/dependencies/HarmonyCompatibilityDependency"
+);
+
+HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{
+			module,
+			runtimeTemplate,
+			moduleGraph,
+			initFragments,
+			runtimeRequirements,
+			runtime,
+			concatenationScope
+		}
+	) {
+		if (concatenationScope) return;
+		const exportsInfo = moduleGraph.getExportsInfo(module);
+		if (
+			exportsInfo.getReadOnlyExportInfo("__esModule").getUsed(runtime) !==
+			UsageState.Unused
+		) {
+			const content = runtimeTemplate.defineEsModuleFlagStatement({
+				exportsArgument: module.exportsArgument,
+				runtimeRequirements
+			});
+			initFragments.push(
+				new InitFragment(
+					content,
+					InitFragment.STAGE_HARMONY_EXPORTS,
+					0,
+					"harmony compatibility"
+				)
+			);
+		}
+		if (moduleGraph.isAsync(module)) {
+			runtimeRequirements.add(RuntimeGlobals.module);
+			runtimeRequirements.add(RuntimeGlobals.asyncModule);
+			initFragments.push(
+				new InitFragment(
+					runtimeTemplate.supportsArrowFunction()
+						? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n`
+						: `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`,
+					InitFragment.STAGE_ASYNC_BOUNDARY,
+					0,
+					undefined,
+					`\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }${
+						/** @type {BuildMeta} */ (module.buildMeta).async ? ", 1" : ""
+					});`
+				)
+			);
+		}
+	}
+};
+
+module.exports = HarmonyCompatibilityDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyDetectionParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyDetectionParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyDetectionParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,126 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants");
+const EnvironmentNotSupportAsyncWarning = require("../errors/EnvironmentNotSupportAsyncWarning");
+const DynamicExports = require("./DynamicExports");
+const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
+const HarmonyExports = require("./HarmonyExports");
+
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+
+const PLUGIN_NAME = "HarmonyDetectionParserPlugin";
+
+module.exports = class HarmonyDetectionParserPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.program.tap(PLUGIN_NAME, (ast) => {
+			const isStrictHarmony =
+				parser.state.module.type === JAVASCRIPT_MODULE_TYPE_ESM;
+			const isHarmony =
+				isStrictHarmony ||
+				ast.body.some(
+					(statement) =>
+						statement.type === "ImportDeclaration" ||
+						statement.type === "ExportDefaultDeclaration" ||
+						statement.type === "ExportNamedDeclaration" ||
+						statement.type === "ExportAllDeclaration"
+				);
+			if (isHarmony) {
+				const module = parser.state.module;
+				const compatDep = new HarmonyCompatibilityDependency();
+				compatDep.loc = {
+					start: {
+						line: -1,
+						column: 0
+					},
+					end: {
+						line: -1,
+						column: 0
+					},
+					index: -3
+				};
+				module.addPresentationalDependency(compatDep);
+				DynamicExports.bailout(parser.state);
+				HarmonyExports.enable(parser.state, isStrictHarmony);
+				parser.scope.isStrict = true;
+			}
+		});
+
+		parser.hooks.topLevelAwait.tap(PLUGIN_NAME, () => {
+			const module = parser.state.module;
+			if (!HarmonyExports.isEnabled(parser.state)) {
+				throw new Error(
+					"Top-level-await is only supported in EcmaScript Modules"
+				);
+			}
+			/** @type {BuildMeta} */
+			(module.buildMeta).async = true;
+			EnvironmentNotSupportAsyncWarning.check(
+				module,
+				parser.state.compilation.runtimeTemplate,
+				"topLevelAwait"
+			);
+		});
+
+		/**
+		 * Returns true if in harmony.
+		 * @returns {boolean | undefined} true if in harmony
+		 */
+		const skipInHarmony = () => {
+			if (HarmonyExports.isEnabled(parser.state)) {
+				return true;
+			}
+		};
+
+		/**
+		 * Returns null if in harmony.
+		 * @returns {null | undefined} null if in harmony
+		 */
+		const nullInHarmony = () => {
+			if (HarmonyExports.isEnabled(parser.state)) {
+				return null;
+			}
+		};
+
+		/**
+		 * Walks call arguments so import bindings used inside callbacks are
+		 * still tracked, then skips default AMD/CommonJS handling.
+		 * @param {import("estree").CallExpression} expr call expression
+		 * @returns {boolean | undefined} true if in harmony
+		 */
+		const walkArgumentsAndSkipInHarmony = (expr) => {
+			if (HarmonyExports.isEnabled(parser.state)) {
+				if (expr.arguments) parser.walkExpressions(expr.arguments);
+				return true;
+			}
+		};
+
+		const nonHarmonyIdentifiers = ["define", "exports"];
+		for (const identifier of nonHarmonyIdentifiers) {
+			parser.hooks.evaluateTypeof
+				.for(identifier)
+				.tap(PLUGIN_NAME, nullInHarmony);
+			parser.hooks.typeof.for(identifier).tap(PLUGIN_NAME, skipInHarmony);
+			parser.hooks.evaluate.for(identifier).tap(PLUGIN_NAME, nullInHarmony);
+			parser.hooks.expression.for(identifier).tap(PLUGIN_NAME, skipInHarmony);
+			parser.hooks.call
+				.for(identifier)
+				.tap(
+					PLUGIN_NAME,
+					identifier === "define"
+						? walkArgumentsAndSkipInHarmony
+						: skipInHarmony
+				);
+		}
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,169 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const { ExportPresenceModes } = require("./HarmonyImportDependency");
+const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
+const { ImportPhase } = require("./ImportPhase");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./HarmonyImportDependency").Ids} Ids */
+
+/**
+ * Dependency for static evaluating import specifier. e.g.
+ * @example
+ * import a from "a";
+ * "x" in a;
+ * a.x !== undefined; // if x value statically analyzable
+ */
+class HarmonyEvaluatedImportSpecifierDependency extends HarmonyImportSpecifierDependency {
+	/**
+	 * Creates an instance of HarmonyEvaluatedImportSpecifierDependency.
+	 * @param {string} request the request string
+	 * @param {number} sourceOrder source order
+	 * @param {Ids} ids ids
+	 * @param {string} name name
+	 * @param {Range} range location in source code
+	 * @param {ImportAttributes | undefined} attributes import assertions
+	 * @param {string} operator operator
+	 */
+	constructor(request, sourceOrder, ids, name, range, attributes, operator) {
+		super(
+			request,
+			sourceOrder,
+			ids,
+			name,
+			range,
+			ExportPresenceModes.NONE,
+			ImportPhase.Evaluation,
+			attributes,
+			[]
+		);
+		this.operator = operator;
+	}
+
+	get type() {
+		return `evaluated X ${this.operator} harmony import specifier`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		super.serialize(context);
+		const { write } = context;
+		write(this.operator);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		super.deserialize(context);
+		const { read } = context;
+		this.operator = read();
+	}
+}
+
+makeSerializable(
+	HarmonyEvaluatedImportSpecifierDependency,
+	"webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency"
+);
+
+HarmonyEvaluatedImportSpecifierDependency.Template = class HarmonyEvaluatedImportSpecifierDependencyTemplate extends (
+	HarmonyImportSpecifierDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep =
+			/** @type {HarmonyEvaluatedImportSpecifierDependency} */
+			(dependency);
+		const { module, moduleGraph, runtime } = templateContext;
+		const connection = moduleGraph.getConnection(dep);
+		// Skip rendering depending when dependency is conditional
+		if (connection && !connection.isTargetActive(runtime)) return;
+
+		const exportsInfo = moduleGraph.getExportsInfo(
+			/** @type {ModuleGraphConnection} */ (connection).module
+		);
+		const ids = dep.getIds(moduleGraph);
+
+		/** @type {boolean | undefined | null} */
+		let value;
+
+		const exportsType =
+			/** @type {ModuleGraphConnection} */
+			(connection).module.getExportsType(
+				moduleGraph,
+				/** @type {BuildMeta} */
+				(module.buildMeta).strictHarmonyModule
+			);
+		switch (exportsType) {
+			case "default-with-named": {
+				if (ids[0] === "default") {
+					value =
+						ids.length === 1 || exportsInfo.isExportProvided(ids.slice(1));
+				} else {
+					value = exportsInfo.isExportProvided(ids);
+				}
+				break;
+			}
+			case "namespace": {
+				value =
+					ids[0] === "__esModule"
+						? ids.length === 1 || undefined
+						: exportsInfo.isExportProvided(ids);
+				break;
+			}
+			case "dynamic": {
+				if (ids[0] !== "default") {
+					value = exportsInfo.isExportProvided(ids);
+				}
+				break;
+			}
+			// default-only could lead to runtime error, when default value is primitive
+		}
+
+		if (typeof value === "boolean") {
+			source.replace(dep.range[0], dep.range[1] - 1, ` ${value}`);
+		} else {
+			const usedName = exportsInfo.getUsedName(ids, runtime);
+
+			const code = this._getCodeForIds(
+				dep,
+				source,
+				templateContext,
+				ids.slice(0, -1)
+			);
+			source.replace(
+				dep.range[0],
+				dep.range[1] - 1,
+				`${
+					usedName ? JSON.stringify(usedName[usedName.length - 1]) : '""'
+				} in ${code}`
+			);
+		}
+	}
+};
+
+module.exports = HarmonyEvaluatedImportSpecifierDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,268 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const CompatibilityPlugin = require("../CompatibilityPlugin");
+const WebpackError = require("../errors/WebpackError");
+const { getImportAttributes } = require("../javascript/JavascriptParser");
+const InnerGraph = require("../optimize/InnerGraph");
+const ConstDependency = require("./ConstDependency");
+const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDependency");
+const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency");
+const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency");
+const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency");
+const { ExportPresenceModes } = require("./HarmonyImportDependency");
+const {
+	harmonySpecifierTag
+} = require("./HarmonyImportDependencyParserPlugin");
+const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
+const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").ClassDeclaration} ClassDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").FunctionDeclaration} FunctionDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
+/** @typedef {import("../CompatibilityPlugin").CompatibilitySettings} CompatibilitySettings */
+
+const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency;
+
+const PLUGIN_NAME = "HarmonyExportDependencyParserPlugin";
+
+module.exports = class HarmonyExportDependencyParserPlugin {
+	/**
+	 * Creates an instance of HarmonyExportDependencyParserPlugin.
+	 * @param {JavascriptParserOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+		this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
+			options.reexportExportsPresence,
+			options
+		);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const { exportPresenceMode } = this;
+		const getImportPhase = createGetImportPhase(
+			this.options.deferImport,
+			false
+		);
+
+		parser.hooks.export.tap(PLUGIN_NAME, (statement) => {
+			const dep = new HarmonyExportHeaderDependency(
+				/** @type {Range | false} */ (
+					statement.declaration && statement.declaration.range
+				),
+				/** @type {Range} */ (statement.range)
+			);
+			dep.loc = Object.create(
+				/** @type {DependencyLocation} */ (statement.loc)
+			);
+			dep.loc.index = -1;
+			parser.state.module.addPresentationalDependency(dep);
+			return true;
+		});
+		parser.hooks.exportImport.tap(PLUGIN_NAME, (statement, source) => {
+			parser.state.lastHarmonyImportOrder =
+				(parser.state.lastHarmonyImportOrder || 0) + 1;
+			const clearDep = new ConstDependency(
+				"",
+				/** @type {Range} */ (statement.range)
+			);
+			clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
+			clearDep.loc.index = -1;
+			parser.state.module.addPresentationalDependency(clearDep);
+
+			const phase = getImportPhase(parser, statement);
+			if (phase && ImportPhaseUtils.isDefer(phase)) {
+				const error = new WebpackError(
+					"Deferred re-export (`export defer * as namespace from '...'`) is not a part of the Import Defer proposal.\nUse the following code instead:\n    import defer * as namespace from '...';\n    export { namespace };"
+				);
+				error.loc = statement.loc || undefined;
+				parser.state.current.addError(error);
+			}
+			const sideEffectDep = new HarmonyImportSideEffectDependency(
+				/** @type {string} */ (source),
+				parser.state.lastHarmonyImportOrder,
+				phase,
+				getImportAttributes(statement)
+			);
+			sideEffectDep.loc = Object.create(
+				/** @type {DependencyLocation} */ (statement.loc)
+			);
+			sideEffectDep.loc.index = -1;
+			parser.state.current.addDependency(sideEffectDep);
+			return true;
+		});
+		parser.hooks.exportExpression.tap(PLUGIN_NAME, (statement, node) => {
+			const isFunctionDeclaration = node.type === "FunctionDeclaration";
+			const exprRange = /** @type {Range} */ (node.range);
+			const statementRange = /** @type {Range} */ (statement.range);
+			const comments = parser.getComments([statementRange[0], exprRange[0]]);
+			const dep = new HarmonyExportExpressionDependency(
+				exprRange,
+				statementRange,
+				comments
+					.map((c) => {
+						switch (c.type) {
+							case "Block":
+								return `/*${c.value}*/`;
+							case "Line":
+								return `//${c.value}\n`;
+						}
+						return "";
+					})
+					.join(""),
+				node.type.endsWith("Declaration") &&
+					/** @type {FunctionDeclaration | ClassDeclaration} */ (node).id
+					? /** @type {FunctionDeclaration | ClassDeclaration} */
+						(node).id.name
+					: isFunctionDeclaration
+						? {
+								range: [
+									exprRange[0],
+									node.params.length > 0
+										? /** @type {Range} */ (node.params[0].range)[0]
+										: /** @type {Range} */ (node.body.range)[0]
+								],
+								prefix: `${node.async ? "async " : ""}function${
+									node.generator ? "*" : ""
+								} `,
+								suffix: `(${node.params.length > 0 ? "" : ") "}`
+							}
+						: undefined
+			);
+			dep.isAnonymousDefault =
+				this.options.anonymousDefaultExportName !== false &&
+				(node.type === "ArrowFunctionExpression" ||
+					((node.type === "FunctionDeclaration" ||
+						node.type === "FunctionExpression" ||
+						node.type === "ClassDeclaration" ||
+						node.type === "ClassExpression") &&
+						!node.id));
+			dep.loc = Object.create(
+				/** @type {DependencyLocation} */ (statement.loc)
+			);
+			dep.loc.index = -1;
+			parser.state.current.addDependency(dep);
+			InnerGraph.addVariableUsage(
+				parser,
+				node.type.endsWith("Declaration") &&
+					/** @type {FunctionDeclaration | ClassDeclaration} */ (node).id
+					? /** @type {FunctionDeclaration | ClassDeclaration} */ (node).id.name
+					: "*default*",
+				"default"
+			);
+			return true;
+		});
+		parser.hooks.exportSpecifier.tap(
+			PLUGIN_NAME,
+			(statement, id, name, idx) => {
+				// CompatibilityPlugin may change exports name
+				// not handle re-export or import then export situation as current CompatibilityPlugin only
+				// rename symbol in declaration module, not change exported symbol
+				const variable = parser.getTagData(
+					id,
+					CompatibilityPlugin.nestedWebpackIdentifierTag
+				);
+				if (variable && /** @type {CompatibilitySettings} */ (variable).name) {
+					// CompatibilityPlugin changes exports to a new name, should updates exports name
+					id = /** @type {CompatibilitySettings} */ (variable).name;
+				}
+
+				const settings =
+					/** @type {HarmonySettings} */
+					(parser.getTagData(id, harmonySpecifierTag));
+				const harmonyNamedExports = (parser.state.harmonyNamedExports =
+					parser.state.harmonyNamedExports || new Set());
+				harmonyNamedExports.add(name);
+				InnerGraph.addVariableUsage(parser, id, name);
+				const dep = settings
+					? new HarmonyExportImportedSpecifierDependency(
+							settings.source,
+							settings.sourceOrder,
+							settings.ids,
+							name,
+							harmonyNamedExports,
+							null,
+							exportPresenceMode,
+							null,
+							settings.phase,
+							settings.attributes
+						)
+					: new HarmonyExportSpecifierDependency(id, name);
+				dep.loc = Object.create(
+					/** @type {DependencyLocation} */ (statement.loc)
+				);
+				dep.loc.index = idx;
+				const isAsiSafe = !parser.isAsiPosition(
+					/** @type {Range} */
+					(statement.range)[0]
+				);
+				if (!isAsiSafe) {
+					parser.setAsiPosition(/** @type {Range} */ (statement.range)[1]);
+				}
+				parser.state.current.addDependency(dep);
+				return true;
+			}
+		);
+		parser.hooks.exportImportSpecifier.tap(
+			PLUGIN_NAME,
+			(statement, source, id, name, idx) => {
+				const harmonyNamedExports = (parser.state.harmonyNamedExports =
+					parser.state.harmonyNamedExports || new Set());
+				/** @type {InstanceType<HarmonyStarExportsList> | null} */
+				let harmonyStarExports = null;
+				if (name) {
+					harmonyNamedExports.add(name);
+				} else {
+					harmonyStarExports = parser.state.harmonyStarExports =
+						parser.state.harmonyStarExports || new HarmonyStarExportsList();
+				}
+				const attributes = getImportAttributes(statement);
+				const dep = new HarmonyExportImportedSpecifierDependency(
+					/** @type {string} */
+					(source),
+					/** @type {number} */
+					(parser.state.lastHarmonyImportOrder),
+					id ? [id] : [],
+					name,
+					harmonyNamedExports,
+					// eslint-disable-next-line unicorn/prefer-spread
+					harmonyStarExports && harmonyStarExports.slice(),
+					exportPresenceMode,
+					harmonyStarExports,
+					getImportPhase(parser, statement),
+					attributes
+				);
+				if (harmonyStarExports) {
+					harmonyStarExports.push(dep);
+				}
+				dep.loc = Object.create(
+					/** @type {DependencyLocation} */ (statement.loc)
+				);
+				dep.loc.index = idx;
+				const isAsiSafe = !parser.isAsiPosition(
+					/** @type {Range} */
+					(statement.range)[0]
+				);
+				if (!isAsiSafe) {
+					parser.setAsiPosition(/** @type {Range} */ (statement.range)[1]);
+				}
+				parser.state.current.addDependency(dep);
+				return true;
+			}
+		);
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExportExpressionDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExportExpressionDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExportExpressionDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,254 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ConcatenationScope = require("../ConcatenationScope");
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess } = require("../util/property");
+const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./HarmonyExportInitFragment").ExportMap} ExportMap */
+
+class HarmonyExportExpressionDependency extends NullDependency {
+	/**
+	 * Creates an instance of HarmonyExportExpressionDependency.
+	 * @param {Range} range range
+	 * @param {Range} rangeStatement range statement
+	 * @param {string} prefix prefix
+	 * @param {string | { id?: string | undefined, range: Range, prefix: string, suffix: string }=} declarationId declaration id
+	 */
+	constructor(range, rangeStatement, prefix, declarationId) {
+		super();
+		this.range = range;
+		this.rangeStatement = rangeStatement;
+		this.prefix = prefix;
+		this.declarationId = declarationId;
+		this.isAnonymousDefault = false;
+	}
+
+	get type() {
+		return "harmony export expression";
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		return {
+			exports: ["default"],
+			priority: 1,
+			terminalBinding: true,
+			dependencies: undefined
+		};
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		// The expression/declaration is already covered by SideEffectsFlagPlugin
+		return false;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.rangeStatement);
+		write(this.prefix);
+		write(this.declarationId);
+		write(this.isAnonymousDefault);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.rangeStatement = read();
+		this.prefix = read();
+		this.declarationId = read();
+		this.isAnonymousDefault = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	HarmonyExportExpressionDependency,
+	"webpack/lib/dependencies/HarmonyExportExpressionDependency"
+);
+
+HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{
+			module,
+			moduleGraph,
+			runtimeTemplate,
+			runtimeRequirements,
+			initFragments,
+			runtime,
+			concatenationScope
+		}
+	) {
+		const dep = /** @type {HarmonyExportExpressionDependency} */ (dependency);
+		const { declarationId } = dep;
+		const exportsName = module.exportsArgument;
+		if (declarationId) {
+			/** @type {string} */
+			let name;
+			if (typeof declarationId === "string") {
+				name = declarationId;
+			} else {
+				name = ConcatenationScope.DEFAULT_EXPORT;
+				source.replace(
+					declarationId.range[0],
+					declarationId.range[1] - 1,
+					`${declarationId.prefix}${name}${declarationId.suffix}`
+				);
+			}
+
+			const used = concatenationScope
+				? undefined
+				: moduleGraph.getExportsInfo(module).getUsedName("default", runtime);
+
+			if (concatenationScope) {
+				concatenationScope.registerExport("default", name);
+			} else if (used) {
+				/** @type {ExportMap} */
+				const map = new Map();
+				map.set(used, `/* export default binding */ ${name}`);
+				initFragments.push(new HarmonyExportInitFragment(exportsName, map));
+			}
+
+			source.replace(
+				dep.rangeStatement[0],
+				dep.range[0] - 1,
+				`/* harmony default export */ ${dep.prefix}`
+			);
+
+			if (
+				typeof declarationId !== "string" &&
+				dep.isAnonymousDefault &&
+				(concatenationScope || used)
+			) {
+				// Fix .name for anonymous default export function declarations
+				// see test/test262-cases/test/language/module-code/instn-named-bndng-dflt-fun-anon.js cspell:disable-line
+				runtimeRequirements.add(RuntimeGlobals.setAnonymousDefaultName);
+				initFragments.push(
+					new InitFragment(
+						`${RuntimeGlobals.setAnonymousDefaultName}(${name});\n`,
+						InitFragment.STAGE_HARMONY_EXPORTS,
+						2
+					)
+				);
+			}
+		} else {
+			/** @type {string} */
+			let content;
+			let name = ConcatenationScope.DEFAULT_EXPORT;
+			let defaultIsUsed = Boolean(concatenationScope);
+			if (runtimeTemplate.supportsConst()) {
+				content = `/* harmony default export */ const ${name} = `;
+				if (concatenationScope) {
+					concatenationScope.registerExport("default", name);
+				} else {
+					const used = moduleGraph
+						.getExportsInfo(module)
+						.getUsedName("default", runtime);
+					if (used) {
+						defaultIsUsed = true;
+						runtimeRequirements.add(RuntimeGlobals.exports);
+						/** @type {ExportMap} */
+						const map = new Map();
+						map.set(used, name);
+						initFragments.push(new HarmonyExportInitFragment(exportsName, map));
+					} else {
+						content = `/* unused harmony default export */ var ${name} = `;
+					}
+				}
+			} else if (concatenationScope) {
+				content = `/* harmony default export */ var ${name} = `;
+				concatenationScope.registerExport("default", name);
+			} else {
+				const used = moduleGraph
+					.getExportsInfo(module)
+					.getUsedName("default", runtime);
+				if (used) {
+					defaultIsUsed = true;
+					runtimeRequirements.add(RuntimeGlobals.exports);
+					// This is a little bit incorrect as TDZ is not correct, but we can't use const.
+					// No local `__WEBPACK_DEFAULT_EXPORT__` binding is created in this path,
+					// so the anonymous-default `.name` fix-up below must reference the actual
+					// assignment target instead. See issue #20793.
+					name = `${exportsName}${propertyAccess(
+						typeof used === "string" ? [used] : used
+					)}`;
+					content = `/* harmony default export */ ${name} = `;
+				} else {
+					content = `/* unused harmony default export */ var ${name} = `;
+				}
+			}
+
+			if (dep.range) {
+				source.replace(
+					dep.rangeStatement[0],
+					dep.range[0] - 1,
+					`${content}(${dep.prefix}`
+				);
+				if (dep.isAnonymousDefault && defaultIsUsed) {
+					// Fix .name for anonymous default export expressions
+					// see test/test262-cases/test/language/module-code/eval-export-dflt-cls-anon.js cspell:disable-line
+					runtimeRequirements.add(RuntimeGlobals.setAnonymousDefaultName);
+					source.replace(
+						dep.range[1],
+						dep.rangeStatement[1] - 0.5,
+						`);\n${RuntimeGlobals.setAnonymousDefaultName}(${name});`
+					);
+				} else {
+					source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");");
+				}
+				return;
+			}
+
+			source.replace(dep.rangeStatement[0], dep.rangeStatement[1] - 1, content);
+		}
+	}
+};
+
+module.exports = HarmonyExportExpressionDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExportHeaderDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExportHeaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExportHeaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,82 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class HarmonyExportHeaderDependency extends NullDependency {
+	/**
+	 * Creates an instance of HarmonyExportHeaderDependency.
+	 * @param {Range | false} range range
+	 * @param {Range} rangeStatement range statement
+	 */
+	constructor(range, rangeStatement) {
+		super();
+		this.range = range;
+		this.rangeStatement = rangeStatement;
+	}
+
+	get type() {
+		return "harmony export header";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.rangeStatement);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.rangeStatement = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	HarmonyExportHeaderDependency,
+	"webpack/lib/dependencies/HarmonyExportHeaderDependency"
+);
+
+HarmonyExportHeaderDependency.Template = class HarmonyExportDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {HarmonyExportHeaderDependency} */ (dependency);
+		const content = "";
+		const replaceUntil = dep.range
+			? dep.range[0] - 1
+			: dep.rangeStatement[1] - 1;
+		source.replace(dep.rangeStatement[0], replaceUntil, content);
+	}
+};
+
+module.exports = HarmonyExportHeaderDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1642 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ConditionalInitFragment = require("../ConditionalInitFragment");
+const Dependency = require("../Dependency");
+const { UsageState } = require("../ExportsInfo");
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const {
+	getMakeDeferredNamespaceModeFromExportsType
+} = require("../runtime/MakeDeferredNamespaceObjectRuntime");
+const { countIterable } = require("../util/IterableHelpers");
+const { combine, first } = require("../util/SetHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess, propertyName } = require("../util/property");
+const {
+	filterRuntime,
+	getRuntimeKey,
+	keyToRuntime
+} = require("../util/runtime");
+const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
+const HarmonyImportDependency = require("./HarmonyImportDependency");
+const HarmonyLinkingError = require("./HarmonyLinkingError");
+const { ImportPhaseUtils } = require("./ImportPhase");
+const processExportInfo = require("./processExportInfo");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ExportsInfo")} ExportsInfo */
+/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../ExportsInfo").UsedName} UsedName */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../Module").ExportsType} ExportsType */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./HarmonyImportDependency").Ids} Ids */
+/** @typedef {import("./HarmonyImportDependency").ExportPresenceMode} ExportPresenceMode */
+/** @typedef {import("./HarmonyExportInitFragment").ExportMap} ExportMap */
+/** @typedef {import("../dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
+
+/** @typedef {"missing" | "unused" | "empty-star" | "reexport-dynamic-default" | "reexport-named-default" | "reexport-namespace-object" | "reexport-fake-namespace-object" | "reexport-undefined" | "normal-reexport" | "dynamic-reexport"} ExportModeType */
+
+const { ExportPresenceModes } = HarmonyImportDependency;
+
+const idsSymbol = /** @type {symbol} */ (
+	Symbol("HarmonyExportImportedSpecifierDependency.ids")
+);
+
+class NormalReexportItem {
+	/**
+	 * Creates an instance of NormalReexportItem.
+	 * @param {string} name export name
+	 * @param {Ids} ids reexported ids from other module
+	 * @param {ExportInfo} exportInfo export info from other module
+	 * @param {boolean} checked true, if it should be checked at runtime if this export exists
+	 * @param {boolean} hidden true, if it is hidden behind another active export in the same module
+	 */
+	constructor(name, ids, exportInfo, checked, hidden) {
+		this.name = name;
+		this.ids = ids;
+		this.exportInfo = exportInfo;
+		this.checked = checked;
+		this.hidden = hidden;
+	}
+}
+
+/** @typedef {Set<string>} ExportModeIgnored */
+/** @typedef {Set<string>} ExportModeHidden */
+
+class ExportMode {
+	/**
+	 * Creates an instance of ExportMode.
+	 * @param {ExportModeType} type type of the mode
+	 */
+	constructor(type) {
+		/** @type {ExportModeType} */
+		this.type = type;
+
+		// for "normal-reexport":
+		/** @type {NormalReexportItem[] | null} */
+		this.items = null;
+
+		// for "reexport-named-default" | "reexport-fake-namespace-object" | "reexport-namespace-object"
+		/** @type {string | null} */
+		this.name = null;
+		/** @type {ExportInfo | null} */
+		this.partialNamespaceExportInfo = null;
+
+		// for "dynamic-reexport":
+		/** @type {ExportModeIgnored | null} */
+		this.ignored = null;
+
+		// for "dynamic-reexport" | "empty-star":
+		/** @type {ExportModeHidden | undefined | null} */
+		this.hidden = null;
+
+		// for "missing":
+		/** @type {string | null} */
+		this.userRequest = null;
+
+		// for "reexport-fake-namespace-object":
+		/** @type {number} */
+		this.fakeType = 0;
+	}
+}
+
+/** @typedef {number[]} DependencyIndices */
+
+const RETURNS_TRUE = () => true;
+
+/**
+ * Detect a per-name cycle when collecting `export *` contributions from
+ * `exportInfo`'s module into `parentModule`. The TC39 `ResolveExport`
+ * algorithm tracks a `resolveSet` of `(module, exportName)` pairs and
+ * returns null when an entry is revisited — letting the `StarExportEntries`
+ * loop fall through to a non-cyclic source. Webpack's static export graph
+ * does not run that resolution algorithm, so we approximate it: if the
+ * imported module's same-named export ultimately re-exports from
+ * `parentModule` under the same name, the star contribution is cyclic and
+ * must be skipped. The non-cyclic alternative (a sibling `export *` that
+ * provides a real binding) then wins.
+ *
+ * We walk the target chain one hop at a time using `findTarget` with a
+ * "match anything" filter so we can guard against namespace targets
+ * (`export * as ns from`, where `target.export` is undefined) and against
+ * unrelated cycles in the graph that would otherwise loop forever inside
+ * `_findTarget`.
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ExportInfo} exportInfo export info on the imported module
+ * @param {Module} parentModule the module that contains the star reexport
+ * @returns {boolean} true when this export reexports back to the parent module under the same name
+ */
+const isStarReexportBackToParent = (moduleGraph, exportInfo, parentModule) => {
+	// Fast path: probe the first hop directly. The overwhelmingly common case
+	// in real builds is a terminal local binding (no `_target`) — `findTarget`
+	// returns `undefined` and we exit without allocating a `visited` set.
+	const firstTarget = exportInfo.findTarget(moduleGraph, RETURNS_TRUE);
+	if (!firstTarget || typeof firstTarget !== "object") return false;
+	const name = exportInfo.name;
+	if (
+		firstTarget.module === parentModule &&
+		Array.isArray(firstTarget.export) &&
+		firstTarget.export.length === 1 &&
+		firstTarget.export[0] === name
+	) {
+		return true;
+	}
+	if (!Array.isArray(firstTarget.export) || firstTarget.export.length === 0) {
+		return false;
+	}
+	// Multi-hop chain — allocate visited tracking now. The set protects against
+	// unrelated cycles in the graph that would otherwise spin inside
+	// `_findTarget` (its `alreadyVisited` is only seeded for the entry node).
+	let current = moduleGraph
+		.getExportsInfo(firstTarget.module)
+		.getReadOnlyExportInfo(firstTarget.export[0]);
+	/** @type {Set<ExportInfo>} */
+	const visited = new Set([exportInfo, current]);
+	for (;;) {
+		const target = current.findTarget(moduleGraph, RETURNS_TRUE);
+		if (!target || typeof target !== "object") return false;
+		if (
+			target.module === parentModule &&
+			Array.isArray(target.export) &&
+			target.export.length === 1 &&
+			target.export[0] === name
+		) {
+			return true;
+		}
+		if (!Array.isArray(target.export) || target.export.length === 0) {
+			return false;
+		}
+		const next = moduleGraph
+			.getExportsInfo(target.module)
+			.getReadOnlyExportInfo(target.export[0]);
+		if (visited.has(next)) return false;
+		visited.add(next);
+		current = next;
+	}
+};
+
+/**
+ * Determine export assignments.
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {HarmonyExportImportedSpecifierDependency[]} dependencies dependencies
+ * @param {HarmonyExportImportedSpecifierDependency=} additionalDependency additional dependency
+ * @returns {{ names: ExportInfoName[], dependencyIndices: DependencyIndices }} result
+ */
+const determineExportAssignments = (
+	moduleGraph,
+	dependencies,
+	additionalDependency
+) => {
+	/** @type {Set<ExportInfoName>} */
+	const names = new Set();
+	/** @type {DependencyIndices} */
+	const dependencyIndices = [];
+
+	if (additionalDependency) {
+		dependencies = [...dependencies, additionalDependency];
+	}
+
+	const referenceDep = dependencies[0] || additionalDependency;
+	const parentModule = referenceDep
+		? moduleGraph.getParentModule(referenceDep)
+		: null;
+
+	for (const dep of dependencies) {
+		const i = dependencyIndices.length;
+		dependencyIndices[i] = names.size;
+		const otherImportedModule = moduleGraph.getModule(dep);
+		if (otherImportedModule) {
+			const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule);
+			for (const exportInfo of exportsInfo.exports) {
+				if (
+					exportInfo.provided === true &&
+					exportInfo.name !== "default" &&
+					!names.has(exportInfo.name) &&
+					!(
+						parentModule &&
+						isStarReexportBackToParent(moduleGraph, exportInfo, parentModule)
+					)
+				) {
+					names.add(exportInfo.name);
+					dependencyIndices[i] = names.size;
+				}
+			}
+		}
+	}
+	dependencyIndices.push(names.size);
+
+	return { names: [...names], dependencyIndices };
+};
+
+/**
+ * Finds dependency for name.
+ * @param {object} options options
+ * @param {ExportInfoName[]} options.names names
+ * @param {DependencyIndices} options.dependencyIndices dependency indices
+ * @param {string} name name
+ * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency>} dependencies dependencies
+ * @returns {HarmonyExportImportedSpecifierDependency | undefined} found dependency or nothing
+ */
+const findDependencyForName = (
+	{ names, dependencyIndices },
+	name,
+	dependencies
+) => {
+	const dependenciesIt = dependencies[Symbol.iterator]();
+	const dependencyIndicesIt = dependencyIndices[Symbol.iterator]();
+	let dependenciesItResult = dependenciesIt.next();
+	let dependencyIndicesItResult = dependencyIndicesIt.next();
+	if (dependencyIndicesItResult.done) return;
+	for (let i = 0; i < names.length; i++) {
+		while (i >= dependencyIndicesItResult.value) {
+			dependenciesItResult = dependenciesIt.next();
+			dependencyIndicesItResult = dependencyIndicesIt.next();
+			if (dependencyIndicesItResult.done) return;
+		}
+		if (names[i] === name) return dependenciesItResult.value;
+	}
+	return undefined;
+};
+
+/**
+ * Returns the export mode.
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {HarmonyExportImportedSpecifierDependency} dep the dependency
+ * @param {string} runtimeKey the runtime key
+ * @returns {ExportMode} the export mode
+ */
+const getMode = (moduleGraph, dep, runtimeKey) => {
+	const importedModule = moduleGraph.getModule(dep);
+
+	if (!importedModule) {
+		const mode = new ExportMode("missing");
+
+		mode.userRequest = dep.userRequest;
+
+		return mode;
+	}
+
+	const name = dep.name;
+	const runtime = keyToRuntime(runtimeKey);
+	const parentModule = /** @type {Module} */ (moduleGraph.getParentModule(dep));
+	const exportsInfo = moduleGraph.getExportsInfo(parentModule);
+
+	if (
+		name
+			? exportsInfo.getUsed(name, runtime) === UsageState.Unused
+			: exportsInfo.isUsed(runtime) === false
+	) {
+		const mode = new ExportMode("unused");
+
+		mode.name = name || "*";
+
+		return mode;
+	}
+
+	const importedExportsType = importedModule.getExportsType(
+		moduleGraph,
+		/** @type {BuildMeta} */
+		(parentModule.buildMeta).strictHarmonyModule
+	);
+
+	const ids = dep.getIds(moduleGraph);
+
+	// Special handling for reexporting the default export
+	// from non-namespace modules
+	if (name && ids.length > 0 && ids[0] === "default") {
+		switch (importedExportsType) {
+			case "dynamic": {
+				const mode = new ExportMode("reexport-dynamic-default");
+
+				mode.name = name;
+
+				return mode;
+			}
+			case "default-only":
+			case "default-with-named": {
+				const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
+				const mode = new ExportMode("reexport-named-default");
+
+				mode.name = name;
+				mode.partialNamespaceExportInfo = exportInfo;
+
+				return mode;
+			}
+		}
+	}
+
+	// reexporting with a fixed name
+	if (name) {
+		/** @type {ExportMode} */
+		let mode;
+		const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
+
+		if (ids.length > 0) {
+			// export { name as name }
+			switch (importedExportsType) {
+				case "default-only":
+					mode = new ExportMode("reexport-undefined");
+					mode.name = name;
+					break;
+				default:
+					mode = new ExportMode("normal-reexport");
+					mode.items = [
+						new NormalReexportItem(name, ids, exportInfo, false, false)
+					];
+					break;
+			}
+		} else {
+			// export * as name
+			switch (importedExportsType) {
+				case "default-only":
+					mode = new ExportMode("reexport-fake-namespace-object");
+					mode.name = name;
+					mode.partialNamespaceExportInfo = exportInfo;
+					mode.fakeType = 0;
+					break;
+				case "default-with-named":
+					mode = new ExportMode("reexport-fake-namespace-object");
+					mode.name = name;
+					mode.partialNamespaceExportInfo = exportInfo;
+					mode.fakeType = 2;
+					break;
+				case "dynamic":
+				default:
+					mode = new ExportMode("reexport-namespace-object");
+					mode.name = name;
+					mode.partialNamespaceExportInfo = exportInfo;
+			}
+		}
+
+		return mode;
+	}
+
+	// Star reexporting
+	const { ignoredExports, exports, checked, hidden } = dep.getStarReexports(
+		moduleGraph,
+		runtime,
+		exportsInfo,
+		importedModule
+	);
+	if (!exports) {
+		// We have too few info about the modules
+		// Delegate the logic to the runtime code
+
+		const mode = new ExportMode("dynamic-reexport");
+		mode.ignored = ignoredExports;
+		mode.hidden = hidden;
+
+		return mode;
+	}
+
+	if (exports.size === 0) {
+		const mode = new ExportMode("empty-star");
+		mode.hidden = hidden;
+
+		return mode;
+	}
+
+	const mode = new ExportMode("normal-reexport");
+
+	mode.items = Array.from(
+		exports,
+		(exportName) =>
+			new NormalReexportItem(
+				exportName,
+				[exportName],
+				exportsInfo.getReadOnlyExportInfo(exportName),
+				/** @type {Checked} */
+				(checked).has(exportName),
+				false
+			)
+	);
+	if (hidden !== undefined) {
+		for (const exportName of hidden) {
+			mode.items.push(
+				new NormalReexportItem(
+					exportName,
+					[exportName],
+					exportsInfo.getReadOnlyExportInfo(exportName),
+					false,
+					true
+				)
+			);
+		}
+	}
+
+	return mode;
+};
+
+/** @typedef {Set<string>} Exports */
+/** @typedef {Set<string>} Checked */
+/** @typedef {Set<string>} Hidden */
+/** @typedef {Set<string>} IgnoredExports */
+
+class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
+	/**
+	 * Creates an instance of HarmonyExportImportedSpecifierDependency.
+	 * @param {string} request the request string
+	 * @param {number} sourceOrder the order in the original source file
+	 * @param {Ids} ids the requested export name of the imported module
+	 * @param {string | null} name the export name of for this module
+	 * @param {Set<string>} activeExports other named exports in the module
+	 * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | null} otherStarExports other star exports in the module before this import
+	 * @param {ExportPresenceMode} exportPresenceMode mode of checking export names
+	 * @param {HarmonyStarExportsList | null} allStarExports all star exports in the module
+	 * @param {ImportPhaseType} phase import phase
+	 * @param {ImportAttributes=} attributes import attributes
+	 */
+	constructor(
+		request,
+		sourceOrder,
+		ids,
+		name,
+		activeExports,
+		otherStarExports,
+		exportPresenceMode,
+		allStarExports,
+		phase,
+		attributes
+	) {
+		super(request, sourceOrder, phase, attributes);
+
+		this.ids = ids;
+		this.name = name;
+		this.activeExports = activeExports;
+		this.otherStarExports = otherStarExports;
+		this.exportPresenceMode = exportPresenceMode;
+		this.allStarExports = allStarExports;
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return Dependency.TRANSITIVE;
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Returns id.
+	 * @deprecated
+	 */
+	get id() {
+		throw new Error("id was renamed to ids and type changed to string[]");
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Returns id.
+	 * @deprecated
+	 */
+	getId() {
+		throw new Error("id was renamed to ids and type changed to string[]");
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Updates id.
+	 * @deprecated
+	 */
+	setId() {
+		throw new Error("id was renamed to ids and type changed to string[]");
+	}
+
+	get type() {
+		return "harmony export imported specifier";
+	}
+
+	/**
+	 * Returns the imported id.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {Ids} the imported id
+	 */
+	getIds(moduleGraph) {
+		return moduleGraph.getMeta(this)[idsSymbol] || this.ids;
+	}
+
+	/**
+	 * Updates ids using the provided module graph.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {Ids} ids the imported ids
+	 * @returns {void}
+	 */
+	setIds(moduleGraph, ids) {
+		moduleGraph.getMeta(this)[idsSymbol] = ids;
+	}
+
+	/**
+	 * Returns the export mode.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {ExportMode} the export mode
+	 */
+	getMode(moduleGraph, runtime) {
+		return moduleGraph.dependencyCacheProvide(
+			this,
+			getRuntimeKey(runtime),
+			getMode
+		);
+	}
+
+	/**
+	 * Gets star reexports.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {ExportsInfo} exportsInfo exports info about the current module (optional)
+	 * @param {Module} importedModule the imported module (optional)
+	 * @returns {{ exports?: Exports, checked?: Checked, ignoredExports: IgnoredExports, hidden?: Hidden }} information
+	 */
+	getStarReexports(
+		moduleGraph,
+		runtime,
+		exportsInfo = moduleGraph.getExportsInfo(
+			/** @type {Module} */ (moduleGraph.getParentModule(this))
+		),
+		importedModule = /** @type {Module} */ (moduleGraph.getModule(this))
+	) {
+		const importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
+		const noExtraExports =
+			importedExportsInfo.otherExportsInfo.provided === false;
+		const noExtraImports =
+			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused;
+
+		/** @type {IgnoredExports} */
+		const ignoredExports = new Set(["default", ...this.activeExports]);
+
+		/** @type {Hidden | undefined} */
+		let hiddenExports;
+		const otherStarExports =
+			this._discoverActiveExportsFromOtherStarExports(moduleGraph);
+		if (otherStarExports !== undefined) {
+			hiddenExports = new Set();
+			for (let i = 0; i < otherStarExports.namesSlice; i++) {
+				hiddenExports.add(otherStarExports.names[i]);
+			}
+			for (const e of ignoredExports) hiddenExports.delete(e);
+		}
+
+		if (!noExtraExports && !noExtraImports) {
+			return {
+				ignoredExports,
+				hidden: hiddenExports
+			};
+		}
+
+		/** @type {Exports} */
+		const exports = new Set();
+		/** @type {Checked} */
+		const checked = new Set();
+		/** @type {Hidden | undefined} */
+		const hidden = hiddenExports !== undefined ? new Set() : undefined;
+
+		const parentModule = /** @type {Module} */ (
+			moduleGraph.getParentModule(this)
+		);
+
+		if (noExtraImports) {
+			for (const exportInfo of exportsInfo.orderedExports) {
+				const name = exportInfo.name;
+				if (ignoredExports.has(name)) continue;
+				if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
+				const importedExportInfo =
+					importedExportsInfo.getReadOnlyExportInfo(name);
+				if (importedExportInfo.provided === false) continue;
+				if (hiddenExports !== undefined && hiddenExports.has(name)) {
+					// Earlier star deps already provided this name non-cyclically
+					// (`determineExportAssignments` filters cyclic candidates), so
+					// the cycle check below would be wasted work.
+					/** @type {Hidden} */
+					(hidden).add(name);
+					continue;
+				}
+				if (
+					isStarReexportBackToParent(
+						moduleGraph,
+						importedExportInfo,
+						parentModule
+					)
+				) {
+					continue;
+				}
+				exports.add(name);
+				if (importedExportInfo.provided === true) continue;
+				checked.add(name);
+			}
+		} else if (noExtraExports) {
+			for (const importedExportInfo of importedExportsInfo.orderedExports) {
+				const name = importedExportInfo.name;
+				if (ignoredExports.has(name)) continue;
+				if (importedExportInfo.provided === false) continue;
+				const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
+				if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
+				if (hiddenExports !== undefined && hiddenExports.has(name)) {
+					/** @type {ExportModeHidden} */
+					(hidden).add(name);
+					continue;
+				}
+				if (
+					isStarReexportBackToParent(
+						moduleGraph,
+						importedExportInfo,
+						parentModule
+					)
+				) {
+					continue;
+				}
+				exports.add(name);
+				if (importedExportInfo.provided === true) continue;
+				checked.add(name);
+			}
+		}
+
+		return { ignoredExports, exports, checked, hidden };
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return (connection, runtime) => {
+			const mode = this.getMode(moduleGraph, runtime);
+			return mode.type !== "unused" && mode.type !== "empty-star";
+		};
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		return false;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		const mode = this.getMode(moduleGraph, runtime);
+
+		switch (mode.type) {
+			case "missing":
+			case "unused":
+			case "empty-star":
+			case "reexport-undefined":
+				return Dependency.NO_EXPORTS_REFERENCED;
+
+			case "reexport-dynamic-default":
+				return Dependency.EXPORTS_OBJECT_REFERENCED;
+
+			case "reexport-named-default": {
+				if (!mode.partialNamespaceExportInfo) {
+					return Dependency.EXPORTS_OBJECT_REFERENCED;
+				}
+				/** @type {RawReferencedExports} */
+				const referencedExports = [];
+				processExportInfo(
+					runtime,
+					referencedExports,
+					[],
+					/** @type {ExportInfo} */ (mode.partialNamespaceExportInfo)
+				);
+				return referencedExports;
+			}
+
+			case "reexport-namespace-object":
+			case "reexport-fake-namespace-object": {
+				if (!mode.partialNamespaceExportInfo) {
+					return Dependency.EXPORTS_OBJECT_REFERENCED;
+				}
+				/** @type {RawReferencedExports} */
+				const referencedExports = [];
+				processExportInfo(
+					runtime,
+					referencedExports,
+					[],
+					/** @type {ExportInfo} */ (mode.partialNamespaceExportInfo),
+					mode.type === "reexport-fake-namespace-object"
+				);
+				return referencedExports;
+			}
+
+			case "dynamic-reexport":
+				return Dependency.EXPORTS_OBJECT_REFERENCED;
+
+			case "normal-reexport": {
+				/** @type {RawReferencedExports} */
+				const referencedExports = [];
+				for (const {
+					ids,
+					exportInfo,
+					hidden
+				} of /** @type {NormalReexportItem[]} */ (mode.items)) {
+					if (hidden) continue;
+					processExportInfo(runtime, referencedExports, ids, exportInfo, false);
+				}
+				return referencedExports;
+			}
+
+			default:
+				throw new Error(`Unknown mode ${mode.type}`);
+		}
+	}
+
+	/**
+	 * Discover active exports from other star exports.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {{ names: ExportInfoName[], namesSlice: number, dependencyIndices: DependencyIndices, dependencyIndex: number } | undefined} exported names and their origin dependency
+	 */
+	_discoverActiveExportsFromOtherStarExports(moduleGraph) {
+		if (!this.otherStarExports) return;
+
+		const i =
+			"length" in this.otherStarExports
+				? this.otherStarExports.length
+				: countIterable(this.otherStarExports);
+		if (i === 0) return;
+
+		if (this.allStarExports) {
+			const { names, dependencyIndices } = moduleGraph.cached(
+				determineExportAssignments,
+				this.allStarExports.dependencies
+			);
+
+			return {
+				names,
+				namesSlice: dependencyIndices[i - 1],
+				dependencyIndices,
+				dependencyIndex: i
+			};
+		}
+
+		const { names, dependencyIndices } = moduleGraph.cached(
+			determineExportAssignments,
+			/** @type {HarmonyExportImportedSpecifierDependency[]} */
+			(this.otherStarExports),
+			this
+		);
+
+		return {
+			names,
+			namesSlice: dependencyIndices[i - 1],
+			dependencyIndices,
+			dependencyIndex: i
+		};
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		const mode = this.getMode(moduleGraph, undefined);
+
+		switch (mode.type) {
+			case "missing":
+				return;
+			case "dynamic-reexport": {
+				const from =
+					/** @type {ModuleGraphConnection} */
+					(moduleGraph.getConnection(this));
+				return {
+					exports: true,
+					from,
+					canMangle: false,
+					excludeExports: mode.hidden
+						? combine(
+								/** @type {ExportModeIgnored} */ (mode.ignored),
+								mode.hidden
+							)
+						: /** @type {ExportModeIgnored} */ (mode.ignored),
+					hideExports: mode.hidden,
+					dependencies: [from.module]
+				};
+			}
+			case "empty-star":
+				return {
+					exports: [],
+					hideExports: mode.hidden,
+					dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))]
+				};
+			// falls through
+			case "normal-reexport": {
+				const from =
+					/** @type {ModuleGraphConnection} */
+					(moduleGraph.getConnection(this));
+				return {
+					exports: Array.from(
+						/** @type {NormalReexportItem[]} */ (mode.items),
+						(item) => ({
+							name: item.name,
+							from,
+							export: item.ids,
+							hidden: item.hidden
+						})
+					),
+					priority: 1,
+					dependencies: [from.module]
+				};
+			}
+			case "reexport-dynamic-default": {
+				const from =
+					/** @type {ModuleGraphConnection} */
+					(moduleGraph.getConnection(this));
+				return {
+					exports: [
+						{
+							name: /** @type {string} */ (mode.name),
+							from,
+							export: ["default"]
+						}
+					],
+					priority: 1,
+					dependencies: [from.module]
+				};
+			}
+			case "reexport-undefined":
+				return {
+					exports: [/** @type {string} */ (mode.name)],
+					dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))]
+				};
+			case "reexport-fake-namespace-object": {
+				const from =
+					/** @type {ModuleGraphConnection} */
+					(moduleGraph.getConnection(this));
+				return {
+					exports: [
+						{
+							name: /** @type {string} */ (mode.name),
+							from,
+							export: null,
+							exports: [
+								{
+									name: "default",
+									canMangle: false,
+									from,
+									export: null
+								}
+							]
+						}
+					],
+					priority: 1,
+					dependencies: [from.module]
+				};
+			}
+			case "reexport-namespace-object": {
+				const from =
+					/** @type {ModuleGraphConnection} */
+					(moduleGraph.getConnection(this));
+				return {
+					exports: [
+						{
+							name: /** @type {string} */ (mode.name),
+							from,
+							export: null
+						}
+					],
+					priority: 1,
+					dependencies: [from.module]
+				};
+			}
+			case "reexport-named-default": {
+				const from =
+					/** @type {ModuleGraphConnection} */
+					(moduleGraph.getConnection(this));
+				return {
+					exports: [
+						{
+							name: /** @type {string} */ (mode.name),
+							from,
+							export: ["default"]
+						}
+					],
+					priority: 1,
+					dependencies: [from.module]
+				};
+			}
+			default:
+				throw new Error(`Unknown mode ${mode.type}`);
+		}
+	}
+
+	/**
+	 * Get effective export presence level.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportPresenceMode} effective mode
+	 */
+	_getEffectiveExportPresenceLevel(moduleGraph) {
+		if (this.exportPresenceMode !== ExportPresenceModes.AUTO) {
+			return this.exportPresenceMode;
+		}
+		const module = /** @type {Module} */ (moduleGraph.getParentModule(this));
+		return /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule
+			? ExportPresenceModes.ERROR
+			: ExportPresenceModes.WARN;
+	}
+
+	/**
+	 * Returns warnings.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} warnings
+	 */
+	getWarnings(moduleGraph) {
+		const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
+		if (exportsPresence === ExportPresenceModes.WARN) {
+			return this._getErrors(moduleGraph);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} errors
+	 */
+	getErrors(moduleGraph) {
+		const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
+		if (exportsPresence === ExportPresenceModes.ERROR) {
+			return this._getErrors(moduleGraph);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | undefined} errors
+	 */
+	_getErrors(moduleGraph) {
+		const ids = this.getIds(moduleGraph);
+		let errors = this.getLinkingErrors(
+			moduleGraph,
+			ids,
+			`(reexported as '${this.name}')`
+		);
+		if (ids.length === 0 && this.name === null) {
+			const potentialConflicts =
+				this._discoverActiveExportsFromOtherStarExports(moduleGraph);
+			if (potentialConflicts && potentialConflicts.namesSlice > 0) {
+				const ownNames = new Set(
+					potentialConflicts.names.slice(
+						potentialConflicts.namesSlice,
+						potentialConflicts.dependencyIndices[
+							potentialConflicts.dependencyIndex
+						]
+					)
+				);
+				const importedModule = moduleGraph.getModule(this);
+				if (importedModule) {
+					const exportsInfo = moduleGraph.getExportsInfo(importedModule);
+					/** @type {Map<string, ExportInfoName[]>} */
+					const conflicts = new Map();
+					for (const exportInfo of exportsInfo.orderedExports) {
+						if (exportInfo.provided !== true) continue;
+						if (exportInfo.name === "default") continue;
+						if (this.activeExports.has(exportInfo.name)) continue;
+						if (ownNames.has(exportInfo.name)) continue;
+						const conflictingDependency = findDependencyForName(
+							potentialConflicts,
+							exportInfo.name,
+							this.allStarExports
+								? this.allStarExports.dependencies
+								: [
+										.../** @type {ReadonlyArray<HarmonyExportImportedSpecifierDependency>} */
+										(this.otherStarExports),
+										this
+									]
+						);
+						if (!conflictingDependency) continue;
+						const target = exportInfo.getTerminalBinding(moduleGraph);
+						if (!target) continue;
+						const conflictingModule =
+							/** @type {Module} */
+							(moduleGraph.getModule(conflictingDependency));
+						if (conflictingModule === importedModule) continue;
+						const conflictingExportInfo = moduleGraph.getExportInfo(
+							conflictingModule,
+							exportInfo.name
+						);
+						const conflictingTarget =
+							conflictingExportInfo.getTerminalBinding(moduleGraph);
+						if (!conflictingTarget) continue;
+						if (target === conflictingTarget) continue;
+						const list = conflicts.get(conflictingDependency.request);
+						if (list === undefined) {
+							conflicts.set(conflictingDependency.request, [exportInfo.name]);
+						} else {
+							list.push(exportInfo.name);
+						}
+					}
+					for (const [request, exports] of conflicts) {
+						if (!errors) errors = [];
+						errors.push(
+							new HarmonyLinkingError(
+								`The requested module '${
+									this.request
+								}' contains conflicting star exports for the ${
+									exports.length > 1 ? "names" : "name"
+								} ${exports
+									.map((e) => `'${e}'`)
+									.join(", ")} with the previous requested module '${request}'`
+							)
+						);
+					}
+				}
+			}
+		}
+		return errors;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write, setCircularReference } = context;
+
+		setCircularReference(this);
+		write(this.ids);
+		write(this.name);
+		write(this.activeExports);
+		write(this.otherStarExports);
+		write(this.exportPresenceMode);
+		write(this.allStarExports);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read, setCircularReference } = context;
+
+		setCircularReference(this);
+		this.ids = read();
+		this.name = read();
+		this.activeExports = read();
+		this.otherStarExports = read();
+		this.exportPresenceMode = read();
+		this.allStarExports = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	HarmonyExportImportedSpecifierDependency,
+	"webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency"
+);
+
+HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate extends (
+	HarmonyImportDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const { moduleGraph, runtime, concatenationScope } = templateContext;
+
+		const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (
+			dependency
+		);
+
+		const mode = dep.getMode(moduleGraph, runtime);
+
+		if (concatenationScope) {
+			switch (mode.type) {
+				case "reexport-undefined":
+					concatenationScope.registerRawExport(
+						/** @type {NonNullable<ExportMode["name"]>} */ (mode.name),
+						"/* reexport non-default export from non-harmony */ undefined"
+					);
+			}
+			return;
+		}
+
+		if (mode.type !== "unused" && mode.type !== "empty-star") {
+			super.apply(dependency, source, templateContext);
+
+			this._addExportFragments(
+				templateContext.initFragments,
+				dep,
+				mode,
+				templateContext.module,
+				moduleGraph,
+				templateContext.chunkGraph,
+				runtime,
+				templateContext.runtimeTemplate,
+				templateContext.runtimeRequirements
+			);
+		}
+	}
+
+	/**
+	 * Add export fragments.
+	 * @param {InitFragment<GenerateContext>[]} initFragments target array for init fragments
+	 * @param {HarmonyExportImportedSpecifierDependency} dep dependency
+	 * @param {ExportMode} mode the export mode
+	 * @param {Module} module the current module
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
+	 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
+	 * @returns {void}
+	 */
+	_addExportFragments(
+		initFragments,
+		dep,
+		mode,
+		module,
+		moduleGraph,
+		chunkGraph,
+		runtime,
+		runtimeTemplate,
+		runtimeRequirements
+	) {
+		const importedModule = /** @type {Module} */ (moduleGraph.getModule(dep));
+		const importVar = dep.getImportVar(moduleGraph);
+		const isDeferred =
+			ImportPhaseUtils.isDefer(dep.phase) &&
+			!(/** @type {BuildMeta} */ (importedModule.buildMeta).async);
+
+		if (
+			(mode.type === "reexport-namespace-object" ||
+				mode.type === "reexport-fake-namespace-object") &&
+			isDeferred
+		) {
+			initFragments.push(
+				...this.getReexportDeferredNamespaceObjectFragments(
+					importedModule,
+					chunkGraph,
+					moduleGraph
+						.getExportsInfo(module)
+						.getUsedName(mode.name ? mode.name : [], runtime),
+					importVar,
+					importedModule.getExportsType(
+						moduleGraph,
+						module.buildMeta && module.buildMeta.strictHarmonyModule
+					),
+					runtimeRequirements
+				)
+			);
+			return;
+		}
+		switch (mode.type) {
+			case "missing":
+			case "empty-star":
+				initFragments.push(
+					new InitFragment(
+						"/* empty/unused harmony star reexport */\n",
+						InitFragment.STAGE_HARMONY_EXPORTS,
+						1
+					)
+				);
+				break;
+
+			case "unused":
+				initFragments.push(
+					new InitFragment(
+						`${Template.toNormalComment(
+							`unused harmony reexport ${mode.name}`
+						)}\n`,
+						InitFragment.STAGE_HARMONY_EXPORTS,
+						1
+					)
+				);
+				break;
+
+			case "reexport-dynamic-default":
+				initFragments.push(
+					this.getReexportFragment(
+						module,
+						"reexport default from dynamic",
+						moduleGraph
+							.getExportsInfo(module)
+							.getUsedName(/** @type {string} */ (mode.name), runtime),
+						importVar,
+						null,
+						runtimeRequirements
+					)
+				);
+				break;
+
+			case "reexport-fake-namespace-object":
+				initFragments.push(
+					...this.getReexportFakeNamespaceObjectFragments(
+						module,
+						moduleGraph
+							.getExportsInfo(module)
+							.getUsedName(/** @type {string} */ (mode.name), runtime),
+						importVar,
+						mode.fakeType,
+						runtimeRequirements
+					)
+				);
+				break;
+
+			case "reexport-undefined":
+				initFragments.push(
+					this.getReexportFragment(
+						module,
+						"reexport non-default export from non-harmony",
+						moduleGraph
+							.getExportsInfo(module)
+							.getUsedName(/** @type {string} */ (mode.name), runtime),
+						"undefined",
+						"",
+						runtimeRequirements
+					)
+				);
+				break;
+
+			case "reexport-named-default":
+				initFragments.push(
+					this.getReexportFragment(
+						module,
+						"reexport default export from named module",
+						moduleGraph
+							.getExportsInfo(module)
+							.getUsedName(/** @type {string} */ (mode.name), runtime),
+						importVar,
+						"",
+						runtimeRequirements
+					)
+				);
+				break;
+
+			case "reexport-namespace-object":
+				initFragments.push(
+					this.getReexportFragment(
+						module,
+						"reexport module object",
+						moduleGraph
+							.getExportsInfo(module)
+							.getUsedName(/** @type {string} */ (mode.name), runtime),
+						importVar,
+						"",
+						runtimeRequirements
+					)
+				);
+				break;
+
+			case "normal-reexport":
+				for (const {
+					name,
+					ids,
+					checked,
+					hidden
+				} of /** @type {NormalReexportItem[]} */ (mode.items)) {
+					if (hidden) continue;
+					if (checked) {
+						const connection = moduleGraph.getConnection(dep);
+						const key = `harmony reexport (checked) ${importVar} ${name}`;
+						const runtimeCondition = dep.weak
+							? false
+							: connection
+								? filterRuntime(runtime, (r) => connection.isTargetActive(r))
+								: true;
+						initFragments.push(
+							new ConditionalInitFragment(
+								`/* harmony reexport (checked) */ ${this.getConditionalReexportStatement(
+									module,
+									name,
+									importVar,
+									ids,
+									runtimeRequirements
+								)}`,
+								moduleGraph.isAsync(importedModule)
+									? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
+									: InitFragment.STAGE_HARMONY_IMPORTS,
+								/** @type {number} */ (dep.sourceOrder),
+								key,
+								runtimeCondition
+							)
+						);
+					} else {
+						initFragments.push(
+							this.getReexportFragment(
+								module,
+								"reexport safe",
+								moduleGraph.getExportsInfo(module).getUsedName(name, runtime),
+								importVar,
+								moduleGraph
+									.getExportsInfo(importedModule)
+									.getUsedName(ids, runtime),
+								runtimeRequirements
+							)
+						);
+					}
+				}
+				break;
+
+			case "dynamic-reexport": {
+				const ignored = mode.hidden
+					? combine(
+							/** @type {ExportModeIgnored} */
+							(mode.ignored),
+							mode.hidden
+						)
+					: /** @type {ExportModeIgnored} */ (mode.ignored);
+				let content =
+					"/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n" +
+					`/* harmony reexport (unknown) */ for(${runtimeTemplate.renderConst()} __WEBPACK_IMPORT_KEY__ in ${importVar}) `;
+
+				// Filter out exports which are defined by other exports
+				// and filter out default export because it cannot be reexported with *
+				if (ignored.size > 1) {
+					content += `if(${JSON.stringify([
+						...ignored
+					])}.indexOf(__WEBPACK_IMPORT_KEY__) < 0) `;
+				} else if (ignored.size === 1) {
+					content += `if(__WEBPACK_IMPORT_KEY__ !== ${JSON.stringify(
+						first(ignored)
+					)}) `;
+				}
+
+				content += "__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = ";
+				content +=
+					runtimeTemplate.supportsArrowFunction() &&
+					runtimeTemplate.supportsConst()
+						? `() => ${importVar}[__WEBPACK_IMPORT_KEY__]`
+						: `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`;
+
+				runtimeRequirements.add(RuntimeGlobals.exports);
+				runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+
+				const exportsName = module.exportsArgument;
+				initFragments.push(
+					new InitFragment(
+						`${content}\n/* harmony reexport (unknown) */ ${RuntimeGlobals.definePropertyGetters}(${exportsName}, __WEBPACK_REEXPORT_OBJECT__);\n`,
+						moduleGraph.isAsync(importedModule)
+							? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
+							: InitFragment.STAGE_HARMONY_IMPORTS,
+						/** @type {number} */ (dep.sourceOrder)
+					)
+				);
+				break;
+			}
+
+			default:
+				throw new Error(`Unknown mode ${mode.type}`);
+		}
+	}
+
+	/**
+	 * Gets reexport fragment.
+	 * @param {Module} module the current module
+	 * @param {string} comment comment
+	 * @param {UsedName} key key
+	 * @param {string} name name
+	 * @param {UsedName | null} valueKey value key
+	 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
+	 * @returns {HarmonyExportInitFragment} harmony export init fragment
+	 */
+	getReexportFragment(
+		module,
+		comment,
+		key,
+		name,
+		valueKey,
+		runtimeRequirements
+	) {
+		const returnValue = this.getReturnValue(name, valueKey);
+
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+
+		/** @type {ExportMap} */
+		const map = new Map();
+		map.set(key, `/* ${comment} */ ${returnValue}`);
+
+		return new HarmonyExportInitFragment(module.exportsArgument, map);
+	}
+
+	/**
+	 * Gets reexport fake namespace object fragments.
+	 * @param {Module} module module
+	 * @param {UsedName} key key
+	 * @param {string} name name
+	 * @param {number} fakeType fake type
+	 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
+	 * @returns {[InitFragment<GenerateContext>, HarmonyExportInitFragment]} init fragments
+	 */
+	getReexportFakeNamespaceObjectFragments(
+		module,
+		key,
+		name,
+		fakeType,
+		runtimeRequirements
+	) {
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+		runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+
+		/** @type {ExportMap} */
+		const map = new Map();
+		map.set(
+			key,
+			`/* reexport fake namespace object from non-harmony */ ${name}_namespace_cache || (${name}_namespace_cache = ${
+				RuntimeGlobals.createFakeNamespaceObject
+			}(${name}${fakeType ? `, ${fakeType}` : ""}))`
+		);
+
+		return [
+			new InitFragment(
+				`var ${name}_namespace_cache;\n`,
+				InitFragment.STAGE_CONSTANTS,
+				-1,
+				`${name}_namespace_cache`
+			),
+			new HarmonyExportInitFragment(module.exportsArgument, map)
+		];
+	}
+
+	/**
+	 * Gets reexport deferred namespace object fragments.
+	 * @param {Module} module module
+	 * @param {ChunkGraph} chunkGraph chunkGraph
+	 * @param {UsedName} key key
+	 * @param {string} name name
+	 * @param {ExportsType} exportsType exportsType
+	 * @param {RuntimeRequirements} runtimeRequirements runtimeRequirements
+	 * @returns {InitFragment<GenerateContext>[]} fragments
+	 */
+	getReexportDeferredNamespaceObjectFragments(
+		module,
+		chunkGraph,
+		key,
+		name,
+		exportsType,
+		runtimeRequirements
+	) {
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+		runtimeRequirements.add(RuntimeGlobals.makeDeferredNamespaceObject);
+
+		/** @type {ExportMap} */
+		const map = new Map();
+		const moduleId = JSON.stringify(chunkGraph.getModuleId(module));
+		const mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
+		map.set(
+			key,
+			`/* reexport deferred namespace object */ ${name}_deferred_namespace_cache || (${name}_deferred_namespace_cache = ${RuntimeGlobals.makeDeferredNamespaceObject}(${moduleId}, ${mode}))`
+		);
+
+		return [
+			new InitFragment(
+				`var ${name}_deferred_namespace_cache;\n`,
+				InitFragment.STAGE_CONSTANTS,
+				-1,
+				`${name}_deferred_namespace_cache`
+			),
+			new HarmonyExportInitFragment(module.exportsArgument, map)
+		];
+	}
+
+	/**
+	 * Gets conditional reexport statement.
+	 * @param {Module} module module
+	 * @param {string} key key
+	 * @param {string} name name
+	 * @param {string | string[] | false} valueKey value key
+	 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
+	 * @returns {string} result
+	 */
+	getConditionalReexportStatement(
+		module,
+		key,
+		name,
+		valueKey,
+		runtimeRequirements
+	) {
+		if (valueKey === false) {
+			return "/* unused export */\n";
+		}
+
+		const exportsName = module.exportsArgument;
+		const returnValue = this.getReturnValue(name, valueKey);
+
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+		runtimeRequirements.add(RuntimeGlobals.hasOwnProperty);
+
+		return `if(${RuntimeGlobals.hasOwnProperty}(${name}, ${JSON.stringify(
+			valueKey[0]
+		)})) ${
+			RuntimeGlobals.definePropertyGetters
+		}(${exportsName}, { ${propertyName(
+			key
+		)}: function() { return ${returnValue}; } });\n`;
+	}
+
+	/**
+	 * Returns value.
+	 * @param {string} name name
+	 * @param {null | false | string | string[]} valueKey value key
+	 * @returns {string | undefined} value
+	 */
+	getReturnValue(name, valueKey) {
+		if (valueKey === null) {
+			return `${name}_default.a`;
+		}
+
+		if (valueKey === "") {
+			return name;
+		}
+
+		if (valueKey === false) {
+			return "/* unused export */ undefined";
+		}
+
+		return `${name}${propertyAccess(valueKey)}`;
+	}
+};
+
+class HarmonyStarExportsList {
+	constructor() {
+		/** @type {HarmonyExportImportedSpecifierDependency[]} */
+		this.dependencies = [];
+	}
+
+	/**
+	 * Processes the provided dep.
+	 * @param {HarmonyExportImportedSpecifierDependency} dep dependency
+	 * @returns {void}
+	 */
+	push(dep) {
+		this.dependencies.push(dep);
+	}
+
+	slice() {
+		return [...this.dependencies];
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write, setCircularReference }) {
+		setCircularReference(this);
+		write(this.dependencies);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize({ read, setCircularReference }) {
+		setCircularReference(this);
+		this.dependencies = read();
+	}
+}
+
+makeSerializable(
+	HarmonyStarExportsList,
+	"webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency",
+	"HarmonyStarExportsList"
+);
+
+module.exports = HarmonyExportImportedSpecifierDependency;
+module.exports.HarmonyStarExportsList = HarmonyStarExportsList;
+module.exports.idsSymbol = idsSymbol;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,197 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const { first } = require("../util/SetHelpers");
+const { propertyName } = require("../util/property");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../ExportsInfo").UsedName} UsedName */
+
+/**
+ * Join iterable with comma.
+ * @param {Iterable<string>} iterable iterable strings
+ * @returns {string} result
+ */
+const joinIterableWithComma = (iterable) => {
+	// This is more performant than Array.from().join(", ")
+	// as it doesn't create an array
+	let str = "";
+	let first = true;
+	for (const item of iterable) {
+		if (first) {
+			first = false;
+		} else {
+			str += ", ";
+		}
+		str += item;
+	}
+	return str;
+};
+
+/** @typedef {Map<UsedName, string>} ExportMap */
+/** @typedef {Set<string>} UnusedExports */
+
+/** @type {ExportMap} */
+const EMPTY_MAP = new Map();
+/** @type {UnusedExports} */
+const EMPTY_SET = new Set();
+
+/**
+ * Represents HarmonyExportInitFragment.
+ * @extends {InitFragment<GenerateContext>} Context
+ */
+class HarmonyExportInitFragment extends InitFragment {
+	/**
+	 * Creates an instance of HarmonyExportInitFragment.
+	 * @param {string} exportsArgument the exports identifier
+	 * @param {ExportMap} exportMap mapping from used name to exposed variable name
+	 * @param {UnusedExports} unusedExports list of unused export names
+	 */
+	constructor(
+		exportsArgument,
+		exportMap = EMPTY_MAP,
+		unusedExports = EMPTY_SET
+	) {
+		super(undefined, InitFragment.STAGE_HARMONY_EXPORTS, 1, "harmony-exports");
+		/** @type {string} */
+		this.exportsArgument = exportsArgument;
+		/** @type {ExportMap} */
+		this.exportMap = exportMap;
+		/** @type {UnusedExports} */
+		this.unusedExports = unusedExports;
+	}
+
+	/**
+	 * Merges the provided values into a single result.
+	 * @param {HarmonyExportInitFragment[]} fragments all fragments to merge
+	 * @returns {HarmonyExportInitFragment} merged fragment
+	 */
+	mergeAll(fragments) {
+		/** @type {undefined | ExportMap} */
+		let exportMap;
+		let exportMapOwned = false;
+		/** @type {undefined | UnusedExports} */
+		let unusedExports;
+		let unusedExportsOwned = false;
+
+		for (const fragment of fragments) {
+			if (fragment.exportMap.size !== 0) {
+				if (exportMap === undefined) {
+					exportMap = fragment.exportMap;
+					exportMapOwned = false;
+				} else {
+					if (!exportMapOwned) {
+						exportMap = new Map(exportMap);
+						exportMapOwned = true;
+					}
+					for (const [key, value] of fragment.exportMap) {
+						if (!exportMap.has(key)) exportMap.set(key, value);
+					}
+				}
+			}
+			if (fragment.unusedExports.size !== 0) {
+				if (unusedExports === undefined) {
+					unusedExports = fragment.unusedExports;
+					unusedExportsOwned = false;
+				} else {
+					if (!unusedExportsOwned) {
+						unusedExports = new Set(unusedExports);
+						unusedExportsOwned = true;
+					}
+					for (const value of fragment.unusedExports) {
+						unusedExports.add(value);
+					}
+				}
+			}
+		}
+		return new HarmonyExportInitFragment(
+			this.exportsArgument,
+			exportMap,
+			unusedExports
+		);
+	}
+
+	/**
+	 * Returns merged result.
+	 * @param {HarmonyExportInitFragment} other other
+	 * @returns {HarmonyExportInitFragment} merged result
+	 */
+	merge(other) {
+		/** @type {ExportMap} */
+		let exportMap;
+		if (this.exportMap.size === 0) {
+			exportMap = other.exportMap;
+		} else if (other.exportMap.size === 0) {
+			exportMap = this.exportMap;
+		} else {
+			exportMap = new Map(other.exportMap);
+			for (const [key, value] of this.exportMap) {
+				if (!exportMap.has(key)) exportMap.set(key, value);
+			}
+		}
+		/** @type {UnusedExports} */
+		let unusedExports;
+		if (this.unusedExports.size === 0) {
+			unusedExports = other.unusedExports;
+		} else if (other.unusedExports.size === 0) {
+			unusedExports = this.unusedExports;
+		} else {
+			unusedExports = new Set(other.unusedExports);
+			for (const value of this.unusedExports) {
+				unusedExports.add(value);
+			}
+		}
+		return new HarmonyExportInitFragment(
+			this.exportsArgument,
+			exportMap,
+			unusedExports
+		);
+	}
+
+	/**
+	 * Returns the source code that will be included as initialization code.
+	 * @param {GenerateContext} context context
+	 * @returns {string | Source | undefined} the source code that will be included as initialization code
+	 */
+	getContent({ runtimeTemplate, runtimeRequirements }) {
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+
+		const unusedPart =
+			this.unusedExports.size > 1
+				? `/* unused harmony exports ${joinIterableWithComma(
+						this.unusedExports
+					)} */\n`
+				: this.unusedExports.size > 0
+					? `/* unused harmony export ${first(this.unusedExports)} */\n`
+					: "";
+		/** @type {string[]} */
+		const definitions = [];
+		const orderedExportMap = [...this.exportMap].sort(([a], [b]) =>
+			a < b ? -1 : 1
+		);
+		for (const [key, value] of orderedExportMap) {
+			definitions.push(
+				`\n/* harmony export */   ${propertyName(
+					/** @type {string} */ (key)
+				)}: ${runtimeTemplate.returningFunction(value)}`
+			);
+		}
+		const definePart =
+			this.exportMap.size > 0
+				? `/* harmony export */ ${RuntimeGlobals.definePropertyGetters}(${
+						this.exportsArgument
+					}, {${definitions.join(",")}\n/* harmony export */ });\n`
+				: "";
+		return `${definePart}${unusedPart}`;
+	}
+}
+
+module.exports = HarmonyExportInitFragment;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExportSpecifierDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExportSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExportSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,132 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./HarmonyExportInitFragment").UnusedExports} UnusedExports */
+/** @typedef {import("./HarmonyExportInitFragment").ExportMap} ExportMap */
+
+class HarmonyExportSpecifierDependency extends NullDependency {
+	/**
+	 * Creates an instance of HarmonyExportSpecifierDependency.
+	 * @param {string} id the id
+	 * @param {string} name the name
+	 */
+	constructor(id, name) {
+		super();
+		this.id = id;
+		this.name = name;
+	}
+
+	get type() {
+		return "harmony export specifier";
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		return {
+			exports: [this.name],
+			priority: 1,
+			terminalBinding: true,
+			dependencies: undefined
+		};
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		return false;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.id);
+		write(this.name);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.id = read();
+		this.name = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	HarmonyExportSpecifierDependency,
+	"webpack/lib/dependencies/HarmonyExportSpecifierDependency"
+);
+
+HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ module, moduleGraph, initFragments, runtime, concatenationScope }
+	) {
+		const dep = /** @type {HarmonyExportSpecifierDependency} */ (dependency);
+		if (concatenationScope) {
+			concatenationScope.registerExport(dep.name, dep.id);
+			return;
+		}
+		const used = moduleGraph
+			.getExportsInfo(module)
+			.getUsedName(dep.name, runtime);
+		if (!used) {
+			/** @type {UnusedExports} */
+			const set = new Set();
+			set.add(dep.name || "namespace");
+			initFragments.push(
+				new HarmonyExportInitFragment(module.exportsArgument, undefined, set)
+			);
+			return;
+		}
+
+		/** @type {ExportMap} */
+		const map = new Map();
+		map.set(used, `/* binding */ ${dep.id}`);
+		initFragments.push(
+			new HarmonyExportInitFragment(module.exportsArgument, map, undefined)
+		);
+	}
+};
+
+module.exports = HarmonyExportSpecifierDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyExports.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyExports.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyExports.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,48 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
+
+/** @type {WeakMap<JavascriptParserState, boolean>} */
+const parserStateExportsState = new WeakMap();
+
+/**
+ * Processes the provided parser state.
+ * @param {JavascriptParserState} parserState parser state
+ * @param {boolean} isStrictHarmony strict harmony mode should be enabled
+ * @returns {void}
+ */
+module.exports.enable = (parserState, isStrictHarmony) => {
+	const value = parserStateExportsState.get(parserState);
+	if (value === false) return;
+	parserStateExportsState.set(parserState, true);
+	if (value !== true) {
+		const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta);
+		buildMeta.exportsType = "namespace";
+		const buildInfo = /** @type {BuildInfo} */ (parserState.module.buildInfo);
+		buildInfo.strict = true;
+		buildInfo.exportsArgument = RuntimeGlobals.exports;
+		if (isStrictHarmony) {
+			buildMeta.strictHarmonyModule = true;
+			buildInfo.moduleArgument = "__webpack_module__";
+		}
+	}
+};
+
+/**
+ * Returns true, when enabled.
+ * @param {JavascriptParserState} parserState parser state
+ * @returns {boolean} true, when enabled
+ */
+module.exports.isEnabled = (parserState) => {
+	const value = parserStateExportsState.get(parserState);
+	return value === true;
+};
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,491 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ConditionalInitFragment = require("../ConditionalInitFragment");
+const Dependency = require("../Dependency");
+const InitFragment = require("../InitFragment");
+const Template = require("../Template");
+const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment");
+const { filterRuntime, mergeRuntime } = require("../util/runtime");
+const HarmonyLinkingError = require("./HarmonyLinkingError");
+const { ImportPhase, ImportPhaseUtils } = require("./ImportPhase");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ExportsInfo")} ExportsInfo */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {0 | 1 | 2 | 3} ExportPresenceMode */
+
+const ExportPresenceModes = {
+	NONE: /** @type {ExportPresenceMode} */ (0),
+	WARN: /** @type {ExportPresenceMode} */ (1),
+	AUTO: /** @type {ExportPresenceMode} */ (2),
+	ERROR: /** @type {ExportPresenceMode} */ (3),
+	/**
+	 * Returns result.
+	 * @param {string | false} str param
+	 * @returns {ExportPresenceMode} result
+	 */
+	fromUserOption(str) {
+		switch (str) {
+			case "error":
+				return ExportPresenceModes.ERROR;
+			case "warn":
+				return ExportPresenceModes.WARN;
+			case "auto":
+				return ExportPresenceModes.AUTO;
+			case false:
+				return ExportPresenceModes.NONE;
+			default:
+				throw new Error(`Invalid export presence value ${str}`);
+		}
+	},
+	/**
+	 * Resolve export presence mode from parser options with a specific key and shared fallbacks.
+	 * @param {string | false | undefined} specificValue the type-specific option value (e.g. importExportsPresence or reexportExportsPresence)
+	 * @param {JavascriptParserOptions} options parser options
+	 * @returns {ExportPresenceMode} resolved mode
+	 */
+	resolveFromOptions(specificValue, options) {
+		if (specificValue !== undefined) {
+			return ExportPresenceModes.fromUserOption(specificValue);
+		}
+		if (options.exportsPresence !== undefined) {
+			return ExportPresenceModes.fromUserOption(options.exportsPresence);
+		}
+		return options.strictExportPresence
+			? ExportPresenceModes.ERROR
+			: ExportPresenceModes.AUTO;
+	}
+};
+
+/**
+ * Get the non-optional leading part of a member chain.
+ * @param {string[]} members members
+ * @param {boolean[]} membersOptionals optionality for each member
+ * @returns {string[]} the non-optional prefix
+ */
+const getNonOptionalPart = (members, membersOptionals) => {
+	let i = 0;
+	while (i < members.length && membersOptionals[i] === false) i++;
+	return i !== members.length ? members.slice(0, i) : members;
+};
+
+/** @typedef {string[]} Ids */
+
+class HarmonyImportDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of HarmonyImportDependency.
+	 * @param {string} request request string
+	 * @param {number} sourceOrder source order
+	 * @param {ImportPhaseType=} phase import phase
+	 * @param {ImportAttributes=} attributes import attributes
+	 */
+	constructor(
+		request,
+		sourceOrder,
+		phase = ImportPhase.Evaluation,
+		attributes = undefined
+	) {
+		super(request, sourceOrder);
+		this.phase = phase;
+		this.attributes = attributes;
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	/**
+	 * Returns true if this dependency can be concatenated
+	 * @returns {boolean} true if this dependency can be concatenated
+	 */
+	canConcatenate() {
+		return true;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		let str = super.getResourceIdentifier();
+		// We specifically use this check to avoid writing the default (`evaluation` or `0`) value and save memory
+		if (this.phase) {
+			str += `|phase${ImportPhaseUtils.stringify(this.phase)}`;
+		}
+		if (this.attributes) {
+			str += `|attributes${JSON.stringify(this.attributes)}`;
+		}
+		return str;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return Dependency.NO_EXPORTS_REFERENCED;
+	}
+
+	/**
+	 * Returns name of the variable for the import.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {string} name of the variable for the import
+	 */
+	getImportVar(moduleGraph) {
+		const module = /** @type {Module} */ (moduleGraph.getParentModule(this));
+		const importedModule = /** @type {Module} */ (moduleGraph.getModule(this));
+		const meta = moduleGraph.getMeta(module);
+
+		const isDeferred =
+			ImportPhaseUtils.isDefer(this.phase) &&
+			!(/** @type {BuildMeta} */ (importedModule.buildMeta).async);
+
+		const metaKey = isDeferred ? "deferredImportVarMap" : "importVarMap";
+		let importVarMap = meta[metaKey];
+		if (!importVarMap) {
+			meta[metaKey] = importVarMap =
+				/** @type {Map<Module, string>} */
+				(new Map());
+		}
+
+		let importVar = importVarMap.get(importedModule);
+		if (importVar) return importVar;
+		importVar = `${Template.toIdentifier(`${this.userRequest}`)}__WEBPACK_${
+			isDeferred ? "DEFERRED_" : ""
+		}IMPORTED_MODULE_${importVarMap.size}__`;
+		importVarMap.set(importedModule, importVar);
+		return importVar;
+	}
+
+	/**
+	 * Gets module exports.
+	 * @param {DependencyTemplateContext} context the template context
+	 * @returns {string} the expression
+	 */
+	getModuleExports({
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtimeRequirements
+	}) {
+		return runtimeTemplate.moduleExports({
+			module: moduleGraph.getModule(this),
+			chunkGraph,
+			request: this.request,
+			runtimeRequirements
+		});
+	}
+
+	/**
+	 * Gets import statement.
+	 * @param {boolean} update create new variables or update existing one
+	 * @param {DependencyTemplateContext} templateContext the template context
+	 * @returns {[string, string]} the import statement and the compat statement
+	 */
+	getImportStatement(
+		update,
+		{ runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		return runtimeTemplate.importStatement({
+			update,
+			module: /** @type {Module} */ (moduleGraph.getModule(this)),
+			moduleGraph,
+			chunkGraph,
+			importVar: this.getImportVar(moduleGraph),
+			request: this.request,
+			originModule: module,
+			runtimeRequirements,
+			dependency: this
+		});
+	}
+
+	/**
+	 * Gets linking errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {Ids} ids imported ids
+	 * @param {string} additionalMessage extra info included in the error message
+	 * @returns {WebpackError[] | undefined} errors
+	 */
+	getLinkingErrors(moduleGraph, ids, additionalMessage) {
+		// Source phase imports don't have exports to check
+		if (ImportPhaseUtils.isSource(this.phase)) {
+			return;
+		}
+
+		const importedModule = moduleGraph.getModule(this);
+		// ignore errors for missing or failed modules
+		if (!importedModule || importedModule.getNumberOfErrors() > 0) {
+			return;
+		}
+
+		const parentModule =
+			/** @type {Module} */
+			(moduleGraph.getParentModule(this));
+		const exportsType = importedModule.getExportsType(
+			moduleGraph,
+			/** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule
+		);
+		if (exportsType === "namespace" || exportsType === "default-with-named") {
+			if (ids.length === 0) {
+				return;
+			}
+
+			if (
+				(exportsType !== "default-with-named" || ids[0] !== "default") &&
+				moduleGraph.isExportProvided(importedModule, ids) === false
+			) {
+				// We are sure that it's not provided
+
+				// Try to provide detailed info in the error message
+				let pos = 0;
+				let exportsInfo = moduleGraph.getExportsInfo(importedModule);
+				while (pos < ids.length && exportsInfo) {
+					const id = ids[pos++];
+					const exportInfo = exportsInfo.getReadOnlyExportInfo(id);
+					if (exportInfo.provided === false) {
+						// We are sure that it's not provided
+						const providedExports = exportsInfo.getProvidedExports();
+						const moreInfo = !Array.isArray(providedExports)
+							? " (possible exports unknown)"
+							: providedExports.length === 0
+								? " (module has no exports)"
+								: ` (possible exports: ${providedExports.join(", ")})`;
+						return [
+							new HarmonyLinkingError(
+								`export ${ids
+									.slice(0, pos)
+									.map((id) => `'${id}'`)
+									.join(".")} ${additionalMessage} was not found in '${
+									this.userRequest
+								}'${moreInfo}`
+							)
+						];
+					}
+					exportsInfo =
+						/** @type {ExportsInfo} */
+						(exportInfo.getNestedExportsInfo());
+				}
+
+				// General error message
+				return [
+					new HarmonyLinkingError(
+						`export ${ids
+							.map((id) => `'${id}'`)
+							.join(".")} ${additionalMessage} was not found in '${
+							this.userRequest
+						}'`
+					)
+				];
+			}
+		}
+		switch (exportsType) {
+			case "default-only":
+				// It's has only a default export
+				if (ids.length > 0 && ids[0] !== "default") {
+					// In strict harmony modules we only support the default export
+					return [
+						new HarmonyLinkingError(
+							`Can't import the named export ${ids
+								.map((id) => `'${id}'`)
+								.join(
+									"."
+								)} ${additionalMessage} from default-exporting module (only default export is available)`
+						)
+					];
+				}
+				break;
+			case "default-with-named":
+				// It has a default export and named properties redirect
+				// In some cases we still want to warn here
+				if (
+					ids.length > 0 &&
+					ids[0] !== "default" &&
+					/** @type {BuildMeta} */
+					(importedModule.buildMeta).defaultObject === "redirect-warn"
+				) {
+					// For these modules only the default export is supported
+					return [
+						new HarmonyLinkingError(
+							`Should not import the named export ${ids
+								.map((id) => `'${id}'`)
+								.join(
+									"."
+								)} ${additionalMessage} from default-exporting module (only default export is available soon)`
+						)
+					];
+				}
+				break;
+		}
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.attributes);
+		write(this.phase);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.attributes = read();
+		this.phase = read();
+		super.deserialize(context);
+	}
+}
+
+module.exports = HarmonyImportDependency;
+
+/** @type {WeakMap<Module, WeakMap<Module, RuntimeSpec | boolean>>} */
+const importEmittedMap = new WeakMap();
+
+HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {HarmonyImportDependency} */ (dependency);
+		const { module, chunkGraph, moduleGraph, runtime } = templateContext;
+
+		const connection = moduleGraph.getConnection(dep);
+		if (connection && !connection.isTargetActive(runtime)) return;
+
+		const referencedModule = connection && connection.module;
+
+		if (
+			connection &&
+			connection.weak &&
+			referencedModule &&
+			chunkGraph.getModuleId(referencedModule) === null
+		) {
+			// in weak references, module might not be in any chunk
+			// but that's ok, we don't need that logic in this case
+			return;
+		}
+
+		const moduleKey = referencedModule
+			? referencedModule.identifier()
+			: dep.request;
+		const key = `${
+			ImportPhaseUtils.isDefer(dep.phase)
+				? "deferred "
+				: ImportPhaseUtils.isSource(dep.phase)
+					? "source "
+					: ""
+		}harmony import ${moduleKey}`;
+
+		const runtimeCondition = dep.weak
+			? false
+			: connection
+				? filterRuntime(runtime, (r) => connection.isTargetActive(r))
+				: true;
+
+		if (module && referencedModule) {
+			let emittedModules = importEmittedMap.get(module);
+			if (emittedModules === undefined) {
+				emittedModules = new WeakMap();
+				importEmittedMap.set(module, emittedModules);
+			}
+			let mergedRuntimeCondition = runtimeCondition;
+			const oldRuntimeCondition = emittedModules.get(referencedModule) || false;
+			if (oldRuntimeCondition !== false && mergedRuntimeCondition !== true) {
+				if (mergedRuntimeCondition === false || oldRuntimeCondition === true) {
+					mergedRuntimeCondition = oldRuntimeCondition;
+				} else {
+					mergedRuntimeCondition = mergeRuntime(
+						oldRuntimeCondition,
+						mergedRuntimeCondition
+					);
+				}
+			}
+			emittedModules.set(referencedModule, mergedRuntimeCondition);
+		}
+
+		const importStatement = dep.getImportStatement(false, templateContext);
+		if (
+			referencedModule &&
+			templateContext.moduleGraph.isAsync(referencedModule)
+		) {
+			templateContext.initFragments.push(
+				new ConditionalInitFragment(
+					importStatement[0],
+					InitFragment.STAGE_HARMONY_IMPORTS,
+					/** @type {number} */ (dep.sourceOrder),
+					key,
+					runtimeCondition
+				)
+			);
+			const importVar = dep.getImportVar(templateContext.moduleGraph);
+			templateContext.initFragments.push(
+				new AwaitDependenciesInitFragment(new Map([[importVar, importVar]]))
+			);
+			templateContext.initFragments.push(
+				new ConditionalInitFragment(
+					importStatement[1],
+					InitFragment.STAGE_ASYNC_HARMONY_IMPORTS,
+					/** @type {number} */ (dep.sourceOrder),
+					`${key} compat`,
+					runtimeCondition
+				)
+			);
+		} else {
+			templateContext.initFragments.push(
+				new ConditionalInitFragment(
+					importStatement[0] + importStatement[1],
+					InitFragment.STAGE_HARMONY_IMPORTS,
+					/** @type {number} */ (dep.sourceOrder),
+					key,
+					runtimeCondition
+				)
+			);
+		}
+	}
+
+	/**
+	 * Gets import emitted runtime.
+	 * @param {Module} module the module
+	 * @param {Module} referencedModule the referenced module
+	 * @returns {RuntimeSpec | boolean} runtimeCondition in which this import has been emitted
+	 */
+	static getImportEmittedRuntime(module, referencedModule) {
+		const emittedModules = importEmittedMap.get(module);
+		if (emittedModules === undefined) return false;
+		return emittedModules.get(referencedModule) || false;
+	}
+};
+
+module.exports.ExportPresenceModes = ExportPresenceModes;
+module.exports.getNonOptionalPart = getNonOptionalPart;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,609 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const HotModuleReplacementPlugin = require("../HotModuleReplacementPlugin");
+const WebpackError = require("../errors/WebpackError");
+const {
+	VariableInfo,
+	getImportAttributes
+} = require("../javascript/JavascriptParser");
+const InnerGraph = require("../optimize/InnerGraph");
+const AppendOnlyStackedSet = require("../util/AppendOnlyStackedSet");
+const ConstDependency = require("./ConstDependency");
+const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
+const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
+const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
+const HarmonyExports = require("./HarmonyExports");
+const {
+	ExportPresenceModes,
+	getNonOptionalPart
+} = require("./HarmonyImportDependency");
+const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
+const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
+const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
+
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("estree").MemberExpression} MemberExpression */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").ExportAllDeclaration} ExportAllDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").ExportNamedDeclaration} ExportNamedDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").ImportDeclaration} ImportDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../javascript/JavascriptParser").Members} Members */
+/** @typedef {import("../javascript/JavascriptParser").MembersOptionals} MembersOptionals */
+/** @typedef {import("./HarmonyImportDependency").Ids} Ids */
+/** @typedef {import("./HarmonyImportDependency").ExportPresenceMode} ExportPresenceMode */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+
+/**
+ * Defines the harmony specifier guards type used by this module.
+ * @typedef {object} HarmonySpecifierGuards
+ * @property {AppendOnlyStackedSet<string> | undefined} guards
+ */
+
+/** @typedef {Map<string, Set<string>>} Guards Map of import root to guarded member keys */
+
+const harmonySpecifierTag = Symbol("harmony import");
+const harmonySpecifierGuardTag = Symbol("harmony import guard");
+
+/**
+ * Defines the harmony settings type used by this module.
+ * @typedef {object} HarmonySettings
+ * @property {Ids} ids
+ * @property {string} source
+ * @property {number} sourceOrder
+ * @property {string} name
+ * @property {boolean} await
+ * @property {ImportAttributes=} attributes
+ * @property {ImportPhaseType} phase
+ */
+
+const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
+
+/**
+ * Gets in operator harmony import info.
+ * @param {JavascriptParser} parser the parser
+ * @param {PrivateIdentifier | Expression} left left expression
+ * @param {Expression} right right expression
+ * @returns {{ leftPart: string, members: Members, settings: HarmonySettings } | undefined} info
+ */
+const getInOperatorHarmonyImportInfo = (parser, left, right) => {
+	const leftPartEvaluated = parser.evaluateExpression(left);
+	if (leftPartEvaluated.couldHaveSideEffects()) return;
+	/** @type {string | undefined} */
+	const leftPart = leftPartEvaluated.asString();
+	if (!leftPart) return;
+
+	const rightPart = parser.evaluateExpression(right);
+	if (!rightPart.isIdentifier()) return;
+
+	const rootInfo = rightPart.rootInfo;
+	const root =
+		typeof rootInfo === "string"
+			? rootInfo
+			: rootInfo instanceof VariableInfo
+				? rootInfo.name
+				: undefined;
+	if (!root) return;
+
+	const settings = /** @type {HarmonySettings | undefined} */ (
+		parser.getTagData(root, harmonySpecifierTag)
+	);
+	if (!settings) {
+		return;
+	}
+
+	return {
+		leftPart,
+		members: /** @type {(() => Members)} */ (rightPart.getMembers)(),
+		settings
+	};
+};
+
+module.exports = class HarmonyImportDependencyParserPlugin {
+	/**
+	 * Creates an instance of HarmonyImportDependencyParserPlugin.
+	 * @param {JavascriptParserOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+		/** @type {ExportPresenceMode} */
+		this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
+			options.importExportsPresence,
+			options
+		);
+		this.strictThisContextOnImports = options.strictThisContextOnImports;
+	}
+
+	/**
+	 * Gets export presence mode.
+	 * @param {JavascriptParser} parser the parser
+	 * @param {HarmonySettings} settings settings
+	 * @param {Ids} ids ids
+	 * @returns {ExportPresenceMode} exportPresenceMode
+	 */
+	getExportPresenceMode(parser, settings, ids) {
+		// Guards only apply to namespace imports
+		if (settings.ids.length) return this.exportPresenceMode;
+
+		const harmonySettings = /** @type {HarmonySettings=} */ (
+			parser.currentTagData
+		);
+		if (!harmonySettings) return this.exportPresenceMode;
+
+		const data = /** @type {HarmonySpecifierGuards=} */ (
+			parser.getTagData(harmonySettings.name, harmonySpecifierGuardTag)
+		);
+
+		if (data && data.guards && data.guards.has(ids[0])) {
+			return ExportPresenceModes.NONE;
+		}
+
+		return this.exportPresenceMode;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const getImportPhase = createGetImportPhase(
+			this.options.deferImport,
+			this.options.sourceImport
+		);
+
+		/**
+		 * Gets non optional member chain.
+		 * @param {MemberExpression} node member expression
+		 * @param {number} count count
+		 * @returns {Expression} member expression
+		 */
+		function getNonOptionalMemberChain(node, count) {
+			while (count--) node = /** @type {MemberExpression} */ (node.object);
+			return node;
+		}
+
+		parser.hooks.isPure.for("Identifier").tap(PLUGIN_NAME, (expression) => {
+			const expr = /** @type {Identifier} */ (expression);
+			if (
+				parser.isVariableDefined(expr.name) ||
+				parser.getTagData(expr.name, harmonySpecifierTag)
+			) {
+				return true;
+			}
+		});
+		parser.hooks.import.tap(PLUGIN_NAME, (statement, source) => {
+			parser.state.lastHarmonyImportOrder =
+				(parser.state.lastHarmonyImportOrder || 0) + 1;
+			const clearDep = new ConstDependency(
+				parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
+					? ";"
+					: "",
+				/** @type {Range} */ (statement.range)
+			);
+			clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
+			parser.state.module.addPresentationalDependency(clearDep);
+			parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
+			const attributes = getImportAttributes(statement);
+			const phase = getImportPhase(parser, statement);
+			if (
+				ImportPhaseUtils.isDefer(phase) &&
+				(statement.specifiers.length !== 1 ||
+					statement.specifiers[0].type !== "ImportNamespaceSpecifier")
+			) {
+				const error = new WebpackError(
+					"Deferred import can only be used with `import * as namespace from '...'` syntax."
+				);
+				error.loc = statement.loc || undefined;
+				parser.state.current.addError(error);
+			}
+
+			const sideEffectDep = new HarmonyImportSideEffectDependency(
+				/** @type {string} */ (source),
+				parser.state.lastHarmonyImportOrder,
+				phase,
+				attributes
+			);
+			sideEffectDep.loc = /** @type {DependencyLocation} */ (statement.loc);
+			parser.state.module.addDependency(sideEffectDep);
+			return true;
+		});
+		parser.hooks.importSpecifier.tap(
+			PLUGIN_NAME,
+			(statement, source, id, name) => {
+				const ids = id === null ? [] : [id];
+				const phase = getImportPhase(parser, statement);
+				parser.tagVariable(
+					name,
+					harmonySpecifierTag,
+					/** @type {HarmonySettings} */ ({
+						name,
+						source,
+						ids,
+						sourceOrder: parser.state.lastHarmonyImportOrder,
+						attributes: getImportAttributes(statement),
+						phase
+					})
+				);
+				return true;
+			}
+		);
+		parser.hooks.binaryExpression.tap(PLUGIN_NAME, (expression) => {
+			if (expression.operator !== "in") return;
+			const info = getInOperatorHarmonyImportInfo(
+				parser,
+				expression.left,
+				expression.right
+			);
+			if (!info) return;
+
+			const { leftPart, members, settings } = info;
+			const dep = new HarmonyEvaluatedImportSpecifierDependency(
+				settings.source,
+				settings.sourceOrder,
+				[...settings.ids, ...members, leftPart],
+				settings.name,
+				/** @type {Range} */ (expression.range),
+				settings.attributes,
+				"in"
+			);
+			dep.directImport = members.length === 0;
+			dep.asiSafe = !parser.isAsiPosition(
+				/** @type {Range} */ (expression.range)[0]
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expression.loc);
+			parser.state.module.addDependency(dep);
+			InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
+			return true;
+		});
+		parser.hooks.collectDestructuringAssignmentProperties.tap(
+			PLUGIN_NAME,
+			(expr) => {
+				const nameInfo = parser.getNameForExpression(expr);
+				if (
+					nameInfo &&
+					nameInfo.rootInfo instanceof VariableInfo &&
+					nameInfo.rootInfo.name &&
+					parser.getTagData(nameInfo.rootInfo.name, harmonySpecifierTag)
+				) {
+					return true;
+				}
+			}
+		);
+		parser.hooks.expression
+			.for(harmonySpecifierTag)
+			.tap(PLUGIN_NAME, (expr) => {
+				const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
+
+				const dep = new HarmonyImportSpecifierDependency(
+					settings.source,
+					settings.sourceOrder,
+					settings.ids,
+					settings.name,
+					/** @type {Range} */
+					(expr.range),
+					this.exportPresenceMode,
+					settings.phase,
+					settings.attributes,
+					[]
+				);
+				dep.referencedPropertiesInDestructuring =
+					parser.destructuringAssignmentPropertiesFor(expr);
+				dep.shorthand = parser.scope.inShorthand;
+				dep.directImport = true;
+				dep.asiSafe = !parser.isAsiPosition(
+					/** @type {Range} */ (expr.range)[0]
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				dep.call = parser.scope.inTaggedTemplateTag;
+				parser.state.module.addDependency(dep);
+				InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
+				return true;
+			});
+		parser.hooks.expressionMemberChain
+			.for(harmonySpecifierTag)
+			.tap(
+				PLUGIN_NAME,
+				(expression, members, membersOptionals, memberRanges) => {
+					const settings =
+						/** @type {HarmonySettings} */
+						(parser.currentTagData);
+					const nonOptionalMembers = getNonOptionalPart(
+						members,
+						membersOptionals
+					);
+					/** @type {Range[]} */
+					const ranges = memberRanges.slice(
+						0,
+						memberRanges.length - (members.length - nonOptionalMembers.length)
+					);
+					const expr =
+						nonOptionalMembers !== members
+							? getNonOptionalMemberChain(
+									expression,
+									members.length - nonOptionalMembers.length
+								)
+							: expression;
+					const ids = [...settings.ids, ...nonOptionalMembers];
+					const dep = new HarmonyImportSpecifierDependency(
+						settings.source,
+						settings.sourceOrder,
+						ids,
+						settings.name,
+						/** @type {Range} */
+						(expr.range),
+						this.getExportPresenceMode(parser, settings, ids),
+						settings.phase,
+						settings.attributes,
+						ranges
+					);
+					dep.referencedPropertiesInDestructuring =
+						parser.destructuringAssignmentPropertiesFor(expr);
+					dep.asiSafe = !parser.isAsiPosition(
+						/** @type {Range} */
+						(expr.range)[0]
+					);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					parser.state.module.addDependency(dep);
+					InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
+					return true;
+				}
+			);
+		parser.hooks.callMemberChain
+			.for(harmonySpecifierTag)
+			.tap(
+				PLUGIN_NAME,
+				(expression, members, membersOptionals, memberRanges) => {
+					const { arguments: args } = expression;
+					const callee = /** @type {MemberExpression} */ (expression.callee);
+					const settings = /** @type {HarmonySettings} */ (
+						parser.currentTagData
+					);
+					const nonOptionalMembers = getNonOptionalPart(
+						members,
+						membersOptionals
+					);
+					/** @type {Range[]} */
+					const ranges = memberRanges.slice(
+						0,
+						memberRanges.length - (members.length - nonOptionalMembers.length)
+					);
+					const expr =
+						nonOptionalMembers !== members
+							? getNonOptionalMemberChain(
+									callee,
+									members.length - nonOptionalMembers.length
+								)
+							: callee;
+					const ids = [...settings.ids, ...nonOptionalMembers];
+					const dep = new HarmonyImportSpecifierDependency(
+						settings.source,
+						settings.sourceOrder,
+						ids,
+						settings.name,
+						/** @type {Range} */ (expr.range),
+						this.getExportPresenceMode(parser, settings, ids),
+						settings.phase,
+						settings.attributes,
+						ranges
+					);
+					dep.directImport = members.length === 0;
+					dep.call = true;
+					dep.asiSafe = !parser.isAsiPosition(
+						/** @type {Range} */ (expr.range)[0]
+					);
+					// only in case when we strictly follow the spec we need a special case here
+					dep.namespaceObjectAsContext =
+						members.length > 0 &&
+						/** @type {boolean} */ (this.strictThisContextOnImports);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					parser.state.module.addDependency(dep);
+					if (args) parser.walkExpressions(args);
+					InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
+					return true;
+				}
+			);
+		// Per the TC39 import-defer spec, [[Set]] on a Module Namespace
+		// Exotic Object returns false without triggering evaluation. The
+		// default expressionMemberChain path produces `<importVar>.a.foo`
+		// whose `.a` getter eagerly requires (and thus evaluates) the
+		// deferred module. For top-level `ns.foo = value`, walk only the
+		// bare `ns` identifier so it gets replaced with the deferred
+		// namespace proxy (whose set trap returns false), and leave the
+		// `.foo = value` part as plain code.
+		parser.hooks.assignMemberChain
+			.for(harmonySpecifierTag)
+			.tap(PLUGIN_NAME, (expression, members) => {
+				const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
+				if (!ImportPhaseUtils.isDefer(settings.phase)) return;
+				if (expression.operator !== "=") return;
+				if (members.length !== 1) return;
+				const left = /** @type {MemberExpression} */ (expression.left);
+				if (left.object.type !== "Identifier") return;
+				parser.walkExpression(expression.right);
+				parser.walkExpression(left.object);
+				return true;
+			});
+		const { hotAcceptCallback, hotAcceptWithoutCallback } =
+			HotModuleReplacementPlugin.getParserHooks(parser);
+		hotAcceptCallback.tap(PLUGIN_NAME, (expr, requests) => {
+			if (!HarmonyExports.isEnabled(parser.state)) {
+				// This is not a harmony module, skip it
+				return;
+			}
+			const dependencies = requests.map((request) => {
+				const dep = new HarmonyAcceptImportDependency(request);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addDependency(dep);
+				return dep;
+			});
+			if (dependencies.length > 0) {
+				const dep = new HarmonyAcceptDependency(
+					/** @type {Range} */
+					(expr.range),
+					dependencies,
+					true
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addDependency(dep);
+			}
+		});
+		hotAcceptWithoutCallback.tap(PLUGIN_NAME, (expr, requests) => {
+			if (!HarmonyExports.isEnabled(parser.state)) {
+				// This is not a harmony module, skip it
+				return;
+			}
+			const dependencies = requests.map((request) => {
+				const dep = new HarmonyAcceptImportDependency(request);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addDependency(dep);
+				return dep;
+			});
+			if (dependencies.length > 0) {
+				const dep = new HarmonyAcceptDependency(
+					/** @type {Range} */
+					(expr.range),
+					dependencies,
+					false
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.module.addDependency(dep);
+			}
+		});
+
+		/**
+		 * Processes the provided guard.
+		 * @param {Guards} guards guards
+		 * @param {() => void} walk walk callback
+		 * @returns {void}
+		 */
+		const withGuards = (guards, walk) => {
+			const applyGuards = () => {
+				/** @type {(() => void)[]} */
+				const restoreFns = [];
+
+				for (const [rootName, members] of guards) {
+					const previous = parser.getVariableInfo(rootName);
+					const exist = /** @type {HarmonySpecifierGuards=} */ (
+						parser.getTagData(rootName, harmonySpecifierGuardTag)
+					);
+
+					const mergedGuards =
+						exist && exist.guards
+							? exist.guards.createChild()
+							: new AppendOnlyStackedSet();
+
+					for (const memberKey of members) mergedGuards.add(memberKey);
+					parser.tagVariable(rootName, harmonySpecifierGuardTag, {
+						guards: mergedGuards
+					});
+					restoreFns.push(() => {
+						parser.setVariable(rootName, previous);
+					});
+				}
+
+				return () => {
+					for (const restore of restoreFns) {
+						restore();
+					}
+				};
+			};
+
+			const restore = applyGuards();
+			try {
+				walk();
+			} finally {
+				restore();
+			}
+		};
+
+		if (this.exportPresenceMode !== ExportPresenceModes.NONE) {
+			parser.hooks.collectGuards.tap(PLUGIN_NAME, (expression) => {
+				if (parser.scope.isAsmJs) return;
+				/** @type {Guards} */
+				const guards = new Map();
+
+				/**
+				 * Processes the provided expression.
+				 * @param {Expression} expression expression
+				 * @param {boolean} needTruthy need to be truthy
+				 */
+				const collect = (expression, needTruthy) => {
+					if (
+						expression.type === "UnaryExpression" &&
+						expression.operator === "!"
+					) {
+						collect(expression.argument, !needTruthy);
+						return;
+					} else if (expression.type === "LogicalExpression" && needTruthy) {
+						if (expression.operator === "&&") {
+							collect(expression.left, true);
+							collect(expression.right, true);
+						} else if (expression.operator === "||") {
+							const leftEvaluation = parser.evaluateExpression(expression.left);
+							const leftBool = leftEvaluation.asBool();
+							if (leftBool === false) {
+								collect(expression.right, true);
+							}
+						} else if (expression.operator === "??") {
+							const leftEvaluation = parser.evaluateExpression(expression.left);
+							const leftNullish = leftEvaluation.asNullish();
+							if (leftNullish === true) {
+								collect(expression.right, true);
+							}
+						}
+						return;
+					}
+					if (!needTruthy) return;
+
+					// Direct `"x" in ns` guards
+					if (
+						expression.type === "BinaryExpression" &&
+						expression.operator === "in"
+					) {
+						if (expression.right.type !== "Identifier") {
+							return;
+						}
+						const info = getInOperatorHarmonyImportInfo(
+							parser,
+							expression.left,
+							expression.right
+						);
+						if (!info) return;
+
+						const { settings, leftPart, members } = info;
+						// Only direct namespace guards
+						if (members.length > 0) return;
+						const guarded = guards.get(settings.name);
+						if (guarded) {
+							guarded.add(leftPart);
+							return;
+						}
+
+						guards.set(settings.name, new Set([leftPart]));
+					}
+				};
+
+				collect(expression, true);
+
+				if (guards.size === 0) return;
+				return (walk) => {
+					withGuards(guards, walk);
+				};
+			});
+		}
+	}
+};
+
+module.exports.harmonySpecifierGuardTag = harmonySpecifierGuardTag;
+module.exports.harmonySpecifierTag = harmonySpecifierTag;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,95 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Module = require("../Module");
+const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
+const makeSerializable = require("../util/makeSerializable");
+const HarmonyImportDependency = require("./HarmonyImportDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+
+class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
+	/**
+	 * Creates an instance of HarmonyImportSideEffectDependency.
+	 * @param {string} request the request string
+	 * @param {number} sourceOrder source order
+	 * @param {ImportPhaseType} phase import phase
+	 * @param {ImportAttributes=} attributes import attributes
+	 */
+	constructor(request, sourceOrder, phase, attributes) {
+		super(request, sourceOrder, phase, attributes);
+	}
+
+	get type() {
+		return "harmony side effect evaluation";
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return (connection) => {
+			const refModule = connection.resolvedModule;
+			if (!refModule) return true;
+			return refModule.getSideEffectsConnectionState(moduleGraph);
+		};
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		const refModule = moduleGraph.getModule(this);
+		if (!refModule) return true;
+		return refModule.getSideEffectsConnectionState(moduleGraph);
+	}
+}
+
+makeSerializable(
+	HarmonyImportSideEffectDependency,
+	"webpack/lib/dependencies/HarmonyImportSideEffectDependency"
+);
+
+HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDependencyTemplate extends (
+	HarmonyImportDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const { moduleGraph, concatenationScope } = templateContext;
+
+		const module = /** @type {Module} */ (moduleGraph.getModule(dependency));
+
+		if (module && !Module.getSourceBasicTypes(module).has(JAVASCRIPT_TYPE)) {
+			// no need to render import
+			return;
+		}
+
+		if (concatenationScope && concatenationScope.isModuleInScope(module)) {
+			return;
+		}
+		super.apply(dependency, source, templateContext);
+	}
+};
+
+module.exports = HarmonyImportSideEffectDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,540 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const InitFragment = require("../InitFragment");
+const Template = require("../Template");
+const {
+	getDependencyUsedByExportsCondition
+} = require("../optimize/InnerGraph");
+const { getTrimmedIdsAndRange } = require("../util/chainedImports");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess } = require("../util/property");
+const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
+const HarmonyImportDependency = require("./HarmonyImportDependency");
+const { ImportPhaseUtils } = require("./ImportPhase");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperties} DestructuringAssignmentProperties */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../optimize/InnerGraph").UsedByExports} UsedByExports */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../util/chainedImports").IdRanges} IdRanges */
+/** @typedef {import("./HarmonyImportDependency").ExportPresenceMode} ExportPresenceMode */
+/** @typedef {HarmonyImportDependency.Ids} Ids */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+
+const idsSymbol = /** @type {symbol} */ (
+	Symbol("HarmonyImportSpecifierDependency.ids")
+);
+
+const { ExportPresenceModes } = HarmonyImportDependency;
+
+class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
+	/**
+	 * Creates an instance of HarmonyImportSpecifierDependency.
+	 * @param {string} request request
+	 * @param {number} sourceOrder source order
+	 * @param {Ids} ids ids
+	 * @param {string} name name
+	 * @param {Range} range range
+	 * @param {ExportPresenceMode} exportPresenceMode export presence mode
+	 * @param {ImportPhaseType} phase import phase
+	 * @param {ImportAttributes | undefined} attributes import attributes
+	 * @param {IdRanges | undefined} idRanges ranges for members of ids; the two arrays are right-aligned
+	 */
+	constructor(
+		request,
+		sourceOrder,
+		ids,
+		name,
+		range,
+		exportPresenceMode,
+		phase,
+		attributes,
+		idRanges // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
+	) {
+		super(request, sourceOrder, phase, attributes);
+		this.ids = ids;
+		this.name = name;
+		this.range = range;
+		this.idRanges = idRanges;
+		this.exportPresenceMode = exportPresenceMode;
+		/** @type {undefined | boolean} */
+		this.namespaceObjectAsContext = false;
+		/** @type {undefined | boolean} */
+		this.call = undefined;
+		/** @type {undefined | boolean} */
+		this.directImport = undefined;
+		/** @type {undefined | boolean | string} */
+		this.shorthand = undefined;
+		/** @type {undefined | boolean} */
+		this.asiSafe = undefined;
+		/** @type {UsedByExports | undefined} */
+		this.usedByExports = undefined;
+		/** @type {DestructuringAssignmentProperties | undefined} */
+		this.referencedPropertiesInDestructuring = undefined;
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Returns id.
+	 * @deprecated
+	 */
+	get id() {
+		throw new Error("id was renamed to ids and type changed to string[]");
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Returns id.
+	 * @deprecated
+	 */
+	getId() {
+		throw new Error("id was renamed to ids and type changed to string[]");
+	}
+
+	// TODO webpack 6 remove
+	/**
+	 * Updates id.
+	 * @deprecated
+	 */
+	setId() {
+		throw new Error("id was renamed to ids and type changed to string[]");
+	}
+
+	get type() {
+		return "harmony import specifier";
+	}
+
+	/**
+	 * Returns the imported ids.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {Ids} the imported ids
+	 */
+	getIds(moduleGraph) {
+		const meta = moduleGraph.getMetaIfExisting(this);
+		if (meta === undefined) return this.ids;
+		const ids = meta[idsSymbol];
+		return ids !== undefined ? ids : this.ids;
+	}
+
+	/**
+	 * Updates ids using the provided module graph.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {Ids} ids the imported ids
+	 * @returns {void}
+	 */
+	setIds(moduleGraph, ids) {
+		moduleGraph.getMeta(this)[idsSymbol] = ids;
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return getDependencyUsedByExportsCondition(
+			this,
+			this.usedByExports,
+			moduleGraph
+		);
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		return false;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		let ids = this.getIds(moduleGraph);
+		if (ids.length === 0) return this._getReferencedExportsInDestructuring();
+		let namespaceObjectAsContext = this.namespaceObjectAsContext;
+		if (ids[0] === "default") {
+			const selfModule =
+				/** @type {Module} */
+				(moduleGraph.getParentModule(this));
+			const importedModule =
+				/** @type {Module} */
+				(moduleGraph.getModule(this));
+			switch (
+				importedModule.getExportsType(
+					moduleGraph,
+					/** @type {BuildMeta} */
+					(selfModule.buildMeta).strictHarmonyModule
+				)
+			) {
+				case "default-only":
+				case "default-with-named":
+					if (ids.length === 1) {
+						return this._getReferencedExportsInDestructuring();
+					}
+					ids = ids.slice(1);
+					namespaceObjectAsContext = true;
+					break;
+				case "dynamic":
+					return Dependency.EXPORTS_OBJECT_REFERENCED;
+			}
+		}
+
+		if (
+			this.call &&
+			!this.directImport &&
+			(namespaceObjectAsContext || ids.length > 1)
+		) {
+			if (ids.length === 1) return Dependency.EXPORTS_OBJECT_REFERENCED;
+			ids = ids.slice(0, -1);
+		}
+
+		return this._getReferencedExportsInDestructuring(ids);
+	}
+
+	/**
+	 * Get referenced exports in destructuring.
+	 * @param {Ids=} ids ids
+	 * @returns {RawReferencedExports} referenced exports
+	 */
+	_getReferencedExportsInDestructuring(ids) {
+		if (this.referencedPropertiesInDestructuring) {
+			/** @type {RawReferencedExports} */
+			const refsInDestructuring = [];
+			traverseDestructuringAssignmentProperties(
+				this.referencedPropertiesInDestructuring,
+				(stack) => refsInDestructuring.push(stack.map((p) => p.id))
+			);
+			/** @type {RawReferencedExports} */
+			const refs = [];
+			for (const idsInDestructuring of refsInDestructuring) {
+				refs.push(ids ? [...ids, ...idsInDestructuring] : idsInDestructuring);
+			}
+			return refs;
+		}
+		return ids ? [ids] : Dependency.EXPORTS_OBJECT_REFERENCED;
+	}
+
+	/**
+	 * Get effective export presence level.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportPresenceMode} effective mode
+	 */
+	_getEffectiveExportPresenceLevel(moduleGraph) {
+		if (this.exportPresenceMode !== ExportPresenceModes.AUTO) {
+			return this.exportPresenceMode;
+		}
+		const buildMeta =
+			/** @type {BuildMeta} */
+			(
+				/** @type {Module} */
+				(moduleGraph.getParentModule(this)).buildMeta
+			);
+		return buildMeta.strictHarmonyModule
+			? ExportPresenceModes.ERROR
+			: ExportPresenceModes.WARN;
+	}
+
+	/**
+	 * Returns warnings.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} warnings
+	 */
+	getWarnings(moduleGraph) {
+		const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
+		if (exportsPresence === ExportPresenceModes.WARN) {
+			return this._getErrors(moduleGraph);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} errors
+	 */
+	getErrors(moduleGraph) {
+		const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
+		if (exportsPresence === ExportPresenceModes.ERROR) {
+			return this._getErrors(moduleGraph);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | undefined} errors
+	 */
+	_getErrors(moduleGraph) {
+		const ids = this.getIds(moduleGraph);
+		return this.getLinkingErrors(
+			moduleGraph,
+			ids,
+			`(imported as '${this.name}')`
+		);
+	}
+
+	/**
+	 * implement this method to allow the occurrence order plugin to count correctly
+	 * @returns {number} count how often the id is used in this dependency
+	 */
+	getNumberOfIdOccurrences() {
+		return 0;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.ids);
+		write(this.name);
+		write(this.range);
+		write(this.idRanges);
+		write(this.exportPresenceMode);
+		write(this.namespaceObjectAsContext);
+		write(this.call);
+		write(this.directImport);
+		write(this.shorthand);
+		write(this.asiSafe);
+		write(this.usedByExports);
+		write(this.referencedPropertiesInDestructuring);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.ids = read();
+		this.name = read();
+		this.range = read();
+		this.idRanges = read();
+		this.exportPresenceMode = read();
+		this.namespaceObjectAsContext = read();
+		this.call = read();
+		this.directImport = read();
+		this.shorthand = read();
+		this.asiSafe = read();
+		this.usedByExports = read();
+		this.referencedPropertiesInDestructuring = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	HarmonyImportSpecifierDependency,
+	"webpack/lib/dependencies/HarmonyImportSpecifierDependency"
+);
+
+HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependencyTemplate extends (
+	HarmonyImportDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency);
+		const { moduleGraph, runtime, initFragments } = templateContext;
+		const connection = moduleGraph.getConnection(dep);
+
+		// Only render declaration for import specifier when the dependency is conditional
+		if (connection && !connection.isTargetActive(runtime)) {
+			initFragments.push(
+				new InitFragment(
+					`/* unused harmony import specifier */ var ${dep.name};\n`,
+					InitFragment.STAGE_HARMONY_IMPORTS,
+					0,
+					`unused import specifier ${dep.name}`
+				)
+			);
+
+			return;
+		}
+
+		const ids = dep.getIds(moduleGraph);
+		const {
+			trimmedRange: [trimmedRangeStart, trimmedRangeEnd],
+			trimmedIds
+		} = getTrimmedIdsAndRange(ids, dep.range, dep.idRanges, moduleGraph, dep);
+
+		const exportExpr = this._getCodeForIds(
+			dep,
+			source,
+			templateContext,
+			trimmedIds
+		);
+		if (dep.shorthand) {
+			source.insert(trimmedRangeEnd, `: ${exportExpr}`);
+		} else {
+			source.replace(trimmedRangeStart, trimmedRangeEnd - 1, exportExpr);
+		}
+
+		if (dep.referencedPropertiesInDestructuring) {
+			let prefixedIds = ids;
+
+			if (ids[0] === "default") {
+				const selfModule =
+					/** @type {Module} */
+					(moduleGraph.getParentModule(dep));
+				const importedModule =
+					/** @type {Module} */
+					(moduleGraph.getModule(dep));
+				const exportsType = importedModule.getExportsType(
+					moduleGraph,
+					/** @type {BuildMeta} */
+					(selfModule.buildMeta).strictHarmonyModule
+				);
+				if (
+					(exportsType === "default-only" ||
+						exportsType === "default-with-named") &&
+					ids.length >= 1
+				) {
+					prefixedIds = ids.slice(1);
+				}
+			}
+
+			/** @type {{ ids: Ids, range: Range, shorthand: boolean | string }[]} */
+			const replacementsInDestructuring = [];
+			traverseDestructuringAssignmentProperties(
+				dep.referencedPropertiesInDestructuring,
+				undefined,
+				(stack) => {
+					const property = stack[stack.length - 1];
+					replacementsInDestructuring.push({
+						ids: stack.map((p) => p.id),
+						range: property.range,
+						shorthand: property.shorthand
+					});
+				}
+			);
+			for (const { ids, shorthand, range } of replacementsInDestructuring) {
+				/** @type {Ids} */
+				const concatedIds = [...prefixedIds, ...ids];
+				const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+				const used = moduleGraph
+					.getExportsInfo(module)
+					.getUsedName(concatedIds, runtime);
+				if (!used) return;
+				const newName = used[used.length - 1];
+				const name = concatedIds[concatedIds.length - 1];
+				if (newName === name) continue;
+
+				const comment = `${Template.toNormalComment(name)} `;
+				const key = comment + JSON.stringify(newName);
+				source.replace(
+					range[0],
+					range[1] - 1,
+					shorthand ? `${key}: ${name}` : `${key}`
+				);
+			}
+		}
+	}
+
+	/**
+	 * Returns generated code.
+	 * @param {HarmonyImportSpecifierDependency} dep dependency
+	 * @param {ReplaceSource} source source
+	 * @param {DependencyTemplateContext} templateContext context
+	 * @param {Ids} ids ids
+	 * @returns {string} generated code
+	 */
+	_getCodeForIds(dep, source, templateContext, ids) {
+		const { moduleGraph, module, runtime, concatenationScope } =
+			templateContext;
+		const connection = moduleGraph.getConnection(dep);
+		/** @type {string} */
+		let exportExpr;
+		if (
+			connection &&
+			concatenationScope &&
+			concatenationScope.isModuleInScope(connection.module)
+		) {
+			if (ids.length === 0) {
+				exportExpr = concatenationScope.createModuleReference(
+					connection.module,
+					{
+						asiSafe: dep.asiSafe,
+						deferredImport: ImportPhaseUtils.isDefer(dep.phase)
+					}
+				);
+			} else if (dep.namespaceObjectAsContext && ids.length === 1) {
+				exportExpr =
+					concatenationScope.createModuleReference(connection.module, {
+						asiSafe: dep.asiSafe,
+						deferredImport: ImportPhaseUtils.isDefer(dep.phase)
+					}) + propertyAccess(ids);
+			} else {
+				exportExpr = concatenationScope.createModuleReference(
+					connection.module,
+					{
+						ids,
+						call: dep.call,
+						directImport: dep.directImport,
+						asiSafe: dep.asiSafe,
+						deferredImport: ImportPhaseUtils.isDefer(dep.phase)
+					}
+				);
+			}
+		} else {
+			super.apply(dep, source, templateContext);
+
+			const { runtimeTemplate, initFragments, runtimeRequirements } =
+				templateContext;
+
+			exportExpr = runtimeTemplate.exportFromImport({
+				moduleGraph,
+				module: /** @type {Module} */ (moduleGraph.getModule(dep)),
+				chunkGraph: templateContext.chunkGraph,
+				request: dep.request,
+				exportName: ids,
+				originModule: module,
+				asiSafe: dep.shorthand ? true : dep.asiSafe,
+				isCall: dep.call,
+				callContext: !dep.directImport,
+				defaultInterop: true,
+				importVar: dep.getImportVar(moduleGraph),
+				initFragments,
+				runtime,
+				runtimeRequirements,
+				dependency: dep
+			});
+		}
+		return exportExpr;
+	}
+};
+
+module.exports = HarmonyImportSpecifierDependency;
+module.exports.idsSymbol = idsSymbol;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyLinkingError.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyLinkingError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyLinkingError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+
+class HarmonyLinkingError extends WebpackError {
+	/** @param {string} message Error message */
+	constructor(message) {
+		super(message);
+		/** @type {string} */
+		this.name = "HarmonyLinkingError";
+		this.hideStack = true;
+	}
+}
+
+module.exports = HarmonyLinkingError;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,161 @@
+/*
+	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
+} = require("../ModuleTypeConstants");
+const CreateRequireParserPlugin = require("./CreateRequireParserPlugin");
+const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
+const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
+const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
+const HarmonyDetectionParserPlugin = require("./HarmonyDetectionParserPlugin");
+const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
+const HarmonyExportDependencyParserPlugin = require("./HarmonyExportDependencyParserPlugin");
+const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDependency");
+const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency");
+const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency");
+const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency");
+const HarmonyImportDependencyParserPlugin = require("./HarmonyImportDependencyParserPlugin");
+const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
+const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
+
+const HarmonyTopLevelThisParserPlugin = require("./HarmonyTopLevelThisParserPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+/**
+ * Defines the harmony modules plugin options type used by this module.
+ * @typedef {object} HarmonyModulesPluginOptions
+ * @property {boolean=} deferImport
+ */
+
+const PLUGIN_NAME = "HarmonyModulesPlugin";
+
+class HarmonyModulesPlugin {
+	/**
+	 * Creates an instance of HarmonyModulesPlugin.
+	 * @param {HarmonyModulesPluginOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					HarmonyCompatibilityDependency,
+					new HarmonyCompatibilityDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					HarmonyImportSideEffectDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HarmonyImportSideEffectDependency,
+					new HarmonyImportSideEffectDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					HarmonyImportSpecifierDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HarmonyImportSpecifierDependency,
+					new HarmonyImportSpecifierDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					HarmonyEvaluatedImportSpecifierDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HarmonyEvaluatedImportSpecifierDependency,
+					new HarmonyEvaluatedImportSpecifierDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					HarmonyExportHeaderDependency,
+					new HarmonyExportHeaderDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					HarmonyExportExpressionDependency,
+					new HarmonyExportExpressionDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					HarmonyExportSpecifierDependency,
+					new HarmonyExportSpecifierDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					HarmonyExportImportedSpecifierDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HarmonyExportImportedSpecifierDependency,
+					new HarmonyExportImportedSpecifierDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					HarmonyAcceptDependency,
+					new HarmonyAcceptDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					HarmonyAcceptImportDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HarmonyAcceptImportDependency,
+					new HarmonyAcceptImportDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					// TODO webpack 6: rename harmony to esm or module
+					if (parserOptions.harmony !== undefined && !parserOptions.harmony) {
+						return;
+					}
+
+					new HarmonyDetectionParserPlugin().apply(parser);
+					new HarmonyImportDependencyParserPlugin(parserOptions).apply(parser);
+					new HarmonyExportDependencyParserPlugin(parserOptions).apply(parser);
+					new HarmonyTopLevelThisParserPlugin().apply(parser);
+					if (parserOptions.createRequire) {
+						new CreateRequireParserPlugin(parserOptions).apply(parser);
+					}
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+module.exports = HarmonyModulesPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/HarmonyTopLevelThisParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HarmonyTopLevelThisParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HarmonyTopLevelThisParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const ConstDependency = require("./ConstDependency");
+const HarmonyExports = require("./HarmonyExports");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "HarmonyTopLevelThisParserPlugin";
+
+class HarmonyTopLevelThisParserPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.expression.for("this").tap(PLUGIN_NAME, (node) => {
+			if (!parser.scope.topLevelScope) return;
+			if (HarmonyExports.isEnabled(parser.state)) {
+				const dep = new ConstDependency(
+					"undefined",
+					/** @type {Range} */ (node.range),
+					null
+				);
+				dep.loc = /** @type {DependencyLocation} */ (node.loc);
+				parser.state.module.addPresentationalDependency(dep);
+				return true;
+			}
+		});
+	}
+}
+
+module.exports = HarmonyTopLevelThisParserPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/HtmlInlineScriptDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HtmlInlineScriptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HtmlInlineScriptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,133 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const CssUrlDependency = require("./CssUrlDependency");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/**
+ * Represents an inline `<script>...</script>` block in an HTML module. The
+ * tag's body is bundled as its own entry chunk — the same pipeline that
+ * processes `<script src>` — and the inline body is replaced with a
+ * `src` attribute pointing at the emitted chunk URL.
+ */
+class HtmlInlineScriptDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of HtmlInlineScriptDependency.
+	 * @param {string} request virtual request resolving to the inline JS (data URI)
+	 * @param {number} insertPos position right after `<script` where ` src="…"` is inserted
+	 * @param {Range} contentRange range of the inline JS body (between `<script>` and `</script>`)
+	 * @param {string} entryName name of the entry the inline JS is bundled into
+	 * @param {string=} category dependency category used for resolving and grouping
+	 */
+	constructor(request, insertPos, contentRange, entryName, category) {
+		super(request);
+		this.insertPos = insertPos;
+		this.contentRange = contentRange;
+		this.range = contentRange;
+		this.entryName = entryName;
+		/** @type {string} */
+		this._category = category || "commonjs";
+	}
+
+	get type() {
+		return "html inline script";
+	}
+
+	get category() {
+		return this._category;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.insertPos);
+		write(this.contentRange);
+		write(this.entryName);
+		write(this._category);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.insertPos = read();
+		this.contentRange = read();
+		this.range = this.contentRange;
+		this.entryName = read();
+		this._category = read();
+		super.deserialize(context);
+	}
+}
+
+HtmlInlineScriptDependency.Template = class HtmlInlineScriptDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const { runtimeTemplate } = templateContext;
+		const dep = /** @type {HtmlInlineScriptDependency} */ (dependency);
+		const compilation = runtimeTemplate.compilation;
+		const entrypoint = /** @type {Entrypoint | undefined} */ (
+			compilation.entrypoints.get(dep.entryName)
+		);
+
+		/** @type {string} */
+		let url = "data:,";
+
+		if (entrypoint) {
+			const chunk = /** @type {Chunk} */ (entrypoint.getEntrypointChunk());
+			const outputOptions = runtimeTemplate.outputOptions;
+			const filenameTemplate =
+				chunk.filenameTemplate ||
+				(chunk.canBeInitial()
+					? outputOptions.filename
+					: outputOptions.chunkFilename);
+
+			const filename = compilation.getPath(filenameTemplate, {
+				chunk,
+				contentHashType: "javascript"
+			});
+
+			url = `${CssUrlDependency.PUBLIC_PATH_AUTO}${filename}`;
+		}
+
+		// Insert ` src="…"` right after `<script` so the inline body is
+		// served from the emitted chunk instead. The browser ignores the
+		// remaining inline body once `src` is present, but we still clear
+		// it below so the unprocessed JS doesn't ride along.
+		source.insert(dep.insertPos, ` src="${url}"`);
+		source.replace(dep.contentRange[0], dep.contentRange[1] - 1, "");
+	}
+};
+
+makeSerializable(
+	HtmlInlineScriptDependency,
+	"webpack/lib/dependencies/HtmlInlineScriptDependency"
+);
+
+module.exports = HtmlInlineScriptDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HtmlInlineStyleDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HtmlInlineStyleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HtmlInlineStyleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,101 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { CSS_TEXT_TYPE } = require("../ModuleSourceTypeConstants");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Represents an inline `<style>...</style>` block in an HTML module. The
+ * tag's content is fed into webpack's CSS pipeline as a virtual CSS module
+ * with `exportType: "text"` so `url()` and `\@import` references are
+ * resolved relative to the HTML file. At render time the original content
+ * range is replaced with the processed CSS text read from the CSS module's
+ * code generation data.
+ */
+class HtmlInlineStyleDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of HtmlInlineStyleDependency.
+	 * @param {string} request virtual request resolving to the inline CSS (data URI)
+	 * @param {Range} range range of the inline CSS content (between `<style>` and `</style>`)
+	 */
+	constructor(request, range) {
+		super(request);
+		this.range = range;
+	}
+
+	get type() {
+		return "html inline style";
+	}
+
+	get category() {
+		return "html-style";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		super.deserialize(context);
+	}
+}
+
+HtmlInlineStyleDependency.Template = class HtmlInlineStyleDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { moduleGraph, runtime, codeGenerationResults }) {
+		const dep = /** @type {HtmlInlineStyleDependency} */ (dependency);
+		const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+
+		/** @type {string} */
+		let cssText = "";
+
+		if (module) {
+			const codeGen =
+				/** @type {CodeGenerationResults} */
+				(codeGenerationResults).get(module, runtime);
+			const cssTextSource = codeGen.sources.get(CSS_TEXT_TYPE);
+			if (cssTextSource) {
+				cssText = /** @type {string} */ (cssTextSource.source());
+			}
+		}
+
+		source.replace(dep.range[0], dep.range[1] - 1, cssText);
+	}
+};
+
+makeSerializable(
+	HtmlInlineStyleDependency,
+	"webpack/lib/dependencies/HtmlInlineStyleDependency"
+);
+
+module.exports = HtmlInlineStyleDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HtmlScriptSrcDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HtmlScriptSrcDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HtmlScriptSrcDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,557 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const {
+	CSS_IMPORT_TYPE,
+	CSS_TYPE,
+	JAVASCRIPT_TYPE
+} = require("../ModuleSourceTypeConstants");
+const makeSerializable = require("../util/makeSerializable");
+const CssUrlDependency = require("./CssUrlDependency");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {"script-classic" | "script-module" | "modulepreload" | "stylesheet"} HtmlScriptElementKind */
+
+class HtmlScriptSrcDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of HtmlScriptSrcDependency.
+	 * @param {string} request request
+	 * @param {Range} range range of the attribute value in the source
+	 * @param {string} entryName name of the entry this script src is bundled into
+	 * @param {string=} category dependency category used for resolving and grouping
+	 * @param {HtmlScriptElementKind=} elementKind shape of the originating HTML element; used when expanding sibling tags for split/runtime chunks
+	 * @param {number=} tagStart position of the opening `<` of the originating tag in the source; sibling tags emitted for additional entry chunks are inserted right before this
+	 * @param {number=} tagOpenEnd position of the character immediately after the opening tag's `>` in the source; combined with `tagStart` this lets the template clone the original opening tag verbatim (preserving attributes like `nonce`, `crossorigin`, `referrerpolicy`, `defer`, `async`) when generating sibling tags
+	 */
+	constructor(
+		request,
+		range,
+		entryName,
+		category,
+		elementKind,
+		tagStart,
+		tagOpenEnd
+	) {
+		super(request);
+		this.range = range;
+		this.entryName = entryName;
+		/** @type {string} */
+		this._category = category || "commonjs";
+		/** @type {HtmlScriptElementKind} */
+		this.elementKind = elementKind || "script-classic";
+		/** @type {number} */
+		this.tagStart = tagStart === undefined ? -1 : tagStart;
+		/** @type {number} */
+		this.tagOpenEnd = tagOpenEnd === undefined ? -1 : tagOpenEnd;
+	}
+
+	get type() {
+		return "html script src";
+	}
+
+	get category() {
+		return this._category;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.entryName);
+		write(this._category);
+		write(this.elementKind);
+		write(this.tagStart);
+		write(this.tagOpenEnd);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.entryName = read();
+		this._category = read();
+		this.elementKind = read();
+		this.tagStart = read();
+		this.tagOpenEnd = read();
+		super.deserialize(context);
+	}
+}
+
+/**
+ * @param {Chunk} chunk a chunk
+ * @param {import("../Compilation")} compilation compilation
+ * @param {"javascript" | "css"} contentHashType which content hash to plug into the filename template
+ * @returns {string} chunk filename path (no public-path prefix)
+ */
+const getChunkFilename = (chunk, compilation, contentHashType) => {
+	const outputOptions = compilation.outputOptions;
+	let filenameTemplate;
+	if (contentHashType === "css") {
+		// For a CSS-typed chunk, use the same template the CSS pipeline
+		// will use when it actually emits the `.css` file, so the `<link
+		// rel="stylesheet" href>` URL we write into the HTML matches the
+		// asset on disk.
+		filenameTemplate =
+			require("../css/CssModulesPlugin").getChunkFilenameTemplate(
+				chunk,
+				outputOptions
+			);
+	} else {
+		filenameTemplate =
+			chunk.filenameTemplate ||
+			(chunk.canBeInitial()
+				? outputOptions.filename
+				: outputOptions.chunkFilename);
+	}
+
+	return compilation.getPath(filenameTemplate, {
+		chunk,
+		contentHashType
+	});
+};
+
+/**
+ * @param {Entrypoint} entrypoint entrypoint
+ * @returns {Chunk[]} every chunk this entrypoint needs in load order: the
+ * runtime chunk first (when `optimization.runtimeChunk` splits it off), then
+ * any intermediate chunks (e.g. from `optimization.splitChunks`), and finally
+ * the entry chunk itself. The entry chunk is always returned last so callers
+ * can identify it as the tag whose `src`/`href` attribute is being rewritten
+ * in place. Chunks that are already loaded by an ancestor (`dependOn`) entry's
+ * own script tag — i.e. the parent entrypoint's entry chunk *and* its runtime
+ * chunk — are skipped, otherwise they would be loaded twice when the same
+ * HTML contains tags for both the leader and the dependant entries.
+ */
+const getEntrypointChunksInLoadOrder = (entrypoint) => {
+	const entryChunk = /** @type {Chunk} */ (entrypoint.getEntrypointChunk());
+	const runtimeChunk = entrypoint.getRuntimeChunk();
+
+	/** @type {Set<Chunk>} */
+	const chunksLoadedByAncestorTags = new Set();
+	/** @type {Set<import("../ChunkGroup")>} */
+	const visitedGroups = new Set();
+	const walk = (/** @type {import("../ChunkGroup")} */ group) => {
+		if (visitedGroups.has(group)) return;
+		visitedGroups.add(group);
+		for (const parent of group.parentsIterable) {
+			if (
+				typeof (/** @type {Entrypoint} */ (parent).getEntrypointChunk) ===
+				"function"
+			) {
+				const parentEntry =
+					/** @type {Entrypoint} */
+					(parent).getEntrypointChunk();
+				if (parentEntry) chunksLoadedByAncestorTags.add(parentEntry);
+				const parentRuntime =
+					/** @type {Entrypoint} */
+					(parent).getRuntimeChunk();
+				if (parentRuntime) chunksLoadedByAncestorTags.add(parentRuntime);
+			}
+			walk(parent);
+		}
+	};
+	walk(entrypoint);
+
+	/** @type {Chunk[]} */
+	const ordered = [];
+	/** @type {Set<Chunk>} */
+	const seen = new Set();
+	const push = (/** @type {Chunk | null | undefined} */ chunk) => {
+		if (!chunk || seen.has(chunk) || chunk === entryChunk) return;
+		if (chunksLoadedByAncestorTags.has(chunk)) return;
+		seen.add(chunk);
+		ordered.push(chunk);
+	};
+	if (runtimeChunk !== entryChunk) {
+		push(runtimeChunk);
+	}
+	for (const chunk of entrypoint.chunks) {
+		push(chunk);
+	}
+	ordered.push(entryChunk);
+	return ordered;
+};
+
+/**
+ * Whether webpack will emit a `.js` file for this chunk that must be
+ * loaded with a `<script>` tag. Covers three independent reasons a
+ * chunk needs JS output: it owns one or more JS-source-type modules;
+ * it has entry modules whose source types include JavaScript (entry
+ * modules don't show up in `getChunkModulesIterableBySourceType` until
+ * they're connected as regular modules — this is why
+ * `JavascriptModulesPlugin#_chunkHasJs` checks them separately); or it
+ * is a runtime chunk — `chunk.hasRuntime()` — which produces a `.js`
+ * file holding the webpack runtime, but its `RuntimeModule`s live in
+ * a separate `runtimeModules` set and are *not* surfaced via
+ * `getChunkModulesIterableBySourceType`. Missing the runtime case
+ * would cause a `runtimeChunk`-split chunk to fall out of the
+ * `<script>` list and re-emerge after the chunks that depend on it,
+ * producing `__webpack_require__ is not defined` at load time.
+ * @param {Chunk} chunk chunk
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @returns {boolean} true if the chunk emits a `.js` file
+ */
+const chunkHasJs = (chunk, chunkGraph) => {
+	if (chunk.hasRuntime()) return true;
+	if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
+		for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
+			if (chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
+				return true;
+			}
+		}
+	}
+	return Boolean(
+		chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
+	);
+};
+
+/**
+ * Whether webpack will emit a `.css` file for this chunk that must be
+ * loaded with a `<link rel="stylesheet">` tag. Matches
+ * `CssModulesPlugin.chunkHasCss` exactly — both regular CSS modules
+ * and pure `@import` placeholder modules count, since the latter
+ * still contribute a `.css` asset to the chunk.
+ * @param {Chunk} chunk chunk
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @returns {boolean} true if the chunk emits a `.css` file
+ */
+const chunkHasCss = (chunk, chunkGraph) =>
+	Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_TYPE)) ||
+	Boolean(
+		chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_IMPORT_TYPE)
+	);
+
+/**
+ * Compare two chunks for a deterministic tie-break in CSS link ordering.
+ * `chunk.name` and `chunk.id` are both stable strings (when present);
+ * one of them is set for every chunk webpack emits. We can't rely on
+ * `Array.prototype.sort` being stable — webpack still supports Node
+ * 10.13 where V8's sort is not guaranteed stable for arrays larger
+ * than ten elements — so any time `firstCssModulePostOrderIndex`
+ * returns the same value for two chunks (most commonly when several
+ * chunks have no reachable CSS module in the entrypoint's dependency
+ * walk and all map to `Infinity`) this comparator picks the canonical
+ * order.
+ * @param {Chunk} a first chunk
+ * @param {Chunk} b second chunk
+ * @returns {-1 | 0 | 1} ordering
+ */
+const compareChunksForCssTieBreak = (a, b) => {
+	const an = `${a.name || ""} ${a.id === null || a.id === undefined ? "" : a.id}`;
+	const bn = `${b.name || ""} ${b.id === null || b.id === undefined ? "" : b.id}`;
+	if (an < bn) return -1;
+	if (an > bn) return 1;
+	return 0;
+};
+
+/**
+ * Smallest post-order index among the CSS modules of a chunk, taken
+ * from the entrypoint's view of the dependency graph. Used to sort
+ * sibling CSS chunks so they appear in source import order in the
+ * extracted HTML — `entrypoint.chunks` itself does not give that
+ * ordering for arbitrary splitChunks layouts. Considers both
+ * `CSS_TYPE` and `CSS_IMPORT_TYPE` modules so a chunk made up
+ * exclusively of `@import` placeholder modules (e.g. when splitChunks
+ * separates them from their target CSS) still sorts by its true
+ * source position rather than collapsing to `Infinity` and relying on
+ * the chunk-name tie-breaker.
+ * @param {Chunk} chunk chunk
+ * @param {Entrypoint} entrypoint entrypoint the chunk belongs to
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @returns {number} the lowest post-order index of any CSS or
+ * CSS-import module in the chunk, or `Number.POSITIVE_INFINITY` when
+ * no such module has a defined index (e.g. for a module the
+ * entrypoint never reached on its own dependency walk — runtime-only
+ * modules, modules reached via `dependOn`, etc.) so such chunks sort
+ * last among CSS chunks
+ */
+const firstCssModulePostOrderIndex = (chunk, entrypoint, chunkGraph) => {
+	let min = Number.POSITIVE_INFINITY;
+	for (const sourceType of [CSS_TYPE, CSS_IMPORT_TYPE]) {
+		const modules = chunkGraph.getChunkModulesIterableBySourceType(
+			chunk,
+			sourceType
+		);
+		if (!modules) continue;
+		for (const module of modules) {
+			const idx = entrypoint.getModulePostOrderIndex(module);
+			if (idx !== undefined && idx < min) min = idx;
+		}
+	}
+	return min;
+};
+
+const COPYABLE_LINK_ATTRS = ["nonce", "crossorigin", "referrerpolicy"];
+
+/**
+ * Build a fresh `<link rel="stylesheet" href="…">` for a CSS chunk that
+ * was pulled in by a `<script src>` entry — the originating tag was a
+ * `<script>`, but the chunk is CSS so cloning the script tag verbatim
+ * would produce nonsense (`<script src="…\.css">`). Copy
+ * `nonce`/`crossorigin`/`referrerpolicy` from the original element so
+ * the same CSP and fetch policy applies; `defer`/`async`/`type` have no
+ * meaning on `<link>` and are dropped.
+ * @param {string} originalTag the originating `<script>`/`<link>` tag's source text
+ * @param {string} href URL for the stylesheet
+ * @returns {string} the sibling `<link>` tag's HTML
+ */
+const buildStylesheetLink = (originalTag, href) => {
+	let extra = "";
+	for (const attr of COPYABLE_LINK_ATTRS) {
+		// Match ` <attr>`, ` <attr>=value`, ` <attr>="value"`, ` <attr>='value'`.
+		const re = new RegExp(
+			`\\s${attr}(?:\\s*=\\s*(?:"[^"]*"|'[^']*'|[^\\s>]+))?(?=[\\s/>])`,
+			"i"
+		);
+		const m = originalTag.match(re);
+		if (m) extra += m[0];
+	}
+	const safeHref = href.replace(/"/g, "&quot;");
+	return `<link rel="stylesheet" href="${safeHref}"${extra}>`;
+};
+
+/**
+ * Clone the original `<script>`/`<link>` opening tag with its `src`/`href`
+ * value swapped for a different chunk URL. Reusing the source text verbatim
+ * preserves attributes such as `nonce`, `crossorigin`, `referrerpolicy`,
+ * `defer`, and `async` so the sibling tags load with the same semantics as
+ * the entry tag that's already there. `integrity` is dropped because it's
+ * content-specific. When the original tag was upgraded to a module script
+ * (either by the author or by the `output.module` auto-upgrade in
+ * `HtmlParser`), the sibling is forced to `type="module"` regardless of what
+ * the source originally said.
+ * @param {string} originalTag the opening tag's source text including `>`
+ * @param {number} srcStartInTag offset of the src/href value start within `originalTag`
+ * @param {number} srcEndInTag offset of the src/href value end within `originalTag`
+ * @param {string} newUrl URL to put into the cloned tag's src/href slot
+ * @param {HtmlScriptElementKind} elementKind shape of the originating tag
+ * @returns {string} the sibling tag's HTML (including a closing `</script>` for script tags)
+ */
+const cloneTagWithUrl = (
+	originalTag,
+	srcStartInTag,
+	srcEndInTag,
+	newUrl,
+	elementKind
+) => {
+	let body =
+		originalTag.slice(0, srcStartInTag) +
+		newUrl +
+		originalTag.slice(srcEndInTag);
+
+	// Strip dangerous-to-copy attributes from the cloned tag — currently
+	// just `integrity`. The match handles all three quoting styles
+	// (`"…"`, `'…'`, unquoted) and the bare-attribute form.
+	body = body.replace(
+		/\s+integrity(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?(?=[\s/>])/gi,
+		""
+	);
+
+	if (elementKind === "script-module") {
+		if (/\stype\s*=/i.test(body)) {
+			body = body.replace(
+				/(\stype\s*=\s*)(?:"[^"]*"|'[^']*'|[^\s>]+)/i,
+				'$1"module"'
+			);
+		} else {
+			body = body.replace(/^<script\b/i, '<script type="module"');
+		}
+	}
+
+	// `<link>` is a void element — no closing tag. `<script>` needs `</script>`.
+	return elementKind === "modulepreload" || elementKind === "stylesheet"
+		? body
+		: `${body}</script>`;
+};
+
+HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const { runtimeTemplate } = templateContext;
+		const dep = /** @type {HtmlScriptSrcDependency} */ (dependency);
+		const compilation = runtimeTemplate.compilation;
+		const { chunkGraph } = compilation;
+		const entrypoint = /** @type {Entrypoint | undefined} */ (
+			compilation.entrypoints.get(dep.entryName)
+		);
+
+		if (!entrypoint) {
+			source.replace(dep.range[0], dep.range[1] - 1, "data:,");
+			return;
+		}
+
+		const orderedChunks = getEntrypointChunksInLoadOrder(entrypoint);
+		const entryChunk = orderedChunks[orderedChunks.length - 1];
+		const isStylesheet = dep.elementKind === "stylesheet";
+
+		// Rewrite the originating tag's src/href to the entry chunk's
+		// primary asset for that element kind: `.css` for
+		// `<link rel="stylesheet">`, `.js` for everything else.
+		const entryContentHashType = isStylesheet ? "css" : "javascript";
+		const entryUrl = `${CssUrlDependency.PUBLIC_PATH_AUTO}${getChunkFilename(
+			entryChunk,
+			compilation,
+			entryContentHashType
+		)}`;
+		source.replace(dep.range[0], dep.range[1] - 1, entryUrl);
+
+		if (dep.tagStart < 0 || dep.tagOpenEnd <= dep.tagStart) {
+			return;
+		}
+
+		// The browser must load every chunk the entry needs, not just the
+		// entry chunk. For `<script>` entries that's the JS for sibling
+		// chunks plus — critically — the CSS for any chunk that holds
+		// stylesheets imported transitively from the JS source. Previously
+		// every sibling was cloned as a `<script>` pointing at a `.js`
+		// filename, so CSS chunks ended up as `<script src="foo.css">`
+		// pointing at non-existent `.js` files (the bug in
+		// html-webpack-plugin#1838 / webpack/mini-css-extract-plugin#959,
+		// magnified here because the entry chunk's own CSS was emitted to
+		// disk but never linked from the HTML at all).
+		const originalContent = /** @type {string} */ (source.original().source());
+		const originalTag = originalContent.slice(dep.tagStart, dep.tagOpenEnd);
+		const srcStartInTag = dep.range[0] - dep.tagStart;
+		const srcEndInTag = dep.range[1] - dep.tagStart;
+
+		/**
+		 * @param {Chunk} chunk chunk to emit a sibling tag for
+		 * @param {"javascript" | "css"} kind content type slice of the chunk to emit
+		 * @returns {string} a single sibling tag's HTML
+		 */
+		const buildSibling = (chunk, kind) => {
+			const url = `${CssUrlDependency.PUBLIC_PATH_AUTO}${getChunkFilename(
+				chunk,
+				compilation,
+				kind
+			)}`;
+			if (kind === "css" && !isStylesheet) {
+				// Originating tag is `<script>` (or `<link rel=modulepreload>`)
+				// but this chunk is CSS — emit a fresh `<link>` rather than
+				// cloning the script.
+				return buildStylesheetLink(originalTag, url);
+			}
+			return cloneTagWithUrl(
+				originalTag,
+				srcStartInTag,
+				srcEndInTag,
+				url,
+				dep.elementKind
+			);
+		};
+
+		const siblings = [];
+
+		if (isStylesheet) {
+			// `<link rel="stylesheet">` entries are CSS-only — every sibling
+			// chunk in the entrypoint is also CSS. Keep cloning the original
+			// `<link>` for them so attributes like `media` carry over.
+			for (let i = 0; i < orderedChunks.length - 1; i++) {
+				siblings.push(buildSibling(orderedChunks[i], "css"));
+			}
+		} else {
+			// CSS chunks are emitted before JS chunks so the cascade is set
+			// up before any script runs. Within CSS the order needs to match
+			// the source's import order — `entrypoint.chunks` alone doesn't
+			// give us that for arbitrary splitChunks layouts (splitChunks
+			// inserts each new chunk before the entry chunk via
+			// `insertChunk(_, before)`, so split CSS siblings end up in
+			// *reverse* of the order they were processed — exactly the
+			// html-webpack-plugin#1838 / mini-css-extract#959 symptom). We
+			// re-derive the order from the entrypoint's module post-order
+			// index, which mirrors the dependency walk and so reflects the
+			// import order.
+			/** @type {{ chunk: Chunk, index: number }[]} */
+			const cssChunkOrder = [];
+			/** @type {Chunk[]} */
+			const jsChunks = [];
+			for (let i = 0; i < orderedChunks.length - 1; i++) {
+				const chunk = orderedChunks[i];
+				const hasCss = chunkHasCss(chunk, chunkGraph);
+				const hasJs = chunkHasJs(chunk, chunkGraph);
+				if (hasCss) {
+					cssChunkOrder.push({
+						chunk,
+						index: firstCssModulePostOrderIndex(chunk, entrypoint, chunkGraph)
+					});
+				}
+				// Anything that isn't CSS-only stays on the JS lane, in the
+				// `orderedChunks` order — that preserves the runtime-first /
+				// vendor-before-entry invariant of `getEntrypointChunksInLoadOrder`.
+				// Chunks that produce no `.js` and no `.css` (e.g. wasm-only
+				// or asset-only) still get a `<script>` clone here so we
+				// keep prior behavior for users who relied on it.
+				if (hasJs || !hasCss) jsChunks.push(chunk);
+			}
+			// If the entry chunk itself contains CSS (entry JS imports CSS
+			// without splitChunks separating it), fold it into the same CSS
+			// ordering so the entry-chunk `<link>` lands in the correct
+			// cascade position relative to sibling CSS chunks.
+			if (chunkHasCss(entryChunk, chunkGraph)) {
+				cssChunkOrder.push({
+					chunk: entryChunk,
+					index: firstCssModulePostOrderIndex(
+						entryChunk,
+						entrypoint,
+						chunkGraph
+					)
+				});
+			}
+			cssChunkOrder.sort((a, b) => {
+				// Direct subtraction would yield `NaN` when both indices are
+				// `Infinity` (the documented fallback for chunks whose CSS
+				// modules the entrypoint's walk never reaches), and
+				// `Array#sort` doesn't promise stable ordering on the legacy
+				// Node 10 targets this repo still supports — so the
+				// tie-breaker must always run when the indices match,
+				// including the `Infinity === Infinity` case.
+				if (a.index < b.index) return -1;
+				if (a.index > b.index) return 1;
+				return compareChunksForCssTieBreak(a.chunk, b.chunk);
+			});
+			for (const { chunk } of cssChunkOrder) {
+				siblings.push(buildSibling(chunk, "css"));
+			}
+			for (const chunk of jsChunks) {
+				siblings.push(buildSibling(chunk, "javascript"));
+			}
+		}
+
+		if (siblings.length > 0) {
+			source.insert(dep.tagStart, siblings.join(""));
+		}
+	}
+};
+
+makeSerializable(
+	HtmlScriptSrcDependency,
+	"webpack/lib/dependencies/HtmlScriptSrcDependency"
+);
+
+module.exports = HtmlScriptSrcDependency;
Index: frontend/node_modules/webpack/lib/dependencies/HtmlSourceDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/HtmlSourceDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/HtmlSourceDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,128 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const { ASSET_URL_TYPE } = require("../ModuleSourceTypeConstants");
+const RawDataUrlModule = require("../asset/RawDataUrlModule");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+const getIgnoredRawDataUrlModule = memoize(
+	() => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)")
+);
+
+class HtmlSourceDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of HtmlSourceDependency.
+	 * @param {string} request request
+	 * @param {Range} range range of the argument
+	 */
+	constructor(request, range) {
+		super(request);
+		this.range = range;
+	}
+
+	get type() {
+		return "html source()";
+	}
+
+	get category() {
+		return "url";
+	}
+
+	/**
+	 * Creates an ignored module.
+	 * @param {string} context context directory
+	 * @returns {Module} ignored module
+	 */
+	createIgnoredModule(context) {
+		return getIgnoredRawDataUrlModule();
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		super.deserialize(context);
+	}
+}
+
+HtmlSourceDependency.Template = class HtmlSourceDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ moduleGraph, runtimeTemplate, codeGenerationResults }
+	) {
+		const dep = /** @type {HtmlSourceDependency} */ (dependency);
+		const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+
+		/** @type {string | undefined} */
+		const newValue = this.assetUrl({
+			module,
+			codeGenerationResults
+		});
+
+		source.replace(dep.range[0], dep.range[1] - 1, newValue);
+	}
+
+	/**
+	 * Returns the url of the asset.
+	 * @param {object} options options object
+	 * @param {Module} options.module the module
+	 * @param {RuntimeSpec=} options.runtime runtime
+	 * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
+	 * @returns {string} the url of the asset
+	 */
+	assetUrl({ runtime, module, codeGenerationResults }) {
+		if (!module) {
+			return "data:,";
+		}
+		const codeGen = codeGenerationResults.get(module, runtime);
+		const data = codeGen.data;
+		if (!data) return "data:,";
+		const url = data.get("url");
+		if (!url || !url[ASSET_URL_TYPE]) return "data:,";
+		return url[ASSET_URL_TYPE];
+	}
+};
+
+makeSerializable(
+	HtmlSourceDependency,
+	"webpack/lib/dependencies/HtmlSourceDependency"
+);
+
+module.exports = HtmlSourceDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+
+class ImportContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of ImportContextDependency.
+	 * @param {ContextDependencyOptions} options options
+	 * @param {Range} range range
+	 * @param {Range} valueRange value range
+	 */
+	constructor(options, range, valueRange) {
+		super(options);
+
+		this.range = range;
+		this.valueRange = valueRange;
+	}
+
+	get type() {
+		return `import() context ${this.options.mode}`;
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		let str = super.getResourceIdentifier();
+
+		if (this.options.attributes) {
+			str += `|attributes${JSON.stringify(this.options.attributes)}`;
+		}
+
+		return str;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.valueRange);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.valueRange = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ImportContextDependency,
+	"webpack/lib/dependencies/ImportContextDependency"
+);
+
+ImportContextDependency.Template = ContextDependencyTemplateAsRequireCall;
+
+module.exports = ImportContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,177 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+const { ImportPhaseUtils } = require("./ImportPhase");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+
+class ImportDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ImportDependency.
+	 * @param {string} request the request
+	 * @param {Range} range expression range
+	 * @param {RawReferencedExports | null} referencedExports list of referenced exports
+	 * @param {ImportPhaseType} phase import phase
+	 * @param {ImportAttributes=} attributes import attributes
+	 */
+	constructor(request, range, referencedExports, phase, attributes) {
+		super(request);
+		this.range = range;
+		this.referencedExports = referencedExports;
+		this.phase = phase;
+		this.attributes = attributes;
+	}
+
+	get type() {
+		return "import()";
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		let str = super.getResourceIdentifier();
+		// We specifically use this check to avoid writing the default (`evaluation` or `0`) value and save memory
+		if (this.phase) {
+			str += `|phase${ImportPhaseUtils.stringify(this.phase)}`;
+		}
+		if (this.attributes) {
+			str += `|attributes${JSON.stringify(this.attributes)}`;
+		}
+		return str;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
+		/** @type {ReferencedExports} */
+		const refs = [];
+		for (const referencedExport of this.referencedExports) {
+			if (referencedExport[0] === "default") {
+				const selfModule =
+					/** @type {Module} */
+					(moduleGraph.getParentModule(this));
+				const importedModule =
+					/** @type {Module} */
+					(moduleGraph.getModule(this));
+				const exportsType = importedModule.getExportsType(
+					moduleGraph,
+					/** @type {BuildMeta} */
+					(selfModule.buildMeta).strictHarmonyModule
+				);
+				if (
+					exportsType === "default-only" ||
+					exportsType === "default-with-named"
+				) {
+					return Dependency.EXPORTS_OBJECT_REFERENCED;
+				}
+			}
+			refs.push({
+				name: referencedExport,
+				canMangle: false
+			});
+		}
+		return refs;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		context.write(this.range);
+		context.write(this.referencedExports);
+		context.write(this.phase);
+		context.write(this.attributes);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		this.range = context.read();
+		this.referencedExports = context.read();
+		this.phase = context.read();
+		this.attributes = context.read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ImportDependency, "webpack/lib/dependencies/ImportDependency");
+
+ImportDependency.Template = class ImportDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {ImportDependency} */ (dependency);
+		const block = /** @type {AsyncDependenciesBlock} */ (
+			moduleGraph.getParentBlock(dep)
+		);
+		let content = runtimeTemplate.moduleNamespacePromise({
+			chunkGraph,
+			block,
+			module: /** @type {Module} */ (moduleGraph.getModule(dep)),
+			request: dep.request,
+			strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
+			dependency: dep,
+			message: "import()",
+			runtimeRequirements
+		});
+
+		// For source phase imports, unwrap the default export
+		// import.source() should return the source directly, not a namespace
+		if (ImportPhaseUtils.isSource(dep.phase)) {
+			content = `${content}.then(${runtimeTemplate.returningFunction(
+				'm["default"]',
+				"m"
+			)})`;
+		}
+
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+	}
+};
+
+module.exports = ImportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportEagerDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportEagerDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportEagerDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,78 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ImportDependency = require("./ImportDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {ImportDependency.RawReferencedExports} RawReferencedExports */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+
+class ImportEagerDependency extends ImportDependency {
+	/**
+	 * Creates an instance of ImportEagerDependency.
+	 * @param {string} request the request
+	 * @param {Range} range expression range
+	 * @param {RawReferencedExports | null} referencedExports list of referenced exports
+	 * @param {ImportPhaseType} phase import phase
+	 * @param {ImportAttributes=} attributes import attributes
+	 */
+	constructor(request, range, referencedExports, phase, attributes) {
+		super(request, range, referencedExports, phase, attributes);
+	}
+
+	get type() {
+		return "import() eager";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	ImportEagerDependency,
+	"webpack/lib/dependencies/ImportEagerDependency"
+);
+
+ImportEagerDependency.Template = class ImportEagerDependencyTemplate extends (
+	ImportDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {ImportEagerDependency} */ (dependency);
+		const content = runtimeTemplate.moduleNamespacePromise({
+			chunkGraph,
+			module: /** @type {Module} */ (moduleGraph.getModule(dep)),
+			request: dep.request,
+			strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
+			message: "import() eager",
+			dependency: dep,
+			runtimeRequirements
+		});
+
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+	}
+};
+
+module.exports = ImportEagerDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportMetaContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportMetaContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportMetaContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+
+class ImportMetaContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of ImportMetaContextDependency.
+	 * @param {ContextDependencyOptions} options options
+	 * @param {Range} range range
+	 */
+	constructor(options, range) {
+		super(options);
+
+		this.range = range;
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	get type() {
+		return `import.meta.webpackContext ${this.options.mode}`;
+	}
+}
+
+makeSerializable(
+	ImportMetaContextDependency,
+	"webpack/lib/dependencies/ImportMetaContextDependency"
+);
+
+ImportMetaContextDependency.Template = ModuleDependencyTemplateAsRequireId;
+
+module.exports = ImportMetaContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportMetaContextDependencyParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportMetaContextDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportMetaContextDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,315 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const {
+	evaluateToIdentifier
+} = require("../javascript/JavascriptParserHelpers");
+const ImportMetaContextDependency = require("./ImportMetaContextDependency");
+
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").ObjectExpression} ObjectExpression */
+/** @typedef {import("estree").Property} Property */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../ContextModule").ContextModuleOptions} ContextModuleOptions */
+/** @typedef {import("../ContextModule").ContextMode} ContextMode */
+/** @typedef {import("../Chunk").ChunkName} ChunkName */
+/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+
+/** @typedef {Pick<ContextModuleOptions, "mode" | "recursive" | "regExp" | "include" | "exclude" | "chunkName"> & { groupOptions: RawChunkGroupOptions, exports?: RawReferencedExports }} ImportMetaContextOptions */
+
+/**
+ * Creates a property parse error.
+ * @param {Property} prop property
+ * @param {string} expect except message
+ * @returns {WebpackError} error
+ */
+function createPropertyParseError(prop, expect) {
+	return createError(
+		`Parsing import.meta.webpackContext options failed. Unknown value for property ${JSON.stringify(
+			/** @type {Identifier} */
+			(prop.key).name
+		)}, expected type ${expect}.`,
+		/** @type {DependencyLocation} */
+		(prop.value.loc)
+	);
+}
+
+/**
+ * Creates an error from the provided msg.
+ * @param {string} msg message
+ * @param {DependencyLocation} loc location
+ * @returns {WebpackError} error
+ */
+function createError(msg, loc) {
+	const error = new WebpackError(msg);
+	error.name = "ImportMetaContextError";
+	error.loc = loc;
+	return error;
+}
+
+const PLUGIN_NAME = "ImportMetaContextDependencyParserPlugin";
+
+module.exports = class ImportMetaContextDependencyParserPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.evaluateIdentifier
+			.for("import.meta.webpackContext")
+			.tap(PLUGIN_NAME, (expr) =>
+				evaluateToIdentifier(
+					"import.meta.webpackContext",
+					"import.meta",
+					() => ["webpackContext"],
+					true
+				)(expr)
+			);
+		parser.hooks.call
+			.for("import.meta.webpackContext")
+			.tap(PLUGIN_NAME, (expr) => {
+				if (expr.arguments.length < 1 || expr.arguments.length > 2) return;
+				const [directoryNode, optionsNode] = expr.arguments;
+				if (optionsNode && optionsNode.type !== "ObjectExpression") return;
+				const requestExpr = parser.evaluateExpression(
+					/** @type {Expression} */ (directoryNode)
+				);
+				if (!requestExpr.isString()) return;
+				const request = /** @type {string} */ (requestExpr.string);
+				/** @type {WebpackError[]} */
+				const errors = [];
+				let regExp = /^\.\/.*$/;
+				let recursive = true;
+				/** @type {ContextMode} */
+				let mode = "sync";
+				/** @type {ContextModuleOptions["include"]} */
+				let include;
+				/** @type {ContextModuleOptions["exclude"]} */
+				let exclude;
+				/** @type {RawChunkGroupOptions} */
+				const groupOptions = {};
+				/** @type {ChunkName | undefined} */
+				let chunkName;
+				/** @type {RawReferencedExports | undefined} */
+				let exports;
+				if (optionsNode) {
+					for (const prop of /** @type {ObjectExpression} */ (optionsNode)
+						.properties) {
+						if (prop.type !== "Property" || prop.key.type !== "Identifier") {
+							errors.push(
+								createError(
+									"Parsing import.meta.webpackContext options failed.",
+									/** @type {DependencyLocation} */
+									(optionsNode.loc)
+								)
+							);
+							break;
+						}
+						switch (prop.key.name) {
+							case "regExp": {
+								const regExpExpr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (!regExpExpr.isRegExp()) {
+									errors.push(createPropertyParseError(prop, "RegExp"));
+								} else {
+									regExp = /** @type {RegExp} */ (regExpExpr.regExp);
+								}
+								break;
+							}
+							case "include": {
+								const regExpExpr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (!regExpExpr.isRegExp()) {
+									errors.push(createPropertyParseError(prop, "RegExp"));
+								} else {
+									include = regExpExpr.regExp;
+								}
+								break;
+							}
+							case "exclude": {
+								const regExpExpr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (!regExpExpr.isRegExp()) {
+									errors.push(createPropertyParseError(prop, "RegExp"));
+								} else {
+									exclude = regExpExpr.regExp;
+								}
+								break;
+							}
+							case "mode": {
+								const modeExpr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (!modeExpr.isString()) {
+									errors.push(createPropertyParseError(prop, "string"));
+								} else {
+									mode = /** @type {ContextModuleOptions["mode"]} */ (
+										modeExpr.string
+									);
+								}
+								break;
+							}
+							case "chunkName": {
+								const expr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (!expr.isString()) {
+									errors.push(createPropertyParseError(prop, "string"));
+								} else {
+									chunkName = expr.string;
+								}
+								break;
+							}
+							case "exports": {
+								const expr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (expr.isString()) {
+									exports = [[/** @type {string} */ (expr.string)]];
+								} else if (expr.isArray()) {
+									const items =
+										/** @type {BasicEvaluatedExpression[]} */
+										(expr.items);
+									if (
+										items.every((i) => {
+											if (!i.isArray()) return false;
+											const innerItems =
+												/** @type {BasicEvaluatedExpression[]} */ (i.items);
+											return innerItems.every((i) => i.isString());
+										})
+									) {
+										exports = [];
+
+										for (const i1 of items) {
+											/** @type {string[]} */
+											const export_ = [];
+											for (const i2 of /** @type {BasicEvaluatedExpression[]} */ (
+												i1.items
+											)) {
+												export_.push(/** @type {string} */ (i2.string));
+											}
+											exports.push(export_);
+										}
+									} else {
+										errors.push(
+											createPropertyParseError(prop, "string|string[][]")
+										);
+									}
+								} else {
+									errors.push(
+										createPropertyParseError(prop, "string|string[][]")
+									);
+								}
+								break;
+							}
+							case "prefetch": {
+								const expr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (expr.isBoolean()) {
+									groupOptions.prefetchOrder = 0;
+								} else if (expr.isNumber()) {
+									groupOptions.prefetchOrder = expr.number;
+								} else {
+									errors.push(createPropertyParseError(prop, "boolean|number"));
+								}
+								break;
+							}
+							case "preload": {
+								const expr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (expr.isBoolean()) {
+									groupOptions.preloadOrder = 0;
+								} else if (expr.isNumber()) {
+									groupOptions.preloadOrder = expr.number;
+								} else {
+									errors.push(createPropertyParseError(prop, "boolean|number"));
+								}
+								break;
+							}
+							case "fetchPriority": {
+								const expr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (
+									expr.isString() &&
+									["high", "low", "auto"].includes(
+										/** @type {string} */ (expr.string)
+									)
+								) {
+									groupOptions.fetchPriority =
+										/** @type {RawChunkGroupOptions["fetchPriority"]} */ (
+											expr.string
+										);
+								} else {
+									errors.push(
+										createPropertyParseError(prop, '"high"|"low"|"auto"')
+									);
+								}
+								break;
+							}
+							case "recursive": {
+								const recursiveExpr = parser.evaluateExpression(
+									/** @type {Expression} */ (prop.value)
+								);
+								if (!recursiveExpr.isBoolean()) {
+									errors.push(createPropertyParseError(prop, "boolean"));
+								} else {
+									recursive = /** @type {boolean} */ (recursiveExpr.bool);
+								}
+								break;
+							}
+							default:
+								errors.push(
+									createError(
+										`Parsing import.meta.webpackContext options failed. Unknown property ${JSON.stringify(
+											prop.key.name
+										)}.`,
+										/** @type {DependencyLocation} */ (optionsNode.loc)
+									)
+								);
+						}
+					}
+				}
+				if (errors.length) {
+					for (const error of errors) parser.state.current.addError(error);
+					return;
+				}
+
+				const dep = new ImportMetaContextDependency(
+					{
+						request,
+						include,
+						exclude,
+						recursive,
+						regExp,
+						groupOptions,
+						chunkName,
+						referencedExports: exports,
+						mode,
+						category: "esm"
+					},
+					/** @type {Range} */ (expr.range)
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				dep.optional = Boolean(parser.scope.inTry);
+				parser.state.current.addDependency(dep);
+				return true;
+			});
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/ImportMetaContextPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportMetaContextPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportMetaContextPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,73 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+const ContextElementDependency = require("./ContextElementDependency");
+const ImportMetaContextDependency = require("./ImportMetaContextDependency");
+const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+const PLUGIN_NAME = "ImportMetaContextPlugin";
+
+class ImportMetaContextPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { contextModuleFactory, normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					ImportMetaContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportMetaContextDependency,
+					new ImportMetaContextDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					ContextElementDependency,
+					normalModuleFactory
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (
+						parserOptions.importMetaContext !== undefined &&
+						!parserOptions.importMetaContext
+					) {
+						return;
+					}
+
+					new ImportMetaContextDependencyParserPlugin().apply(parser);
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+module.exports = ImportMetaContextPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/ImportMetaHotAcceptDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportMetaHotAcceptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportMetaHotAcceptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+class ImportMetaHotAcceptDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ImportMetaHotAcceptDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super(request);
+		this.range = range;
+		this.weak = true;
+	}
+
+	get type() {
+		return "import.meta.webpackHot.accept";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	ImportMetaHotAcceptDependency,
+	"webpack/lib/dependencies/ImportMetaHotAcceptDependency"
+);
+
+ImportMetaHotAcceptDependency.Template = ModuleDependencyTemplateAsId;
+
+module.exports = ImportMetaHotAcceptDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportMetaHotDeclineDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportMetaHotDeclineDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportMetaHotDeclineDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+class ImportMetaHotDeclineDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ImportMetaHotDeclineDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super(request);
+
+		this.range = range;
+		this.weak = true;
+	}
+
+	get type() {
+		return "import.meta.webpackHot.decline";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	ImportMetaHotDeclineDependency,
+	"webpack/lib/dependencies/ImportMetaHotDeclineDependency"
+);
+
+ImportMetaHotDeclineDependency.Template = ModuleDependencyTemplateAsId;
+
+module.exports = ImportMetaHotDeclineDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ImportMetaPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportMetaPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportMetaPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,463 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const { pathToFileURL } = require("url");
+const { SyncBailHook } = require("tapable");
+const Compilation = require("../Compilation");
+const DefinePlugin = require("../DefinePlugin");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
+const {
+	evaluateToIdentifier,
+	evaluateToNumber,
+	evaluateToString,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const { propertyAccess } = require("../util/property");
+const ConstDependency = require("./ConstDependency");
+const ModuleInitFragmentDependency = require("./ModuleInitFragmentDependency");
+
+/** @typedef {import("estree").MemberExpression} MemberExpression */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../javascript/JavascriptParser").Members} Members */
+/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */
+/** @typedef {import("./ConstDependency").RawRuntimeRequirements} RawRuntimeRequirements */
+
+const PLUGIN_NAME = "ImportMetaPlugin";
+
+/** @type {WeakMap<Compilation, { stringify: string, env: Record<string, string> }>} */
+const compilationMetaEnvMap = new WeakMap();
+
+/**
+ * Collect import.meta.env definitions from DefinePlugin and build JSON string
+ * @param {Compilation} compilation the compilation
+ * @returns {{ stringify: string, env: Record<string, string> }} env object as JSON string
+ */
+const collectImportMetaEnvDefinitions = (compilation) => {
+	const cached = compilationMetaEnvMap.get(compilation);
+	if (cached) {
+		return cached;
+	}
+
+	const definePluginHooks = DefinePlugin.getCompilationHooks(compilation);
+	const definitions = definePluginHooks.definitions.call({});
+	/** @type {Record<string, string>} */
+	const env = {};
+	/** @type {string[]} */
+	const pairs = [];
+	for (const key of Object.keys(definitions)) {
+		if (key.startsWith("import.meta.env.")) {
+			const envKey = key.slice("import.meta.env.".length);
+			const value = definitions[key];
+			pairs.push(`${JSON.stringify(envKey)}:${value}`);
+			env[envKey] = /** @type {string} */ (value);
+		}
+	}
+	const result = { stringify: `{${pairs.join(",")}}`, env };
+	compilationMetaEnvMap.set(compilation, result);
+	return result;
+};
+
+/**
+ * Defines the import meta plugin hooks type used by this module.
+ * @typedef {object} ImportMetaPluginHooks
+ * @property {SyncBailHook<[DestructuringAssignmentProperty], string | void>} propertyInDestructuring
+ */
+
+/** @type {WeakMap<Compilation, ImportMetaPluginHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class ImportMetaPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {ImportMetaPluginHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				propertyInDestructuring: new SyncBailHook(["property"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler compiler
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const hooks = ImportMetaPlugin.getCompilationHooks(compilation);
+
+				compilation.dependencyTemplates.set(
+					ModuleInitFragmentDependency,
+					new ModuleInitFragmentDependency.Template()
+				);
+
+				/**
+				 * Returns file url.
+				 * @param {NormalModule} module module
+				 * @returns {string} file url
+				 */
+				const getUrl = (module) => pathToFileURL(module.resource).toString();
+				/**
+				 * Processes the provided parser.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const parserHandler = (parser, { importMeta }) => {
+					if (importMeta === false) {
+						const { importMetaName } = compilation.outputOptions;
+						if (importMetaName === "import.meta") return;
+
+						parser.hooks.expression
+							.for("import.meta")
+							.tap(PLUGIN_NAME, (metaProperty) => {
+								const dep = new ConstDependency(
+									/** @type {string} */ (importMetaName),
+									/** @type {Range} */ (metaProperty.range)
+								);
+								dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc);
+								parser.state.module.addPresentationalDependency(dep);
+								return true;
+							});
+						return;
+					}
+
+					// import.meta direct
+					const webpackVersion = Number.parseInt(
+						require("../../package.json").version,
+						10
+					);
+					const importMetaUrl = () =>
+						JSON.stringify(getUrl(parser.state.module));
+					const importMetaWebpackVersion = () => JSON.stringify(webpackVersion);
+					/**
+					 * Import meta unknown property.
+					 * @param {Members} members members
+					 * @returns {string} error message
+					 */
+					const importMetaUnknownProperty = (members) => {
+						if (importMeta === "preserve-unknown") {
+							return `import.meta${propertyAccess(members, 0)}`;
+						}
+						return `${Template.toNormalComment(
+							`unsupported import.meta.${members.join(".")}`
+						)} undefined${propertyAccess(members, 1)}`;
+					};
+
+					parser.hooks.typeof
+						.for("import.meta")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("object"))
+						);
+					parser.hooks.collectDestructuringAssignmentProperties.tap(
+						PLUGIN_NAME,
+						(expr) => {
+							if (expr.type === "MetaProperty") return true;
+						}
+					);
+					parser.hooks.expression
+						.for("import.meta")
+						.tap(PLUGIN_NAME, (metaProperty) => {
+							/** @type {RawRuntimeRequirements} */
+							const runtimeRequirements = [];
+							const moduleArgument = parser.state.module.moduleArgument;
+
+							const referencedPropertiesInDestructuring =
+								parser.destructuringAssignmentPropertiesFor(metaProperty);
+							if (!referencedPropertiesInDestructuring) {
+								const varName = "__webpack_import_meta__";
+								const { stringify: envStringify } =
+									collectImportMetaEnvDefinitions(compilation);
+								const knownProps =
+									`{url: ${importMetaUrl()}, ` +
+									`webpack: ${importMetaWebpackVersion()}, ` +
+									`main: ${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${moduleArgument}, ` +
+									`env: ${envStringify}}`;
+								const initCode =
+									importMeta === "preserve-unknown"
+										? `var ${varName} = Object.assign(import.meta, ${knownProps});\n`
+										: `var ${varName} = ${knownProps};\n`;
+								const initDep = new ModuleInitFragmentDependency(
+									initCode,
+									[
+										RuntimeGlobals.moduleCache,
+										RuntimeGlobals.entryModuleId,
+										RuntimeGlobals.module
+									],
+									varName
+								);
+								initDep.loc = /** @type {DependencyLocation} */ (
+									metaProperty.loc
+								);
+								parser.state.module.addPresentationalDependency(initDep);
+								const dep = new ConstDependency(
+									varName,
+									/** @type {Range} */ (metaProperty.range),
+									runtimeRequirements
+								);
+								dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc);
+								parser.state.module.addPresentationalDependency(dep);
+								return true;
+							}
+
+							let str = "";
+							for (const prop of referencedPropertiesInDestructuring) {
+								const value = hooks.propertyInDestructuring.call(prop);
+
+								if (value) {
+									str += value;
+									continue;
+								}
+
+								switch (prop.id) {
+									case "url":
+										str += `url: ${importMetaUrl()},`;
+										break;
+									case "webpack":
+										str += `webpack: ${importMetaWebpackVersion()},`;
+										break;
+									case "main":
+										str += `main: ${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${moduleArgument},`;
+										runtimeRequirements.push(
+											RuntimeGlobals.moduleCache,
+											RuntimeGlobals.entryModuleId,
+											RuntimeGlobals.module
+										);
+										break;
+									case "env":
+										str += `env: ${collectImportMetaEnvDefinitions(compilation).stringify},`;
+										break;
+									default:
+										str += `[${JSON.stringify(
+											prop.id
+										)}]: ${importMetaUnknownProperty([prop.id])},`;
+										break;
+								}
+							}
+							const dep = new ConstDependency(
+								`({${str}})`,
+								/** @type {Range} */ (metaProperty.range),
+								runtimeRequirements
+							);
+							dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+					parser.hooks.evaluateTypeof
+						.for("import.meta")
+						.tap(PLUGIN_NAME, evaluateToString("object"));
+					parser.hooks.evaluateIdentifier.for("import.meta").tap(
+						PLUGIN_NAME,
+						evaluateToIdentifier("import.meta", "import.meta", () => [], true)
+					);
+
+					// import.meta.url
+					parser.hooks.typeof
+						.for("import.meta.url")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("string"))
+						);
+					parser.hooks.expression
+						.for("import.meta.url")
+						.tap(PLUGIN_NAME, (expr) => {
+							const dep = new ConstDependency(
+								importMetaUrl(),
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+					parser.hooks.evaluateTypeof
+						.for("import.meta.url")
+						.tap(PLUGIN_NAME, evaluateToString("string"));
+					parser.hooks.evaluateIdentifier
+						.for("import.meta.url")
+						.tap(PLUGIN_NAME, (expr) =>
+							new BasicEvaluatedExpression()
+								.setString(getUrl(parser.state.module))
+								.setRange(/** @type {Range} */ (expr.range))
+						);
+
+					// import.meta.webpack
+					parser.hooks.expression
+						.for("import.meta.webpack")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, importMetaWebpackVersion())
+						);
+					parser.hooks.typeof
+						.for("import.meta.webpack")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("number"))
+						);
+					parser.hooks.evaluateTypeof
+						.for("import.meta.webpack")
+						.tap(PLUGIN_NAME, evaluateToString("number"));
+					parser.hooks.evaluateIdentifier
+						.for("import.meta.webpack")
+						.tap(PLUGIN_NAME, evaluateToNumber(webpackVersion));
+
+					parser.hooks.expression
+						.for("import.meta.main")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(
+								parser,
+								`${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${RuntimeGlobals.module}`,
+								[
+									RuntimeGlobals.moduleCache,
+									RuntimeGlobals.entryModuleId,
+									RuntimeGlobals.module
+								]
+							)
+						);
+					parser.hooks.typeof
+						.for("import.meta.main")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("boolean"))
+						);
+					parser.hooks.evaluateTypeof
+						.for("import.meta.main")
+						.tap(PLUGIN_NAME, evaluateToString("boolean"));
+
+					// import.meta.env
+					parser.hooks.typeof
+						.for("import.meta.env")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("object"))
+						);
+					parser.hooks.expressionMemberChain
+						.for("import.meta")
+						.tap(PLUGIN_NAME, (expr, members) => {
+							if (members[0] === "env" && members[1]) {
+								const name = members[1];
+								const { env } = collectImportMetaEnvDefinitions(compilation);
+								if (!Object.prototype.hasOwnProperty.call(env, name)) {
+									const dep = new ConstDependency(
+										"undefined",
+										/** @type {Range} */ (expr.range)
+									);
+									dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+									parser.state.module.addPresentationalDependency(dep);
+									return true;
+								}
+							}
+						});
+					parser.hooks.expression
+						.for("import.meta.env")
+						.tap(PLUGIN_NAME, (expr) => {
+							const { stringify } =
+								collectImportMetaEnvDefinitions(compilation);
+
+							const dep = new ConstDependency(
+								stringify,
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+					parser.hooks.evaluateTypeof
+						.for("import.meta.env")
+						.tap(PLUGIN_NAME, evaluateToString("object"));
+					parser.hooks.evaluateIdentifier
+						.for("import.meta.env")
+						.tap(PLUGIN_NAME, (expr) =>
+							new BasicEvaluatedExpression()
+								.setTruthy()
+								.setSideEffects(false)
+								.setRange(/** @type {Range} */ (expr.range))
+						);
+
+					// Unknown properties
+					parser.hooks.unhandledExpressionMemberChain
+						.for("import.meta")
+						.tap(PLUGIN_NAME, (expr, members) => {
+							// unknown import.meta properties should be determined at runtime
+							if (importMeta === "preserve-unknown") {
+								return true;
+							}
+
+							// keep import.meta.env unknown property
+							// don't evaluate import.meta.env.UNKNOWN_PROPERTY -> undefined.UNKNOWN_PROPERTY
+							// `dirname` and `filename` logic in NodeStuffPlugin
+							if (
+								members[0] === "env" ||
+								members[0] === "dirname" ||
+								members[0] === "filename"
+							) {
+								return true;
+							}
+							const dep = new ConstDependency(
+								importMetaUnknownProperty(members),
+								/** @type {Range} */ (expr.range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+							return true;
+						});
+
+					parser.hooks.evaluate
+						.for("MemberExpression")
+						.tap(PLUGIN_NAME, (expression) => {
+							const expr = /** @type {MemberExpression} */ (expression);
+							if (
+								expr.object.type === "MetaProperty" &&
+								expr.object.meta.name === "import" &&
+								expr.object.property.name === "meta" &&
+								expr.property.type ===
+									(expr.computed ? "Literal" : "Identifier")
+							) {
+								return new BasicEvaluatedExpression()
+									.setUndefined()
+									.setRange(/** @type {Range} */ (expr.range));
+							}
+						});
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, parserHandler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, parserHandler);
+			}
+		);
+	}
+}
+
+module.exports = ImportMetaPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/ImportParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,608 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const {
+	VariableInfo,
+	getImportAttributes
+} = require("../javascript/JavascriptParser");
+const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
+const ContextDependencyHelpers = require("./ContextDependencyHelpers");
+const { getNonOptionalPart } = require("./HarmonyImportDependency");
+const ImportContextDependency = require("./ImportContextDependency");
+const ImportDependency = require("./ImportDependency");
+const ImportEagerDependency = require("./ImportEagerDependency");
+const { createGetImportPhase } = require("./ImportPhase");
+const ImportWeakDependency = require("./ImportWeakDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
+/** @typedef {import("../ContextModule").ContextMode} ContextMode */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").ImportExpression} ImportExpression */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
+/** @typedef {import("../javascript/JavascriptParser").Members} Members */
+/** @typedef {import("../javascript/JavascriptParser").MembersOptionals} MembersOptionals */
+/** @typedef {import("../javascript/JavascriptParser").ArrowFunctionExpression} ArrowFunctionExpression */
+/** @typedef {import("../javascript/JavascriptParser").FunctionExpression} FunctionExpression */
+/** @typedef {import("../javascript/JavascriptParser").Identifier} Identifier */
+/** @typedef {import("../javascript/JavascriptParser").ObjectPattern} ObjectPattern */
+/** @typedef {import("../javascript/JavascriptParser").CallExpression} CallExpression */
+
+/** @typedef {{ references: RawReferencedExports, expression: ImportExpression }} ImportSettings */
+/** @typedef {WeakMap<ImportExpression, RawReferencedExports>} State */
+
+/** @type {WeakMap<JavascriptParserState, State>} */
+const parserStateMap = new WeakMap();
+const dynamicImportTag = Symbol("import()");
+
+/**
+ * Returns import parser plugin state.
+ * @param {JavascriptParser} parser javascript parser
+ * @returns {State} import parser plugin state
+ */
+function getState(parser) {
+	if (!parserStateMap.has(parser.state)) {
+		parserStateMap.set(parser.state, new WeakMap());
+	}
+	return /** @type {State} */ (parserStateMap.get(parser.state));
+}
+
+/**
+ * Tag dynamic import referenced.
+ * @param {JavascriptParser} parser javascript parser
+ * @param {ImportExpression} importCall import expression
+ * @param {string} variableName variable name
+ */
+function tagDynamicImportReferenced(parser, importCall, variableName) {
+	const state = getState(parser);
+	/** @type {RawReferencedExports} */
+	const references = state.get(importCall) || [];
+	state.set(importCall, references);
+	parser.tagVariable(
+		variableName,
+		dynamicImportTag,
+		/** @type {ImportSettings} */ ({
+			references,
+			expression: importCall
+		})
+	);
+}
+
+/**
+ * Gets fulfilled callback namespace obj.
+ * @param {CallExpression} importThen import().then() call
+ * @returns {Identifier | ObjectPattern | undefined} the dynamic imported namespace obj
+ */
+function getFulfilledCallbackNamespaceObj(importThen) {
+	const fulfilledCallback = importThen.arguments[0];
+	if (
+		fulfilledCallback &&
+		(fulfilledCallback.type === "ArrowFunctionExpression" ||
+			fulfilledCallback.type === "FunctionExpression") &&
+		fulfilledCallback.params[0] &&
+		(fulfilledCallback.params[0].type === "Identifier" ||
+			fulfilledCallback.params[0].type === "ObjectPattern")
+	) {
+		return fulfilledCallback.params[0];
+	}
+}
+
+/**
+ * Walk import then fulfilled callback.
+ * @param {JavascriptParser} parser javascript parser
+ * @param {ImportExpression} importCall import expression
+ * @param {ArrowFunctionExpression | FunctionExpression} fulfilledCallback the fulfilled callback
+ * @param {Identifier | ObjectPattern} namespaceObjArg the argument of namespace object=
+ */
+function walkImportThenFulfilledCallback(
+	parser,
+	importCall,
+	fulfilledCallback,
+	namespaceObjArg
+) {
+	const arrow = fulfilledCallback.type === "ArrowFunctionExpression";
+	const wasTopLevel = parser.scope.topLevelScope;
+	parser.scope.topLevelScope = arrow ? (wasTopLevel ? "arrow" : false) : false;
+	const scopeParams = [...fulfilledCallback.params];
+
+	// Add function name in scope for recursive calls
+	if (!arrow && fulfilledCallback.id) {
+		scopeParams.push(fulfilledCallback.id);
+	}
+
+	parser.inFunctionScope(!arrow, scopeParams, () => {
+		if (namespaceObjArg.type === "Identifier") {
+			tagDynamicImportReferenced(parser, importCall, namespaceObjArg.name);
+		} else {
+			parser.enterDestructuringAssignment(namespaceObjArg, importCall);
+			const referencedPropertiesInDestructuring =
+				parser.destructuringAssignmentPropertiesFor(importCall);
+			if (referencedPropertiesInDestructuring) {
+				const state = getState(parser);
+				const references = /** @type {RawReferencedExports} */ (
+					state.get(importCall)
+				);
+				/** @type {RawReferencedExports} */
+				const refsInDestructuring = [];
+				traverseDestructuringAssignmentProperties(
+					referencedPropertiesInDestructuring,
+					(stack) => refsInDestructuring.push(stack.map((p) => p.id))
+				);
+				for (const ids of refsInDestructuring) {
+					references.push(ids);
+				}
+			}
+		}
+		for (const param of fulfilledCallback.params) {
+			parser.walkPattern(param);
+		}
+		if (fulfilledCallback.body.type === "BlockStatement") {
+			parser.detectMode(fulfilledCallback.body.body);
+			const prev = parser.prevStatement;
+			parser.preWalkStatement(fulfilledCallback.body);
+			parser.prevStatement = prev;
+			parser.walkStatement(fulfilledCallback.body);
+		} else {
+			parser.walkExpression(fulfilledCallback.body);
+		}
+	});
+	parser.scope.topLevelScope = wasTopLevel;
+}
+
+/**
+ * Exports from enumerable.
+ * @template T
+ * @param {Iterable<T>} enumerable enumerable
+ * @returns {T[][]} array of array
+ */
+const exportsFromEnumerable = (enumerable) =>
+	Array.from(enumerable, (e) => [e]);
+
+const PLUGIN_NAME = "ImportParserPlugin";
+
+class ImportParserPlugin {
+	/**
+	 * Creates an instance of ImportParserPlugin.
+	 * @param {JavascriptParserOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.collectDestructuringAssignmentProperties.tap(
+			PLUGIN_NAME,
+			(expr) => {
+				if (expr.type === "ImportExpression") return true;
+				const nameInfo = parser.getNameForExpression(expr);
+				if (
+					nameInfo &&
+					nameInfo.rootInfo instanceof VariableInfo &&
+					nameInfo.rootInfo.name &&
+					parser.getTagData(nameInfo.rootInfo.name, dynamicImportTag)
+				) {
+					return true;
+				}
+			}
+		);
+		parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl) => {
+			if (
+				decl.init &&
+				decl.init.type === "AwaitExpression" &&
+				decl.init.argument.type === "ImportExpression" &&
+				decl.id.type === "Identifier"
+			) {
+				parser.defineVariable(decl.id.name);
+				tagDynamicImportReferenced(parser, decl.init.argument, decl.id.name);
+			}
+		});
+		parser.hooks.expression.for(dynamicImportTag).tap(PLUGIN_NAME, (expr) => {
+			const settings = /** @type {ImportSettings} */ (parser.currentTagData);
+			const referencedPropertiesInDestructuring =
+				parser.destructuringAssignmentPropertiesFor(expr);
+			if (referencedPropertiesInDestructuring) {
+				/** @type {RawReferencedExports} */
+				const refsInDestructuring = [];
+				traverseDestructuringAssignmentProperties(
+					referencedPropertiesInDestructuring,
+					(stack) => refsInDestructuring.push(stack.map((p) => p.id))
+				);
+				for (const ids of refsInDestructuring) {
+					settings.references.push(ids);
+				}
+			} else {
+				settings.references.push([]);
+			}
+			return true;
+		});
+		parser.hooks.expressionMemberChain
+			.for(dynamicImportTag)
+			.tap(PLUGIN_NAME, (_expression, members, membersOptionals) => {
+				const settings = /** @type {ImportSettings} */ (parser.currentTagData);
+				const ids = getNonOptionalPart(members, membersOptionals);
+				settings.references.push(ids);
+				return true;
+			});
+		parser.hooks.callMemberChain
+			.for(dynamicImportTag)
+			.tap(PLUGIN_NAME, (expression, members, membersOptionals) => {
+				const { arguments: args } = expression;
+				const settings = /** @type {ImportSettings} */ (parser.currentTagData);
+				let ids = getNonOptionalPart(members, membersOptionals);
+				const directImport = members.length === 0;
+				if (
+					!directImport &&
+					(this.options.strictThisContextOnImports || ids.length > 1)
+				) {
+					ids = ids.slice(0, -1);
+				}
+				settings.references.push(ids);
+				if (args) parser.walkExpressions(args);
+				return true;
+			});
+		parser.hooks.importCall.tap(PLUGIN_NAME, (expr, importThen) => {
+			const param = parser.evaluateExpression(expr.source);
+
+			/** @type {null | string} */
+			let chunkName = null;
+			let mode = /** @type {ContextMode} */ (this.options.dynamicImportMode);
+			/** @type {null | RegExp} */
+			let include = null;
+			/** @type {null | RegExp} */
+			let exclude = null;
+			/** @type {null | RawReferencedExports} */
+			let exports = null;
+			/** @type {RawChunkGroupOptions} */
+			const groupOptions = {};
+
+			const {
+				dynamicImportPreload,
+				dynamicImportPrefetch,
+				dynamicImportFetchPriority
+			} = this.options;
+			if (
+				dynamicImportPreload !== undefined &&
+				dynamicImportPreload !== false
+			) {
+				groupOptions.preloadOrder =
+					dynamicImportPreload === true ? 0 : dynamicImportPreload;
+			}
+			if (
+				dynamicImportPrefetch !== undefined &&
+				dynamicImportPrefetch !== false
+			) {
+				groupOptions.prefetchOrder =
+					dynamicImportPrefetch === true ? 0 : dynamicImportPrefetch;
+			}
+			if (
+				dynamicImportFetchPriority !== undefined &&
+				dynamicImportFetchPriority !== false
+			) {
+				groupOptions.fetchPriority = dynamicImportFetchPriority;
+			}
+
+			const { options: importOptions, errors: commentErrors } =
+				parser.parseCommentOptions(/** @type {Range} */ (expr.range));
+
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					parser.state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							/** @type {DependencyLocation} */ (comment.loc)
+						)
+					);
+				}
+			}
+
+			const phase = createGetImportPhase(
+				this.options.deferImport,
+				this.options.sourceImport
+			)(parser, expr, () => importOptions);
+
+			if (importOptions) {
+				if (importOptions.webpackIgnore !== undefined) {
+					if (typeof importOptions.webpackIgnore !== "boolean") {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else if (importOptions.webpackIgnore) {
+						// Do not instrument `import()` if `webpackIgnore` is `true`
+						return false;
+					}
+				}
+				if (importOptions.webpackChunkName !== undefined) {
+					if (typeof importOptions.webpackChunkName !== "string") {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else {
+						chunkName = importOptions.webpackChunkName;
+					}
+				}
+				if (importOptions.webpackMode !== undefined) {
+					if (typeof importOptions.webpackMode !== "string") {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackMode\` expected a string, but received: ${importOptions.webpackMode}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else {
+						mode = /** @type {ContextMode} */ (importOptions.webpackMode);
+					}
+				}
+				if (importOptions.webpackPrefetch !== undefined) {
+					if (importOptions.webpackPrefetch === true) {
+						groupOptions.prefetchOrder = 0;
+					} else if (typeof importOptions.webpackPrefetch === "number") {
+						groupOptions.prefetchOrder = importOptions.webpackPrefetch;
+					} else {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackPrefetch\` expected true or a number, but received: ${importOptions.webpackPrefetch}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					}
+				}
+				if (importOptions.webpackPreload !== undefined) {
+					if (importOptions.webpackPreload === true) {
+						groupOptions.preloadOrder = 0;
+					} else if (typeof importOptions.webpackPreload === "number") {
+						groupOptions.preloadOrder = importOptions.webpackPreload;
+					} else {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackPreload\` expected true or a number, but received: ${importOptions.webpackPreload}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					}
+				}
+				if (importOptions.webpackFetchPriority !== undefined) {
+					if (
+						typeof importOptions.webpackFetchPriority === "string" &&
+						["high", "low", "auto"].includes(importOptions.webpackFetchPriority)
+					) {
+						groupOptions.fetchPriority =
+							/** @type {"low" | "high" | "auto"} */
+							(importOptions.webpackFetchPriority);
+					} else {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackFetchPriority\` expected true or "low", "high" or "auto", but received: ${importOptions.webpackFetchPriority}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					}
+				}
+				if (importOptions.webpackInclude !== undefined) {
+					if (
+						!importOptions.webpackInclude ||
+						!(importOptions.webpackInclude instanceof RegExp)
+					) {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackInclude\` expected a regular expression, but received: ${importOptions.webpackInclude}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else {
+						include = importOptions.webpackInclude;
+					}
+				}
+				if (importOptions.webpackExclude !== undefined) {
+					if (
+						!importOptions.webpackExclude ||
+						!(importOptions.webpackExclude instanceof RegExp)
+					) {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackExclude\` expected a regular expression, but received: ${importOptions.webpackExclude}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else {
+						exclude = importOptions.webpackExclude;
+					}
+				}
+				if (importOptions.webpackExports !== undefined) {
+					if (
+						!(
+							typeof importOptions.webpackExports === "string" ||
+							(Array.isArray(importOptions.webpackExports) &&
+								importOptions.webpackExports.every(
+									(item) => typeof item === "string"
+								))
+						)
+					) {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackExports\` expected a string or an array of strings, but received: ${importOptions.webpackExports}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else if (typeof importOptions.webpackExports === "string") {
+						exports = [[importOptions.webpackExports]];
+					} else {
+						exports = exportsFromEnumerable(importOptions.webpackExports);
+					}
+				}
+			}
+
+			if (
+				mode !== "lazy" &&
+				mode !== "lazy-once" &&
+				mode !== "eager" &&
+				mode !== "weak"
+			) {
+				parser.state.module.addWarning(
+					new UnsupportedFeatureWarning(
+						`\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`,
+						/** @type {DependencyLocation} */ (expr.loc)
+					)
+				);
+				mode = "lazy";
+			}
+
+			const referencedPropertiesInDestructuring =
+				parser.destructuringAssignmentPropertiesFor(expr);
+			const state = getState(parser);
+			const referencedPropertiesInMember = state.get(expr);
+			const fulfilledNamespaceObj =
+				importThen && getFulfilledCallbackNamespaceObj(importThen);
+			if (
+				referencedPropertiesInDestructuring ||
+				referencedPropertiesInMember ||
+				fulfilledNamespaceObj
+			) {
+				if (exports) {
+					parser.state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							"You don't need `webpackExports` if the usage of dynamic import is statically analyse-able. You can safely remove the `webpackExports` magic comment.",
+							/** @type {DependencyLocation} */ (expr.loc)
+						)
+					);
+				}
+
+				if (referencedPropertiesInDestructuring) {
+					/** @type {RawReferencedExports} */
+					const refsInDestructuring = [];
+					traverseDestructuringAssignmentProperties(
+						referencedPropertiesInDestructuring,
+						(stack) => refsInDestructuring.push(stack.map((p) => p.id))
+					);
+
+					exports = refsInDestructuring;
+				} else if (referencedPropertiesInMember) {
+					exports = referencedPropertiesInMember;
+				} else {
+					/** @type {RawReferencedExports} */
+					const references = [];
+					state.set(expr, references);
+
+					exports = references;
+				}
+			}
+
+			if (param.isString()) {
+				const attributes = getImportAttributes(expr);
+
+				if (mode === "eager") {
+					const dep = new ImportEagerDependency(
+						/** @type {string} */ (param.string),
+						/** @type {Range} */ (expr.range),
+						exports,
+						phase,
+						attributes
+					);
+					parser.state.current.addDependency(dep);
+				} else if (mode === "weak") {
+					const dep = new ImportWeakDependency(
+						/** @type {string} */ (param.string),
+						/** @type {Range} */ (expr.range),
+						exports,
+						phase,
+						attributes
+					);
+					parser.state.current.addDependency(dep);
+				} else {
+					const depBlock = new AsyncDependenciesBlock(
+						{
+							...groupOptions,
+							name: chunkName
+						},
+						/** @type {DependencyLocation} */ (expr.loc),
+						param.string
+					);
+					const dep = new ImportDependency(
+						/** @type {string} */ (param.string),
+						/** @type {Range} */ (expr.range),
+						exports,
+						phase,
+						attributes
+					);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					dep.optional = Boolean(parser.scope.inTry);
+					depBlock.addDependency(dep);
+					parser.state.current.addBlock(depBlock);
+				}
+			} else {
+				if (mode === "weak") {
+					mode = "async-weak";
+				}
+
+				const dep = ContextDependencyHelpers.create(
+					ImportContextDependency,
+					/** @type {Range} */ (expr.range),
+					param,
+					expr,
+					this.options,
+					{
+						chunkName,
+						groupOptions,
+						include,
+						exclude,
+						mode,
+						namespaceObject:
+							/** @type {BuildMeta} */
+							(parser.state.module.buildMeta).strictHarmonyModule
+								? "strict"
+								: true,
+						typePrefix: "import()",
+						category: "esm",
+						referencedExports: exports,
+						attributes: getImportAttributes(expr),
+						phase
+					},
+					parser
+				);
+				if (!dep) return;
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				dep.optional = Boolean(parser.scope.inTry);
+				parser.state.current.addDependency(dep);
+			}
+
+			if (fulfilledNamespaceObj) {
+				walkImportThenFulfilledCallback(
+					parser,
+					expr,
+					/** @type {ArrowFunctionExpression | FunctionExpression} */
+					(importThen.arguments[0]),
+					fulfilledNamespaceObj
+				);
+				parser.walkExpressions(importThen.arguments.slice(1));
+			} else if (importThen) {
+				parser.walkExpressions(importThen.arguments);
+			}
+
+			return true;
+		});
+	}
+}
+
+module.exports = ImportParserPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/ImportPhase.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportPhase.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportPhase.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,172 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Haijie Xie @hai-x
+*/
+
+"use strict";
+
+const memoize = require("../util/memoize");
+
+const getCommentCompilationWarning = memoize(() =>
+	require("../errors/CommentCompilationWarning")
+);
+
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").ExportAllDeclaration} ExportAllDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").ExportNamedDeclaration} ExportNamedDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").ImportDeclaration} ImportDeclaration */
+/** @typedef {import("../javascript/JavascriptParser").ImportExpression} ImportExpression */
+
+/** @typedef {typeof ImportPhase.Evaluation | typeof ImportPhase.Defer | typeof ImportPhase.Source}  ImportPhaseType */
+
+const ImportPhase = Object.freeze({
+	Evaluation: 0b00,
+	Defer: 0b01,
+	Source: 0b10
+});
+
+/** @typedef {"defer" | "source" | "evaluation"} ImportPhaseName */
+
+/**
+ * Defines the import phase utils type used by this module.
+ * @typedef {object} ImportPhaseUtils
+ * @property {(phase: ImportPhaseType | undefined) => boolean} isEvaluation true if phase is evaluation
+ * @property {(phase: ImportPhaseType | undefined) => boolean} isDefer true if phase is defer
+ * @property {(phase: ImportPhaseType | undefined) => boolean} isSource true if phase is source
+ * @property {(phase: ImportPhaseType) => ImportPhaseName} stringify return stringified name of phase
+ */
+
+/** @type {ImportPhaseUtils} */
+const ImportPhaseUtils = {
+	isEvaluation(phase) {
+		return phase === ImportPhase.Evaluation;
+	},
+	isDefer(phase) {
+		return phase === ImportPhase.Defer;
+	},
+	isSource(phase) {
+		return phase === ImportPhase.Source;
+	},
+	stringify(phase) {
+		switch (phase) {
+			case ImportPhase.Defer:
+				return "defer";
+			case ImportPhase.Source:
+				return "source";
+			default:
+				return "evaluation";
+		}
+	}
+};
+
+/**
+ * Defines the get comment options type used by this module.
+ * @typedef {() => Record<string, EXPECTED_ANY> | null} GetCommentOptions
+ */
+
+/**
+ * Defines the get import phase callback.
+ * @callback GetImportPhase
+ * @param {JavascriptParser} parser parser
+ * @param {ExportNamedDeclaration | ExportAllDeclaration | ImportDeclaration | ImportExpression} node node
+ * @param {GetCommentOptions=} getCommentOptions optional function that returns the comment options object.
+ * @returns {ImportPhaseType} import phase
+ */
+
+/**
+ * Creates an import phase resolver.
+ * @param {boolean=} enableDeferPhase enable defer phase detection
+ * @param {boolean=} enableSourcePhase enable source phase detection
+ * @returns {GetImportPhase} evaluates the import phase for ast node
+ */
+function createGetImportPhase(enableDeferPhase, enableSourcePhase) {
+	return (parser, node, getCommentOptions) => {
+		if (!enableDeferPhase && !enableSourcePhase) return ImportPhase.Evaluation;
+
+		// We now only support `defer import` and `source import` syntax
+		const phaseBySyntax =
+			"phase" in node
+				? node.phase === "defer" && enableDeferPhase
+					? ImportPhase.Defer
+					: node.phase === "source" && enableSourcePhase
+						? ImportPhase.Source
+						: ImportPhase.Evaluation
+				: ImportPhase.Evaluation;
+
+		if (!node.range) {
+			return phaseBySyntax;
+		}
+
+		getCommentOptions =
+			getCommentOptions ||
+			(() => {
+				if (!node.range) return null;
+				const { options, errors } = parser.parseCommentOptions(node.range);
+				if (errors) {
+					for (const e of errors) {
+						const { comment } = e;
+						if (!comment.loc) continue;
+
+						const CommentCompilationWarning = getCommentCompilationWarning();
+						parser.state.module.addWarning(
+							new CommentCompilationWarning(
+								`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+								comment.loc
+							)
+						);
+					}
+				}
+				return options;
+			});
+
+		const options = getCommentOptions();
+
+		if (!options) {
+			return phaseBySyntax;
+		}
+
+		if (!options.webpackDefer && !options.webpackSource) {
+			return phaseBySyntax;
+		}
+
+		const { webpackDefer, webpackSource } = options;
+
+		if (enableDeferPhase && typeof options.webpackDefer !== "undefined") {
+			if (typeof webpackDefer === "boolean") {
+				return webpackDefer ? ImportPhase.Defer : phaseBySyntax;
+			} else if (node.loc) {
+				const CommentCompilationWarning = getCommentCompilationWarning();
+
+				parser.state.module.addWarning(
+					new CommentCompilationWarning(
+						"webpackDefer magic comment expected a boolean value.",
+						node.loc
+					)
+				);
+			}
+		}
+
+		if (enableSourcePhase && typeof options.webpackSource !== "undefined") {
+			if (typeof webpackSource === "boolean") {
+				return webpackSource ? ImportPhase.Source : phaseBySyntax;
+			} else if (node.loc) {
+				const CommentCompilationWarning = getCommentCompilationWarning();
+
+				parser.state.module.addWarning(
+					new CommentCompilationWarning(
+						"webpackSource magic comment expected a boolean value.",
+						node.loc
+					)
+				);
+			}
+		}
+
+		return phaseBySyntax;
+	};
+}
+
+module.exports = {
+	ImportPhase,
+	ImportPhaseUtils,
+	createGetImportPhase
+};
Index: frontend/node_modules/webpack/lib/dependencies/ImportPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,99 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+const ImportContextDependency = require("./ImportContextDependency");
+const ImportDependency = require("./ImportDependency");
+const ImportEagerDependency = require("./ImportEagerDependency");
+const ImportParserPlugin = require("./ImportParserPlugin");
+const ImportWeakDependency = require("./ImportWeakDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+const PLUGIN_NAME = "ImportPlugin";
+
+class ImportPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { contextModuleFactory, normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					ImportDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportDependency,
+					new ImportDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					ImportEagerDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportEagerDependency,
+					new ImportEagerDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					ImportWeakDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportWeakDependency,
+					new ImportWeakDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					ImportContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					ImportContextDependency,
+					new ImportContextDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (parserOptions.import !== undefined && !parserOptions.import) {
+						return;
+					}
+
+					new ImportParserPlugin(parserOptions).apply(parser);
+				};
+
+				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);
+			}
+		);
+	}
+}
+
+module.exports = ImportPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/ImportWeakDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ImportWeakDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ImportWeakDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,76 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ImportDependency = require("./ImportDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {ImportDependency.RawReferencedExports} RawReferencedExports */
+/** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
+
+class ImportWeakDependency extends ImportDependency {
+	/**
+	 * Creates an instance of ImportWeakDependency.
+	 * @param {string} request the request
+	 * @param {Range} range expression range
+	 * @param {RawReferencedExports | null} referencedExports list of referenced exports
+	 * @param {ImportPhaseType} phase import phase
+	 * @param {ImportAttributes=} attributes import attributes
+	 */
+	constructor(request, range, referencedExports, phase, attributes) {
+		super(request, range, referencedExports, phase, attributes);
+		this.weak = true;
+	}
+
+	get type() {
+		return "import() weak";
+	}
+}
+
+makeSerializable(
+	ImportWeakDependency,
+	"webpack/lib/dependencies/ImportWeakDependency"
+);
+
+ImportWeakDependency.Template = class ImportDependencyTemplate extends (
+	ImportDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {ImportWeakDependency} */ (dependency);
+		const content = runtimeTemplate.moduleNamespacePromise({
+			chunkGraph,
+			module: /** @type {Module} */ (moduleGraph.getModule(dep)),
+			request: dep.request,
+			strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
+			message: "import() weak",
+			weak: true,
+			dependency: dep,
+			runtimeRequirements
+		});
+
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+	}
+};
+
+module.exports = ImportWeakDependency;
Index: frontend/node_modules/webpack/lib/dependencies/JsonExportsDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/JsonExportsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/JsonExportsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,142 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("../Dependency").ExportSpec} ExportSpec */
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../json/JsonData")} JsonData */
+/** @typedef {import("../json/JsonData").JsonValue} JsonValue */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+/**
+ * Defines the get exports from data fn callback.
+ * @callback GetExportsFromDataFn
+ * @param {JsonValue} data raw json data
+ * @param {number=} curDepth current depth
+ * @returns {ExportSpec[] | null} export spec or nothing
+ */
+
+/**
+ * Gets exports with depth.
+ * @param {number} exportsDepth exportsDepth
+ * @returns {GetExportsFromDataFn} value
+ */
+const getExportsWithDepth = (exportsDepth) =>
+	/** @type {GetExportsFromDataFn} */
+	function getExportsFromData(data, curDepth = 1) {
+		if (curDepth > exportsDepth) {
+			return null;
+		}
+
+		if (data && typeof data === "object") {
+			if (Array.isArray(data)) {
+				return data.length < 100
+					? data.map((item, idx) => ({
+							name: `${idx}`,
+							canMangle: true,
+							exports: getExportsFromData(item, curDepth + 1) || undefined
+						}))
+					: null;
+			}
+
+			/** @type {ExportSpec[]} */
+			const exports = [];
+
+			for (const key of Object.keys(data)) {
+				exports.push({
+					name: key,
+					canMangle: true,
+					exports:
+						getExportsFromData(
+							/** @type {JsonValue} */
+							(data[key]),
+							curDepth + 1
+						) || undefined
+				});
+			}
+
+			return exports;
+		}
+
+		return null;
+	};
+
+class JsonExportsDependency extends NullDependency {
+	/**
+	 * Creates an instance of JsonExportsDependency.
+	 * @param {JsonData} data json data
+	 * @param {number} exportsDepth the depth of json exports to analyze
+	 */
+	constructor(data, exportsDepth) {
+		super();
+		this.data = data;
+		this.exportsDepth = exportsDepth;
+	}
+
+	get type() {
+		return "json exports";
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		return {
+			exports: getExportsWithDepth(this.exportsDepth)(
+				this.data && /** @type {JsonValue} */ (this.data.get())
+			),
+			dependencies: undefined
+		};
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		this.data.updateHash(hash);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.data);
+		write(this.exportsDepth);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.data = read();
+		this.exportsDepth = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	JsonExportsDependency,
+	"webpack/lib/dependencies/JsonExportsDependency"
+);
+
+module.exports = JsonExportsDependency;
Index: frontend/node_modules/webpack/lib/dependencies/LoaderDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/LoaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/LoaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+
+class LoaderDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of LoaderDependency.
+	 * @param {string} request request string
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "loader";
+	}
+
+	get category() {
+		return "loader";
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return false;
+	}
+}
+
+module.exports = LoaderDependency;
Index: frontend/node_modules/webpack/lib/dependencies/LoaderImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/LoaderImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/LoaderImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+
+class LoaderImportDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of LoaderImportDependency.
+	 * @param {string} request request string
+	 */
+	constructor(request) {
+		super(request);
+		this.weak = true;
+	}
+
+	get type() {
+		return "loader import";
+	}
+
+	get category() {
+		return "loaderImport";
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return false;
+	}
+}
+
+module.exports = LoaderImportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/LoaderPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/LoaderPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/LoaderPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,297 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const NormalModule = require("../NormalModule");
+const LazySet = require("../util/LazySet");
+const LoaderDependency = require("./LoaderDependency");
+const LoaderImportDependency = require("./LoaderImportDependency");
+
+/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
+/** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
+/** @typedef {import("../Compilation").ExecuteModuleExports} ExecuteModuleExports */
+/** @typedef {import("../Compilation").ExecuteModuleResult} ExecuteModuleResult */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").FileSystemDependencies} FileSystemDependencies */
+
+/**
+ * Defines the import module callback callback.
+ * @callback ImportModuleCallback
+ * @param {(Error | null)=} err error object
+ * @param {ExecuteModuleExports=} exports exports of the evaluated module
+ * @returns {void}
+ */
+
+/**
+ * Defines the import module options type used by this module.
+ * @typedef {object} ImportModuleOptions
+ * @property {string=} layer the target layer
+ * @property {string=} publicPath the target public path
+ * @property {string=} baseUri target base uri
+ */
+
+const PLUGIN_NAME = "LoaderPlugin";
+
+class LoaderPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					LoaderDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyFactories.set(
+					LoaderImportDependency,
+					normalModuleFactory
+				);
+			}
+		);
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			NormalModule.getCompilationHooks(compilation).loader.tap(
+				PLUGIN_NAME,
+				(loaderContext) => {
+					loaderContext.loadModule = (request, callback) => {
+						const dep = new LoaderDependency(request);
+						dep.loc = {
+							name: request
+						};
+						const factory = compilation.dependencyFactories.get(
+							/** @type {DependencyConstructor} */
+							(dep.constructor)
+						);
+						if (factory === undefined) {
+							return callback(
+								new Error(
+									`No module factory available for dependency type: ${dep.constructor.name}`
+								)
+							);
+						}
+						const oldFactorizeQueueContext =
+							compilation.factorizeQueue.getContext();
+						compilation.factorizeQueue.setContext("load-module");
+						const oldAddModuleQueueContext =
+							compilation.addModuleQueue.getContext();
+						compilation.addModuleQueue.setContext("load-module");
+						compilation.buildQueue.increaseParallelism();
+						compilation.handleModuleCreation(
+							{
+								factory,
+								dependencies: [dep],
+								originModule:
+									/** @type {NormalModule} */
+									(loaderContext._module),
+								context: loaderContext.context,
+								recursive: false
+							},
+							(err) => {
+								compilation.factorizeQueue.setContext(oldFactorizeQueueContext);
+								compilation.addModuleQueue.setContext(oldAddModuleQueueContext);
+								compilation.buildQueue.decreaseParallelism();
+								if (err) {
+									return callback(err);
+								}
+								const referencedModule = moduleGraph.getModule(dep);
+								if (!referencedModule) {
+									return callback(new Error("Cannot load the module"));
+								}
+								if (referencedModule.getNumberOfErrors() > 0) {
+									return callback(
+										new Error("The loaded module contains errors")
+									);
+								}
+								const moduleSource = referencedModule.originalSource();
+								if (!moduleSource) {
+									return callback(
+										new Error(
+											"The module created for a LoaderDependency must have an original source"
+										)
+									);
+								}
+								/** @type {null | RawSourceMap} */
+								let map;
+								/** @type {string | Buffer | undefined} */
+								let source;
+								if (moduleSource.sourceAndMap) {
+									const sourceAndMap = moduleSource.sourceAndMap();
+									map = sourceAndMap.map;
+									source = sourceAndMap.source;
+								} else {
+									map = moduleSource.map();
+									source = moduleSource.source();
+								}
+								/** @type {FileSystemDependencies} */
+								const fileDependencies = new LazySet();
+								/** @type {FileSystemDependencies} */
+								const contextDependencies = new LazySet();
+								/** @type {FileSystemDependencies} */
+								const missingDependencies = new LazySet();
+								/** @type {FileSystemDependencies} */
+								const buildDependencies = new LazySet();
+								referencedModule.addCacheDependencies(
+									fileDependencies,
+									contextDependencies,
+									missingDependencies,
+									buildDependencies
+								);
+
+								for (const d of fileDependencies) {
+									loaderContext.addDependency(d);
+								}
+								for (const d of contextDependencies) {
+									loaderContext.addContextDependency(d);
+								}
+								for (const d of missingDependencies) {
+									loaderContext.addMissingDependency(d);
+								}
+								for (const d of buildDependencies) {
+									loaderContext.addBuildDependency(d);
+								}
+								return callback(null, source, map, referencedModule);
+							}
+						);
+					};
+
+					/**
+					 * Processes the provided request.
+					 * @param {string} request the request string to load the module from
+					 * @param {ImportModuleOptions} options options
+					 * @param {ImportModuleCallback} callback callback returning the exports
+					 * @returns {void}
+					 */
+					const importModule = (request, options, callback) => {
+						const dep = new LoaderImportDependency(request);
+						dep.loc = {
+							name: request
+						};
+						const factory = compilation.dependencyFactories.get(
+							/** @type {DependencyConstructor} */
+							(dep.constructor)
+						);
+						if (factory === undefined) {
+							return callback(
+								new Error(
+									`No module factory available for dependency type: ${dep.constructor.name}`
+								)
+							);
+						}
+
+						const oldFactorizeQueueContext =
+							compilation.factorizeQueue.getContext();
+						compilation.factorizeQueue.setContext("import-module");
+						const oldAddModuleQueueContext =
+							compilation.addModuleQueue.getContext();
+						compilation.addModuleQueue.setContext("import-module");
+						compilation.buildQueue.increaseParallelism();
+						compilation.handleModuleCreation(
+							{
+								factory,
+								dependencies: [dep],
+								originModule:
+									/** @type {NormalModule} */
+									(loaderContext._module),
+								contextInfo: {
+									issuerLayer: options.layer
+								},
+								context: loaderContext.context,
+								connectOrigin: false,
+								checkCycle: true
+							},
+							(err) => {
+								compilation.factorizeQueue.setContext(oldFactorizeQueueContext);
+								compilation.addModuleQueue.setContext(oldAddModuleQueueContext);
+								compilation.buildQueue.decreaseParallelism();
+								if (err) {
+									return callback(err);
+								}
+								const referencedModule = moduleGraph.getModule(dep);
+								if (!referencedModule) {
+									return callback(new Error("Cannot load the module"));
+								}
+								compilation.buildQueue.increaseParallelism();
+								compilation.executeModule(
+									referencedModule,
+									{
+										entryOptions: {
+											baseUri: options.baseUri,
+											publicPath: options.publicPath
+										}
+									},
+									(err, result) => {
+										compilation.buildQueue.decreaseParallelism();
+										if (err) return callback(err);
+										const {
+											fileDependencies,
+											contextDependencies,
+											missingDependencies,
+											buildDependencies,
+											cacheable,
+											assets,
+											exports
+										} = /** @type {ExecuteModuleResult} */ (result);
+										for (const d of fileDependencies) {
+											loaderContext.addDependency(d);
+										}
+										for (const d of contextDependencies) {
+											loaderContext.addContextDependency(d);
+										}
+										for (const d of missingDependencies) {
+											loaderContext.addMissingDependency(d);
+										}
+										for (const d of buildDependencies) {
+											loaderContext.addBuildDependency(d);
+										}
+										if (cacheable === false) loaderContext.cacheable(false);
+										for (const [name, { source, info }] of assets) {
+											const buildInfo =
+												/** @type {BuildInfo} */
+												(
+													/** @type {NormalModule} */ (loaderContext._module)
+														.buildInfo
+												);
+											if (!buildInfo.assets) {
+												buildInfo.assets = Object.create(null);
+												buildInfo.assetsInfo = new Map();
+											}
+											/** @type {NonNullable<BuildInfo["assets"]>} */
+											(buildInfo.assets)[name] = source;
+											/** @type {NonNullable<BuildInfo["assetsInfo"]>} */
+											(buildInfo.assetsInfo).set(name, info);
+										}
+										callback(null, exports);
+									}
+								);
+							}
+						);
+					};
+
+					// @ts-expect-error overloading doesn't work
+					loaderContext.importModule = (request, options, callback) => {
+						if (!callback) {
+							return new Promise((resolve, reject) => {
+								importModule(request, options || {}, (err, result) => {
+									if (err) reject(err);
+									else resolve(result);
+								});
+							});
+						}
+						return importModule(request, options || {}, callback);
+					};
+				}
+			);
+		});
+	}
+}
+
+module.exports = LoaderPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/LocalModule.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/LocalModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/LocalModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,64 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class LocalModule {
+	/**
+	 * Creates an instance of LocalModule.
+	 * @param {string} name name
+	 * @param {number} idx index
+	 */
+	constructor(name, idx) {
+		this.name = name;
+		this.idx = idx;
+		this.used = false;
+	}
+
+	flagUsed() {
+		this.used = true;
+	}
+
+	/**
+	 * Returns variable name.
+	 * @returns {string} variable name
+	 */
+	variableName() {
+		return `__WEBPACK_LOCAL_MODULE_${this.idx}__`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.name);
+		write(this.idx);
+		write(this.used);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.name = read();
+		this.idx = read();
+		this.used = read();
+	}
+}
+
+makeSerializable(LocalModule, "webpack/lib/dependencies/LocalModule");
+
+module.exports = LocalModule;
Index: frontend/node_modules/webpack/lib/dependencies/LocalModuleDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/LocalModuleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/LocalModuleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,88 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./LocalModule")} LocalModule */
+
+class LocalModuleDependency extends NullDependency {
+	/**
+	 * Creates an instance of LocalModuleDependency.
+	 * @param {LocalModule} localModule local module
+	 * @param {Range | undefined} range range
+	 * @param {boolean} callNew true, when the local module should be called with new
+	 */
+	constructor(localModule, range, callNew) {
+		super();
+
+		this.localModule = localModule;
+		this.range = range;
+		this.callNew = callNew;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.localModule);
+		write(this.range);
+		write(this.callNew);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.localModule = read();
+		this.range = read();
+		this.callNew = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	LocalModuleDependency,
+	"webpack/lib/dependencies/LocalModuleDependency"
+);
+
+LocalModuleDependency.Template = class LocalModuleDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {LocalModuleDependency} */ (dependency);
+		if (!dep.range) return;
+		const moduleInstance = dep.callNew
+			? `new (function () { return ${dep.localModule.variableName()}; })()`
+			: dep.localModule.variableName();
+		source.replace(dep.range[0], dep.range[1] - 1, moduleInstance);
+	}
+};
+
+module.exports = LocalModuleDependency;
Index: frontend/node_modules/webpack/lib/dependencies/LocalModulesHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/LocalModulesHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/LocalModulesHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const LocalModule = require("./LocalModule");
+
+/** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
+
+/**
+ * Returns resolved module.
+ * @param {string} parent parent module
+ * @param {string} mod module to resolve
+ * @returns {string} resolved module
+ */
+const lookup = (parent, mod) => {
+	if (mod.charAt(0) !== ".") return mod;
+
+	const path = parent.split("/");
+	const segments = mod.split("/");
+	path.pop();
+
+	for (let i = 0; i < segments.length; i++) {
+		const seg = segments[i];
+		if (seg === "..") {
+			path.pop();
+		} else if (seg !== ".") {
+			path.push(seg);
+		}
+	}
+
+	return path.join("/");
+};
+
+/**
+ * Returns local module.
+ * @param {JavascriptParserState} state parser state
+ * @param {string} name name
+ * @returns {LocalModule} local module
+ */
+module.exports.addLocalModule = (state, name) => {
+	if (!state.localModules) {
+		state.localModules = [];
+	}
+	const m = new LocalModule(name, state.localModules.length);
+	state.localModules.push(m);
+	return m;
+};
+
+/**
+ * Returns local module or null.
+ * @param {JavascriptParserState} state parser state
+ * @param {string} name name
+ * @param {string=} namedModule named module
+ * @returns {LocalModule | null} local module or null
+ */
+module.exports.getLocalModule = (state, name, namedModule) => {
+	if (!state.localModules) return null;
+	if (namedModule) {
+		// resolve dependency name relative to the defining named module
+		name = lookup(namedModule, name);
+	}
+	for (let i = 0; i < state.localModules.length; i++) {
+		if (state.localModules[i].name === name) {
+			return state.localModules[i];
+		}
+	}
+	return null;
+};
Index: frontend/node_modules/webpack/lib/dependencies/ModuleDecoratorDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleDecoratorDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleDecoratorDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,142 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class ModuleDecoratorDependency extends NullDependency {
+	/**
+	 * Creates an instance of ModuleDecoratorDependency.
+	 * @param {string} decorator the decorator requirement
+	 * @param {boolean} allowExportsAccess allow to access exports from module
+	 */
+	constructor(decorator, allowExportsAccess) {
+		super();
+		this.decorator = decorator;
+		this.allowExportsAccess = allowExportsAccess;
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	/**
+	 * Returns a display name for the type of dependency.
+	 * @returns {string} a display name for the type of dependency
+	 */
+	get type() {
+		return "module decorator";
+	}
+
+	get category() {
+		return "self";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return "self";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return this.allowExportsAccess
+			? Dependency.EXPORTS_OBJECT_REFERENCED
+			: Dependency.NO_EXPORTS_REFERENCED;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			this._hashUpdate = `${this.decorator}${this.allowExportsAccess}`;
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.decorator);
+		write(this.allowExportsAccess);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.decorator = read();
+		this.allowExportsAccess = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ModuleDecoratorDependency,
+	"webpack/lib/dependencies/ModuleDecoratorDependency"
+);
+
+ModuleDecoratorDependency.Template = class ModuleDecoratorDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ module, chunkGraph, initFragments, runtimeRequirements }
+	) {
+		const dep = /** @type {ModuleDecoratorDependency} */ (dependency);
+		runtimeRequirements.add(RuntimeGlobals.moduleLoaded);
+		runtimeRequirements.add(RuntimeGlobals.moduleId);
+		runtimeRequirements.add(RuntimeGlobals.module);
+		runtimeRequirements.add(dep.decorator);
+		initFragments.push(
+			new InitFragment(
+				`/* module decorator */ ${module.moduleArgument} = ${dep.decorator}(${module.moduleArgument});\n`,
+				InitFragment.STAGE_PROVIDES,
+				0,
+				`module decorator ${chunkGraph.getModuleId(module)}`
+			)
+		);
+	}
+};
+
+module.exports = ModuleDecoratorDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ModuleDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,107 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const DependencyTemplate = require("../DependencyTemplate");
+
+/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ModuleDependency extends Dependency {
+	/**
+	 * Creates an instance of ModuleDependency.
+	 * @param {string} request request path which needs resolving
+	 * @param {number=} sourceOrder source order
+	 */
+	constructor(request, sourceOrder) {
+		super();
+		this.request = request;
+		this.userRequest = request;
+		this.sourceOrder = sourceOrder;
+		/** @type {Range | undefined} */
+		this.range = undefined;
+		/** @type {undefined | string} */
+		this._context = undefined;
+	}
+
+	/**
+	 * Returns a request context.
+	 * @returns {string | undefined} a request context
+	 */
+	getContext() {
+		return this._context;
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return `context${this._context || ""}|module${this.request}`;
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return true;
+	}
+
+	/**
+	 * Creates an ignored module.
+	 * @param {string} context context directory
+	 * @returns {Module} ignored module
+	 */
+	createIgnoredModule(context) {
+		const RawModule = require("../RawModule");
+
+		const module = new RawModule(
+			"/* (ignored) */",
+			`ignored|${context}|${this.request}`,
+			`${this.request} (ignored)`
+		);
+		module.factoryMeta = { sideEffectFree: true };
+		return module;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.request);
+		write(this.userRequest);
+		write(this._context);
+		write(this.range);
+		write(this.sourceOrder);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.request = read();
+		this.userRequest = read();
+		this._context = read();
+		this.range = read();
+		this.sourceOrder = read();
+		super.deserialize(context);
+	}
+}
+
+ModuleDependency.Template = DependencyTemplate;
+
+module.exports = ModuleDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsId.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+
+class ModuleDependencyTemplateAsId extends ModuleDependency.Template {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeTemplate, moduleGraph, chunkGraph }) {
+		const dep = /** @type {ModuleDependency} */ (dependency);
+		if (!dep.range) return;
+		const content = runtimeTemplate.moduleId({
+			module: /** @type {Module} */ (moduleGraph.getModule(dep)),
+			chunkGraph,
+			request: dep.request,
+			weak: dep.weak
+		});
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+	}
+}
+
+module.exports = ModuleDependencyTemplateAsId;
Index: frontend/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsRequireId.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsRequireId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsRequireId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+
+class ModuleDependencyTemplateAsRequireId extends ModuleDependency.Template {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {ModuleDependency} */ (dependency);
+		if (!dep.range) return;
+		const content = runtimeTemplate.moduleExports({
+			module: moduleGraph.getModule(dep),
+			chunkGraph,
+			request: dep.request,
+			weak: dep.weak,
+			runtimeRequirements
+		});
+		source.replace(dep.range[0], dep.range[1] - 1, content);
+	}
+}
+
+module.exports = ModuleDependencyTemplateAsRequireId;
Index: frontend/node_modules/webpack/lib/dependencies/ModuleHotAcceptDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleHotAcceptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleHotAcceptDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+class ModuleHotAcceptDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ModuleHotAcceptDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super(request, Infinity);
+		this.range = range;
+		this.weak = true;
+	}
+
+	get type() {
+		return "module.hot.accept";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+}
+
+makeSerializable(
+	ModuleHotAcceptDependency,
+	"webpack/lib/dependencies/ModuleHotAcceptDependency"
+);
+
+ModuleHotAcceptDependency.Template = ModuleDependencyTemplateAsId;
+
+module.exports = ModuleHotAcceptDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ModuleHotDeclineDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleHotDeclineDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleHotDeclineDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+class ModuleHotDeclineDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ModuleHotDeclineDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super(request);
+
+		this.range = range;
+		this.weak = true;
+	}
+
+	get type() {
+		return "module.hot.decline";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+}
+
+makeSerializable(
+	ModuleHotDeclineDependency,
+	"webpack/lib/dependencies/ModuleHotDeclineDependency"
+);
+
+ModuleHotDeclineDependency.Template = ModuleDependencyTemplateAsId;
+
+module.exports = ModuleHotDeclineDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ModuleInitFragmentDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ModuleInitFragmentDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ModuleInitFragmentDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+const InitFragment = require("../InitFragment");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/**
+ * A dependency that adds an init fragment to the module
+ */
+class ModuleInitFragmentDependency extends NullDependency {
+	/**
+	 * Creates an instance of ModuleInitFragmentDependency.
+	 * @param {string} initCode the initialization code
+	 * @param {string[]} runtimeRequirements runtime requirements
+	 * @param {string=} key unique key to avoid emitting the same initialization code twice
+	 */
+	constructor(initCode, runtimeRequirements, key) {
+		super();
+		this.initCode = initCode;
+		this.runtimeRequirements = runtimeRequirements;
+		this.key = key;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.initCode);
+		write(this.runtimeRequirements);
+		write(this.key);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.initCode = read();
+		this.runtimeRequirements = read();
+		this.key = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ModuleInitFragmentDependency,
+	"webpack/lib/dependencies/ModuleInitFragmentDependency"
+);
+
+ModuleInitFragmentDependency.Template = class ModuleInitFragmentDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { initFragments, runtimeRequirements }) {
+		const dep = /** @type {ModuleInitFragmentDependency} */ (dependency);
+		for (const req of dep.runtimeRequirements) {
+			runtimeRequirements.add(req);
+		}
+		initFragments.push(
+			new InitFragment(
+				dep.initCode,
+				InitFragment.STAGE_CONSTANTS,
+				0,
+				dep.key,
+				undefined
+			)
+		);
+	}
+};
+
+module.exports = ModuleInitFragmentDependency;
Index: frontend/node_modules/webpack/lib/dependencies/NullDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/NullDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/NullDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const DependencyTemplate = require("../DependencyTemplate");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+
+/** @typedef {string[]} RawRuntimeRequirements */
+
+class NullDependency extends Dependency {
+	get type() {
+		return "null";
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return false;
+	}
+}
+
+NullDependency.Template = class NullDependencyTemplate extends (
+	DependencyTemplate
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {}
+};
+
+module.exports = NullDependency;
Index: frontend/node_modules/webpack/lib/dependencies/PrefetchDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/PrefetchDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/PrefetchDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("./ModuleDependency");
+
+class PrefetchDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of PrefetchDependency.
+	 * @param {string} request the request string
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "prefetch";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+module.exports = PrefetchDependency;
Index: frontend/node_modules/webpack/lib/dependencies/ProvidedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/ProvidedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/ProvidedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,161 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const InitFragment = require("../InitFragment");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Returns the converted path.
+ * @param {string[] | null} path the property path array
+ * @returns {string} the converted path
+ */
+const pathToString = (path) =>
+	path !== null && path.length > 0
+		? path.map((part) => `[${JSON.stringify(part)}]`).join("")
+		: "";
+
+class ProvidedDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ProvidedDependency.
+	 * @param {string} request request
+	 * @param {string} identifier identifier
+	 * @param {ExportInfoName[]} ids ids
+	 * @param {Range} range range
+	 */
+	constructor(request, identifier, ids, range) {
+		super(request);
+		this.identifier = identifier;
+		this.ids = ids;
+		this.range = range;
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	get type() {
+		return "provided";
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		const ids = this.ids;
+		if (ids.length === 0) return Dependency.EXPORTS_OBJECT_REFERENCED;
+		return [ids];
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			this._hashUpdate = this.identifier + (this.ids ? this.ids.join(",") : "");
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.identifier);
+		write(this.ids);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.identifier = read();
+		this.ids = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ProvidedDependency,
+	"webpack/lib/dependencies/ProvidedDependency"
+);
+
+class ProvidedDependencyTemplate extends ModuleDependency.Template {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{
+			runtime,
+			runtimeTemplate,
+			moduleGraph,
+			chunkGraph,
+			initFragments,
+			runtimeRequirements
+		}
+	) {
+		const dep = /** @type {ProvidedDependency} */ (dependency);
+		const connection =
+			/** @type {ModuleGraphConnection} */
+			(moduleGraph.getConnection(dep));
+		const exportsInfo = moduleGraph.getExportsInfo(connection.module);
+		const usedName = exportsInfo.getUsedName(dep.ids, runtime);
+		initFragments.push(
+			new InitFragment(
+				`/* provided dependency */ var ${
+					dep.identifier
+				} = ${runtimeTemplate.moduleExports({
+					module: moduleGraph.getModule(dep),
+					chunkGraph,
+					request: dep.request,
+					runtimeRequirements
+				})}${pathToString(/** @type {string[] | null} */ (usedName))};\n`,
+				InitFragment.STAGE_PROVIDES,
+				1,
+				`provided ${dep.identifier}`
+			)
+		);
+		source.replace(dep.range[0], dep.range[1] - 1, dep.identifier);
+	}
+}
+
+ProvidedDependency.Template = ProvidedDependencyTemplate;
+
+module.exports = ProvidedDependency;
Index: frontend/node_modules/webpack/lib/dependencies/PureExpressionDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/PureExpressionDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/PureExpressionDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,167 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+const makeSerializable = require("../util/makeSerializable");
+const { filterRuntime, runtimeToString } = require("../util/runtime");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+class PureExpressionDependency extends NullDependency {
+	/**
+	 * Creates an instance of PureExpressionDependency.
+	 * @param {Range} range the source range
+	 */
+	constructor(range) {
+		super();
+		this.range = range;
+		/** @type {Set<string> | false} */
+		this.usedByExports = false;
+	}
+
+	/**
+	 * Get runtime condition.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime current runtimes
+	 * @returns {boolean | RuntimeSpec} runtime condition
+	 */
+	_getRuntimeCondition(moduleGraph, runtime) {
+		const usedByExports = this.usedByExports;
+		if (usedByExports !== false) {
+			const selfModule =
+				/** @type {Module} */
+				(moduleGraph.getParentModule(this));
+			const exportsInfo = moduleGraph.getExportsInfo(selfModule);
+			const runtimeCondition = filterRuntime(runtime, (runtime) => {
+				for (const exportName of usedByExports) {
+					if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) {
+						return true;
+					}
+				}
+				return false;
+			});
+			return runtimeCondition;
+		}
+		return false;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		const runtimeCondition = this._getRuntimeCondition(
+			context.chunkGraph.moduleGraph,
+			context.runtime
+		);
+		if (runtimeCondition === true) {
+			return;
+		} else if (runtimeCondition === false) {
+			hash.update("null");
+		} else {
+			hash.update(
+				`${runtimeToString(runtimeCondition)}|${runtimeToString(
+					context.runtime
+				)}`
+			);
+		}
+		hash.update(String(this.range));
+	}
+
+	/**
+	 * Gets module evaluation side effects state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
+	 */
+	getModuleEvaluationSideEffectsState(moduleGraph) {
+		return false;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		write(this.usedByExports);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.range = read();
+		this.usedByExports = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	PureExpressionDependency,
+	"webpack/lib/dependencies/PureExpressionDependency"
+);
+
+PureExpressionDependency.Template = class PureExpressionDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ chunkGraph, moduleGraph, runtime, runtimeTemplate, runtimeRequirements }
+	) {
+		const dep = /** @type {PureExpressionDependency} */ (dependency);
+		const runtimeCondition = dep._getRuntimeCondition(moduleGraph, runtime);
+		if (runtimeCondition === true) {
+			// Do nothing
+		} else if (runtimeCondition === false) {
+			source.insert(
+				dep.range[0],
+				"(/* unused pure expression or super */ null && ("
+			);
+			source.insert(dep.range[1], "))");
+		} else {
+			const condition = runtimeTemplate.runtimeConditionExpression({
+				chunkGraph,
+				runtime,
+				runtimeCondition,
+				runtimeRequirements
+			});
+			source.insert(
+				dep.range[0],
+				`(/* runtime-dependent pure expression or super */ ${condition} ? (`
+			);
+			source.insert(dep.range[1], ") : null)");
+		}
+	}
+};
+
+module.exports = PureExpressionDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+
+class RequireContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of RequireContextDependency.
+	 * @param {ContextDependencyOptions} options options
+	 * @param {Range} range range
+	 */
+	constructor(options, range) {
+		super(options);
+
+		this.range = range;
+	}
+
+	get type() {
+		return "require.context";
+	}
+}
+
+makeSerializable(
+	RequireContextDependency,
+	"webpack/lib/dependencies/RequireContextDependency"
+);
+
+RequireContextDependency.Template = ModuleDependencyTemplateAsRequireId;
+
+module.exports = RequireContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RequireContextDependency = require("./RequireContextDependency");
+
+/** @typedef {import("../ContextModule").ContextMode} ContextMode */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "RequireContextDependencyParserPlugin";
+
+module.exports = class RequireContextDependencyParserPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.call.for("require.context").tap(PLUGIN_NAME, (expr) => {
+			let regExp = /^\.\/.*$/;
+			let recursive = true;
+			/** @type {ContextMode} */
+			let mode = "sync";
+			switch (expr.arguments.length) {
+				case 4: {
+					const modeExpr = parser.evaluateExpression(expr.arguments[3]);
+					if (!modeExpr.isString()) return;
+					mode = /** @type {ContextMode} */ (modeExpr.string);
+				}
+				// falls through
+				case 3: {
+					const regExpExpr = parser.evaluateExpression(expr.arguments[2]);
+					if (!regExpExpr.isRegExp()) return;
+					regExp = /** @type {RegExp} */ (regExpExpr.regExp);
+				}
+				// falls through
+				case 2: {
+					const recursiveExpr = parser.evaluateExpression(expr.arguments[1]);
+					if (!recursiveExpr.isBoolean()) return;
+					recursive = /** @type {boolean} */ (recursiveExpr.bool);
+				}
+				// falls through
+				case 1: {
+					const requestExpr = parser.evaluateExpression(expr.arguments[0]);
+					if (!requestExpr.isString()) return;
+					const dep = new RequireContextDependency(
+						{
+							request: /** @type {string} */ (requestExpr.string),
+							recursive,
+							regExp,
+							mode,
+							category: "commonjs"
+						},
+						/** @type {Range} */
+						(expr.range)
+					);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					dep.optional = Boolean(parser.scope.inTry);
+					parser.state.current.addDependency(dep);
+					return true;
+				}
+			}
+		});
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/RequireContextPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireContextPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireContextPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,168 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const { cachedSetProperty } = require("../util/cleverMerge");
+const ContextElementDependency = require("./ContextElementDependency");
+const RequireContextDependency = require("./RequireContextDependency");
+const RequireContextDependencyParserPlugin = require("./RequireContextDependencyParserPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+/** @type {ResolveOptions} */
+const EMPTY_RESOLVE_OPTIONS = {};
+
+const PLUGIN_NAME = "RequireContextPlugin";
+
+class RequireContextPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { contextModuleFactory, normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					RequireContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					RequireContextDependency,
+					new RequireContextDependency.Template()
+				);
+
+				compilation.dependencyFactories.set(
+					ContextElementDependency,
+					normalModuleFactory
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (
+						parserOptions.requireContext !== undefined &&
+						!parserOptions.requireContext
+					) {
+						return;
+					}
+
+					new RequireContextDependencyParserPlugin().apply(parser);
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+
+				contextModuleFactory.hooks.alternativeRequests.tap(
+					PLUGIN_NAME,
+					(items, options) => {
+						if (items.length === 0) return items;
+
+						const finalResolveOptions = compiler.resolverFactory.get(
+							"normal",
+							cachedSetProperty(
+								options.resolveOptions || EMPTY_RESOLVE_OPTIONS,
+								"dependencyType",
+								/** @type {string} */
+								(options.category)
+							)
+						).options;
+
+						/** @type {{ context: string, request: string }[]} */
+						let newItems;
+						if (!finalResolveOptions.fullySpecified) {
+							newItems = [];
+							for (const item of items) {
+								const { request, context } = item;
+								for (const ext of finalResolveOptions.extensions) {
+									if (request.endsWith(ext)) {
+										newItems.push({
+											context,
+											request: request.slice(0, -ext.length)
+										});
+									}
+								}
+								if (!finalResolveOptions.enforceExtension) {
+									newItems.push(item);
+								}
+							}
+							items = newItems;
+
+							newItems = [];
+							for (const obj of items) {
+								const { request, context } = obj;
+								for (const mainFile of finalResolveOptions.mainFiles) {
+									if (request.endsWith(`/${mainFile}`)) {
+										newItems.push({
+											context,
+											request: request.slice(0, -mainFile.length)
+										});
+										newItems.push({
+											context,
+											request: request.slice(0, -mainFile.length - 1)
+										});
+									}
+								}
+								newItems.push(obj);
+							}
+							items = newItems;
+						}
+
+						newItems = [];
+						for (const item of items) {
+							let hideOriginal = false;
+							for (const modulesItems of finalResolveOptions.modules) {
+								if (Array.isArray(modulesItems)) {
+									for (const dir of modulesItems) {
+										if (item.request.startsWith(`./${dir}/`)) {
+											newItems.push({
+												context: item.context,
+												request: item.request.slice(dir.length + 3)
+											});
+											hideOriginal = true;
+										}
+									}
+								} else {
+									const dir = modulesItems.replace(/\\/g, "/");
+									const fullPath =
+										item.context.replace(/\\/g, "/") + item.request.slice(1);
+									if (fullPath.startsWith(dir)) {
+										newItems.push({
+											context: item.context,
+											request: fullPath.slice(dir.length + 1)
+										});
+									}
+								}
+							}
+							if (!hideOriginal) {
+								newItems.push(item);
+							}
+						}
+						return newItems;
+					}
+				);
+			}
+		);
+	}
+}
+
+module.exports = RequireContextPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../AsyncDependenciesBlock").GroupOptions} GroupOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+
+class RequireEnsureDependenciesBlock extends AsyncDependenciesBlock {
+	/**
+	 * Creates an instance of RequireEnsureDependenciesBlock.
+	 * @param {GroupOptions | string | null} chunkName chunk name
+	 * @param {(DependencyLocation | null)=} loc location info
+	 */
+	constructor(chunkName, loc) {
+		super(chunkName, loc, null);
+	}
+}
+
+makeSerializable(
+	RequireEnsureDependenciesBlock,
+	"webpack/lib/dependencies/RequireEnsureDependenciesBlock"
+);
+
+module.exports = RequireEnsureDependenciesBlock;
Index: frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,146 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RequireEnsureDependenciesBlock = require("./RequireEnsureDependenciesBlock");
+const RequireEnsureDependency = require("./RequireEnsureDependency");
+const RequireEnsureItemDependency = require("./RequireEnsureItemDependency");
+const getFunctionExpression = require("./getFunctionExpression");
+
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+/** @typedef {import("../AsyncDependenciesBlock").GroupOptions} GroupOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./getFunctionExpression").FunctionExpressionResult} FunctionExpressionResult */
+
+const PLUGIN_NAME = "RequireEnsureDependenciesBlockParserPlugin";
+
+module.exports = class RequireEnsureDependenciesBlockParserPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		parser.hooks.call.for("require.ensure").tap(PLUGIN_NAME, (expr) => {
+			/** @type {string | GroupOptions | null} */
+			let chunkName = null;
+			/** @type {undefined | Expression | SpreadElement} */
+			let errorExpressionArg;
+			/** @type {undefined | FunctionExpressionResult} */
+			let errorExpression;
+			switch (expr.arguments.length) {
+				case 4: {
+					const chunkNameExpr = parser.evaluateExpression(expr.arguments[3]);
+					if (!chunkNameExpr.isString()) return;
+					chunkName =
+						/** @type {string} */
+						(chunkNameExpr.string);
+				}
+				// falls through
+				case 3: {
+					errorExpressionArg = expr.arguments[2];
+					errorExpression = getFunctionExpression(errorExpressionArg);
+
+					if (!errorExpression && !chunkName) {
+						const chunkNameExpr = parser.evaluateExpression(expr.arguments[2]);
+						if (!chunkNameExpr.isString()) return;
+						chunkName =
+							/** @type {string} */
+							(chunkNameExpr.string);
+					}
+				}
+				// falls through
+				case 2: {
+					const dependenciesExpr = parser.evaluateExpression(expr.arguments[0]);
+					const dependenciesItems = /** @type {BasicEvaluatedExpression[]} */ (
+						dependenciesExpr.isArray()
+							? dependenciesExpr.items
+							: [dependenciesExpr]
+					);
+					const successExpressionArg = expr.arguments[1];
+					const successExpression = getFunctionExpression(successExpressionArg);
+
+					if (successExpression) {
+						parser.walkExpressions(successExpression.expressions);
+					}
+					if (errorExpression) {
+						parser.walkExpressions(errorExpression.expressions);
+					}
+
+					const depBlock = new RequireEnsureDependenciesBlock(
+						chunkName,
+						/** @type {DependencyLocation} */
+						(expr.loc)
+					);
+					const errorCallbackExists =
+						expr.arguments.length === 4 ||
+						(!chunkName && expr.arguments.length === 3);
+					const dep = new RequireEnsureDependency(
+						/** @type {Range} */ (expr.range),
+						/** @type {Range} */ (expr.arguments[1].range),
+						errorCallbackExists &&
+							/** @type {Range} */ (expr.arguments[2].range)
+					);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					depBlock.addDependency(dep);
+					const old = parser.state.current;
+					parser.state.current = /** @type {EXPECTED_ANY} */ (depBlock);
+					try {
+						let failed = false;
+						parser.inFunctionScope(true, [], () => {
+							for (const ee of dependenciesItems) {
+								if (ee.isString()) {
+									const ensureDependency = new RequireEnsureItemDependency(
+										/** @type {string} */ (ee.string)
+									);
+									ensureDependency.loc =
+										/** @type {DependencyLocation} */
+										(expr.loc);
+									depBlock.addDependency(ensureDependency);
+								} else {
+									failed = true;
+								}
+							}
+						});
+						if (failed) {
+							return;
+						}
+						if (successExpression) {
+							if (successExpression.fn.body.type === "BlockStatement") {
+								// Opt-out of Dead Control Flow detection for this block
+								const oldTerminated = parser.scope.terminated;
+								parser.walkStatement(successExpression.fn.body);
+								parser.scope.terminated = oldTerminated;
+							} else {
+								parser.walkExpression(successExpression.fn.body);
+							}
+						}
+						old.addBlock(depBlock);
+					} finally {
+						parser.state.current = old;
+					}
+					if (!successExpression) {
+						parser.walkExpression(successExpressionArg);
+					}
+					if (errorExpression) {
+						if (errorExpression.fn.body.type === "BlockStatement") {
+							parser.walkStatement(errorExpression.fn.body);
+						} else {
+							parser.walkExpression(errorExpression.fn.body);
+						}
+					} else if (errorExpressionArg) {
+						parser.walkExpression(errorExpressionArg);
+					}
+					return true;
+				}
+			}
+		});
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireEnsureDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,119 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class RequireEnsureDependency extends NullDependency {
+	/**
+	 * Creates an instance of RequireEnsureDependency.
+	 * @param {Range} range range
+	 * @param {Range} contentRange content range
+	 * @param {Range | false} errorHandlerRange error handler range
+	 */
+	constructor(range, contentRange, errorHandlerRange) {
+		super();
+
+		this.range = range;
+		this.contentRange = contentRange;
+		this.errorHandlerRange = errorHandlerRange;
+	}
+
+	get type() {
+		return "require.ensure";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.range);
+		write(this.contentRange);
+		write(this.errorHandlerRange);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.range = read();
+		this.contentRange = read();
+		this.errorHandlerRange = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	RequireEnsureDependency,
+	"webpack/lib/dependencies/RequireEnsureDependency"
+);
+
+RequireEnsureDependency.Template = class RequireEnsureDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(
+		dependency,
+		source,
+		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
+	) {
+		const dep = /** @type {RequireEnsureDependency} */ (dependency);
+		const depBlock = /** @type {AsyncDependenciesBlock} */ (
+			moduleGraph.getParentBlock(dep)
+		);
+		const promise = runtimeTemplate.blockPromise({
+			chunkGraph,
+			block: depBlock,
+			message: "require.ensure",
+			runtimeRequirements
+		});
+		const range = dep.range;
+		const contentRange = dep.contentRange;
+		const errorHandlerRange = dep.errorHandlerRange;
+		source.replace(range[0], contentRange[0] - 1, `${promise}.then((`);
+		if (errorHandlerRange) {
+			source.replace(
+				contentRange[1],
+				errorHandlerRange[0] - 1,
+				`).bind(null, ${RuntimeGlobals.require}))['catch'](`
+			);
+			source.replace(errorHandlerRange[1], range[1] - 1, ")");
+		} else {
+			source.replace(
+				contentRange[1],
+				range[1] - 1,
+				`).bind(null, ${RuntimeGlobals.require}))['catch'](${RuntimeGlobals.uncaughtErrorHandler})`
+			);
+		}
+	}
+};
+
+module.exports = RequireEnsureDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireEnsureItemDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireEnsureItemDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireEnsureItemDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const NullDependency = require("./NullDependency");
+
+class RequireEnsureItemDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of RequireEnsureItemDependency.
+	 * @param {string} request the request string
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "require.ensure item";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+}
+
+makeSerializable(
+	RequireEnsureItemDependency,
+	"webpack/lib/dependencies/RequireEnsureItemDependency"
+);
+
+RequireEnsureItemDependency.Template = NullDependency.Template;
+
+module.exports = RequireEnsureItemDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireEnsurePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireEnsurePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireEnsurePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,87 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const {
+	evaluateToString,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const RequireEnsureDependenciesBlockParserPlugin = require("./RequireEnsureDependenciesBlockParserPlugin");
+const RequireEnsureDependency = require("./RequireEnsureDependency");
+const RequireEnsureItemDependency = require("./RequireEnsureItemDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+const PLUGIN_NAME = "RequireEnsurePlugin";
+
+class RequireEnsurePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					RequireEnsureItemDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					RequireEnsureItemDependency,
+					new RequireEnsureItemDependency.Template()
+				);
+
+				compilation.dependencyTemplates.set(
+					RequireEnsureDependency,
+					new RequireEnsureDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (
+						parserOptions.requireEnsure !== undefined &&
+						!parserOptions.requireEnsure
+					) {
+						return;
+					}
+
+					new RequireEnsureDependenciesBlockParserPlugin().apply(parser);
+					parser.hooks.evaluateTypeof
+						.for("require.ensure")
+						.tap(PLUGIN_NAME, evaluateToString("function"));
+					parser.hooks.typeof
+						.for("require.ensure")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("function"))
+						);
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+module.exports = RequireEnsurePlugin;
Index: frontend/node_modules/webpack/lib/dependencies/RequireHeaderDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireHeaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireHeaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,74 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class RequireHeaderDependency extends NullDependency {
+	/**
+	 * Creates an instance of RequireHeaderDependency.
+	 * @param {Range} range range
+	 */
+	constructor(range) {
+		super();
+		if (!Array.isArray(range)) throw new Error("range must be valid");
+		this.range = range;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.range);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {RequireHeaderDependency} RequireHeaderDependency
+	 */
+	static deserialize(context) {
+		const obj = new RequireHeaderDependency(context.read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	RequireHeaderDependency,
+	"webpack/lib/dependencies/RequireHeaderDependency"
+);
+
+RequireHeaderDependency.Template = class RequireHeaderDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeRequirements }) {
+		const dep = /** @type {RequireHeaderDependency} */ (dependency);
+		runtimeRequirements.add(RuntimeGlobals.require);
+		source.replace(dep.range[0], dep.range[1] - 1, RuntimeGlobals.require);
+	}
+};
+
+module.exports = RequireHeaderDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireIncludeDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireIncludeDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireIncludeDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,81 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const Template = require("../Template");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class RequireIncludeDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of RequireIncludeDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super(request);
+
+		this.range = range;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		// This doesn't use any export
+		return Dependency.NO_EXPORTS_REFERENCED;
+	}
+
+	get type() {
+		return "require.include";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+}
+
+makeSerializable(
+	RequireIncludeDependency,
+	"webpack/lib/dependencies/RequireIncludeDependency"
+);
+
+RequireIncludeDependency.Template = class RequireIncludeDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeTemplate }) {
+		const dep = /** @type {RequireIncludeDependency} */ (dependency);
+		const comment = runtimeTemplate.outputOptions.pathinfo
+			? Template.toComment(
+					`require.include ${runtimeTemplate.requestShortener.shorten(
+						dep.request
+					)}`
+				)
+			: "";
+
+		source.replace(dep.range[0], dep.range[1] - 1, `undefined${comment}`);
+	}
+};
+
+module.exports = RequireIncludeDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireIncludeDependencyParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireIncludeDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireIncludeDependencyParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,103 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const {
+	evaluateToString,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const RequireIncludeDependency = require("./RequireIncludeDependency");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "RequireIncludeDependencyParserPlugin";
+
+module.exports = class RequireIncludeDependencyParserPlugin {
+	/**
+	 * Creates an instance of RequireIncludeDependencyParserPlugin.
+	 * @param {boolean} warn true: warn about deprecation, false: don't warn
+	 */
+	constructor(warn) {
+		this.warn = warn;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const { warn } = this;
+		parser.hooks.call.for("require.include").tap(PLUGIN_NAME, (expr) => {
+			if (expr.arguments.length !== 1) return;
+			const param = parser.evaluateExpression(expr.arguments[0]);
+			if (!param.isString()) return;
+
+			if (warn) {
+				parser.state.module.addWarning(
+					new RequireIncludeDeprecationWarning(
+						/** @type {DependencyLocation} */
+						(expr.loc)
+					)
+				);
+			}
+
+			const dep = new RequireIncludeDependency(
+				/** @type {string} */ (param.string),
+				/** @type {Range} */ (expr.range)
+			);
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			parser.state.current.addDependency(dep);
+			return true;
+		});
+		parser.hooks.evaluateTypeof
+			.for("require.include")
+			.tap(PLUGIN_NAME, (expr) => {
+				if (warn) {
+					parser.state.module.addWarning(
+						new RequireIncludeDeprecationWarning(
+							/** @type {DependencyLocation} */ (expr.loc)
+						)
+					);
+				}
+				return evaluateToString("function")(expr);
+			});
+		parser.hooks.typeof.for("require.include").tap(PLUGIN_NAME, (expr) => {
+			if (warn) {
+				parser.state.module.addWarning(
+					new RequireIncludeDeprecationWarning(
+						/** @type {DependencyLocation} */ (expr.loc)
+					)
+				);
+			}
+			return toConstantDependency(parser, JSON.stringify("function"))(expr);
+		});
+	}
+};
+
+class RequireIncludeDeprecationWarning extends WebpackError {
+	/**
+	 * Creates an instance of RequireIncludeDeprecationWarning.
+	 * @param {DependencyLocation} loc location
+	 */
+	constructor(loc) {
+		super("require.include() is deprecated and will be removed soon.");
+
+		this.name = "RequireIncludeDeprecationWarning";
+
+		this.loc = loc;
+	}
+}
+
+makeSerializable(
+	RequireIncludeDeprecationWarning,
+	"webpack/lib/dependencies/RequireIncludeDependencyParserPlugin",
+	"RequireIncludeDeprecationWarning"
+);
Index: frontend/node_modules/webpack/lib/dependencies/RequireIncludePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireIncludePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireIncludePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,64 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const RequireIncludeDependency = require("./RequireIncludeDependency");
+const RequireIncludeDependencyParserPlugin = require("./RequireIncludeDependencyParserPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+
+const PLUGIN_NAME = "RequireIncludePlugin";
+
+class RequireIncludePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					RequireIncludeDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					RequireIncludeDependency,
+					new RequireIncludeDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (parserOptions.requireInclude === false) return;
+					const warn = parserOptions.requireInclude === undefined;
+
+					new RequireIncludeDependencyParserPlugin(warn).apply(parser);
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+module.exports = RequireIncludePlugin;
Index: frontend/node_modules/webpack/lib/dependencies/RequireJsStuffPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireJsStuffPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireJsStuffPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const {
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const ConstDependency = require("./ConstDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+
+const PLUGIN_NAME = "RequireJsStuffPlugin";
+
+module.exports = class RequireJsStuffPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyTemplates.set(
+					ConstDependency,
+					new ConstDependency.Template()
+				);
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {JavascriptParserOptions} parserOptions options
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (
+						parserOptions.requireJs === undefined ||
+						!parserOptions.requireJs
+					) {
+						return;
+					}
+
+					parser.hooks.call
+						.for("require.config")
+						.tap(PLUGIN_NAME, toConstantDependency(parser, "undefined"));
+					parser.hooks.call
+						.for("requirejs.config")
+						.tap(PLUGIN_NAME, toConstantDependency(parser, "undefined"));
+
+					parser.hooks.expression
+						.for("require.version")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("0.0.0"))
+						);
+					parser.hooks.expression
+						.for("requirejs.onError")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(
+								parser,
+								RuntimeGlobals.uncaughtErrorHandler,
+								[RuntimeGlobals.uncaughtErrorHandler]
+							)
+						);
+				};
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/RequireResolveContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireResolveContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireResolveContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+const ContextDependencyTemplateAsId = require("./ContextDependencyTemplateAsId");
+
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
+
+class RequireResolveContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of RequireResolveContextDependency.
+	 * @param {ContextDependencyOptions} options options
+	 * @param {Range} range range
+	 * @param {Range} valueRange value range
+	 * @param {string=} context context
+	 */
+	constructor(options, range, valueRange, context) {
+		super(options, context);
+
+		this.range = range;
+		this.valueRange = valueRange;
+	}
+
+	get type() {
+		return "amd require context";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.range);
+		write(this.valueRange);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.range = read();
+		this.valueRange = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	RequireResolveContextDependency,
+	"webpack/lib/dependencies/RequireResolveContextDependency"
+);
+
+RequireResolveContextDependency.Template = ContextDependencyTemplateAsId;
+
+module.exports = RequireResolveContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireResolveDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireResolveDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireResolveDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,59 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+const ModuleDependencyAsId = require("./ModuleDependencyTemplateAsId");
+
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class RequireResolveDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of RequireResolveDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 * @param {string=} context context
+	 */
+	constructor(request, range, context) {
+		super(request);
+
+		this.range = range;
+		this._context = context;
+	}
+
+	get type() {
+		return "require.resolve";
+	}
+
+	get category() {
+		return "commonjs";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		// This doesn't use any export
+		return Dependency.NO_EXPORTS_REFERENCED;
+	}
+}
+
+makeSerializable(
+	RequireResolveDependency,
+	"webpack/lib/dependencies/RequireResolveDependency"
+);
+
+RequireResolveDependency.Template = ModuleDependencyAsId;
+
+module.exports = RequireResolveDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RequireResolveHeaderDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RequireResolveHeaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RequireResolveHeaderDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,86 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class RequireResolveHeaderDependency extends NullDependency {
+	/**
+	 * Creates an instance of RequireResolveHeaderDependency.
+	 * @param {Range} range range
+	 */
+	constructor(range) {
+		super();
+
+		if (!Array.isArray(range)) throw new Error("range must be valid");
+
+		this.range = range;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.range);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {RequireResolveHeaderDependency} RequireResolveHeaderDependency
+	 */
+	static deserialize(context) {
+		const obj = new RequireResolveHeaderDependency(context.read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	RequireResolveHeaderDependency,
+	"webpack/lib/dependencies/RequireResolveHeaderDependency"
+);
+
+RequireResolveHeaderDependency.Template = class RequireResolveHeaderDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const dep = /** @type {RequireResolveHeaderDependency} */ (dependency);
+		source.replace(dep.range[0], dep.range[1] - 1, "/*require.resolve*/");
+	}
+
+	/**
+	 * Apply as template argument.
+	 * @param {string} name name
+	 * @param {RequireResolveHeaderDependency} dep dependency
+	 * @param {ReplaceSource} source source
+	 */
+	applyAsTemplateArgument(name, dep, source) {
+		source.replace(dep.range[0], dep.range[1] - 1, "/*require.resolve*/");
+	}
+};
+
+module.exports = RequireResolveHeaderDependency;
Index: frontend/node_modules/webpack/lib/dependencies/RuntimeRequirementsDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/RuntimeRequirementsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/RuntimeRequirementsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,89 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("./NullDependency").RawRuntimeRequirements} RawRuntimeRequirements */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+class RuntimeRequirementsDependency extends NullDependency {
+	/**
+	 * Creates an instance of RuntimeRequirementsDependency.
+	 * @param {RawRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super();
+		this.runtimeRequirements = new Set(runtimeRequirements);
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			this._hashUpdate = `${[...this.runtimeRequirements].join()}`;
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.runtimeRequirements);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.runtimeRequirements = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	RuntimeRequirementsDependency,
+	"webpack/lib/dependencies/RuntimeRequirementsDependency"
+);
+
+RuntimeRequirementsDependency.Template = class RuntimeRequirementsDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeRequirements }) {
+		const dep = /** @type {RuntimeRequirementsDependency} */ (dependency);
+		for (const req of dep.runtimeRequirements) {
+			runtimeRequirements.add(req);
+		}
+	}
+};
+
+module.exports = RuntimeRequirementsDependency;
Index: frontend/node_modules/webpack/lib/dependencies/StaticExportsDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/StaticExportsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/StaticExportsDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {string[] | true} Exports */
+
+class StaticExportsDependency extends NullDependency {
+	/**
+	 * Creates an instance of StaticExportsDependency.
+	 * @param {Exports} exports export names
+	 * @param {boolean} canMangle true, if mangling exports names is allowed
+	 */
+	constructor(exports, canMangle) {
+		super();
+		this.exports = exports;
+		this.canMangle = canMangle;
+	}
+
+	get type() {
+		return "static exports";
+	}
+
+	/**
+	 * Returns the exported names
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {ExportsSpec | undefined} export names
+	 */
+	getExports(moduleGraph) {
+		return {
+			exports: this.exports,
+			canMangle: this.canMangle,
+			dependencies: undefined
+		};
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.exports);
+		write(this.canMangle);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.exports = read();
+		this.canMangle = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	StaticExportsDependency,
+	"webpack/lib/dependencies/StaticExportsDependency"
+);
+
+module.exports = StaticExportsDependency;
Index: frontend/node_modules/webpack/lib/dependencies/SystemPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/SystemPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/SystemPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,171 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const WebpackError = require("../errors/WebpackError");
+const {
+	evaluateToString,
+	expressionIsUnsupported,
+	toConstantDependency
+} = require("../javascript/JavascriptParserHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const ConstDependency = require("./ConstDependency");
+const SystemRuntimeModule = require("./SystemRuntimeModule");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "SystemPlugin";
+
+class SystemPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.hooks.runtimeRequirementInModule
+					.for(RuntimeGlobals.system)
+					.tap(PLUGIN_NAME, (module, set) => {
+						set.add(RuntimeGlobals.requireScope);
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.system)
+					.tap(PLUGIN_NAME, (chunk, _set) => {
+						compilation.addRuntimeModule(chunk, new SystemRuntimeModule());
+					});
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (parserOptions.system === undefined || !parserOptions.system) {
+						return;
+					}
+
+					/**
+					 * Sets not supported.
+					 * @param {string} name name
+					 */
+					const setNotSupported = (name) => {
+						parser.hooks.evaluateTypeof
+							.for(name)
+							.tap(PLUGIN_NAME, evaluateToString("undefined"));
+						parser.hooks.expression
+							.for(name)
+							.tap(
+								PLUGIN_NAME,
+								expressionIsUnsupported(
+									parser,
+									`${name} is not supported by webpack.`
+								)
+							);
+					};
+
+					parser.hooks.typeof
+						.for("System.import")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("function"))
+						);
+					parser.hooks.evaluateTypeof
+						.for("System.import")
+						.tap(PLUGIN_NAME, evaluateToString("function"));
+					parser.hooks.typeof
+						.for("System")
+						.tap(
+							PLUGIN_NAME,
+							toConstantDependency(parser, JSON.stringify("object"))
+						);
+					parser.hooks.evaluateTypeof
+						.for("System")
+						.tap(PLUGIN_NAME, evaluateToString("object"));
+
+					setNotSupported("System.set");
+					setNotSupported("System.get");
+					setNotSupported("System.register");
+
+					parser.hooks.expression.for("System").tap(PLUGIN_NAME, (expr) => {
+						const dep = new ConstDependency(
+							RuntimeGlobals.system,
+							/** @type {Range} */ (expr.range),
+							[RuntimeGlobals.system]
+						);
+						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+						parser.state.module.addPresentationalDependency(dep);
+						return true;
+					});
+
+					parser.hooks.call.for("System.import").tap(PLUGIN_NAME, (expr) => {
+						parser.state.module.addWarning(
+							new SystemImportDeprecationWarning(
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+
+						return parser.hooks.importCall.call({
+							type: "ImportExpression",
+							source:
+								/** @type {import("estree").Literal} */
+								(expr.arguments[0]),
+							loc: expr.loc,
+							range: expr.range,
+							options: null
+						});
+					});
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+class SystemImportDeprecationWarning extends WebpackError {
+	/**
+	 * Creates an instance of SystemImportDeprecationWarning.
+	 * @param {DependencyLocation} loc location
+	 */
+	constructor(loc) {
+		super(
+			"System.import() is deprecated and will be removed soon. Use import() instead.\n" +
+				"For more info visit https://webpack.js.org/guides/code-splitting/"
+		);
+
+		this.name = "SystemImportDeprecationWarning";
+
+		this.loc = loc;
+	}
+}
+
+makeSerializable(
+	SystemImportDeprecationWarning,
+	"webpack/lib/dependencies/SystemPlugin",
+	"SystemImportDeprecationWarning"
+);
+
+module.exports = SystemPlugin;
+module.exports.SystemImportDeprecationWarning = SystemImportDeprecationWarning;
Index: frontend/node_modules/webpack/lib/dependencies/SystemRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/SystemRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/SystemRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+class SystemRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("system");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return Template.asString([
+			`${RuntimeGlobals.system} = {`,
+			Template.indent([
+				"import: function () {",
+				Template.indent(
+					"throw new Error('System.import cannot be used indirectly');"
+				),
+				"}"
+			]),
+			"};"
+		]);
+	}
+}
+
+module.exports = SystemRuntimeModule;
Index: frontend/node_modules/webpack/lib/dependencies/URLContextDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/URLContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/URLContextDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,68 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Haijie Xie @hai-x
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const ContextDependency = require("./ContextDependency");
+const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");
+
+/** @typedef {import("../ContextModule").ContextOptions} ContextOptions */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */
+
+class URLContextDependency extends ContextDependency {
+	/**
+	 * Creates an instance of URLContextDependency.
+	 * @param {ContextDependencyOptions} options options
+	 * @param {Range} range range
+	 * @param {Range} valueRange value range
+	 */
+	constructor(options, range, valueRange) {
+		super(options);
+		this.range = range;
+		this.valueRange = valueRange;
+	}
+
+	get type() {
+		return "new URL() context";
+	}
+
+	get category() {
+		return "url";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.valueRange);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.valueRange = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	URLContextDependency,
+	"webpack/lib/dependencies/URLContextDependency"
+);
+
+URLContextDependency.Template = ContextDependencyTemplateAsRequireCall;
+
+module.exports = URLContextDependency;
Index: frontend/node_modules/webpack/lib/dependencies/URLDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/URLDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/URLDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,171 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RawDataUrlModule = require("../asset/RawDataUrlModule");
+const {
+	getDependencyUsedByExportsCondition
+} = require("../optimize/InnerGraph");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../optimize/InnerGraph").UsedByExports} UsedByExports */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+const getIgnoredRawDataUrlModule = memoize(
+	() => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)")
+);
+
+class URLDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of URLDependency.
+	 * @param {string} request request
+	 * @param {Range} range range of the arguments of new URL( |> ... <| )
+	 * @param {Range} outerRange range of the full |> new URL(...) <|
+	 * @param {boolean=} relative use relative urls instead of absolute with base uri
+	 */
+	constructor(request, range, outerRange, relative) {
+		super(request);
+		this.range = range;
+		this.outerRange = outerRange;
+		this.relative = relative || false;
+		/** @type {UsedByExports | undefined} */
+		this.usedByExports = undefined;
+	}
+
+	get type() {
+		return "new URL()";
+	}
+
+	get category() {
+		return "url";
+	}
+
+	/**
+	 * Returns function to determine if the connection is active.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active
+	 */
+	getCondition(moduleGraph) {
+		return getDependencyUsedByExportsCondition(
+			this,
+			this.usedByExports,
+			moduleGraph
+		);
+	}
+
+	/**
+	 * Creates an ignored module.
+	 * @param {string} context context directory
+	 * @returns {Module} ignored module
+	 */
+	createIgnoredModule(context) {
+		return getIgnoredRawDataUrlModule();
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.outerRange);
+		write(this.relative);
+		write(this.usedByExports);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.outerRange = read();
+		this.relative = read();
+		this.usedByExports = read();
+		super.deserialize(context);
+	}
+}
+
+URLDependency.Template = class URLDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const {
+			chunkGraph,
+			moduleGraph,
+			runtimeRequirements,
+			runtimeTemplate,
+			runtime
+		} = templateContext;
+		const dep = /** @type {URLDependency} */ (dependency);
+		const connection = moduleGraph.getConnection(dep);
+		// Skip rendering depending when dependency is conditional
+		if (connection && !connection.isTargetActive(runtime)) {
+			source.replace(
+				dep.outerRange[0],
+				dep.outerRange[1] - 1,
+				"/* unused asset import */ undefined"
+			);
+			return;
+		}
+
+		runtimeRequirements.add(RuntimeGlobals.require);
+
+		if (dep.relative) {
+			runtimeRequirements.add(RuntimeGlobals.relativeUrl);
+			source.replace(
+				dep.outerRange[0],
+				dep.outerRange[1] - 1,
+				`/* asset import */ new ${
+					RuntimeGlobals.relativeUrl
+				}(${runtimeTemplate.moduleRaw({
+					chunkGraph,
+					module: moduleGraph.getModule(dep),
+					request: dep.request,
+					runtimeRequirements,
+					weak: false
+				})})`
+			);
+		} else {
+			runtimeRequirements.add(RuntimeGlobals.baseURI);
+
+			source.replace(
+				dep.range[0],
+				dep.range[1] - 1,
+				`/* asset import */ ${runtimeTemplate.moduleRaw({
+					chunkGraph,
+					module: moduleGraph.getModule(dep),
+					request: dep.request,
+					runtimeRequirements,
+					weak: false
+				})}, ${RuntimeGlobals.baseURI}`
+			);
+		}
+	}
+};
+
+makeSerializable(URLDependency, "webpack/lib/dependencies/URLDependency");
+
+module.exports = URLDependency;
Index: frontend/node_modules/webpack/lib/dependencies/URLPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/URLPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/URLPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,69 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+
+const URLContextDependency = require("../dependencies/URLContextDependency");
+const URLDependency = require("../dependencies/URLDependency");
+const URLParserPlugin = require("../url/URLParserPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+
+const PLUGIN_NAME = "URLPlugin";
+
+class URLPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler compiler
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory, contextModuleFactory }) => {
+				compilation.dependencyFactories.set(URLDependency, normalModuleFactory);
+				compilation.dependencyTemplates.set(
+					URLDependency,
+					new URLDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					URLContextDependency,
+					contextModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					URLContextDependency,
+					new URLContextDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					if (parserOptions.url === false) return;
+					new URLParserPlugin(parserOptions).apply(parser);
+				};
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, handler);
+			}
+		);
+	}
+}
+
+module.exports = URLPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/UnsupportedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/UnsupportedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/UnsupportedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,86 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const NullDependency = require("./NullDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class UnsupportedDependency extends NullDependency {
+	/**
+	 * Creates an instance of UnsupportedDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super();
+
+		this.request = request;
+		this.range = range;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.request);
+		write(this.range);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.request = read();
+		this.range = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	UnsupportedDependency,
+	"webpack/lib/dependencies/UnsupportedDependency"
+);
+
+UnsupportedDependency.Template = class UnsupportedDependencyTemplate extends (
+	NullDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeTemplate }) {
+		const dep = /** @type {UnsupportedDependency} */ (dependency);
+
+		source.replace(
+			dep.range[0],
+			dep.range[1],
+			runtimeTemplate.missingModule({
+				request: dep.request
+			})
+		);
+	}
+};
+
+module.exports = UnsupportedDependency;
Index: frontend/node_modules/webpack/lib/dependencies/WebAssemblyExportImportedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/WebAssemblyExportImportedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/WebAssemblyExportImportedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,97 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class WebAssemblyExportImportedDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of WebAssemblyExportImportedDependency.
+	 * @param {string} exportName export name
+	 * @param {string} request request
+	 * @param {string} name name
+	 * @param {string} valueType value type
+	 */
+	constructor(exportName, request, name, valueType) {
+		super(request);
+		/** @type {string} */
+		this.exportName = exportName;
+		/** @type {string} */
+		this.name = name;
+		/** @type {string} */
+		this.valueType = valueType;
+	}
+
+	/**
+	 * Could affect referencing module.
+	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
+	 */
+	couldAffectReferencingModule() {
+		return Dependency.TRANSITIVE;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return [[this.name]];
+	}
+
+	get type() {
+		return "wasm export import";
+	}
+
+	get category() {
+		return "wasm";
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.exportName);
+		write(this.name);
+		write(this.valueType);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.exportName = read();
+		this.name = read();
+		this.valueType = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	WebAssemblyExportImportedDependency,
+	"webpack/lib/dependencies/WebAssemblyExportImportedDependency"
+);
+
+module.exports = WebAssemblyExportImportedDependency;
Index: frontend/node_modules/webpack/lib/dependencies/WebAssemblyImportDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/WebAssemblyImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/WebAssemblyImportDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,111 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const UnsupportedWebAssemblyFeatureError = require("../wasm-sync/UnsupportedWebAssemblyFeatureError");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("@webassemblyjs/ast").ModuleImportDescription} ModuleImportDescription */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class WebAssemblyImportDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of WebAssemblyImportDependency.
+	 * @param {string} request the request
+	 * @param {string} name the imported name
+	 * @param {ModuleImportDescription} description the WASM ast node
+	 * @param {false | string} onlyDirectImport if only direct imports are allowed
+	 */
+	constructor(request, name, description, onlyDirectImport) {
+		super(request);
+		/** @type {string} */
+		this.name = name;
+		/** @type {ModuleImportDescription} */
+		this.description = description;
+		/** @type {false | string} */
+		this.onlyDirectImport = onlyDirectImport;
+	}
+
+	get type() {
+		return "wasm import";
+	}
+
+	get category() {
+		return "wasm";
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return [[this.name]];
+	}
+
+	/**
+	 * Returns errors.
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @returns {WebpackError[] | null | undefined} errors
+	 */
+	getErrors(moduleGraph) {
+		const module = moduleGraph.getModule(this);
+
+		if (
+			this.onlyDirectImport &&
+			module &&
+			!module.type.startsWith("webassembly")
+		) {
+			return [
+				new UnsupportedWebAssemblyFeatureError(
+					`Import "${this.name}" from "${this.request}" with ${this.onlyDirectImport} can only be used for direct wasm to wasm dependencies`
+				)
+			];
+		}
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.name);
+		write(this.description);
+		write(this.onlyDirectImport);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.name = read();
+		this.description = read();
+		this.onlyDirectImport = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	WebAssemblyImportDependency,
+	"webpack/lib/dependencies/WebAssemblyImportDependency"
+);
+
+module.exports = WebAssemblyImportDependency;
Index: frontend/node_modules/webpack/lib/dependencies/WebpackIsIncludedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/WebpackIsIncludedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/WebpackIsIncludedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,86 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const Template = require("../Template");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+class WebpackIsIncludedDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of WebpackIsIncludedDependency.
+	 * @param {string} request the request string
+	 * @param {Range} range location in source code
+	 */
+	constructor(request, range) {
+		super(request);
+
+		this.weak = true;
+		this.range = range;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		// This doesn't use any export
+		return Dependency.NO_EXPORTS_REFERENCED;
+	}
+
+	get type() {
+		return "__webpack_is_included__";
+	}
+}
+
+makeSerializable(
+	WebpackIsIncludedDependency,
+	"webpack/lib/dependencies/WebpackIsIncludedDependency"
+);
+
+WebpackIsIncludedDependency.Template = class WebpackIsIncludedDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, { runtimeTemplate, chunkGraph, moduleGraph }) {
+		const dep = /** @type {WebpackIsIncludedDependency} */ (dependency);
+		const connection = moduleGraph.getConnection(dep);
+		const included = connection
+			? chunkGraph.getNumberOfModuleChunks(connection.module) > 0
+			: false;
+		const comment = runtimeTemplate.outputOptions.pathinfo
+			? Template.toComment(
+					`__webpack_is_included__ ${runtimeTemplate.requestShortener.shorten(
+						dep.request
+					)}`
+				)
+			: "";
+
+		source.replace(
+			dep.range[0],
+			dep.range[1] - 1,
+			`${comment}${JSON.stringify(included)}`
+		);
+	}
+};
+
+module.exports = WebpackIsIncludedDependency;
Index: frontend/node_modules/webpack/lib/dependencies/WorkerDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/WorkerDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/WorkerDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,146 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const ModuleDependency = require("./ModuleDependency");
+
+/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
+/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */
+/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Represents the worker dependency runtime component.
+ * @typedef {object} WorkerDependencyOptions
+ * @property {string=} publicPath public path for the worker
+ * @property {boolean=} needNewUrl true when need generate `new URL(...)`, otherwise false
+ */
+
+class WorkerDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of WorkerDependency.
+	 * @param {string} request request
+	 * @param {Range} range range
+	 * @param {WorkerDependencyOptions} workerDependencyOptions options
+	 */
+	constructor(request, range, workerDependencyOptions) {
+		super(request);
+		this.range = range;
+		// If options are updated, don't forget to update the hash and serialization functions
+		/** @type {WorkerDependencyOptions} */
+		this.options = workerDependencyOptions;
+		/** Cache the hash */
+		/** @type {undefined | string} */
+		this._hashUpdate = undefined;
+	}
+
+	/**
+	 * Returns list of exports referenced by this dependency
+	 * @param {ModuleGraph} moduleGraph module graph
+	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
+	 * @returns {ReferencedExports} referenced exports
+	 */
+	getReferencedExports(moduleGraph, runtime) {
+		return Dependency.NO_EXPORTS_REFERENCED;
+	}
+
+	get type() {
+		return "new Worker()";
+	}
+
+	get category() {
+		return "worker";
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		if (this._hashUpdate === undefined) {
+			this._hashUpdate = JSON.stringify(this.options);
+		}
+		hash.update(this._hashUpdate);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.options);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.options = read();
+		super.deserialize(context);
+	}
+}
+
+WorkerDependency.Template = class WorkerDependencyTemplate extends (
+	ModuleDependency.Template
+) {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Dependency} dependency the dependency for which the template should be applied
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {DependencyTemplateContext} templateContext the context object
+	 * @returns {void}
+	 */
+	apply(dependency, source, templateContext) {
+		const { chunkGraph, moduleGraph, runtimeRequirements } = templateContext;
+		const dep = /** @type {WorkerDependency} */ (dependency);
+		const block = /** @type {AsyncDependenciesBlock} */ (
+			moduleGraph.getParentBlock(dependency)
+		);
+		const entrypoint = /** @type {Entrypoint} */ (
+			chunkGraph.getBlockChunkGroup(block)
+		);
+		const chunk = entrypoint.getEntrypointChunk();
+		// We use the workerPublicPath option if provided, else we fallback to the RuntimeGlobal publicPath
+		const workerImportBaseUrl = dep.options.publicPath
+			? `"${dep.options.publicPath}"`
+			: RuntimeGlobals.publicPath;
+
+		runtimeRequirements.add(RuntimeGlobals.publicPath);
+		runtimeRequirements.add(RuntimeGlobals.baseURI);
+		runtimeRequirements.add(RuntimeGlobals.getChunkScriptFilename);
+
+		const workerImportStr = `/* worker import */ ${workerImportBaseUrl} + ${
+			RuntimeGlobals.getChunkScriptFilename
+		}(${JSON.stringify(chunk.id)}), ${RuntimeGlobals.baseURI}`;
+
+		source.replace(
+			dep.range[0],
+			dep.range[1] - 1,
+			dep.options.needNewUrl ? `new URL(${workerImportStr})` : workerImportStr
+		);
+	}
+};
+
+makeSerializable(WorkerDependency, "webpack/lib/dependencies/WorkerDependency");
+
+module.exports = WorkerDependency;
Index: frontend/node_modules/webpack/lib/dependencies/WorkerPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/WorkerPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/WorkerPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,573 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { pathToFileURL } = require("url");
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
+const { equals } = require("../util/ArrayHelpers");
+const createHash = require("../util/createHash");
+const { contextify } = require("../util/identifier");
+const EnableWasmLoadingPlugin = require("../wasm/EnableWasmLoadingPlugin");
+const ConstDependency = require("./ConstDependency");
+const CreateScriptUrlDependency = require("./CreateScriptUrlDependency");
+const {
+	harmonySpecifierTag
+} = require("./HarmonyImportDependencyParserPlugin");
+const WorkerDependency = require("./WorkerDependency");
+
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").MemberExpression} MemberExpression */
+/** @typedef {import("estree").ObjectExpression} ObjectExpression */
+/** @typedef {import("estree").Pattern} Pattern */
+/** @typedef {import("estree").Property} Property */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+/** @typedef {import("../../declarations/WebpackOptions").ChunkLoading} ChunkLoading */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../../declarations/WebpackOptions").OutputModule} OutputModule */
+/** @typedef {import("../../declarations/WebpackOptions").WasmLoading} WasmLoading */
+/** @typedef {import("../../declarations/WebpackOptions").WorkerPublicPath} WorkerPublicPath */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser")} Parser */
+/** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
+
+/**
+ * Returns url.
+ * @param {NormalModule} module module
+ * @returns {string} url
+ */
+const getUrl = (module) => pathToFileURL(module.resource).toString();
+
+const WorkerSpecifierTag = Symbol("worker specifier tag");
+
+const DEFAULT_SYNTAX = [
+	"Worker",
+	"SharedWorker",
+	"navigator.serviceWorker.register()",
+	"Worker from worker_threads"
+];
+
+/** @type {WeakMap<JavascriptParserState, number>} */
+const workerIndexMap = new WeakMap();
+
+const PLUGIN_NAME = "WorkerPlugin";
+
+class WorkerPlugin {
+	/**
+	 * Creates an instance of WorkerPlugin.
+	 * @param {ChunkLoading=} chunkLoading chunk loading
+	 * @param {WasmLoading=} wasmLoading wasm loading
+	 * @param {OutputModule=} module output module
+	 * @param {WorkerPublicPath=} workerPublicPath worker public path
+	 */
+	constructor(chunkLoading, wasmLoading, module, workerPublicPath) {
+		this._chunkLoading = chunkLoading;
+		this._wasmLoading = wasmLoading;
+		this._module = module;
+		this._workerPublicPath = workerPublicPath;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		if (this._chunkLoading) {
+			new EnableChunkLoadingPlugin(this._chunkLoading).apply(compiler);
+		}
+		if (this._wasmLoading) {
+			new EnableWasmLoadingPlugin(this._wasmLoading).apply(compiler);
+		}
+		const cachedContextify = contextify.bindContextCache(
+			compiler.context,
+			compiler.root
+		);
+		compiler.hooks.thisCompilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					WorkerDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					WorkerDependency,
+					new WorkerDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					CreateScriptUrlDependency,
+					new CreateScriptUrlDependency.Template()
+				);
+
+				/**
+				 * Returns parsed.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {Expression} expr expression
+				 * @returns {[string, Range] | void} parsed
+				 */
+				const parseModuleUrl = (parser, expr) => {
+					if (expr.type !== "NewExpression" || expr.callee.type === "Super") {
+						return;
+					}
+					if (
+						expr.arguments.length === 1 &&
+						expr.arguments[0].type === "MemberExpression" &&
+						isMetaUrl(parser, expr.arguments[0])
+					) {
+						const arg1 = expr.arguments[0];
+						return [
+							getUrl(parser.state.module),
+							[
+								/** @type {Range} */ (arg1.range)[0],
+								/** @type {Range} */ (arg1.range)[1]
+							]
+						];
+					} else if (expr.arguments.length === 2) {
+						const [arg1, arg2] = expr.arguments;
+						if (arg1.type === "SpreadElement") return;
+						if (arg2.type === "SpreadElement") return;
+						const callee = parser.evaluateExpression(expr.callee);
+						if (!callee.isIdentifier() || callee.identifier !== "URL") return;
+						const arg2Value = parser.evaluateExpression(arg2);
+						if (
+							!arg2Value.isString() ||
+							!(
+								/** @type {string} */ (arg2Value.string).startsWith("file://")
+							) ||
+							arg2Value.string !== getUrl(parser.state.module)
+						) {
+							return;
+						}
+						const arg1Value = parser.evaluateExpression(arg1);
+						if (!arg1Value.isString()) return;
+						return [
+							/** @type {string} */ (arg1Value.string),
+							[
+								/** @type {Range} */ (arg1.range)[0],
+								/** @type {Range} */ (arg2.range)[1]
+							]
+						];
+					}
+				};
+
+				/**
+				 * Checks whether this worker plugin is meta url.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {MemberExpression} expr expression
+				 * @returns {boolean} is `import.meta.url`
+				 */
+				const isMetaUrl = (parser, expr) => {
+					const chain = parser.extractMemberExpressionChain(expr);
+
+					if (
+						chain.members.length !== 1 ||
+						chain.object.type !== "MetaProperty" ||
+						chain.object.meta.name !== "import" ||
+						chain.object.property.name !== "meta" ||
+						chain.members[0] !== "url"
+					) {
+						return false;
+					}
+
+					return true;
+				};
+
+				/** @typedef {Record<string, EXPECTED_ANY>} Values */
+
+				/**
+				 * Parses object expression.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {ObjectExpression} expr expression
+				 * @returns {{ expressions: Record<string, Expression | Pattern>, otherElements: (Property | SpreadElement)[], values: Values, spread: boolean, insertType: "comma" | "single", insertLocation: number }} parsed object
+				 */
+				const parseObjectExpression = (parser, expr) => {
+					/** @type {Values} */
+					const values = {};
+					/** @type {Record<string, Expression | Pattern>} */
+					const expressions = {};
+					/** @type {(Property | SpreadElement)[]} */
+					const otherElements = [];
+					let spread = false;
+					for (const prop of expr.properties) {
+						if (prop.type === "SpreadElement") {
+							spread = true;
+						} else if (
+							prop.type === "Property" &&
+							!prop.method &&
+							!prop.computed &&
+							prop.key.type === "Identifier"
+						) {
+							expressions[prop.key.name] = prop.value;
+							if (!prop.shorthand && !prop.value.type.endsWith("Pattern")) {
+								const value = parser.evaluateExpression(
+									/** @type {Expression} */
+									(prop.value)
+								);
+								if (value.isCompileTimeValue()) {
+									values[prop.key.name] = value.asCompileTimeValue();
+								}
+							}
+						} else {
+							otherElements.push(prop);
+						}
+					}
+					const insertType = expr.properties.length > 0 ? "comma" : "single";
+					const insertLocation = /** @type {Range} */ (
+						expr.properties[expr.properties.length - 1].range
+					)[1];
+					return {
+						expressions,
+						otherElements,
+						values,
+						spread,
+						insertType,
+						insertLocation
+					};
+				};
+
+				/**
+				 * Processes the provided parser.
+				 * @param {Parser} parser parser parser
+				 * @param {JavascriptParserOptions} parserOptions parserOptions
+				 * @returns {void}
+				 */
+				const parserPlugin = (parser, parserOptions) => {
+					if (parserOptions.worker === false) return;
+					const options = !Array.isArray(parserOptions.worker)
+						? ["..."]
+						: parserOptions.worker;
+					/**
+					 * Returns true when handled.
+					 * @param {CallExpression} expr expression
+					 * @returns {boolean | void} true when handled
+					 */
+					const handleNewWorker = (expr) => {
+						if (expr.arguments.length === 0 || expr.arguments.length > 2) {
+							return;
+						}
+						const [arg1, arg2] = expr.arguments;
+						if (arg1.type === "SpreadElement") return;
+						if (arg2 && arg2.type === "SpreadElement") return;
+
+						/** @type {string} */
+						let url;
+						/** @type {Range} */
+						let range;
+						/** @type {boolean} */
+						let needNewUrl = false;
+
+						if (arg1.type === "MemberExpression" && isMetaUrl(parser, arg1)) {
+							url = getUrl(parser.state.module);
+							range = [
+								/** @type {Range} */ (arg1.range)[0],
+								/** @type {Range} */ (arg1.range)[1]
+							];
+							needNewUrl = true;
+						} else {
+							const parsedUrl = parseModuleUrl(parser, arg1);
+							if (!parsedUrl) return;
+							[url, range] = parsedUrl;
+						}
+
+						const {
+							expressions,
+							otherElements,
+							values: options,
+							spread: hasSpreadInOptions,
+							insertType,
+							insertLocation
+						} = arg2 && arg2.type === "ObjectExpression"
+							? parseObjectExpression(parser, arg2)
+							: {
+									expressions:
+										/** @type {Record<string, Expression | Pattern>} */ ({}),
+									otherElements: [],
+									/** @type {Values} */
+									values: {},
+									spread: false,
+									insertType: arg2 ? "spread" : "argument",
+									insertLocation: arg2
+										? /** @type {Range} */ (arg2.range)
+										: /** @type {Range} */ (arg1.range)[1]
+								};
+						const { options: importOptions, errors: commentErrors } =
+							parser.parseCommentOptions(/** @type {Range} */ (expr.range));
+
+						if (commentErrors) {
+							for (const e of commentErrors) {
+								const { comment } = e;
+								parser.state.module.addWarning(
+									new CommentCompilationWarning(
+										`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+										/** @type {DependencyLocation} */ (comment.loc)
+									)
+								);
+							}
+						}
+
+						/** @type {EntryOptions} */
+						const entryOptions = {};
+
+						if (importOptions) {
+							if (importOptions.webpackIgnore !== undefined) {
+								if (typeof importOptions.webpackIgnore !== "boolean") {
+									parser.state.module.addWarning(
+										new UnsupportedFeatureWarning(
+											`\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`,
+											/** @type {DependencyLocation} */ (expr.loc)
+										)
+									);
+								} else if (importOptions.webpackIgnore) {
+									return false;
+								}
+							}
+							if (importOptions.webpackEntryOptions !== undefined) {
+								if (
+									typeof importOptions.webpackEntryOptions !== "object" ||
+									importOptions.webpackEntryOptions === null
+								) {
+									parser.state.module.addWarning(
+										new UnsupportedFeatureWarning(
+											`\`webpackEntryOptions\` expected a object, but received: ${importOptions.webpackEntryOptions}.`,
+											/** @type {DependencyLocation} */ (expr.loc)
+										)
+									);
+								} else {
+									Object.assign(
+										entryOptions,
+										importOptions.webpackEntryOptions
+									);
+								}
+							}
+							if (importOptions.webpackChunkName !== undefined) {
+								if (typeof importOptions.webpackChunkName !== "string") {
+									parser.state.module.addWarning(
+										new UnsupportedFeatureWarning(
+											`\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`,
+											/** @type {DependencyLocation} */ (expr.loc)
+										)
+									);
+								} else {
+									entryOptions.name = importOptions.webpackChunkName;
+								}
+							}
+						}
+
+						if (
+							!Object.prototype.hasOwnProperty.call(entryOptions, "name") &&
+							options &&
+							typeof options.name === "string"
+						) {
+							entryOptions.name = options.name;
+						}
+
+						if (entryOptions.runtime === undefined) {
+							const i = workerIndexMap.get(parser.state) || 0;
+							workerIndexMap.set(parser.state, i + 1);
+							const name = `${cachedContextify(
+								parser.state.module.identifier()
+							)}|${i}`;
+							const hash = createHash(compilation.outputOptions.hashFunction);
+							hash.update(name);
+							const digest = hash.digest(compilation.outputOptions.hashDigest);
+							entryOptions.runtime = digest.slice(
+								0,
+								compilation.outputOptions.hashDigestLength
+							);
+						}
+
+						const block = new AsyncDependenciesBlock({
+							name: entryOptions.name,
+							circular: false,
+							entryOptions: {
+								chunkLoading: this._chunkLoading,
+								wasmLoading: this._wasmLoading,
+								...entryOptions
+							}
+						});
+						block.loc = expr.loc;
+						const dep = new WorkerDependency(url, range, {
+							publicPath: this._workerPublicPath,
+							needNewUrl
+						});
+						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+						block.addDependency(dep);
+						parser.state.module.addBlock(block);
+
+						if (compilation.outputOptions.trustedTypes) {
+							const dep = new CreateScriptUrlDependency(
+								/** @type {Range} */ (expr.arguments[0].range)
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addDependency(dep);
+						}
+
+						if (expressions.type) {
+							const expr = expressions.type;
+							if (options.type !== false) {
+								const dep = new ConstDependency(
+									this._module ? '"module"' : "undefined",
+									/** @type {Range} */ (expr.range)
+								);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+								/** @type {EXPECTED_ANY} */
+								(expressions).type = undefined;
+							}
+						} else if (insertType === "comma") {
+							if (this._module || hasSpreadInOptions) {
+								const dep = new ConstDependency(
+									`, type: ${this._module ? '"module"' : "undefined"}`,
+									insertLocation
+								);
+								dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+								parser.state.module.addPresentationalDependency(dep);
+							}
+						} else if (insertType === "spread") {
+							const dep1 = new ConstDependency(
+								"Object.assign({}, ",
+								/** @type {Range} */ (insertLocation)[0]
+							);
+							const dep2 = new ConstDependency(
+								`, { type: ${this._module ? '"module"' : "undefined"} })`,
+								/** @type {Range} */ (insertLocation)[1]
+							);
+							dep1.loc = /** @type {DependencyLocation} */ (expr.loc);
+							dep2.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep1);
+							parser.state.module.addPresentationalDependency(dep2);
+						} else if (insertType === "argument" && this._module) {
+							const dep = new ConstDependency(
+								', { type: "module" }',
+								insertLocation
+							);
+							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+							parser.state.module.addPresentationalDependency(dep);
+						}
+
+						parser.walkExpression(expr.callee);
+						for (const key of Object.keys(expressions)) {
+							if (expressions[key]) {
+								if (expressions[key].type.endsWith("Pattern")) continue;
+								parser.walkExpression(
+									/** @type {Expression} */
+									(expressions[key])
+								);
+							}
+						}
+						for (const prop of otherElements) {
+							parser.walkProperty(prop);
+						}
+						if (insertType === "spread") {
+							parser.walkExpression(arg2);
+						}
+
+						return true;
+					};
+					/**
+					 * Processes the provided item.
+					 * @param {string} item item
+					 */
+					const processItem = (item) => {
+						if (
+							item.startsWith("*") &&
+							item.includes(".") &&
+							item.endsWith("()")
+						) {
+							const firstDot = item.indexOf(".");
+							const pattern = item.slice(1, firstDot);
+							const itemMembers = item.slice(firstDot + 1, -2);
+
+							parser.hooks.preDeclarator.tap(
+								PLUGIN_NAME,
+								(decl, _statement) => {
+									if (
+										decl.id.type === "Identifier" &&
+										decl.id.name === pattern
+									) {
+										parser.tagVariable(decl.id.name, WorkerSpecifierTag);
+										return true;
+									}
+								}
+							);
+							parser.hooks.pattern.for(pattern).tap(PLUGIN_NAME, (pattern) => {
+								parser.tagVariable(pattern.name, WorkerSpecifierTag);
+								return true;
+							});
+							parser.hooks.callMemberChain
+								.for(WorkerSpecifierTag)
+								.tap(PLUGIN_NAME, (expression, members) => {
+									if (itemMembers !== members.join(".")) {
+										return;
+									}
+
+									return handleNewWorker(expression);
+								});
+						} else if (item.endsWith("()")) {
+							parser.hooks.call
+								.for(item.slice(0, -2))
+								.tap(PLUGIN_NAME, handleNewWorker);
+						} else {
+							const match = /^(.+?)(\(\))?\s+from\s+(.+)$/.exec(item);
+							if (match) {
+								const ids = match[1].split(".");
+								const call = match[2];
+								const source = match[3];
+								(call ? parser.hooks.call : parser.hooks.new)
+									.for(harmonySpecifierTag)
+									.tap(PLUGIN_NAME, (expr) => {
+										const settings = /** @type {HarmonySettings} */ (
+											parser.currentTagData
+										);
+										if (
+											!settings ||
+											settings.source !== source ||
+											!equals(settings.ids, ids)
+										) {
+											return;
+										}
+										return handleNewWorker(expr);
+									});
+							} else {
+								parser.hooks.new.for(item).tap(PLUGIN_NAME, handleNewWorker);
+							}
+						}
+					};
+					for (const item of options) {
+						if (item === "...") {
+							for (const itemFromDefault of DEFAULT_SYNTAX) {
+								processItem(itemFromDefault);
+							}
+						} else {
+							processItem(item);
+						}
+					}
+				};
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, parserPlugin);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, parserPlugin);
+			}
+		);
+	}
+}
+
+module.exports = WorkerPlugin;
Index: frontend/node_modules/webpack/lib/dependencies/getFunctionExpression.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/getFunctionExpression.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/getFunctionExpression.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,67 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").FunctionExpression} FunctionExpression */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+
+/** @typedef {{ fn: FunctionExpression | ArrowFunctionExpression, expressions: (Expression | SpreadElement)[], needThis: boolean | undefined }} FunctionExpressionResult */
+
+/**
+ * Returns function expression with additional information.
+ * @param {Expression | SpreadElement} expr expressions
+ * @returns {FunctionExpressionResult | undefined} function expression with additional information
+ */
+module.exports = (expr) => {
+	// <FunctionExpression>
+	if (
+		expr.type === "FunctionExpression" ||
+		expr.type === "ArrowFunctionExpression"
+	) {
+		return {
+			fn: expr,
+			expressions: [],
+			needThis: false
+		};
+	}
+
+	// <FunctionExpression>.bind(<Expression>)
+	if (
+		expr.type === "CallExpression" &&
+		expr.callee.type === "MemberExpression" &&
+		expr.callee.object.type === "FunctionExpression" &&
+		expr.callee.property.type === "Identifier" &&
+		expr.callee.property.name === "bind" &&
+		expr.arguments.length === 1
+	) {
+		return {
+			fn: expr.callee.object,
+			expressions: [expr.arguments[0]],
+			needThis: undefined
+		};
+	}
+	// (function(_this) {return <FunctionExpression>})(this) (Coffeescript)
+	if (
+		expr.type === "CallExpression" &&
+		expr.callee.type === "FunctionExpression" &&
+		expr.callee.body.type === "BlockStatement" &&
+		expr.arguments.length === 1 &&
+		expr.arguments[0].type === "ThisExpression" &&
+		expr.callee.body.body &&
+		expr.callee.body.body.length === 1 &&
+		expr.callee.body.body[0].type === "ReturnStatement" &&
+		expr.callee.body.body[0].argument &&
+		expr.callee.body.body[0].argument.type === "FunctionExpression"
+	) {
+		return {
+			fn: expr.callee.body.body[0].argument,
+			expressions: [],
+			needThis: true
+		};
+	}
+};
Index: frontend/node_modules/webpack/lib/dependencies/processExportInfo.js
===================================================================
--- frontend/node_modules/webpack/lib/dependencies/processExportInfo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dependencies/processExportInfo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,68 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+
+/** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
+/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * Process export info.
+ * @param {RuntimeSpec} runtime the runtime
+ * @param {RawReferencedExports} referencedExports list of referenced exports, will be added to
+ * @param {string[]} prefix export prefix
+ * @param {ExportInfo=} exportInfo the export info
+ * @param {boolean} defaultPointsToSelf when true, using default will reference itself
+ * @param {Set<ExportInfo>} alreadyVisited already visited export info (to handle circular reexports)
+ */
+const processExportInfo = (
+	runtime,
+	referencedExports,
+	prefix,
+	exportInfo,
+	defaultPointsToSelf = false,
+	alreadyVisited = new Set()
+) => {
+	if (!exportInfo) {
+		referencedExports.push(prefix);
+		return;
+	}
+	const used = exportInfo.getUsed(runtime);
+	if (used === UsageState.Unused) return;
+	if (alreadyVisited.has(exportInfo)) {
+		referencedExports.push(prefix);
+		return;
+	}
+	alreadyVisited.add(exportInfo);
+	if (
+		used !== UsageState.OnlyPropertiesUsed ||
+		!exportInfo.exportsInfo ||
+		exportInfo.exportsInfo.otherExportsInfo.getUsed(runtime) !==
+			UsageState.Unused
+	) {
+		alreadyVisited.delete(exportInfo);
+		referencedExports.push(prefix);
+		return;
+	}
+	const exportsInfo = exportInfo.exportsInfo;
+	for (const exportInfo of exportsInfo.orderedExports) {
+		processExportInfo(
+			runtime,
+			referencedExports,
+			defaultPointsToSelf && exportInfo.name === "default"
+				? prefix
+				: [...prefix, exportInfo.name],
+			exportInfo,
+			false,
+			alreadyVisited
+		);
+	}
+	alreadyVisited.delete(exportInfo);
+};
+
+module.exports = processExportInfo;
Index: frontend/node_modules/webpack/lib/dll/DelegatedModule.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DelegatedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DelegatedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,292 @@
+/*
+	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_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+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("../../declarations/plugins/dll/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Generator").SourceTypes} SourceTypes */
+/** @typedef {import("./LibManifestPlugin").ManifestModuleData} ManifestModuleData */
+/** @typedef {import("../Module").ModuleId} ModuleId */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../dependencies/StaticExportsDependency").Exports} Exports */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+/** @typedef {string} DelegatedModuleSourceRequest */
+
+/** @typedef {NonNullable<DllReferencePluginOptions["type"]>} DelegatedModuleType */
+
+/**
+ * Defines the delegated module data type used by this module.
+ * @typedef {object} DelegatedModuleData
+ * @property {BuildMeta=} buildMeta build meta
+ * @property {Exports=} exports exports
+ * @property {ModuleId} id module id
+ */
+
+const RUNTIME_REQUIREMENTS = new Set([
+	RuntimeGlobals.module,
+	RuntimeGlobals.require
+]);
+
+class DelegatedModule extends Module {
+	/**
+	 * Creates an instance of DelegatedModule.
+	 * @param {DelegatedModuleSourceRequest} sourceRequest source request
+	 * @param {DelegatedModuleData} data data
+	 * @param {DelegatedModuleType} 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;
+		this.delegateData = data;
+
+		// Build info
+		/** @type {undefined | DelegatedSourceDependency} */
+		this.delegatedSourceDependency = undefined;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return typeof this.originalRequest === "string"
+			? this.originalRequest
+			: this.originalRequest.libIdent(options);
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return `delegated ${JSON.stringify(this.request)} from ${
+			this.sourceRequest
+		}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `delegated ${this.userRequest} from ${this.sourceRequest}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, !this.buildMeta);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} 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();
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @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);
+		/** @type {string} */
+		let str;
+
+		if (!sourceModule) {
+			str = runtimeTemplate.throwMissingModuleErrorBlock({
+				request: this.sourceRequest
+			});
+		} else {
+			str = `module.exports = (${runtimeTemplate.moduleExports({
+				module: sourceModule,
+				chunkGraph,
+				request: dep.request,
+				/** @type {RuntimeRequirements} */
+				runtimeRequirements: new Set()
+			})})`;
+
+			switch (this.delegationType) {
+				case "require":
+					str += `(${JSON.stringify(this.request)})`;
+					break;
+				case "object":
+					str += `[${JSON.stringify(this.request)}]`;
+					break;
+			}
+
+			str += ";";
+		}
+
+		/** @type {Sources} */
+		const sources = new Map();
+		if (this.useSourceMap || this.useSimpleSourceMap) {
+			sources.set(JAVASCRIPT_TYPE, new OriginalSource(str, this.identifier()));
+		} else {
+			sources.set(JAVASCRIPT_TYPE, new RawSource(str));
+		}
+
+		return {
+			sources,
+			runtimeRequirements: RUNTIME_REQUIREMENTS
+		};
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @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);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer 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);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer 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 =
+			/** @type {EXPECTED_ANY} */
+			(undefined);
+	}
+}
+
+makeSerializable(DelegatedModule, "webpack/lib/dll/DelegatedModule");
+
+module.exports = DelegatedModule;
Index: frontend/node_modules/webpack/lib/dll/DelegatedModuleFactoryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DelegatedModuleFactoryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DelegatedModuleFactoryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,119 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DelegatedModule = require("./DelegatedModule");
+
+/** @typedef {import("../../declarations/plugins/dll/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
+/** @typedef {import("../../declarations/plugins/dll/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */
+/** @typedef {import("./DelegatedModule").DelegatedModuleData} DelegatedModuleData */
+/** @typedef {import("./DelegatedModule").DelegatedModuleSourceRequest} DelegatedModuleSourceRequest */
+/** @typedef {import("./DelegatedModule").DelegatedModuleType} DelegatedModuleType */
+/** @typedef {import("../NormalModuleFactory")} NormalModuleFactory */
+/** @typedef {import("../util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+
+/**
+ * Defines the options type used by this module.
+ * @typedef {object} Options
+ * @property {DelegatedModuleSourceRequest} source source
+ * @property {NonNullable<DllReferencePluginOptions["context"]>} context absolute context path to which lib ident is relative to
+ * @property {DllReferencePluginOptionsContent} content content
+ * @property {DllReferencePluginOptions["type"]} type type
+ * @property {DllReferencePluginOptions["extensions"]} extensions extensions
+ * @property {DllReferencePluginOptions["scope"]} scope scope
+ * @property {AssociatedObjectForCache=} associatedObjectForCache object for caching
+ */
+
+const PLUGIN_NAME = "DelegatedModuleFactoryPlugin";
+
+class DelegatedModuleFactoryPlugin {
+	/**
+	 * Creates an instance of DelegatedModuleFactoryPlugin.
+	 * @param {Options} options options
+	 */
+	constructor(options) {
+		this.options = options;
+		options.type = options.type || "require";
+		options.extensions = options.extensions || ["", ".js", ".json", ".wasm"];
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory
+	 * @returns {void}
+	 */
+	apply(normalModuleFactory) {
+		const scope = this.options.scope;
+		if (scope) {
+			normalModuleFactory.hooks.factorize.tapAsync(
+				PLUGIN_NAME,
+				(data, callback) => {
+					const [dependency] = data.dependencies;
+					const { request } = dependency;
+					if (request && request.startsWith(`${scope}/`)) {
+						const innerRequest = `.${request.slice(scope.length)}`;
+						/** @type {undefined | DelegatedModuleData} */
+						let resolved;
+						if (innerRequest in this.options.content) {
+							resolved = this.options.content[innerRequest];
+							return callback(
+								null,
+								new DelegatedModule(
+									this.options.source,
+									resolved,
+									/** @type {DelegatedModuleType} */
+									(this.options.type),
+									innerRequest,
+									request
+								)
+							);
+						}
+						const extensions =
+							/** @type {string[]} */
+							(this.options.extensions);
+						for (let i = 0; i < extensions.length; i++) {
+							const extension = 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,
+										/** @type {DelegatedModuleType} */
+										(this.options.type),
+										requestPlusExt,
+										request + extension
+									)
+								);
+							}
+						}
+					}
+					return callback();
+				}
+			);
+		} else {
+			normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module) => {
+				const request = module.libIdent(this.options);
+				if (request && request in this.options.content) {
+					const resolved = this.options.content[request];
+					return new DelegatedModule(
+						this.options.source,
+						resolved,
+						/** @type {DelegatedModuleType} */
+						(this.options.type),
+						request,
+						module
+					);
+				}
+				return module;
+			});
+		}
+	}
+}
+
+module.exports = DelegatedModuleFactoryPlugin;
Index: frontend/node_modules/webpack/lib/dll/DelegatedPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DelegatedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DelegatedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,50 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DelegatedSourceDependency = require("../dependencies/DelegatedSourceDependency");
+const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./DelegatedModuleFactoryPlugin").Options} Options */
+
+const PLUGIN_NAME = "DelegatedPlugin";
+
+class DelegatedPlugin {
+	/**
+	 * Creates an instance of DelegatedPlugin.
+	 * @param {Options} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					DelegatedSourceDependency,
+					normalModuleFactory
+				);
+			}
+		);
+
+		compiler.hooks.compile.tap(PLUGIN_NAME, ({ normalModuleFactory }) => {
+			new DelegatedModuleFactoryPlugin({
+				associatedObjectForCache: compiler.root,
+				...this.options
+			}).apply(normalModuleFactory);
+		});
+	}
+}
+
+module.exports = DelegatedPlugin;
Index: frontend/node_modules/webpack/lib/dll/DllEntryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DllEntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DllEntryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,77 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DllEntryDependency = require("../dependencies/DllEntryDependency");
+const EntryDependency = require("../dependencies/EntryDependency");
+const DllModuleFactory = require("./DllModuleFactory");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
+
+/** @typedef {string[]} Entries */
+/** @typedef {EntryOptions & { name: string }} Options */
+
+const PLUGIN_NAME = "DllEntryPlugin";
+
+class DllEntryPlugin {
+	/**
+	 * Creates an instance of DllEntryPlugin.
+	 * @param {string} context context
+	 * @param {Entries} entries entry names
+	 * @param {Options} options options
+	 */
+	constructor(context, entries, options) {
+		this.context = context;
+		this.entries = entries;
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const dllModuleFactory = new DllModuleFactory();
+				compilation.dependencyFactories.set(
+					DllEntryDependency,
+					dllModuleFactory
+				);
+				compilation.dependencyFactories.set(
+					EntryDependency,
+					normalModuleFactory
+				);
+			}
+		);
+		compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
+			compilation.addEntry(
+				this.context,
+				new DllEntryDependency(
+					this.entries.map((e, idx) => {
+						const dep = new EntryDependency(e);
+						dep.loc = {
+							name: this.options.name,
+							index: idx
+						};
+						return dep;
+					}),
+					this.options.name
+				),
+				this.options,
+				(error) => {
+					if (error) return callback(error);
+					callback();
+				}
+			);
+		});
+	}
+}
+
+module.exports = DllEntryPlugin;
Index: frontend/node_modules/webpack/lib/dll/DllModule.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DllModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DllModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,186 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Module = require("../Module");
+const {
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Generator").SourceTypes} SourceTypes */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+const RUNTIME_REQUIREMENTS = new Set([
+	RuntimeGlobals.require,
+	RuntimeGlobals.module
+]);
+
+class DllModule extends Module {
+	/**
+	 * Creates an instance of DllModule.
+	 * @param {string} context context path
+	 * @param {Dependency[]} dependencies dependencies
+	 * @param {string} name name
+	 */
+	constructor(context, dependencies, name) {
+		super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, context);
+
+		// Info from Factory
+		/** @type {Dependency[]} */
+		this.dependencies = dependencies;
+		this.name = name;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return `dll ${this.name}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `dll ${this.name}`;
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {};
+		return callback();
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration(context) {
+		/** @type {Sources} */
+		const sources = new Map();
+		sources.set(
+			JAVASCRIPT_TYPE,
+			new RawSource(`module.exports = ${RuntimeGlobals.require};`)
+		);
+		return {
+			sources,
+			runtimeRequirements: RUNTIME_REQUIREMENTS
+		};
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		return callback(null, !this.buildMeta);
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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 12;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		hash.update(`dll module${this.name || ""}`);
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		context.write(this.name);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		this.name = context.read();
+		super.deserialize(context);
+	}
+
+	/**
+	 * 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);
+		this.dependencies = module.dependencies;
+	}
+
+	/**
+	 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
+	 */
+	cleanupForCache() {
+		super.cleanupForCache();
+		this.dependencies = /** @type {EXPECTED_ANY} */ (undefined);
+	}
+}
+
+makeSerializable(DllModule, "webpack/lib/dll/DllModule");
+
+module.exports = DllModule;
Index: frontend/node_modules/webpack/lib/dll/DllModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DllModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DllModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleFactory = require("../ModuleFactory");
+const DllModule = require("./DllModule");
+
+/** @typedef {import("../ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("../dependencies/DllEntryDependency")} DllEntryDependency */
+
+class DllModuleFactory extends ModuleFactory {
+	constructor() {
+		super();
+		this.hooks = Object.freeze({});
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const dependency = /** @type {DllEntryDependency} */ (data.dependencies[0]);
+		callback(null, {
+			module: new DllModule(
+				data.context,
+				dependency.dependencies,
+				dependency.name
+			)
+		});
+	}
+}
+
+module.exports = DllModuleFactory;
Index: frontend/node_modules/webpack/lib/dll/DllPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DllPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DllPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const FlagAllModulesAsUsedPlugin = require("../FlagAllModulesAsUsedPlugin");
+const DllEntryPlugin = require("./DllEntryPlugin");
+const LibManifestPlugin = require("./LibManifestPlugin");
+
+/** @typedef {import("../../declarations/plugins/dll/DllPlugin").DllPluginOptions} DllPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./DllEntryPlugin").Entries} Entries */
+/** @typedef {import("./DllEntryPlugin").Options} Options */
+
+const PLUGIN_NAME = "DllPlugin";
+
+class DllPlugin {
+	/**
+	 * Creates an instance of DllPlugin.
+	 * @param {DllPluginOptions} options options object
+	 */
+	constructor(options) {
+		/** @type {DllPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/dll/DllPlugin.json"),
+				this.options,
+				{
+					name: "Dll Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/dll/DllPlugin.check")(options)
+			);
+		});
+
+		const entryOnly = this.options.entryOnly !== false;
+		compiler.hooks.entryOption.tap(PLUGIN_NAME, (context, entry) => {
+			if (typeof entry !== "function") {
+				for (const name of Object.keys(entry)) {
+					/** @type {Options} */
+					const options = { name };
+					new DllEntryPlugin(
+						context,
+						/** @type {Entries} */
+						(entry[name].import),
+						options
+					).apply(compiler);
+				}
+			} else {
+				throw new Error(
+					`${PLUGIN_NAME} doesn't support dynamic entry (function) yet`
+				);
+			}
+			return true;
+		});
+		new LibManifestPlugin({ ...this.options, entryOnly }).apply(compiler);
+		if (!entryOnly) {
+			new FlagAllModulesAsUsedPlugin(PLUGIN_NAME).apply(compiler);
+		}
+	}
+}
+
+module.exports = DllPlugin;
Index: frontend/node_modules/webpack/lib/dll/DllReferencePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/DllReferencePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/DllReferencePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,196 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ExternalModuleFactoryPlugin = require("../ExternalModuleFactoryPlugin");
+const DelegatedSourceDependency = require("../dependencies/DelegatedSourceDependency");
+const WebpackError = require("../errors/WebpackError");
+const { makePathsRelative } = require("../util/identifier");
+const parseJson = require("../util/parseJson");
+const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").Externals} Externals */
+/** @typedef {import("../../declarations/plugins/dll/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
+/** @typedef {import("../../declarations/plugins/dll/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */
+/** @typedef {import("../../declarations/plugins/dll/DllReferencePlugin").DllReferencePluginOptionsManifest} DllReferencePluginOptionsManifest */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Compiler").CompilationParams} CompilationParams */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+/** @typedef {{ path: string, data: DllReferencePluginOptionsManifest | undefined, error: Error | undefined }} CompilationDataItem */
+
+const PLUGIN_NAME = "DllReferencePlugin";
+
+class DllReferencePlugin {
+	/**
+	 * Creates an instance of DllReferencePlugin.
+	 * @param {DllReferencePluginOptions} options options object
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/dll/DllReferencePlugin.json"),
+				this.options,
+				{
+					name: "Dll Reference Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/dll/DllReferencePlugin.check")(options)
+			);
+		});
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					DelegatedSourceDependency,
+					normalModuleFactory
+				);
+			}
+		);
+
+		/** @type {WeakMap<CompilationParams, CompilationDataItem>} */
+		const compilationData = new WeakMap();
+
+		compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, (params, callback) => {
+			if ("manifest" in this.options) {
+				const manifest = this.options.manifest;
+				if (typeof manifest === "string") {
+					/** @type {InputFileSystem} */
+					(compiler.inputFileSystem).readFile(manifest, (err, result) => {
+						if (err) return callback(err);
+						/** @type {CompilationDataItem} */
+						const data = {
+							path: manifest,
+							data: undefined,
+							error: undefined
+						};
+						// Catch errors parsing the manifest so that blank
+						// or malformed manifest files don't kill the process.
+						try {
+							data.data =
+								/** @type {DllReferencePluginOptionsManifest} */
+								(
+									/** @type {unknown} */
+									(parseJson(/** @type {Buffer} */ (result).toString("utf8")))
+								);
+						} catch (parseErr) {
+							// Store the error in the params so that it can
+							// be added as a compilation error later on.
+							const manifestPath = makePathsRelative(
+								compiler.context,
+								manifest,
+								compiler.root
+							);
+							data.error = new DllManifestError(
+								manifestPath,
+								/** @type {Error} */ (parseErr).message
+							);
+						}
+						compilationData.set(params, data);
+						return callback();
+					});
+					return;
+				}
+			}
+			return callback();
+		});
+
+		compiler.hooks.compile.tap(PLUGIN_NAME, (params) => {
+			let name = this.options.name;
+			let sourceType = this.options.sourceType;
+			let resolvedContent =
+				"content" in this.options ? this.options.content : undefined;
+			if ("manifest" in this.options) {
+				const manifestParameter = this.options.manifest;
+				/** @type {undefined | DllReferencePluginOptionsManifest} */
+				let manifest;
+				if (typeof manifestParameter === "string") {
+					const data =
+						/** @type {CompilationDataItem} */
+						(compilationData.get(params));
+					// If there was an error parsing the manifest
+					// file, exit now because the error will be added
+					// as a compilation error in the "compilation" hook.
+					if (data.error) {
+						return;
+					}
+					manifest = data.data;
+				} else {
+					manifest = manifestParameter;
+				}
+				if (manifest) {
+					if (!name) name = manifest.name;
+					if (!sourceType) sourceType = manifest.type;
+					if (!resolvedContent) resolvedContent = manifest.content;
+				}
+			}
+			/** @type {Externals} */
+			const externals = {};
+			const source = `dll-reference ${name}`;
+			externals[source] = /** @type {string} */ (name);
+			const normalModuleFactory = params.normalModuleFactory;
+			new ExternalModuleFactoryPlugin(sourceType || "var", externals).apply(
+				normalModuleFactory
+			);
+			new DelegatedModuleFactoryPlugin({
+				source,
+				type: this.options.type,
+				scope: this.options.scope,
+				context: this.options.context || compiler.context,
+				content:
+					/** @type {DllReferencePluginOptionsContent} */
+					(resolvedContent),
+				extensions: this.options.extensions,
+				associatedObjectForCache: compiler.root
+			}).apply(normalModuleFactory);
+		});
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation, params) => {
+			if ("manifest" in this.options) {
+				const manifest = this.options.manifest;
+				if (typeof manifest === "string") {
+					const data =
+						/** @type {CompilationDataItem} */
+						(compilationData.get(params));
+					// If there was an error parsing the manifest file, add the
+					// error as a compilation error to make the compilation fail.
+					if (data.error) {
+						compilation.errors.push(
+							/** @type {DllManifestError} */ (data.error)
+						);
+					}
+					compilation.fileDependencies.add(manifest);
+				}
+			}
+		});
+	}
+}
+
+class DllManifestError extends WebpackError {
+	/**
+	 * Creates an instance of DllManifestError.
+	 * @param {string} filename filename of the manifest
+	 * @param {string} message error message
+	 */
+	constructor(filename, message) {
+		super();
+
+		this.name = "DllManifestError";
+		this.message = `Dll manifest ${filename}\n${message}`;
+	}
+}
+
+module.exports = DllReferencePlugin;
Index: frontend/node_modules/webpack/lib/dll/LibManifestPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/dll/LibManifestPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/dll/LibManifestPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,147 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const EntryDependency = require("../dependencies/EntryDependency");
+const { someInIterable } = require("../util/IterableHelpers");
+const { compareModulesById } = require("../util/comparators");
+const { dirname, mkdirp } = require("../util/fs");
+
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Compiler").IntermediateFileSystem} IntermediateFileSystem */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+
+/**
+ * Defines the manifest module data type used by this module.
+ * @typedef {object} ManifestModuleData
+ * @property {ModuleId} id
+ * @property {BuildMeta=} buildMeta
+ * @property {ExportInfoName[]=} exports
+ */
+
+/**
+ * Defines the lib manifest plugin options type used by this module.
+ * @typedef {object} LibManifestPluginOptions
+ * @property {string=} context Context of requests in the manifest file (defaults to the webpack context).
+ * @property {boolean=} entryOnly If true, only entry points will be exposed (default: true).
+ * @property {boolean=} format If true, manifest json file (output) will be formatted.
+ * @property {string=} name Name of the exposed dll function (external name, use value of 'output.library').
+ * @property {string} path Absolute path to the manifest json file (output).
+ * @property {string=} type Type of the dll bundle (external type, use value of 'output.libraryTarget').
+ */
+
+const PLUGIN_NAME = "LibManifestPlugin";
+
+class LibManifestPlugin {
+	/**
+	 * Creates an instance of LibManifestPlugin.
+	 * @param {LibManifestPluginOptions} options the options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.emit.tapAsync(
+			{ name: PLUGIN_NAME, stage: 110 },
+			(compilation, callback) => {
+				const moduleGraph = compilation.moduleGraph;
+				// store used paths to detect issue and output an error. #18200
+				/** @type {Set<string>} */
+				const usedPaths = new Set();
+				asyncLib.each(
+					[...compilation.chunks],
+					(chunk, callback) => {
+						if (!chunk.canBeInitial()) {
+							callback();
+							return;
+						}
+						const chunkGraph = compilation.chunkGraph;
+						const targetPath = compilation.getPath(this.options.path, {
+							chunk
+						});
+						if (usedPaths.has(targetPath)) {
+							callback(new Error("each chunk must have a unique path"));
+							return;
+						}
+						usedPaths.add(targetPath);
+						const name =
+							this.options.name &&
+							compilation.getPath(this.options.name, {
+								chunk,
+								contentHashType: "javascript"
+							});
+						const content = Object.create(null);
+						for (const module of chunkGraph.getOrderedChunkModulesIterable(
+							chunk,
+							compareModulesById(chunkGraph)
+						)) {
+							if (
+								this.options.entryOnly &&
+								!someInIterable(
+									moduleGraph.getIncomingConnections(module),
+									(c) => c.dependency instanceof EntryDependency
+								)
+							) {
+								continue;
+							}
+							const ident = module.libIdent({
+								context: this.options.context || compiler.context,
+								associatedObjectForCache: compiler.root
+							});
+							if (ident) {
+								const exportsInfo = moduleGraph.getExportsInfo(module);
+								const providedExports = exportsInfo.getProvidedExports();
+								/** @type {ManifestModuleData} */
+								const data = {
+									id: /** @type {ModuleId} */ (chunkGraph.getModuleId(module)),
+									buildMeta: /** @type {BuildMeta} */ (module.buildMeta),
+									exports: Array.isArray(providedExports)
+										? providedExports
+										: undefined
+								};
+								content[ident] = data;
+							}
+						}
+						const manifest = {
+							name,
+							type: this.options.type,
+							content
+						};
+						// Apply formatting to content if format flag is true;
+						const manifestContent = this.options.format
+							? JSON.stringify(manifest, null, 2)
+							: JSON.stringify(manifest);
+						const buffer = Buffer.from(manifestContent, "utf8");
+						const intermediateFileSystem =
+							/** @type {IntermediateFileSystem} */ (
+								compiler.intermediateFileSystem
+							);
+						mkdirp(
+							intermediateFileSystem,
+							dirname(intermediateFileSystem, targetPath),
+							(err) => {
+								if (err) return callback(err);
+								intermediateFileSystem.writeFile(targetPath, buffer, callback);
+							}
+						);
+					},
+					callback
+				);
+			}
+		);
+	}
+}
+
+module.exports = LibManifestPlugin;
Index: frontend/node_modules/webpack/lib/electron/ElectronTargetPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/electron/ElectronTargetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/electron/ElectronTargetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,72 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ExternalsPlugin = require("../ExternalsPlugin");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {"main" | "preload" | "renderer"} ElectronContext */
+
+class ElectronTargetPlugin {
+	/**
+	 * Creates an instance of ElectronTargetPlugin.
+	 * @param {ElectronContext=} context in main, preload or renderer context?
+	 */
+	constructor(context) {
+		/** @type {ElectronContext | undefined} */
+		this._context = context;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		new ExternalsPlugin("node-commonjs", [
+			"clipboard",
+			"crash-reporter",
+			"electron",
+			"ipc",
+			"native-image",
+			"original-fs",
+			"screen",
+			"shell"
+		]).apply(compiler);
+		switch (this._context) {
+			case "main":
+				new ExternalsPlugin("node-commonjs", [
+					"app",
+					"auto-updater",
+					"browser-window",
+					"content-tracing",
+					"dialog",
+					"global-shortcut",
+					"ipc-main",
+					"menu",
+					"menu-item",
+					"power-monitor",
+					"power-save-blocker",
+					"protocol",
+					"session",
+					"tray",
+					"web-contents"
+				]).apply(compiler);
+				break;
+			case "preload":
+			case "renderer":
+				new ExternalsPlugin("node-commonjs", [
+					"desktop-capturer",
+					"ipc-renderer",
+					"remote",
+					"web-frame"
+				]).apply(compiler);
+				break;
+		}
+	}
+}
+
+module.exports = ElectronTargetPlugin;
Index: frontend/node_modules/webpack/lib/errors/AbstractMethodError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/AbstractMethodError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/AbstractMethodError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,65 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+const CURRENT_METHOD_REGEXP = /at ([a-zA-Z0-9_.]*)/;
+
+/**
+ * Creates the error message shown when an abstract API is called without
+ * being implemented by a subclass.
+ * @param {string=} method method name
+ * @returns {string} message
+ */
+function createMessage(method) {
+	return `Abstract method${method ? ` ${method}` : ""}. Must be overridden.`;
+}
+
+/**
+ * Captures a stack trace so the calling method name can be folded into the
+ * final abstract-method error message.
+ * @constructor
+ */
+function Message() {
+	/** @type {string | undefined} */
+	this.stack = undefined;
+	Error.captureStackTrace(this);
+	/** @type {RegExpMatchArray | null} */
+	const match =
+		/** @type {string} */
+		(/** @type {unknown} */ (this.stack))
+			.split("\n")[3]
+			.match(CURRENT_METHOD_REGEXP);
+
+	this.message = match && match[1] ? createMessage(match[1]) : createMessage();
+}
+
+/**
+ * Error thrown when code reaches a method that is intended to be overridden by
+ * a subclass.
+ * @example
+ * ```js
+ * class FooClass {
+ *     abstractMethod() {
+ *         throw new AbstractMethodError(); // error message: Abstract method FooClass.abstractMethod. Must be overridden.
+ *     }
+ * }
+ * ```
+ */
+class AbstractMethodError extends WebpackError {
+	/**
+	 * Creates an error whose message points at the abstract method that was
+	 * invoked.
+	 */
+	constructor() {
+		super(new Message().message);
+		/** @type {string} */
+		this.name = "AbstractMethodError";
+	}
+}
+
+module.exports = AbstractMethodError;
Index: frontend/node_modules/webpack/lib/errors/AsyncDependencyToInitialChunkError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/AsyncDependencyToInitialChunkError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/AsyncDependencyToInitialChunkError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+
+/**
+ * Error raised when webpack detects an attempt to lazy-load a chunk name that
+ * is already claimed by an entrypoint's initial chunk.
+ */
+class AsyncDependencyToInitialChunkError extends WebpackError {
+	/**
+	 * Captures the chunk name, originating module, and source location for an
+	 * invalid async dependency targeting an initial chunk.
+	 * @param {string} chunkName Name of Chunk
+	 * @param {Module} module module tied to dependency
+	 * @param {DependencyLocation} loc location of dependency
+	 */
+	constructor(chunkName, module, loc) {
+		super(
+			`It's not allowed to load an initial chunk on demand. The chunk name "${chunkName}" is already used by an entrypoint.`
+		);
+
+		/** @type {string} */
+		this.name = "AsyncDependencyToInitialChunkError";
+		/** @type {Module} */
+		this.module = module;
+		/** @type {DependencyLocation} */
+		this.loc = loc;
+	}
+}
+
+module.exports = AsyncDependencyToInitialChunkError;
Index: frontend/node_modules/webpack/lib/errors/BuildCycleError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/BuildCycleError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/BuildCycleError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+
+class BuildCycleError extends WebpackError {
+	/**
+	 * Creates an instance of BuildCycleError.
+	 * @param {Module} module the module starting the cycle
+	 */
+	constructor(module) {
+		super(
+			"There is a circular build dependency, which makes it impossible to create this module"
+		);
+
+		/** @type {string} */
+		this.name = "BuildCycleError";
+		/** @type {Module} */
+		this.module = module;
+	}
+}
+
+/** @type {typeof BuildCycleError} */
+module.exports = BuildCycleError;
Index: frontend/node_modules/webpack/lib/errors/ChunkRenderError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ChunkRenderError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ChunkRenderError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Chunk")} Chunk */
+
+class ChunkRenderError extends WebpackError {
+	/**
+	 * Create a new ChunkRenderError
+	 * @param {Chunk} chunk A chunk
+	 * @param {string} file Related file
+	 * @param {Error} error Original error
+	 */
+	constructor(chunk, file, error) {
+		super();
+
+		/** @type {string} */
+		this.name = "ChunkRenderError";
+		/** @type {Chunk} */
+		this.chunk = chunk;
+		/** @type {string} */
+		this.file = file;
+		/** @type {Error} */
+		this.error = error;
+		/** @type {string} */
+		this.message = error.message;
+		/** @type {string} */
+		this.details = error.stack;
+	}
+}
+
+/** @type {typeof ChunkRenderError} */
+module.exports = ChunkRenderError;
Index: frontend/node_modules/webpack/lib/errors/CodeGenerationError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/CodeGenerationError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/CodeGenerationError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+
+class CodeGenerationError extends WebpackError {
+	/**
+	 * Create a new CodeGenerationError
+	 * @param {Module} module related module
+	 * @param {Error} error Original error
+	 */
+	constructor(module, error) {
+		super();
+
+		/** @type {string} */
+		this.name = "CodeGenerationError";
+		/** @type {Module} */
+		this.module = module;
+		/** @type {Error} */
+		this.error = error;
+		/** @type {string} */
+		this.message = error.message;
+		/** @type {string} */
+		this.details = error.stack;
+	}
+}
+
+/** @type {typeof CodeGenerationError} */
+module.exports = CodeGenerationError;
Index: frontend/node_modules/webpack/lib/errors/CommentCompilationWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/CommentCompilationWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/CommentCompilationWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+
+/**
+ * Warning used for comment-related compilation issues, such as malformed magic
+ * comments that webpack can parse but wants to report.
+ */
+class CommentCompilationWarning extends WebpackError {
+	/**
+	 * Captures a warning message together with the dependency location that
+	 * triggered it.
+	 * @param {string} message warning message
+	 * @param {DependencyLocation} loc affected lines of code
+	 */
+	constructor(message, loc) {
+		super(message);
+
+		/** @type {string} */
+		this.name = "CommentCompilationWarning";
+		/** @type {DependencyLocation} */
+		this.loc = loc;
+	}
+}
+
+makeSerializable(
+	CommentCompilationWarning,
+	"webpack/lib/errors/CommentCompilationWarning"
+);
+
+module.exports = CommentCompilationWarning;
Index: frontend/node_modules/webpack/lib/errors/ConcurrentCompilationError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ConcurrentCompilationError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ConcurrentCompilationError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Maksim Nazarjev @acupofspirt
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+class ConcurrentCompilationError extends WebpackError {
+	constructor() {
+		super(
+			"You ran Webpack twice. Each instance only supports a single concurrent compilation at a time."
+		);
+
+		this.name = "ConcurrentCompilationError";
+	}
+}
+
+module.exports = ConcurrentCompilationError;
Index: frontend/node_modules/webpack/lib/errors/EnvironmentNotSupportAsyncWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/EnvironmentNotSupportAsyncWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/EnvironmentNotSupportAsyncWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,51 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Gengkun He @ahabhgk
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {"asyncWebAssembly" | "topLevelAwait" | "external promise" | "external script" | "external import" | "external module"} Feature */
+
+class EnvironmentNotSupportAsyncWarning extends WebpackError {
+	/**
+	 * Creates an instance of EnvironmentNotSupportAsyncWarning.
+	 * @param {Module} module module
+	 * @param {Feature} feature feature
+	 */
+	constructor(module, feature) {
+		const message = `The generated code contains 'async/await' because this module is using "${feature}".
+However, your target environment does not appear to support 'async/await'.
+As a result, the code may not run as expected or may cause runtime errors.`;
+		super(message);
+
+		/** @type {string} */
+		this.name = "EnvironmentNotSupportAsyncWarning";
+		/** @type {Module} */
+		this.module = module;
+	}
+
+	/**
+	 * Creates an instance of EnvironmentNotSupportAsyncWarning.
+	 * @param {Module} module module
+	 * @param {RuntimeTemplate} runtimeTemplate compilation
+	 * @param {Feature} feature feature
+	 */
+	static check(module, runtimeTemplate, feature) {
+		if (!runtimeTemplate.supportsAsyncFunction()) {
+			module.addWarning(new EnvironmentNotSupportAsyncWarning(module, feature));
+		}
+	}
+}
+
+makeSerializable(
+	EnvironmentNotSupportAsyncWarning,
+	"webpack/lib/errors/EnvironmentNotSupportAsyncWarning"
+);
+
+module.exports = EnvironmentNotSupportAsyncWarning;
Index: frontend/node_modules/webpack/lib/errors/HookWebpackError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/HookWebpackError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/HookWebpackError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,127 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/**
+ * Defines the callback callback.
+ * @template T
+ * @callback Callback
+ * @param {Error | null} err
+ * @param {T=} stats
+ * @returns {void}
+ */
+
+class HookWebpackError extends WebpackError {
+	/**
+	 * Creates an instance of HookWebpackError.
+	 * @param {Error} error inner error
+	 * @param {string} hook name of hook
+	 */
+	constructor(error, hook) {
+		super(error ? error.message : undefined, error ? { cause: error } : {});
+
+		this.hook = hook;
+		this.error = error;
+		/** @type {string} */
+		this.name = "HookWebpackError";
+		this.hideStack = true;
+		this.stack += `\n-- inner error --\n${error ? error.stack : ""}`;
+		this.details = `caused by plugins in ${hook}\n${error ? error.stack : ""}`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.error);
+		write(this.hook);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.error = read();
+		this.hook = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(HookWebpackError, "webpack/lib/errors/HookWebpackError");
+
+module.exports = HookWebpackError;
+
+/**
+ * Creates webpack error.
+ * @param {Error} error an error
+ * @param {string} hook name of the hook
+ * @returns {WebpackError} a webpack error
+ */
+const makeWebpackError = (error, hook) => {
+	if (error instanceof WebpackError) return error;
+	return new HookWebpackError(error, hook);
+};
+
+module.exports.makeWebpackError = makeWebpackError;
+
+/**
+ * Creates webpack error callback.
+ * @template T
+ * @param {(err: Error | null, result?: T) => void} callback webpack error callback
+ * @param {string} hook name of hook
+ * @returns {Callback<T>} generic callback
+ */
+const makeWebpackErrorCallback = (callback, hook) => (err, result) => {
+	if (err) {
+		if (err instanceof WebpackError) {
+			callback(err);
+			return;
+		}
+		callback(new HookWebpackError(err, hook));
+		return;
+	}
+	callback(null, result);
+};
+
+module.exports.makeWebpackErrorCallback = makeWebpackErrorCallback;
+
+/**
+ * Try run or webpack error.
+ * @template T
+ * @param {() => T} fn function which will be wrapping in try catch
+ * @param {string} hook name of hook
+ * @returns {T} the result
+ */
+const tryRunOrWebpackError = (fn, hook) => {
+	/** @type {T} */
+	let r;
+	try {
+		r = fn();
+	} catch (err) {
+		if (err instanceof WebpackError) {
+			throw err;
+		}
+		throw new HookWebpackError(/** @type {Error} */ (err), hook);
+	}
+	return r;
+};
+
+module.exports.tryRunOrWebpackError = tryRunOrWebpackError;
Index: frontend/node_modules/webpack/lib/errors/IgnoreErrorModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/IgnoreErrorModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/IgnoreErrorModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const ModuleFactory = require("../ModuleFactory");
+
+/** @typedef {import("../ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("../NormalModuleFactory")} NormalModuleFactory */
+
+/**
+ * Ignores error when module is unresolved
+ */
+class IgnoreErrorModuleFactory extends ModuleFactory {
+	/**
+	 * Creates an instance of IgnoreErrorModuleFactory.
+	 * @param {NormalModuleFactory} normalModuleFactory normalModuleFactory instance
+	 */
+	constructor(normalModuleFactory) {
+		super();
+
+		this.normalModuleFactory = normalModuleFactory;
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		this.normalModuleFactory.create(data, (err, result) =>
+			callback(null, result)
+		);
+	}
+}
+
+module.exports = IgnoreErrorModuleFactory;
Index: frontend/node_modules/webpack/lib/errors/InvalidDependenciesModuleWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/InvalidDependenciesModuleWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/InvalidDependenciesModuleWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,45 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+
+class InvalidDependenciesModuleWarning extends WebpackError {
+	/**
+	 * Creates an instance of InvalidDependenciesModuleWarning.
+	 * @param {Module} module module tied to dependency
+	 * @param {Iterable<string>} deps invalid dependencies
+	 */
+	constructor(module, deps) {
+		const orderedDeps = deps ? [...deps].sort() : [];
+		const depsList = orderedDeps.map((dep) => ` * ${JSON.stringify(dep)}`);
+		super(`Invalid dependencies have been reported by plugins or loaders for this module. All reported dependencies need to be absolute paths.
+Invalid dependencies may lead to broken watching and caching.
+As best effort we try to convert all invalid values to absolute paths and converting globs into context dependencies, but this is deprecated behavior.
+Loaders: Pass absolute paths to this.addDependency (existing files), this.addMissingDependency (not existing files), and this.addContextDependency (directories).
+Plugins: Pass absolute paths to fileDependencies (existing files), missingDependencies (not existing files), and contextDependencies (directories).
+Globs: They are not supported. Pass absolute path to the directory as context dependencies.
+The following invalid values have been reported:
+${depsList.slice(0, 3).join("\n")}${
+			depsList.length > 3 ? "\n * and more ..." : ""
+		}`);
+
+		/** @type {string} */
+		this.name = "InvalidDependenciesModuleWarning";
+		this.details = depsList.slice(3).join("\n");
+		this.module = module;
+	}
+}
+
+makeSerializable(
+	InvalidDependenciesModuleWarning,
+	"webpack/lib/errors/InvalidDependenciesModuleWarning"
+);
+
+module.exports = InvalidDependenciesModuleWarning;
Index: frontend/node_modules/webpack/lib/errors/JSONParseError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/JSONParseError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/JSONParseError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,114 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+const makeSerializable = require("../util/makeSerializable");
+
+const CONTEXT = 20;
+
+class JSONParseError extends SyntaxError {
+	/**
+	 * @param {Error} err err
+	 * @param {EXPECTED_ANY} raw raw
+	 * @param {string} txt text
+	 */
+	constructor(err, raw, txt) {
+		let originalMessage = err.message;
+		/** @type {string} */
+		let message;
+		/** @type {number} */
+		let position;
+
+		if (typeof raw !== "string") {
+			message = `Cannot parse ${Array.isArray(raw) && raw.length === 0 ? "an empty array" : String(raw)}`;
+			position = 0;
+		} else if (!txt) {
+			message = `${originalMessage} while parsing empty string`;
+			position = 0;
+		} else {
+			// Node 20 puts single quotes around the token and a comma after it
+			const UNEXPECTED_TOKEN = /^Unexpected token '?(.)'?(,)? /i;
+			const badTokenMatch = originalMessage.match(UNEXPECTED_TOKEN);
+			const badIndexMatch = originalMessage.match(/ position\s+(\d+)/i);
+
+			if (badTokenMatch) {
+				const h = badTokenMatch[1].charCodeAt(0).toString(16).toUpperCase();
+				const hex = `0x${h.length % 2 ? "0" : ""}${h}`;
+
+				originalMessage = originalMessage.replace(
+					UNEXPECTED_TOKEN,
+					`Unexpected token ${JSON.stringify(badTokenMatch[1])} (${hex})$2 `
+				);
+			}
+
+			/** @type {number | undefined} */
+			let errIdx;
+
+			if (badIndexMatch) {
+				errIdx = Number(badIndexMatch[1]);
+			} else if (
+				// doesn't happen in Node 22+
+				/^Unexpected end of JSON.*/i.test(originalMessage)
+			) {
+				errIdx = txt.length - 1;
+			}
+
+			if (errIdx === undefined) {
+				message = `${originalMessage} while parsing '${txt.slice(0, CONTEXT * 2)}'`;
+				position = 0;
+			} else {
+				const start = errIdx <= CONTEXT ? 0 : errIdx - CONTEXT;
+				const end =
+					errIdx + CONTEXT >= txt.length ? txt.length : errIdx + CONTEXT;
+				const slice = `${start ? "..." : ""}${txt.slice(start, end)}${end === txt.length ? "" : "..."}`;
+
+				message = `${originalMessage} while parsing ${txt === slice ? "" : "near "}${JSON.stringify(slice)}`;
+				position = errIdx;
+			}
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "JSONParseError";
+		/** @type {string | undefined} */
+		this.stack = undefined;
+		/** @type {Error} */
+		this.systemError = err;
+		/** @type {EXPECTED_ANY} */
+		this.raw = raw;
+		/** @type {string} */
+		this.txt = txt;
+		/** @type {number} */
+		this.position = position;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this.systemError);
+		write(this.raw);
+		write(this.txt);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {JSONParseError} DelegatedModule
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		return new JSONParseError(read(), read(), read());
+	}
+}
+
+makeSerializable(JSONParseError, "webpack/lib/errors/JSONParseError");
+
+module.exports = JSONParseError;
Index: frontend/node_modules/webpack/lib/errors/ModuleBuildError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleBuildError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleBuildError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,86 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { cutOffLoaderExecution } = require("../ErrorHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {Error & { hideStack?: boolean }} ErrorWithHideStack */
+
+class ModuleBuildError extends WebpackError {
+	/**
+	 * Creates an instance of ModuleBuildError.
+	 * @param {string | ErrorWithHideStack} err error thrown
+	 * @param {{ from?: string | null }} info additional info
+	 */
+	constructor(err, { from = null } = {}) {
+		let message = "Module build failed";
+		/** @type {undefined | string} */
+		let details;
+
+		message += from ? ` (from ${from}):\n` : ": ";
+
+		if (err !== null && typeof err === "object") {
+			if (typeof err.stack === "string" && err.stack) {
+				const stack = cutOffLoaderExecution(err.stack);
+
+				if (!err.hideStack) {
+					message += stack;
+				} else {
+					details = stack;
+
+					message +=
+						typeof err.message === "string" && err.message ? err.message : err;
+				}
+			} else if (typeof err.message === "string" && err.message) {
+				message += err.message;
+			} else {
+				message += String(err);
+			}
+		} else {
+			message += String(err);
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleBuildError";
+		this.details = details;
+		this.error = err;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.error);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.error = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ModuleBuildError, "webpack/lib/errors/ModuleBuildError");
+
+module.exports = ModuleBuildError;
Index: frontend/node_modules/webpack/lib/errors/ModuleDependencyError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleDependencyError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleDependencyError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("./ModuleBuildError").ErrorWithHideStack} ErrorWithHideStack */
+
+class ModuleDependencyError extends WebpackError {
+	/**
+	 * Creates an instance of ModuleDependencyError.
+	 * @param {Module} module module tied to dependency
+	 * @param {ErrorWithHideStack} err error thrown
+	 * @param {DependencyLocation} loc location of dependency
+	 */
+	constructor(module, err, loc) {
+		super(err.message);
+
+		/** @type {string} */
+		this.name = "ModuleDependencyError";
+		this.details =
+			err && !err.hideStack
+				? /** @type {string} */ (err.stack).split("\n").slice(1).join("\n")
+				: undefined;
+		this.module = module;
+		this.loc = loc;
+		/** error is not (de)serialized, so it might be undefined after deserialization */
+		this.error = err;
+
+		if (err && err.hideStack && err.stack) {
+			this.stack = /** @type {string} */ `${err.stack
+				.split("\n")
+				.slice(1)
+				.join("\n")}\n\n${this.stack}`;
+		}
+	}
+}
+
+module.exports = ModuleDependencyError;
Index: frontend/node_modules/webpack/lib/errors/ModuleDependencyWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleDependencyWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleDependencyWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,50 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("./ModuleDependencyError").ErrorWithHideStack} ErrorWithHideStack */
+
+class ModuleDependencyWarning extends WebpackError {
+	/**
+	 * Creates an instance of ModuleDependencyWarning.
+	 * @param {Module} module module tied to dependency
+	 * @param {ErrorWithHideStack} err error thrown
+	 * @param {DependencyLocation} loc location of dependency
+	 */
+	constructor(module, err, loc) {
+		super(err ? err.message : "");
+
+		/** @type {string} */
+		this.name = "ModuleDependencyWarning";
+		this.details =
+			err && !err.hideStack
+				? /** @type {string} */ (err.stack).split("\n").slice(1).join("\n")
+				: undefined;
+		this.module = module;
+		this.loc = loc;
+		/** error is not (de)serialized, so it might be undefined after deserialization */
+		this.error = err;
+
+		if (err && err.hideStack && err.stack) {
+			this.stack = /** @type {string} */ `${err.stack
+				.split("\n")
+				.slice(1)
+				.join("\n")}\n\n${this.stack}`;
+		}
+	}
+}
+
+makeSerializable(
+	ModuleDependencyWarning,
+	"webpack/lib/errors/ModuleDependencyWarning"
+);
+
+module.exports = ModuleDependencyWarning;
Index: frontend/node_modules/webpack/lib/errors/ModuleError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { cleanUp } = require("../ErrorHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ModuleError extends WebpackError {
+	/**
+	 * @param {Error} err error thrown
+	 * @param {{ from?: string | null }} info additional info
+	 */
+	constructor(err, { from = null } = {}) {
+		let message = "Module Error";
+
+		message += from ? ` (from ${from}):\n` : ": ";
+
+		if (err && typeof err === "object" && err.message) {
+			message += err.message;
+		} else if (err) {
+			message += err;
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleError";
+		/** @type {Error} */
+		this.error = err;
+		/** @type {string | undefined} */
+		this.details =
+			err && typeof err === "object" && err.stack
+				? cleanUp(err.stack, this.message)
+				: undefined;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.error);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.error = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ModuleError, "webpack/lib/errors/ModuleError");
+
+module.exports = ModuleError;
Index: frontend/node_modules/webpack/lib/errors/ModuleHashingError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleHashingError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleHashingError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+
+class ModuleHashingError extends WebpackError {
+	/**
+	 * Create a new ModuleHashingError
+	 * @param {Module} module related module
+	 * @param {Error} error Original error
+	 */
+	constructor(module, error) {
+		super();
+
+		/** @type {string} */
+		this.name = "ModuleHashingError";
+		this.error = error;
+		this.message = error.message;
+		this.details = error.stack;
+		this.module = module;
+	}
+}
+
+/** @type {typeof ModuleHashingError} */
+module.exports = ModuleHashingError;
Index: frontend/node_modules/webpack/lib/errors/ModuleNotFoundError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleNotFoundError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleNotFoundError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+
+const previouslyPolyfilledBuiltinModules = {
+	assert: "assert/",
+	buffer: "buffer/",
+	console: "console-browserify",
+	constants: "constants-browserify",
+	crypto: "crypto-browserify",
+	domain: "domain-browser",
+	events: "events/",
+	http: "stream-http",
+	https: "https-browserify",
+	os: "os-browserify/browser",
+	path: "path-browserify",
+	punycode: "punycode/",
+	process: "process/browser",
+	querystring: "querystring-es3",
+	stream: "stream-browserify",
+	_stream_duplex: "readable-stream/duplex",
+	_stream_passthrough: "readable-stream/passthrough",
+	_stream_readable: "readable-stream/readable",
+	_stream_transform: "readable-stream/transform",
+	_stream_writable: "readable-stream/writable",
+	string_decoder: "string_decoder/",
+	sys: "util/",
+	timers: "timers-browserify",
+	tty: "tty-browserify",
+	url: "url/",
+	util: "util/",
+	vm: "vm-browserify",
+	zlib: "browserify-zlib"
+};
+
+class ModuleNotFoundError extends WebpackError {
+	/**
+	 * Creates an instance of ModuleNotFoundError.
+	 * @param {Module | null} module module tied to dependency
+	 * @param {Error & { details?: string }} err error thrown
+	 * @param {DependencyLocation} loc location of dependency
+	 */
+	constructor(module, err, loc) {
+		let message = `Module not found: ${err.toString()}`;
+
+		// TODO remove in webpack 6
+		const match = err.message.match(/Can't resolve '([^']+)'/);
+		if (match) {
+			const request = match[1];
+			const alias =
+				previouslyPolyfilledBuiltinModules[
+					/** @type {keyof previouslyPolyfilledBuiltinModules} */ (request)
+				];
+			if (alias) {
+				const pathIndex = alias.indexOf("/");
+				const dependency = pathIndex > 0 ? alias.slice(0, pathIndex) : alias;
+				message +=
+					"\n\n" +
+					"BREAKING CHANGE: " +
+					"webpack < 5 used to include polyfills for node.js core modules by default.\n" +
+					"This is no longer the case. Verify if you need this module and configure a polyfill for it.\n\n";
+				message +=
+					"If you want to include a polyfill, you need to:\n" +
+					`\t- add a fallback 'resolve.fallback: { "${request}": require.resolve("${alias}") }'\n` +
+					`\t- install '${dependency}'\n`;
+				message +=
+					"If you don't want to include a polyfill, you can use an empty module like this:\n" +
+					`\tresolve.fallback: { "${request}": false }`;
+			}
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleNotFoundError";
+		this.details = err.details;
+		this.module = module;
+		this.error = err;
+		this.loc = loc;
+	}
+}
+
+module.exports = ModuleNotFoundError;
Index: frontend/node_modules/webpack/lib/errors/ModuleParseError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleParseError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleParseError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,130 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Dependency").SourcePosition} SourcePosition */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+const WASM_HEADER = Buffer.from([0x00, 0x61, 0x73, 0x6d]);
+
+class ModuleParseError extends WebpackError {
+	/**
+	 * Creates an instance of ModuleParseError.
+	 * @param {string | Buffer} source source code
+	 * @param {Error & { loc?: SourcePosition }} err the parse error
+	 * @param {string[]} loaders the loaders used
+	 * @param {string} type module type
+	 */
+	constructor(source, err, loaders, type) {
+		let message = `Module parse failed: ${err && err.message}`;
+		/** @type {undefined | DependencyLocation} */
+		let loc;
+
+		if (
+			((Buffer.isBuffer(source) && source.subarray(0, 4).equals(WASM_HEADER)) ||
+				(typeof source === "string" && /^\0asm/.test(source))) &&
+			!type.startsWith("webassembly")
+		) {
+			message +=
+				"\nThe module seem to be a WebAssembly module, but module is not flagged as WebAssembly module for webpack.";
+			message +=
+				"\nBREAKING CHANGE: Since webpack 5 WebAssembly is not enabled by default and flagged as experimental feature.";
+			message +=
+				"\nYou need to enable one of the WebAssembly experiments via 'experiments.asyncWebAssembly: true' (based on async modules) or 'experiments.syncWebAssembly: true' (like webpack 4, deprecated).";
+			message +=
+				"\nFor files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: \"webassembly/async\"').";
+		} else if (!loaders) {
+			message +=
+				"\nYou may need an appropriate loader to handle this file type. " +
+				"See https://webpack.js.org/concepts/loaders";
+		} else if (loaders.length >= 1) {
+			message += `\nFile was processed with these loaders:${loaders
+				.map((loader) => `\n * ${loader}`)
+				.join("")}`;
+			message +=
+				"\nYou may need an additional loader to handle the result of these loaders.";
+		} else {
+			message +=
+				"\nYou may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders";
+		}
+
+		if (
+			err &&
+			err.loc &&
+			typeof err.loc === "object" &&
+			typeof err.loc.line === "number"
+		) {
+			const lineNumber = err.loc.line;
+
+			if (
+				Buffer.isBuffer(source) ||
+				// eslint-disable-next-line no-control-regex
+				/[\0\u0001\u0002\u0003\u0004\u0005\u0006\u0007]/.test(source)
+			) {
+				// binary file
+				message += "\n(Source code omitted for this binary file)";
+			} else {
+				const sourceLines = source.split(/\r?\n/);
+				const start = Math.max(0, lineNumber - 3);
+				const linesBefore = sourceLines.slice(start, lineNumber - 1);
+				const theLine = sourceLines[lineNumber - 1];
+				const linesAfter = sourceLines.slice(lineNumber, lineNumber + 2);
+
+				message += `${linesBefore
+					.map((l) => `\n| ${l}`)
+					.join(
+						""
+					)}\n> ${theLine}${linesAfter.map((l) => `\n| ${l}`).join("")}`;
+			}
+
+			loc = { start: err.loc };
+		} else if (err && err.stack) {
+			message += `\n${err.stack}`;
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleParseError";
+		/** @type {undefined | DependencyLocation} */
+		this.loc = loc;
+		/** @type {Error} */
+		this.error = err;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.error);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.error = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ModuleParseError, "webpack/lib/errors/ModuleParseError");
+
+module.exports = ModuleParseError;
Index: frontend/node_modules/webpack/lib/errors/ModuleRestoreError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleRestoreError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleRestoreError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+
+class ModuleRestoreError extends WebpackError {
+	/**
+	 * Creates an instance of ModuleRestoreError.
+	 * @param {Module} module module tied to dependency
+	 * @param {string | Error} err error thrown
+	 */
+	constructor(module, err) {
+		let message = "Module restore failed: ";
+		/** @type {string | undefined} */
+		const details = undefined;
+		if (err !== null && typeof err === "object") {
+			if (typeof err.stack === "string" && err.stack) {
+				const stack = err.stack;
+				message += stack;
+			} else if (typeof err.message === "string" && err.message) {
+				message += err.message;
+			} else {
+				message += err;
+			}
+		} else {
+			message += String(err);
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleRestoreError";
+		/** @type {string | undefined} */
+		this.details = details;
+		this.module = module;
+		this.error = err;
+	}
+}
+
+/** @type {typeof ModuleRestoreError} */
+module.exports = ModuleRestoreError;
Index: frontend/node_modules/webpack/lib/errors/ModuleStoreError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleStoreError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleStoreError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,46 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Module")} Module */
+
+class ModuleStoreError extends WebpackError {
+	/**
+	 * Creates an instance of ModuleStoreError.
+	 * @param {Module} module module tied to dependency
+	 * @param {string | Error} err error thrown
+	 */
+	constructor(module, err) {
+		let message = "Module storing failed: ";
+		/** @type {string | undefined} */
+		const details = undefined;
+		if (err !== null && typeof err === "object") {
+			if (typeof err.stack === "string" && err.stack) {
+				const stack = err.stack;
+				message += stack;
+			} else if (typeof err.message === "string" && err.message) {
+				message += err.message;
+			} else {
+				message += err;
+			}
+		} else {
+			message += String(err);
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleStoreError";
+		this.details = /** @type {string | undefined} */ (details);
+		this.module = module;
+		this.error = err;
+	}
+}
+
+/** @type {typeof ModuleStoreError} */
+module.exports = ModuleStoreError;
Index: frontend/node_modules/webpack/lib/errors/ModuleWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/ModuleWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/ModuleWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { cleanUp } = require("../ErrorHelpers");
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ModuleWarning extends WebpackError {
+	/**
+	 * Creates an instance of ModuleWarning.
+	 * @param {Error} warning error thrown
+	 * @param {{ from?: string | null }} info additional info
+	 */
+	constructor(warning, { from = null } = {}) {
+		let message = "Module Warning";
+
+		message += from ? ` (from ${from}):\n` : ": ";
+
+		if (warning && typeof warning === "object" && warning.message) {
+			message += warning.message;
+		} else if (warning) {
+			message += String(warning);
+		}
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "ModuleWarning";
+		this.warning = warning;
+		this.details =
+			warning && typeof warning === "object" && warning.stack
+				? cleanUp(warning.stack, this.message)
+				: undefined;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+
+		write(this.warning);
+
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+
+		this.warning = read();
+
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(ModuleWarning, "webpack/lib/errors/ModuleWarning");
+
+/** @type {typeof ModuleWarning} */
+module.exports = ModuleWarning;
Index: frontend/node_modules/webpack/lib/errors/NodeStuffInWebError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/NodeStuffInWebError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/NodeStuffInWebError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+class NodeStuffInWebError extends WebpackError {
+	/**
+	 * Creates an instance of NodeStuffInWebError.
+	 * @param {DependencyLocation} loc loc
+	 * @param {string} expression expression
+	 * @param {string} description description
+	 */
+	constructor(loc, expression, description) {
+		super(
+			`${JSON.stringify(
+				expression
+			)} has been used, it will be undefined in next major version.
+${description}`
+		);
+
+		/** @type {string} */
+		this.name = "NodeStuffInWebError";
+		this.loc = loc;
+	}
+}
+
+makeSerializable(NodeStuffInWebError, "webpack/lib/NodeStuffInWebError");
+
+module.exports = NodeStuffInWebError;
Index: frontend/node_modules/webpack/lib/errors/NonErrorEmittedError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/NonErrorEmittedError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/NonErrorEmittedError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+class NonErrorEmittedError extends WebpackError {
+	/**
+	 * @param {EXPECTED_ANY} error value which is not an instance of Error
+	 */
+	constructor(error) {
+		super();
+
+		this.name = "NonErrorEmittedError";
+		this.message = `(Emitted value instead of an instance of Error) ${error}`;
+	}
+}
+
+makeSerializable(
+	NonErrorEmittedError,
+	"webpack/lib/errors/NonErrorEmittedError"
+);
+
+module.exports = NonErrorEmittedError;
Index: frontend/node_modules/webpack/lib/errors/UnhandledSchemeError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/UnhandledSchemeError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/UnhandledSchemeError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/**
+ * Error raised when webpack encounters a resource URI scheme that no installed
+ * plugin knows how to read.
+ */
+class UnhandledSchemeError extends WebpackError {
+	/**
+	 * Creates an error explaining that the current resource scheme is not
+	 * supported by the active plugin set.
+	 * @param {string} scheme scheme
+	 * @param {string} resource resource
+	 */
+	constructor(scheme, resource) {
+		super(
+			`Reading from "${resource}" is not handled by plugins (Unhandled scheme).` +
+				'\nWebpack supports "data:" and "file:" URIs by default.' +
+				`\nYou may need an additional plugin to handle "${scheme}:" URIs.`
+		);
+		this.file = resource;
+		/** @type {string} */
+		this.name = "UnhandledSchemeError";
+	}
+}
+
+makeSerializable(
+	UnhandledSchemeError,
+	"webpack/lib/errors/UnhandledSchemeError",
+	"UnhandledSchemeError"
+);
+
+module.exports = UnhandledSchemeError;
Index: frontend/node_modules/webpack/lib/errors/UnsupportedFeatureWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/UnsupportedFeatureWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/UnsupportedFeatureWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("../util/makeSerializable");
+const WebpackError = require("./WebpackError");
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+
+class UnsupportedFeatureWarning extends WebpackError {
+	/**
+	 * Creates an instance of UnsupportedFeatureWarning.
+	 * @param {string} message description of warning
+	 * @param {DependencyLocation} loc location start and end positions of the module
+	 */
+	constructor(message, loc) {
+		super(message);
+
+		/** @type {string} */
+		this.name = "UnsupportedFeatureWarning";
+		/** @type {DependencyLocation} */
+		this.loc = loc;
+		/** @type {boolean} */
+		this.hideStack = true;
+	}
+}
+
+makeSerializable(
+	UnsupportedFeatureWarning,
+	"webpack/lib/errors/UnsupportedFeatureWarning"
+);
+
+module.exports = UnsupportedFeatureWarning;
Index: frontend/node_modules/webpack/lib/errors/WebpackError.js
===================================================================
--- frontend/node_modules/webpack/lib/errors/WebpackError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/errors/WebpackError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,84 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Jarid Margolin @jaridmargolin
+*/
+
+"use strict";
+
+const inspect = require("util").inspect.custom;
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class WebpackError extends Error {
+	/**
+	 * Creates an instance of WebpackError.
+	 * @param {string=} message error message
+	 * @param {{ cause?: unknown }} options error options
+	 */
+	constructor(message, options = {}) {
+		super(message, options);
+
+		/** @type {string=} */
+		this.details = undefined;
+		/** @type {(Module | null)=} */
+		this.module = undefined;
+		/** @type {DependencyLocation=} */
+		this.loc = undefined;
+		/** @type {boolean=} */
+		this.hideStack = undefined;
+		/** @type {Chunk=} */
+		this.chunk = undefined;
+		/** @type {string=} */
+		this.file = undefined;
+	}
+
+	/**
+	 * Returns inspect message.
+	 * @returns {string} inspect message
+	 */
+	[inspect]() {
+		return (
+			this.stack +
+			(this.details ? `\n${this.details}` : "") +
+			(this.cause ? `\n${this.cause}` : "")
+		);
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		write(this.name);
+		write(this.message);
+		write(this.stack);
+		write(this.cause);
+		write(this.details);
+		write(this.loc);
+		write(this.hideStack);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize({ read }) {
+		this.name = read();
+		this.message = read();
+		this.stack = read();
+		this.cause = read();
+		this.details = read();
+		this.loc = read();
+		this.hideStack = read();
+	}
+}
+
+makeSerializable(WebpackError, "webpack/lib/errors/WebpackError");
+
+/** @type {typeof WebpackError} */
+module.exports = WebpackError;
Index: frontend/node_modules/webpack/lib/esm/ExportWebpackRequireRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/esm/ExportWebpackRequireRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/esm/ExportWebpackRequireRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,32 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+class ExportWebpackRequireRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("export webpack runtime", RuntimeModule.STAGE_ATTACH);
+	}
+
+	/**
+	 * Returns true, if the runtime module should get it's own scope.
+	 * @returns {boolean} true, if the runtime module should get it's own scope
+	 */
+	shouldIsolate() {
+		return false;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return `export { ${RuntimeGlobals.require} };`;
+	}
+}
+
+module.exports = ExportWebpackRequireRuntimeModule;
Index: frontend/node_modules/webpack/lib/esm/ModuleChunkFormatPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/esm/ModuleChunkFormatPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/esm/ModuleChunkFormatPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,274 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const { HotUpdateChunk, RuntimeGlobals } = require("..");
+const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
+const Template = require("../Template");
+const {
+	createChunkHashHandler,
+	getChunkInfo
+} = require("../javascript/ChunkFormatHelpers");
+const { getAllChunks } = require("../javascript/ChunkHelpers");
+const {
+	chunkHasJs,
+	getChunkFilenameTemplate,
+	getCompilationHooks
+} = require("../javascript/JavascriptModulesPlugin");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+
+/**
+ * Gets relative path.
+ * @param {Compilation} compilation the compilation instance
+ * @param {Chunk} chunk the chunk
+ * @param {Chunk} runtimeChunk the runtime chunk
+ * @returns {string} the relative path
+ */
+const getRelativePath = (compilation, chunk, runtimeChunk) => {
+	const currentOutputName = compilation
+		.getPath(
+			getChunkFilenameTemplate(runtimeChunk, compilation.outputOptions),
+			{
+				chunk: runtimeChunk,
+				contentHashType: "javascript"
+			}
+		)
+		.replace(/^\/+/g, "")
+		.split("/");
+	const baseOutputName = [...currentOutputName];
+	const chunkOutputName = compilation
+		.getPath(getChunkFilenameTemplate(chunk, compilation.outputOptions), {
+			chunk,
+			contentHashType: "javascript"
+		})
+		.replace(/^\/+/g, "")
+		.split("/");
+
+	// remove common parts except filename
+	while (
+		baseOutputName.length > 1 &&
+		chunkOutputName.length > 1 &&
+		baseOutputName[0] === chunkOutputName[0]
+	) {
+		baseOutputName.shift();
+		chunkOutputName.shift();
+	}
+	const last = chunkOutputName.join("/");
+	// create final path
+	return getUndoPath(baseOutputName.join("/"), last, true) + last;
+};
+
+/**
+ * Renders chunk import.
+ * @param {Compilation} compilation the compilation instance
+ * @param {Chunk} chunk the chunk to render the import for
+ * @param {string=} namedImport the named import to use for the import
+ * @param {Chunk=} runtimeChunk the runtime chunk
+ * @returns {string} the import source
+ */
+function renderChunkImport(compilation, chunk, namedImport, runtimeChunk) {
+	return `import ${namedImport ? `* as ${namedImport}` : `{ ${RuntimeGlobals.require} }`} from ${JSON.stringify(
+		getRelativePath(compilation, chunk, runtimeChunk || chunk)
+	)};\n`;
+}
+
+/**
+ * Gets chunk named import.
+ * @param {number} index the index of the chunk
+ * @returns {string} the named import to use for the import
+ */
+function getChunkNamedImport(index) {
+	return `__webpack_chunk_${index}__`;
+}
+
+const PLUGIN_NAME = "ModuleChunkFormatPlugin";
+
+class ModuleChunkFormatPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.additionalChunkRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set) => {
+					if (chunk.hasRuntime()) return;
+					if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
+						set.add(RuntimeGlobals.require);
+						set.add(RuntimeGlobals.externalInstallChunk);
+					}
+				}
+			);
+			const hooks = getCompilationHooks(compilation);
+			/**
+			 * With dependent chunks.
+			 * @param {Iterable<Chunk>} chunks the chunks to render
+			 * @param {ChunkGraph} chunkGraph the chunk graph
+			 * @param {Chunk=} runtimeChunk the runtime chunk
+			 * @returns {Source | undefined} the source
+			 */
+			const withDependentChunks = (chunks, chunkGraph, runtimeChunk) => {
+				if (/** @type {Set<Chunk>} */ (chunks).size > 0) {
+					const source = new ConcatSource();
+					let index = 0;
+
+					for (const chunk of chunks) {
+						index++;
+
+						if (!chunkHasJs(chunk, chunkGraph)) {
+							continue;
+						}
+						const namedImport = getChunkNamedImport(index);
+						source.add(
+							renderChunkImport(
+								compilation,
+								chunk,
+								namedImport,
+								runtimeChunk || chunk
+							)
+						);
+						source.add(
+							`${RuntimeGlobals.externalInstallChunk}(${namedImport});\n`
+						);
+					}
+					return source;
+				}
+			};
+			hooks.renderStartup.tap(
+				PLUGIN_NAME,
+				(modules, _lastModule, renderContext) => {
+					const { chunk, chunkGraph } = renderContext;
+					if (
+						chunkGraph.getNumberOfEntryModules(chunk) > 0 &&
+						chunk.hasRuntime()
+					) {
+						const entryDependentChunks =
+							chunkGraph.getChunkEntryDependentChunksIterable(chunk);
+						const sourceWithDependentChunks = withDependentChunks(
+							entryDependentChunks,
+							chunkGraph,
+							chunk
+						);
+						if (!sourceWithDependentChunks) {
+							return modules;
+						}
+						if (modules.size() === 0) {
+							return sourceWithDependentChunks;
+						}
+						const source = new ConcatSource();
+						source.add(sourceWithDependentChunks);
+						source.add("\n");
+						source.add(modules);
+						return source;
+					}
+					return modules;
+				}
+			);
+			hooks.renderChunk.tap(PLUGIN_NAME, (modules, renderContext) => {
+				const { chunk, chunkGraph, runtimeTemplate } = renderContext;
+				const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
+				const source = new ConcatSource();
+				source.add(
+					`export const ${RuntimeGlobals.esmId} = ${JSON.stringify(chunk.id)};\n`
+				);
+				source.add(
+					`export const ${RuntimeGlobals.esmIds} = ${JSON.stringify(chunk.ids)};\n`
+				);
+				source.add(`export const ${RuntimeGlobals.esmModules} = `);
+				source.add(modules);
+				source.add(";\n");
+				const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder(chunk);
+				if (runtimeModules.length > 0) {
+					source.add(`export const ${RuntimeGlobals.esmRuntime} =\n`);
+					source.add(
+						Template.renderChunkRuntimeModules(runtimeModules, renderContext)
+					);
+				}
+				if (hotUpdateChunk) {
+					return source;
+				}
+				const { entries, runtimeChunk } = getChunkInfo(chunk, chunkGraph);
+				if (runtimeChunk) {
+					const entrySource = new ConcatSource();
+					entrySource.add(source);
+					entrySource.add(";\n\n// load runtime\n");
+					entrySource.add(
+						renderChunkImport(compilation, runtimeChunk, "", chunk)
+					);
+					const startupSource = new ConcatSource();
+					startupSource.add(
+						`var __webpack_exec__ = ${runtimeTemplate.returningFunction(
+							`${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)`,
+							"moduleId"
+						)}\n`
+					);
+
+					/** @type {Set<Chunk>} */
+					const loadedChunks = new Set();
+					for (let i = 0; i < entries.length; i++) {
+						const [module, entrypoint] = entries[i];
+						if (!chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
+							continue;
+						}
+						const final = i + 1 === entries.length;
+						const moduleId = chunkGraph.getModuleId(module);
+						const chunks = getAllChunks(
+							/** @type {Entrypoint} */ (entrypoint),
+							/** @type {Chunk} */ (runtimeChunk),
+							undefined
+						);
+						/** @type {Set<Chunk>} */
+						const processChunks = new Set();
+						for (const chunk of chunks) {
+							if (loadedChunks.has(chunk)) {
+								continue;
+							}
+							loadedChunks.add(chunk);
+							processChunks.add(chunk);
+						}
+						const sourceWithDependentChunks = withDependentChunks(
+							processChunks,
+							chunkGraph,
+							chunk
+						);
+						if (sourceWithDependentChunks) {
+							startupSource.add("\n");
+							startupSource.add(sourceWithDependentChunks);
+						}
+						startupSource.add(
+							`${
+								final ? `var ${RuntimeGlobals.exports} = ` : ""
+							}__webpack_exec__(${JSON.stringify(moduleId)});\n`
+						);
+					}
+
+					entrySource.add(
+						hooks.renderStartup.call(
+							startupSource,
+							entries[entries.length - 1][0],
+							renderContext
+						)
+					);
+					return entrySource;
+				}
+				return source;
+			});
+			hooks.chunkHash.tap(PLUGIN_NAME, createChunkHashHandler(PLUGIN_NAME));
+		});
+	}
+}
+
+module.exports = ModuleChunkFormatPlugin;
Index: frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,145 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const ExportWebpackRequireRuntimeModule = require("./ExportWebpackRequireRuntimeModule");
+const ModuleChunkLoadingRuntimeModule = require("./ModuleChunkLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+
+const PLUGIN_NAME = "ModuleChunkLoadingPlugin";
+
+class ModuleChunkLoadingPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalChunkLoading = compilation.outputOptions.chunkLoading;
+			/**
+			 * Checks whether this module chunk loading plugin is enabled for chunk.
+			 * @param {Chunk} chunk chunk to check
+			 * @returns {boolean} true, when the plugin is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const chunkLoading =
+					options && options.chunkLoading !== undefined
+						? options.chunkLoading
+						: globalChunkLoading;
+				return chunkLoading === "import";
+			};
+			/** @type {WeakSet<Chunk>} */
+			const onceForChunkSet = new WeakSet();
+			/**
+			 * Handles the hook callback for this code path.
+			 * @param {Chunk} chunk chunk to check
+			 * @param {RuntimeRequirements} set runtime requirements
+			 */
+			const handler = (chunk, set) => {
+				if (onceForChunkSet.has(chunk)) return;
+				onceForChunkSet.add(chunk);
+				if (!isEnabledForChunk(chunk)) return;
+				set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				set.add(RuntimeGlobals.hasOwnProperty);
+				compilation.addRuntimeModule(
+					chunk,
+					new ModuleChunkLoadingRuntimeModule(set)
+				);
+			};
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.baseURI)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.externalInstallChunk)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.onChunksLoaded)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.externalInstallChunk)
+				.tap(PLUGIN_NAME, (chunk) => {
+					if (!isEnabledForChunk(chunk)) return;
+					compilation.addRuntimeModule(
+						chunk,
+						new ExportWebpackRequireRuntimeModule()
+					);
+				});
+
+			// We need public path only when we prefetch/preload chunk or public path is not `auto`
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.prefetchChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.preloadChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+
+					if (compilation.outputOptions.publicPath !== "auto") {
+						set.add(RuntimeGlobals.publicPath);
+					}
+
+					set.add(RuntimeGlobals.getChunkScriptFilename);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.loadScript);
+					set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
+					set.add(RuntimeGlobals.moduleCache);
+					set.add(RuntimeGlobals.hmrModuleData);
+					set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.getUpdateManifestFilename);
+				});
+
+			compilation.hooks.additionalTreeRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph }) => {
+					if (chunkGraph.hasChunkEntryDependentChunks(chunk)) {
+						set.add(RuntimeGlobals.externalInstallChunk);
+					}
+				}
+			);
+		});
+	}
+}
+
+module.exports = ModuleChunkLoadingPlugin;
Index: frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,431 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+	generateJavascriptHMR
+} = require("../hmr/JavascriptHotModuleReplacementHelper");
+const {
+	chunkHasJs,
+	getChunkFilenameTemplate
+} = require("../javascript/JavascriptModulesPlugin");
+const { getInitialChunkIds } = require("../javascript/StartupHelpers");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+/**
+ * Defines the jsonp compilation plugin hooks type used by this module.
+ * @typedef {object} JsonpCompilationPluginHooks
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
+ */
+
+/** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * Returns hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {JsonpCompilationPluginHooks} hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				linkPreload: new SyncWaterfallHook(["source", "chunk"]),
+				linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Creates an instance of ModuleChunkLoadingRuntimeModule.
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("import chunk loading", RuntimeModule.STAGE_ATTACH);
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this._runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Returns generated code.
+	 * @private
+	 * @param {Chunk} chunk chunk
+	 * @param {string} rootOutputDir root output directory
+	 * @returns {string} generated code
+	 */
+	_generateBaseUri(chunk, rootOutputDir) {
+		const options = chunk.getEntryOptions();
+		if (options && options.baseUri) {
+			return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
+		}
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const {
+			outputOptions: { importMetaName }
+		} = compilation;
+		return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
+			rootOutputDir
+		)}, ${importMetaName}.url);`;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const environment = compilation.outputOptions.environment;
+		const {
+			runtimeTemplate,
+			outputOptions: { importFunctionName, crossOriginLoading, charset }
+		} = compilation;
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
+		const withExternalInstallChunk = this._runtimeRequirements.has(
+			RuntimeGlobals.externalInstallChunk
+		);
+		const withLoading = this._runtimeRequirements.has(
+			RuntimeGlobals.ensureChunkHandlers
+		);
+		const withOnChunkLoad = this._runtimeRequirements.has(
+			RuntimeGlobals.onChunksLoaded
+		);
+		const withHmr = this._runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		const withHmrManifest = this._runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadManifest
+		);
+		const { linkPreload, linkPrefetch } =
+			ModuleChunkLoadingRuntimeModule.getCompilationHooks(compilation);
+		const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
+		const withPrefetch =
+			(environment.document || isNeutralPlatform) &&
+			this._runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers) &&
+			chunk.hasChildByOrder(chunkGraph, "prefetch", true, chunkHasJs);
+		const withPreload =
+			(environment.document || isNeutralPlatform) &&
+			this._runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers) &&
+			chunk.hasChildByOrder(chunkGraph, "preload", true, chunkHasJs);
+		const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
+		const hasJsMatcher = compileBooleanMatcher(conditionMap);
+		const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
+
+		const outputName = compilation.getPath(
+			getChunkFilenameTemplate(chunk, compilation.outputOptions),
+			{
+				chunk,
+				contentHashType: "javascript"
+			}
+		);
+		const rootOutputDir = getUndoPath(
+			outputName,
+			compilation.outputOptions.path,
+			true
+		);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_module`
+			: undefined;
+
+		return Template.asString([
+			withBaseURI
+				? this._generateBaseUri(chunk, rootOutputDir)
+				: "// no baseURI",
+			"",
+			"// object to store loaded and loading chunks",
+			"// undefined = chunk not loaded, null = chunk preloaded/prefetched",
+			"// [resolve, Promise] = chunk loading, 0 = chunk loaded",
+			`var installedChunks = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{`,
+			Template.indent(
+				Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(
+					",\n"
+				)
+			),
+			"};",
+			"",
+			withLoading || withExternalInstallChunk
+				? `var installChunk = ${runtimeTemplate.basicFunction("data", [
+						runtimeTemplate.destructureObject(
+							[
+								RuntimeGlobals.esmIds,
+								RuntimeGlobals.esmModules,
+								RuntimeGlobals.esmRuntime
+							],
+							"data"
+						),
+						'// add "modules" to the modules object,',
+						'// then flag all "ids" as loaded and fire callback',
+						"var moduleId, chunkId, i = 0;",
+						`for(moduleId in ${RuntimeGlobals.esmModules}) {`,
+						Template.indent([
+							`if(${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.esmModules}, moduleId)) {`,
+							Template.indent(
+								`${RuntimeGlobals.moduleFactories}[moduleId] = ${RuntimeGlobals.esmModules}[moduleId];`
+							),
+							"}"
+						]),
+						"}",
+						`if(${RuntimeGlobals.esmRuntime}) ${RuntimeGlobals.esmRuntime}(${RuntimeGlobals.require});`,
+						`for(;i < ${RuntimeGlobals.esmIds}.length; i++) {`,
+						Template.indent([
+							`chunkId = ${RuntimeGlobals.esmIds}[i];`,
+							`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
+							Template.indent("installedChunks[chunkId][0]();"),
+							"}",
+							`installedChunks[${RuntimeGlobals.esmIds}[i]] = 0;`
+						]),
+						"}",
+						withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
+					])}`
+				: "// no install chunk",
+			"",
+			withLoading
+				? Template.asString([
+						`${fn}.j = ${runtimeTemplate.basicFunction(
+							"chunkId, promises",
+							hasJsMatcher !== false
+								? Template.indent([
+										"// import() chunk loading for javascript",
+										`var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
+										'if(installedChunkData !== 0) { // 0 means "already installed".',
+										Template.indent([
+											"",
+											'// a Promise means "currently loading".',
+											"if(installedChunkData) {",
+											Template.indent([
+												"promises.push(installedChunkData[1]);"
+											]),
+											"} else {",
+											Template.indent([
+												hasJsMatcher === true
+													? "if(true) { // all chunks have JS"
+													: `if(${hasJsMatcher("chunkId")}) {`,
+												Template.indent([
+													"// setup Promise in chunk cache",
+													`var promise = ${importFunctionName}(${
+														compilation.outputOptions.publicPath === "auto"
+															? JSON.stringify(rootOutputDir)
+															: RuntimeGlobals.publicPath
+													} + ${
+														RuntimeGlobals.getChunkScriptFilename
+													}(chunkId)).then(installChunk, ${runtimeTemplate.basicFunction(
+														"e",
+														[
+															"if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
+															"throw e;"
+														]
+													)});`,
+													`var promise = Promise.race([promise, new Promise(${runtimeTemplate.expressionFunction(
+														"installedChunkData = installedChunks[chunkId] = [resolve]",
+														"resolve"
+													)})])`,
+													"promises.push(installedChunkData[1] = promise);"
+												]),
+												hasJsMatcher === true
+													? "}"
+													: "} else installedChunks[chunkId] = 0;"
+											]),
+											"}"
+										]),
+										"}"
+									])
+								: Template.indent(["installedChunks[chunkId] = 0;"])
+						)};`
+					])
+				: "// no chunk on demand loading",
+			"",
+			withPrefetch && hasJsMatcher !== false
+				? `${
+						RuntimeGlobals.prefetchChunkHandlers
+					}.j = ${runtimeTemplate.basicFunction("chunkId", [
+						isNeutralPlatform
+							? "if (typeof document === 'undefined') return;"
+							: "",
+						`if((!${
+							RuntimeGlobals.hasOwnProperty
+						}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
+							hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
+						}) {`,
+						Template.indent([
+							"installedChunks[chunkId] = null;",
+							linkPrefetch.call(
+								Template.asString([
+									"var link = document.createElement('link');",
+									charset ? "link.charset = 'utf-8';" : "",
+									crossOriginLoading
+										? `link.crossOrigin = ${JSON.stringify(
+												crossOriginLoading
+											)};`
+										: "",
+									`if (${RuntimeGlobals.scriptNonce}) {`,
+									Template.indent(
+										`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+									),
+									"}",
+									'link.rel = "prefetch";',
+									'link.as = "script";',
+									`link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`
+								]),
+								chunk
+							),
+							"document.head.appendChild(link);"
+						]),
+						"}"
+					])};`
+				: "// no prefetching",
+			"",
+			withPreload && hasJsMatcher !== false
+				? `${
+						RuntimeGlobals.preloadChunkHandlers
+					}.j = ${runtimeTemplate.basicFunction("chunkId", [
+						isNeutralPlatform
+							? "if (typeof document === 'undefined') return;"
+							: "",
+						`if((!${
+							RuntimeGlobals.hasOwnProperty
+						}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
+							hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
+						}) {`,
+						Template.indent([
+							"installedChunks[chunkId] = null;",
+							linkPreload.call(
+								Template.asString([
+									"var link = document.createElement('link');",
+									charset ? "link.charset = 'utf-8';" : "",
+									`if (${RuntimeGlobals.scriptNonce}) {`,
+									Template.indent(
+										`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+									),
+									"}",
+									'link.rel = "modulepreload";',
+									`link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
+									crossOriginLoading
+										? crossOriginLoading === "use-credentials"
+											? 'link.crossOrigin = "use-credentials";'
+											: Template.asString([
+													"if (link.href.indexOf(window.location.origin + '/') !== 0) {",
+													Template.indent(
+														`link.crossOrigin = ${JSON.stringify(
+															crossOriginLoading
+														)};`
+													),
+													"}"
+												])
+										: ""
+								]),
+								chunk
+							),
+							"document.head.appendChild(link);"
+						]),
+						"}"
+					])};`
+				: "// no preloaded",
+			"",
+			withExternalInstallChunk
+				? Template.asString([
+						`${RuntimeGlobals.externalInstallChunk} = installChunk;`
+					])
+				: "// no external install chunk",
+			"",
+			withOnChunkLoad
+				? `${
+						RuntimeGlobals.onChunksLoaded
+					}.j = ${runtimeTemplate.returningFunction(
+						"installedChunks[chunkId] === 0",
+						"chunkId"
+					)};`
+				: "// no on chunks loaded",
+			withHmr
+				? Template.asString([
+						generateJavascriptHMR("module"),
+						"",
+						"function loadUpdateChunk(chunkId, updatedModulesList) {",
+						Template.indent([
+							`return new Promise(${runtimeTemplate.basicFunction(
+								"resolve, reject",
+								[
+									"// start update chunk loading",
+									`var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId);`,
+									`var onResolve = ${runtimeTemplate.basicFunction("obj", [
+										`var updatedModules = obj.${RuntimeGlobals.esmModules};`,
+										`var updatedRuntime = obj.${RuntimeGlobals.esmRuntime};`,
+										"if(updatedRuntime) currentUpdateRuntime.push(updatedRuntime);",
+										"for(var moduleId in updatedModules) {",
+										Template.indent([
+											`if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
+											Template.indent([
+												"currentUpdate[moduleId] = updatedModules[moduleId];",
+												"if(updatedModulesList) updatedModulesList.push(moduleId);"
+											]),
+											"}"
+										]),
+										"}",
+										"resolve(obj);"
+									])};`,
+									`var onReject = ${runtimeTemplate.basicFunction("error", [
+										"var errorMsg = error.message || 'unknown reason';",
+										"error.message = 'Loading hot update chunk ' + chunkId + ' failed.\\n(' + errorMsg + ')';",
+										"error.name = 'ChunkLoadError';",
+										"reject(error);"
+									])}`,
+									`var loadScript = ${runtimeTemplate.basicFunction(
+										"url, onResolve, onReject",
+										[
+											`return ${importFunctionName}(/* webpackIgnore: true */ url).then(onResolve).catch(onReject)`
+										]
+									)}`,
+									"loadScript(url, onResolve, onReject);"
+								]
+							)});`
+						]),
+						"}",
+						""
+					])
+				: "// no HMR",
+			"",
+			withHmrManifest
+				? Template.asString([
+						`${
+							RuntimeGlobals.hmrDownloadManifest
+						} = ${runtimeTemplate.basicFunction("", [
+							`return ${importFunctionName}(/* webpackIgnore: true */ ${RuntimeGlobals.publicPath} + ${
+								RuntimeGlobals.getUpdateManifestFilename
+							}()).then(${runtimeTemplate.basicFunction("obj", [
+								"return obj.default;"
+							])}, ${runtimeTemplate.basicFunction("error", [
+								"if(['MODULE_NOT_FOUND', 'ENOENT'].includes(error.code)) return;",
+								"throw error;"
+							])});`
+						])};`
+					])
+				: "// no HMR manifest"
+		]);
+	}
+}
+
+module.exports = ModuleChunkLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/hmr/HotModuleReplacement.runtime.js
===================================================================
--- frontend/node_modules/webpack/lib/hmr/HotModuleReplacement.runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/hmr/HotModuleReplacement.runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,419 @@
+// @ts-nocheck
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+var $interceptModuleExecution$ = undefined;
+var $moduleCache$ = undefined;
+var $hmrModuleData$ = undefined;
+/** @type {() => Promise}  */
+var $hmrDownloadManifest$ = undefined;
+var $hmrDownloadUpdateHandlers$ = undefined;
+var $hmrInvalidateModuleHandlers$ = undefined;
+var __webpack_require__ = undefined;
+
+module.exports = function () {
+	var currentModuleData = {};
+	var installedModules = $moduleCache$;
+
+	// module and require creation
+	var currentChildModule;
+	var currentParents = [];
+
+	// status
+	var registeredStatusHandlers = [];
+	var currentStatus = "idle";
+
+	// while downloading
+	var blockingPromises = 0;
+	var blockingPromisesWaiting = [];
+
+	// The update info
+	var currentUpdateApplyHandlers;
+	var queuedInvalidatedModules;
+
+	$hmrModuleData$ = currentModuleData;
+
+	$interceptModuleExecution$.push(function (options) {
+		var module = options.module;
+		var require = createRequire(options.require, options.id);
+		module.hot = createModuleHotObject(options.id, module);
+		module.parents = currentParents;
+		module.children = [];
+		currentParents = [];
+		options.require = require;
+	});
+
+	$hmrDownloadUpdateHandlers$ = {};
+	$hmrInvalidateModuleHandlers$ = {};
+
+	function createRequire(require, moduleId) {
+		var me = installedModules[moduleId];
+		if (!me) return require;
+		var fn = function (request) {
+			if (me.hot.active) {
+				if (installedModules[request]) {
+					var parents = installedModules[request].parents;
+					if (parents.indexOf(moduleId) === -1) {
+						parents.push(moduleId);
+					}
+				} else {
+					currentParents = [moduleId];
+					currentChildModule = request;
+				}
+				if (me.children.indexOf(request) === -1) {
+					me.children.push(request);
+				}
+			} else {
+				console.warn(
+					"[HMR] unexpected require(" +
+						request +
+						") from disposed module " +
+						moduleId
+				);
+				currentParents = [];
+			}
+			return require(request);
+		};
+		var createPropertyDescriptor = function (name) {
+			return {
+				configurable: true,
+				enumerable: true,
+				get: function () {
+					return require[name];
+				},
+				set: function (value) {
+					require[name] = value;
+				}
+			};
+		};
+		for (var name in require) {
+			if (Object.prototype.hasOwnProperty.call(require, name) && name !== "e") {
+				Object.defineProperty(fn, name, createPropertyDescriptor(name));
+			}
+		}
+		fn.e = function (chunkId, fetchPriority) {
+			return trackBlockingPromise(require.e(chunkId, fetchPriority));
+		};
+		return fn;
+	}
+
+	function createModuleHotObject(moduleId, me) {
+		var _main = currentChildModule !== moduleId;
+		var hot = {
+			// private stuff
+			_acceptedDependencies: {},
+			_acceptedErrorHandlers: {},
+			_declinedDependencies: {},
+			_selfAccepted: false,
+			_selfDeclined: false,
+			_selfInvalidated: false,
+			_disposeHandlers: [],
+			_main: _main,
+			_requireSelf: function () {
+				currentParents = me.parents.slice();
+				currentChildModule = _main ? undefined : moduleId;
+				__webpack_require__(moduleId);
+			},
+
+			// Module API
+			active: true,
+			accept: function (dep, callback, errorHandler) {
+				if (dep === undefined) hot._selfAccepted = true;
+				else if (typeof dep === "function") hot._selfAccepted = dep;
+				else if (typeof dep === "object" && dep !== null) {
+					for (var i = 0; i < dep.length; i++) {
+						hot._acceptedDependencies[dep[i]] = callback || function () {};
+						hot._acceptedErrorHandlers[dep[i]] = errorHandler;
+					}
+				} else {
+					hot._acceptedDependencies[dep] = callback || function () {};
+					hot._acceptedErrorHandlers[dep] = errorHandler;
+				}
+			},
+			decline: function (dep) {
+				if (dep === undefined) hot._selfDeclined = true;
+				else if (typeof dep === "object" && dep !== null)
+					for (var i = 0; i < dep.length; i++)
+						hot._declinedDependencies[dep[i]] = true;
+				else hot._declinedDependencies[dep] = true;
+			},
+			dispose: function (callback) {
+				hot._disposeHandlers.push(callback);
+			},
+			addDisposeHandler: function (callback) {
+				hot._disposeHandlers.push(callback);
+			},
+			removeDisposeHandler: function (callback) {
+				var idx = hot._disposeHandlers.indexOf(callback);
+				if (idx >= 0) hot._disposeHandlers.splice(idx, 1);
+			},
+			invalidate: function () {
+				this._selfInvalidated = true;
+				switch (currentStatus) {
+					case "idle":
+						currentUpdateApplyHandlers = [];
+						Object.keys($hmrInvalidateModuleHandlers$).forEach(function (key) {
+							$hmrInvalidateModuleHandlers$[key](
+								moduleId,
+								currentUpdateApplyHandlers
+							);
+						});
+						setStatus("ready");
+						break;
+					case "ready":
+						Object.keys($hmrInvalidateModuleHandlers$).forEach(function (key) {
+							$hmrInvalidateModuleHandlers$[key](
+								moduleId,
+								currentUpdateApplyHandlers
+							);
+						});
+						break;
+					case "prepare":
+					case "check":
+					case "dispose":
+					case "apply":
+						(queuedInvalidatedModules = queuedInvalidatedModules || []).push(
+							moduleId
+						);
+						break;
+					default:
+						// ignore requests in error states
+						break;
+				}
+			},
+
+			// Management API
+			check: hotCheck,
+			apply: hotApply,
+			status: function (l) {
+				if (!l) return currentStatus;
+				registeredStatusHandlers.push(l);
+			},
+			addStatusHandler: function (l) {
+				registeredStatusHandlers.push(l);
+			},
+			removeStatusHandler: function (l) {
+				var idx = registeredStatusHandlers.indexOf(l);
+				if (idx >= 0) registeredStatusHandlers.splice(idx, 1);
+			},
+
+			// inherit from previous dispose call
+			data: currentModuleData[moduleId]
+		};
+		currentChildModule = undefined;
+		return hot;
+	}
+
+	function setStatus(newStatus) {
+		currentStatus = newStatus;
+		var results = [];
+
+		for (var i = 0; i < registeredStatusHandlers.length; i++)
+			results[i] = registeredStatusHandlers[i].call(null, newStatus);
+
+		return Promise.all(results).then(function () {});
+	}
+
+	function unblock() {
+		if (--blockingPromises === 0) {
+			setStatus("ready").then(function () {
+				if (blockingPromises === 0) {
+					var list = blockingPromisesWaiting;
+					blockingPromisesWaiting = [];
+					for (var i = 0; i < list.length; i++) {
+						list[i]();
+					}
+				}
+			});
+		}
+	}
+
+	function trackBlockingPromise(promise) {
+		switch (currentStatus) {
+			case "ready":
+				setStatus("prepare");
+			/* fallthrough */
+			case "prepare":
+				blockingPromises++;
+				promise.then(unblock, unblock);
+				return promise;
+			default:
+				return promise;
+		}
+	}
+
+	function waitForBlockingPromises(fn) {
+		if (blockingPromises === 0) return fn();
+		return new Promise(function (resolve) {
+			blockingPromisesWaiting.push(function () {
+				resolve(fn());
+			});
+		});
+	}
+
+	function hotCheck(applyOnUpdate) {
+		if (currentStatus !== "idle") {
+			throw new Error("check() is only allowed in idle status");
+		}
+		return setStatus("check")
+			.then($hmrDownloadManifest$)
+			.then(function (update) {
+				if (!update) {
+					return setStatus(applyInvalidatedModules() ? "ready" : "idle").then(
+						function () {
+							return null;
+						}
+					);
+				}
+
+				return setStatus("prepare").then(function () {
+					var updatedModules = [];
+					currentUpdateApplyHandlers = [];
+
+					return Promise.all(
+						Object.keys($hmrDownloadUpdateHandlers$).reduce(function (
+							promises,
+							key
+						) {
+							$hmrDownloadUpdateHandlers$[key](
+								update.c,
+								update.r,
+								update.m,
+								promises,
+								currentUpdateApplyHandlers,
+								updatedModules,
+								update.css
+							);
+							return promises;
+						}, [])
+					).then(function () {
+						return waitForBlockingPromises(function () {
+							if (applyOnUpdate) {
+								return internalApply(applyOnUpdate);
+							}
+							return setStatus("ready").then(function () {
+								return updatedModules;
+							});
+						});
+					});
+				});
+			});
+	}
+
+	function hotApply(options) {
+		if (currentStatus !== "ready") {
+			return Promise.resolve().then(function () {
+				throw new Error(
+					"apply() is only allowed in ready status (state: " +
+						currentStatus +
+						")"
+				);
+			});
+		}
+		return internalApply(options);
+	}
+
+	function internalApply(options) {
+		options = options || {};
+
+		applyInvalidatedModules();
+
+		var results = currentUpdateApplyHandlers.map(function (handler) {
+			return handler(options);
+		});
+		currentUpdateApplyHandlers = undefined;
+
+		var errors = results
+			.map(function (r) {
+				return r.error;
+			})
+			.filter(Boolean);
+
+		if (errors.length > 0) {
+			return setStatus("abort").then(function () {
+				throw errors[0];
+			});
+		}
+
+		// Now in "dispose" phase
+		var disposePromise = setStatus("dispose");
+
+		results.forEach(function (result) {
+			if (result.dispose) result.dispose();
+		});
+
+		// Now in "apply" phase
+		var applyPromise = setStatus("apply");
+
+		var error;
+		var reportError = function (err) {
+			if (!error) error = err;
+		};
+
+		var outdatedModules = [];
+
+		var onAccepted = function () {
+			return Promise.all([disposePromise, applyPromise]).then(function () {
+				// handle errors in accept handlers and self accepted module load
+				if (error) {
+					return setStatus("fail").then(function () {
+						throw error;
+					});
+				}
+
+				if (queuedInvalidatedModules) {
+					return internalApply(options).then(function (list) {
+						outdatedModules.forEach(function (moduleId) {
+							if (list.indexOf(moduleId) < 0) list.push(moduleId);
+						});
+						return list;
+					});
+				}
+
+				return setStatus("idle").then(function () {
+					return outdatedModules;
+				});
+			});
+		};
+
+		return Promise.all(
+			results
+				.filter(function (result) {
+					return result.apply;
+				})
+				.map(function (result) {
+					return result.apply(reportError);
+				})
+		)
+			.then(function (applyResults) {
+				applyResults.forEach(function (modules) {
+					if (modules) {
+						for (var i = 0; i < modules.length; i++) {
+							outdatedModules.push(modules[i]);
+						}
+					}
+				});
+			})
+			.then(onAccepted);
+	}
+
+	function applyInvalidatedModules() {
+		if (queuedInvalidatedModules) {
+			if (!currentUpdateApplyHandlers) currentUpdateApplyHandlers = [];
+			Object.keys($hmrInvalidateModuleHandlers$).forEach(function (key) {
+				queuedInvalidatedModules.forEach(function (moduleId) {
+					$hmrInvalidateModuleHandlers$[key](
+						moduleId,
+						currentUpdateApplyHandlers
+					);
+				});
+			});
+			queuedInvalidatedModules = undefined;
+			return true;
+		}
+	}
+};
Index: frontend/node_modules/webpack/lib/hmr/HotModuleReplacementRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/hmr/HotModuleReplacementRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/hmr/HotModuleReplacementRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+class HotModuleReplacementRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("hot module replacement", RuntimeModule.STAGE_BASIC);
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return Template.getFunctionContent(
+			require("./HotModuleReplacement.runtime")
+		)
+			.replace(
+				/\$interceptModuleExecution\$/g,
+				RuntimeGlobals.interceptModuleExecution
+			)
+			.replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache)
+			.replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData)
+			.replace(/\$hmrDownloadManifest\$/g, RuntimeGlobals.hmrDownloadManifest)
+			.replace(
+				/\$hmrInvalidateModuleHandlers\$/g,
+				RuntimeGlobals.hmrInvalidateModuleHandlers
+			)
+			.replace(
+				/\$hmrDownloadUpdateHandlers\$/g,
+				RuntimeGlobals.hmrDownloadUpdateHandlers
+			);
+	}
+}
+
+module.exports = HotModuleReplacementRuntimeModule;
Index: frontend/node_modules/webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js
===================================================================
--- frontend/node_modules/webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,471 @@
+// @ts-nocheck
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+var $installedChunks$ = undefined;
+var $loadUpdateChunk$ = undefined;
+var $moduleCache$ = undefined;
+var $moduleFactories$ = undefined;
+var $ensureChunkHandlers$ = undefined;
+var $hasOwnProperty$ = undefined;
+var $hmrModuleData$ = undefined;
+var $hmrDownloadUpdateHandlers$ = undefined;
+var $hmrInvalidateModuleHandlers$ = undefined;
+var __webpack_require__ = undefined;
+
+module.exports = function () {
+	var currentUpdateChunks;
+	var currentUpdate;
+	var currentUpdateRemovedChunks;
+	var currentUpdateRuntime;
+	function applyHandler(options) {
+		if ($ensureChunkHandlers$) delete $ensureChunkHandlers$.$key$Hmr;
+		currentUpdateChunks = undefined;
+		function getAffectedModuleEffects(updateModuleId) {
+			var outdatedModules = [updateModuleId];
+			var outdatedDependencies = {};
+
+			var queue = outdatedModules.map(function (id) {
+				return {
+					chain: [id],
+					id: id
+				};
+			});
+			while (queue.length > 0) {
+				var queueItem = queue.pop();
+				var moduleId = queueItem.id;
+				var chain = queueItem.chain;
+				var module = $moduleCache$[moduleId];
+				if (
+					!module ||
+					(module.hot._selfAccepted && !module.hot._selfInvalidated)
+				)
+					continue;
+				if (module.hot._selfDeclined) {
+					return {
+						type: "self-declined",
+						chain: chain,
+						moduleId: moduleId
+					};
+				}
+				if (module.hot._main) {
+					return {
+						type: "unaccepted",
+						chain: chain,
+						moduleId: moduleId
+					};
+				}
+				for (var i = 0; i < module.parents.length; i++) {
+					var parentId = module.parents[i];
+					var parent = $moduleCache$[parentId];
+					if (!parent) continue;
+					if (parent.hot._declinedDependencies[moduleId]) {
+						return {
+							type: "declined",
+							chain: chain.concat([parentId]),
+							moduleId: moduleId,
+							parentId: parentId
+						};
+					}
+					if (outdatedModules.indexOf(parentId) !== -1) continue;
+					if (parent.hot._acceptedDependencies[moduleId]) {
+						if (!outdatedDependencies[parentId])
+							outdatedDependencies[parentId] = [];
+						addAllToSet(outdatedDependencies[parentId], [moduleId]);
+						continue;
+					}
+					delete outdatedDependencies[parentId];
+					outdatedModules.push(parentId);
+					queue.push({
+						chain: chain.concat([parentId]),
+						id: parentId
+					});
+				}
+			}
+
+			return {
+				type: "accepted",
+				moduleId: updateModuleId,
+				outdatedModules: outdatedModules,
+				outdatedDependencies: outdatedDependencies
+			};
+		}
+
+		function addAllToSet(a, b) {
+			for (var i = 0; i < b.length; i++) {
+				var item = b[i];
+				if (a.indexOf(item) === -1) a.push(item);
+			}
+		}
+
+		// at begin all updates modules are outdated
+		// the "outdated" status can propagate to parents if they don't accept the children
+		var outdatedDependencies = {};
+		var outdatedModules = [];
+		var appliedUpdate = {};
+
+		var warnUnexpectedRequire = function warnUnexpectedRequire(module) {
+			console.warn(
+				"[HMR] unexpected require(" + module.id + ") to disposed module"
+			);
+		};
+
+		for (var moduleId in currentUpdate) {
+			if ($hasOwnProperty$(currentUpdate, moduleId)) {
+				var newModuleFactory = currentUpdate[moduleId];
+				var result = newModuleFactory
+					? getAffectedModuleEffects(moduleId)
+					: {
+							type: "disposed",
+							moduleId: moduleId
+						};
+				/** @type {Error|false} */
+				var abortError = false;
+				var doApply = false;
+				var doDispose = false;
+				var chainInfo = "";
+				if (result.chain) {
+					chainInfo = "\nUpdate propagation: " + result.chain.join(" -> ");
+				}
+				switch (result.type) {
+					case "self-declined":
+						if (options.onDeclined) options.onDeclined(result);
+						if (!options.ignoreDeclined)
+							abortError = new Error(
+								"Aborted because of self decline: " +
+									result.moduleId +
+									chainInfo
+							);
+						break;
+					case "declined":
+						if (options.onDeclined) options.onDeclined(result);
+						if (!options.ignoreDeclined)
+							abortError = new Error(
+								"Aborted because of declined dependency: " +
+									result.moduleId +
+									" in " +
+									result.parentId +
+									chainInfo
+							);
+						break;
+					case "unaccepted":
+						if (options.onUnaccepted) options.onUnaccepted(result);
+						if (!options.ignoreUnaccepted)
+							abortError = new Error(
+								"Aborted because " + moduleId + " is not accepted" + chainInfo
+							);
+						break;
+					case "accepted":
+						if (options.onAccepted) options.onAccepted(result);
+						doApply = true;
+						break;
+					case "disposed":
+						if (options.onDisposed) options.onDisposed(result);
+						doDispose = true;
+						break;
+					default:
+						throw new Error("Unexception type " + result.type);
+				}
+				if (abortError) {
+					return {
+						error: abortError
+					};
+				}
+				if (doApply) {
+					appliedUpdate[moduleId] = newModuleFactory;
+					addAllToSet(outdatedModules, result.outdatedModules);
+					for (moduleId in result.outdatedDependencies) {
+						if ($hasOwnProperty$(result.outdatedDependencies, moduleId)) {
+							if (!outdatedDependencies[moduleId])
+								outdatedDependencies[moduleId] = [];
+							addAllToSet(
+								outdatedDependencies[moduleId],
+								result.outdatedDependencies[moduleId]
+							);
+						}
+					}
+				}
+				if (doDispose) {
+					addAllToSet(outdatedModules, [result.moduleId]);
+					appliedUpdate[moduleId] = warnUnexpectedRequire;
+				}
+			}
+		}
+		currentUpdate = undefined;
+
+		// Store self accepted outdated modules to require them later by the module system
+		var outdatedSelfAcceptedModules = [];
+		for (var j = 0; j < outdatedModules.length; j++) {
+			var outdatedModuleId = outdatedModules[j];
+			var module = $moduleCache$[outdatedModuleId];
+			if (
+				module &&
+				(module.hot._selfAccepted || module.hot._main) &&
+				// removed self-accepted modules should not be required
+				appliedUpdate[outdatedModuleId] !== warnUnexpectedRequire &&
+				// when called invalidate self-accepting is not possible
+				!module.hot._selfInvalidated
+			) {
+				outdatedSelfAcceptedModules.push({
+					module: outdatedModuleId,
+					require: module.hot._requireSelf,
+					errorHandler: module.hot._selfAccepted
+				});
+			}
+		}
+
+		var moduleOutdatedDependencies;
+
+		return {
+			dispose: function () {
+				currentUpdateRemovedChunks.forEach(function (chunkId) {
+					delete $installedChunks$[chunkId];
+				});
+				currentUpdateRemovedChunks = undefined;
+
+				var idx;
+				var queue = outdatedModules.slice();
+				while (queue.length > 0) {
+					var moduleId = queue.pop();
+					var module = $moduleCache$[moduleId];
+					if (!module) continue;
+
+					var data = {};
+
+					// Call dispose handlers
+					var disposeHandlers = module.hot._disposeHandlers;
+					for (j = 0; j < disposeHandlers.length; j++) {
+						disposeHandlers[j].call(null, data);
+					}
+					$hmrModuleData$[moduleId] = data;
+
+					// disable module (this disables requires from this module)
+					module.hot.active = false;
+
+					// remove module from cache
+					delete $moduleCache$[moduleId];
+
+					// when disposing there is no need to call dispose handler
+					delete outdatedDependencies[moduleId];
+
+					// remove "parents" references from all children
+					for (j = 0; j < module.children.length; j++) {
+						var child = $moduleCache$[module.children[j]];
+						if (!child) continue;
+						idx = child.parents.indexOf(moduleId);
+						if (idx >= 0) {
+							child.parents.splice(idx, 1);
+						}
+					}
+				}
+
+				// remove outdated dependency from module children
+				var dependency;
+				for (var outdatedModuleId in outdatedDependencies) {
+					if ($hasOwnProperty$(outdatedDependencies, outdatedModuleId)) {
+						module = $moduleCache$[outdatedModuleId];
+						if (module) {
+							moduleOutdatedDependencies =
+								outdatedDependencies[outdatedModuleId];
+							for (j = 0; j < moduleOutdatedDependencies.length; j++) {
+								dependency = moduleOutdatedDependencies[j];
+								idx = module.children.indexOf(dependency);
+								if (idx >= 0) module.children.splice(idx, 1);
+							}
+						}
+					}
+				}
+			},
+			apply: function (reportError) {
+				var acceptPromises = [];
+				// insert new code
+				for (var updateModuleId in appliedUpdate) {
+					if ($hasOwnProperty$(appliedUpdate, updateModuleId)) {
+						$moduleFactories$[updateModuleId] = appliedUpdate[updateModuleId];
+					}
+				}
+
+				// run new runtime modules
+				for (var i = 0; i < currentUpdateRuntime.length; i++) {
+					currentUpdateRuntime[i](__webpack_require__);
+				}
+
+				// call accept handlers
+				for (var outdatedModuleId in outdatedDependencies) {
+					if ($hasOwnProperty$(outdatedDependencies, outdatedModuleId)) {
+						var module = $moduleCache$[outdatedModuleId];
+						if (module) {
+							moduleOutdatedDependencies =
+								outdatedDependencies[outdatedModuleId];
+							var callbacks = [];
+							var errorHandlers = [];
+							var dependenciesForCallbacks = [];
+							for (var j = 0; j < moduleOutdatedDependencies.length; j++) {
+								var dependency = moduleOutdatedDependencies[j];
+								var acceptCallback =
+									module.hot._acceptedDependencies[dependency];
+								var errorHandler =
+									module.hot._acceptedErrorHandlers[dependency];
+								if (acceptCallback) {
+									if (callbacks.indexOf(acceptCallback) !== -1) continue;
+									callbacks.push(acceptCallback);
+									errorHandlers.push(errorHandler);
+									dependenciesForCallbacks.push(dependency);
+								}
+							}
+							for (var k = 0; k < callbacks.length; k++) {
+								var result;
+								try {
+									result = callbacks[k].call(null, moduleOutdatedDependencies);
+								} catch (err) {
+									if (typeof errorHandlers[k] === "function") {
+										try {
+											errorHandlers[k](err, {
+												moduleId: outdatedModuleId,
+												dependencyId: dependenciesForCallbacks[k]
+											});
+										} catch (err2) {
+											if (options.onErrored) {
+												options.onErrored({
+													type: "accept-error-handler-errored",
+													moduleId: outdatedModuleId,
+													dependencyId: dependenciesForCallbacks[k],
+													error: err2,
+													originalError: err
+												});
+											}
+											if (!options.ignoreErrored) {
+												reportError(err2);
+												reportError(err);
+											}
+										}
+									} else {
+										if (options.onErrored) {
+											options.onErrored({
+												type: "accept-errored",
+												moduleId: outdatedModuleId,
+												dependencyId: dependenciesForCallbacks[k],
+												error: err
+											});
+										}
+										if (!options.ignoreErrored) {
+											reportError(err);
+										}
+									}
+								}
+								if (result && typeof result.then === "function") {
+									acceptPromises.push(result);
+								}
+							}
+						}
+					}
+				}
+
+				var onAccepted = function () {
+					// Load self accepted modules
+					for (var o = 0; o < outdatedSelfAcceptedModules.length; o++) {
+						var item = outdatedSelfAcceptedModules[o];
+						var moduleId = item.module;
+						try {
+							item.require(moduleId);
+						} catch (err) {
+							if (typeof item.errorHandler === "function") {
+								try {
+									item.errorHandler(err, {
+										moduleId: moduleId,
+										module: $moduleCache$[moduleId]
+									});
+								} catch (err1) {
+									if (options.onErrored) {
+										options.onErrored({
+											type: "self-accept-error-handler-errored",
+											moduleId: moduleId,
+											error: err1,
+											originalError: err
+										});
+									}
+									if (!options.ignoreErrored) {
+										reportError(err1);
+										reportError(err);
+									}
+								}
+							} else {
+								if (options.onErrored) {
+									options.onErrored({
+										type: "self-accept-errored",
+										moduleId: moduleId,
+										error: err
+									});
+								}
+								if (!options.ignoreErrored) {
+									reportError(err);
+								}
+							}
+						}
+					}
+				};
+
+				return Promise.all(acceptPromises)
+					.then(onAccepted)
+					.then(function () {
+						return outdatedModules;
+					});
+			}
+		};
+	}
+	$hmrInvalidateModuleHandlers$.$key$ = function (moduleId, applyHandlers) {
+		if (!currentUpdate) {
+			currentUpdate = {};
+			currentUpdateRuntime = [];
+			currentUpdateRemovedChunks = [];
+			applyHandlers.push(applyHandler);
+		}
+		if (!$hasOwnProperty$(currentUpdate, moduleId)) {
+			currentUpdate[moduleId] = $moduleFactories$[moduleId];
+		}
+	};
+	$hmrDownloadUpdateHandlers$.$key$ = function (
+		chunkIds,
+		removedChunks,
+		removedModules,
+		promises,
+		applyHandlers,
+		updatedModulesList
+	) {
+		applyHandlers.push(applyHandler);
+		currentUpdateChunks = {};
+		currentUpdateRemovedChunks = removedChunks;
+		currentUpdate = removedModules.reduce(function (obj, key) {
+			obj[key] = false;
+			return obj;
+		}, {});
+		currentUpdateRuntime = [];
+		chunkIds.forEach(function (chunkId) {
+			if (
+				$hasOwnProperty$($installedChunks$, chunkId) &&
+				$installedChunks$[chunkId] !== undefined
+			) {
+				promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
+				currentUpdateChunks[chunkId] = true;
+			} else {
+				currentUpdateChunks[chunkId] = false;
+			}
+		});
+		if ($ensureChunkHandlers$) {
+			$ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
+				if (
+					currentUpdateChunks &&
+					$hasOwnProperty$(currentUpdateChunks, chunkId) &&
+					!currentUpdateChunks[chunkId]
+				) {
+					promises.push($loadUpdateChunk$(chunkId));
+					currentUpdateChunks[chunkId] = true;
+				}
+			};
+		}
+	};
+};
Index: frontend/node_modules/webpack/lib/hmr/JavascriptHotModuleReplacementHelper.js
===================================================================
--- frontend/node_modules/webpack/lib/hmr/JavascriptHotModuleReplacementHelper.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/hmr/JavascriptHotModuleReplacementHelper.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Haijie Xie @hai-x
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+
+const Template = require("../Template");
+
+/**
+ * Generates javascript hmr.
+ * @param {string} type unique identifier used for HMR runtime properties
+ * @returns {string} HMR runtime code
+ */
+const generateJavascriptHMR = (type) =>
+	Template.getFunctionContent(
+		require("../hmr/JavascriptHotModuleReplacement.runtime")
+	)
+		.replace(/\$key\$/g, type)
+		.replace(/\$installedChunks\$/g, "installedChunks")
+		.replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk")
+		.replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache)
+		.replace(/\$moduleFactories\$/g, RuntimeGlobals.moduleFactories)
+		.replace(/\$ensureChunkHandlers\$/g, RuntimeGlobals.ensureChunkHandlers)
+		.replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty)
+		.replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData)
+		.replace(
+			/\$hmrDownloadUpdateHandlers\$/g,
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		)
+		.replace(
+			/\$hmrInvalidateModuleHandlers\$/g,
+			RuntimeGlobals.hmrInvalidateModuleHandlers
+		);
+
+module.exports.generateJavascriptHMR = generateJavascriptHMR;
Index: frontend/node_modules/webpack/lib/hmr/LazyCompilationPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/hmr/LazyCompilationPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/hmr/LazyCompilationPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,492 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const Dependency = require("../Dependency");
+const Module = require("../Module");
+const ModuleFactory = require("../ModuleFactory");
+const { JAVASCRIPT_TYPES } = require("../ModuleSourceTypeConstants");
+const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
+const {
+	WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const CommonJsRequireDependency = require("../dependencies/CommonJsRequireDependency");
+const { registerNotSerializable } = require("../util/serialization");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../dependencies/HarmonyImportDependency")} HarmonyImportDependency */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+/** @typedef {{ client: string, data: string, active: boolean }} ModuleResult */
+
+/**
+ * Defines the backend api type used by this module.
+ * @typedef {object} BackendApi
+ * @property {(callback: (err?: (Error | null)) => void) => void} dispose
+ * @property {(module: Module) => ModuleResult} module
+ */
+
+const HMR_DEPENDENCY_TYPES = new Set([
+	"import.meta.webpackHot.accept",
+	"import.meta.webpackHot.decline",
+	"module.hot.accept",
+	"module.hot.decline"
+]);
+
+/**
+ * Checks true, if the module should be selected.
+ * @param {Options["test"]} test test option
+ * @param {Module} module the module
+ * @returns {boolean | null | string} true, if the module should be selected
+ */
+const checkTest = (test, module) => {
+	if (test === undefined) return true;
+	if (typeof test === "function") {
+		return test(module);
+	}
+	if (typeof test === "string") {
+		const name = module.nameForCondition();
+		return name && name.startsWith(test);
+	}
+	if (test instanceof RegExp) {
+		const name = module.nameForCondition();
+		return name && test.test(name);
+	}
+	return false;
+};
+
+class LazyCompilationDependency extends Dependency {
+	/**
+	 * Creates an instance of LazyCompilationDependency.
+	 * @param {LazyCompilationProxyModule} proxyModule proxy module
+	 */
+	constructor(proxyModule) {
+		super();
+		this.proxyModule = proxyModule;
+	}
+
+	get category() {
+		return "esm";
+	}
+
+	get type() {
+		return "lazy import()";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return this.proxyModule.originalModule.identifier();
+	}
+}
+
+registerNotSerializable(LazyCompilationDependency);
+
+class LazyCompilationProxyModule extends Module {
+	/**
+	 * Creates an instance of LazyCompilationProxyModule.
+	 * @param {string} context context
+	 * @param {Module} originalModule an original module
+	 * @param {string} request request
+	 * @param {ModuleResult["client"]} client client
+	 * @param {ModuleResult["data"]} data data
+	 * @param {ModuleResult["active"]} active true when active, otherwise false
+	 */
+	constructor(context, originalModule, request, client, data, active) {
+		super(
+			WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY,
+			context,
+			originalModule.layer
+		);
+		this.originalModule = originalModule;
+		this.request = request;
+		this.client = client;
+		this.data = data;
+		this.active = active;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return `${WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY}|${this.originalModule.identifier()}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `${WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY} ${this.originalModule.readableIdentifier(
+			requestShortener
+		)}`;
+	}
+
+	/**
+	 * 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 {LazyCompilationProxyModule} */ (module);
+		this.originalModule = m.originalModule;
+		this.request = m.request;
+		this.client = m.client;
+		this.data = m.data;
+		this.active = m.active;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return `${this.originalModule.libIdent(
+			options
+		)}!${WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		callback(null, !this.buildInfo || this.buildInfo.active !== this.active);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildInfo = {
+			active: this.active
+		};
+		/** @type {BuildMeta} */
+		this.buildMeta = {};
+		this.clearDependenciesAndBlocks();
+		const dep = new CommonJsRequireDependency(this.client);
+		this.addDependency(dep);
+		if (this.active) {
+			const dep = new LazyCompilationDependency(this);
+			const block = new AsyncDependenciesBlock({});
+			block.addDependency(dep);
+			this.addBlock(block);
+		}
+		callback();
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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 200;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({ runtimeTemplate, chunkGraph, moduleGraph }) {
+		/** @type {Sources} */
+		const sources = new Map();
+		/** @type {RuntimeRequirements} */
+		const runtimeRequirements = new Set();
+		runtimeRequirements.add(RuntimeGlobals.module);
+		const clientDep = /** @type {CommonJsRequireDependency} */ (
+			this.dependencies[0]
+		);
+		const clientModule = moduleGraph.getModule(clientDep);
+		const block = this.blocks[0];
+		const client = Template.asString([
+			`var client = ${runtimeTemplate.moduleExports({
+				module: clientModule,
+				chunkGraph,
+				request: clientDep.userRequest,
+				runtimeRequirements
+			})}`,
+			`var data = ${JSON.stringify(this.data)};`
+		]);
+		const keepActive = Template.asString([
+			`var dispose = client.keepAlive({ data: data, active: ${JSON.stringify(
+				Boolean(block)
+			)}, module: module, onError: onError });`
+		]);
+		/** @type {string} */
+		let source;
+		if (block) {
+			const dep = block.dependencies[0];
+			const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+			source = Template.asString([
+				client,
+				`module.exports = ${runtimeTemplate.moduleNamespacePromise({
+					chunkGraph,
+					block,
+					module,
+					request: this.request,
+					dependency: dep,
+					strict: false, // TODO this should be inherited from the original module
+					message: "import()",
+					runtimeRequirements
+				})};`,
+				"if (module.hot) {",
+				Template.indent([
+					"module.hot.accept();",
+					`module.hot.accept(${JSON.stringify(
+						chunkGraph.getModuleId(module)
+					)}, function() { module.hot.invalidate(); });`,
+					"module.hot.dispose(function(data) { delete data.resolveSelf; dispose(data); });",
+					"if (module.hot.data && module.hot.data.resolveSelf) module.hot.data.resolveSelf(module.exports);"
+				]),
+				"}",
+				"function onError() { /* ignore */ }",
+				keepActive
+			]);
+		} else {
+			source = Template.asString([
+				client,
+				"var resolveSelf, onError;",
+				"module.exports = new Promise(function(resolve, reject) { resolveSelf = resolve; onError = reject; });",
+				"if (module.hot) {",
+				Template.indent([
+					"module.hot.accept();",
+					"if (module.hot.data && module.hot.data.resolveSelf) module.hot.data.resolveSelf(module.exports);",
+					"module.hot.dispose(function(data) { data.resolveSelf = resolveSelf; dispose(data); });"
+				]),
+				"}",
+				keepActive
+			]);
+		}
+		sources.set(JAVASCRIPT_TYPE, new RawSource(source));
+		return {
+			sources,
+			runtimeRequirements
+		};
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		super.updateHash(hash, context);
+		hash.update(this.active ? "active" : "");
+		hash.update(JSON.stringify(this.data));
+	}
+}
+
+registerNotSerializable(LazyCompilationProxyModule);
+
+class LazyCompilationDependencyFactory extends ModuleFactory {
+	constructor() {
+		super();
+	}
+
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const dependency =
+			/** @type {LazyCompilationDependency} */
+			(data.dependencies[0]);
+		callback(null, {
+			module: dependency.proxyModule.originalModule
+		});
+	}
+}
+
+/**
+ * Defines the backend handler callback.
+ * @callback BackendHandler
+ * @param {Compiler} compiler compiler
+ * @param {(err: Error | null, backendApi?: BackendApi) => void} callback callback
+ * @returns {void}
+ */
+
+/**
+ * Defines the promise backend handler callback.
+ * @callback PromiseBackendHandler
+ * @param {Compiler} compiler compiler
+ * @returns {Promise<BackendApi>} backend
+ */
+
+/** @typedef {BackendHandler | PromiseBackendHandler} BackEnd */
+
+/** @typedef {(module: Module) => boolean} TestFn */
+
+/**
+ * Defines the options type used by this module.
+ * @typedef {object} Options options
+ * @property {BackEnd} backend the backend
+ * @property {boolean=} entries
+ * @property {boolean=} imports
+ * @property {RegExp | string | TestFn=} test additional filter for lazy compiled entrypoint modules
+ */
+
+const PLUGIN_NAME = "LazyCompilationPlugin";
+
+class LazyCompilationPlugin {
+	/**
+	 * Creates an instance of LazyCompilationPlugin.
+	 * @param {Options} options options
+	 */
+	constructor({ backend, entries, imports, test }) {
+		this.backend = backend;
+		this.entries = entries;
+		this.imports = imports;
+		this.test = test;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		/** @type {BackendApi} */
+		let backend;
+		compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, (params, callback) => {
+			if (backend !== undefined) return callback();
+			const promise = this.backend(compiler, (err, result) => {
+				if (err) return callback(err);
+				backend = /** @type {BackendApi} */ (result);
+				callback();
+			});
+			if (promise && promise.then) {
+				promise.then((b) => {
+					backend = b;
+					callback();
+				}, callback);
+			}
+		});
+		compiler.hooks.thisCompilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				normalModuleFactory.hooks.module.tap(
+					PLUGIN_NAME,
+					(module, createData, resolveData) => {
+						if (
+							resolveData.dependencies.every((dep) =>
+								HMR_DEPENDENCY_TYPES.has(dep.type)
+							)
+						) {
+							// for HMR only resolving, try to determine if the HMR accept/decline refers to
+							// an import() or not
+							const hmrDep = resolveData.dependencies[0];
+							const originModule =
+								/** @type {Module} */
+								(compilation.moduleGraph.getParentModule(hmrDep));
+							const isReferringToDynamicImport = originModule.blocks.some(
+								(block) =>
+									block.dependencies.some(
+										(dep) =>
+											dep.type === "import()" &&
+											/** @type {HarmonyImportDependency} */ (dep).request ===
+												hmrDep.request
+									)
+							);
+							if (!isReferringToDynamicImport) return module;
+						} else if (
+							!resolveData.dependencies.every(
+								(dep) =>
+									HMR_DEPENDENCY_TYPES.has(dep.type) ||
+									(this.imports &&
+										(dep.type === "import()" ||
+											dep.type === "import() context element")) ||
+									(this.entries && dep.type === "entry")
+							)
+						) {
+							return module;
+						}
+						if (
+							/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client|webpack-hot-middleware[/\\]client/.test(
+								resolveData.request
+							) ||
+							!checkTest(this.test, module)
+						) {
+							return module;
+						}
+						const moduleInfo = backend.module(module);
+						if (!moduleInfo) return module;
+						const { client, data, active } = moduleInfo;
+
+						return new LazyCompilationProxyModule(
+							compiler.context,
+							module,
+							resolveData.request,
+							client,
+							data,
+							active
+						);
+					}
+				);
+				compilation.dependencyFactories.set(
+					LazyCompilationDependency,
+					new LazyCompilationDependencyFactory()
+				);
+			}
+		);
+		compiler.hooks.shutdown.tapAsync(PLUGIN_NAME, (callback) => {
+			backend.dispose(callback);
+		});
+	}
+}
+
+module.exports = LazyCompilationPlugin;
Index: frontend/node_modules/webpack/lib/hmr/lazyCompilationBackend.js
===================================================================
--- frontend/node_modules/webpack/lib/hmr/lazyCompilationBackend.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/hmr/lazyCompilationBackend.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,169 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("http").RequestListener} RequestListener */
+/** @typedef {import("http").ServerOptions} HttpServerOptions */
+/** @typedef {import("http").Server} HttpServer */
+/** @typedef {import("https").ServerOptions} HttpsServerOptions */
+/** @typedef {import("https").Server} HttpsServer */
+/** @typedef {import("net").AddressInfo} AddressInfo */
+/** @typedef {import("./LazyCompilationPlugin").BackendHandler} BackendHandler */
+/** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */
+
+/** @typedef {HttpServer | HttpsServer} Server */
+/** @typedef {(server: Server) => void} Listen */
+/** @typedef {() => Server} CreateServerFunction */
+
+/**
+ * Returns backend.
+ * @param {Omit<LazyCompilationDefaultBackendOptions, "client"> & { client: NonNullable<LazyCompilationDefaultBackendOptions["client"]> }} options additional options for the backend
+ * @returns {BackendHandler} backend
+ */
+module.exports = (options) => (compiler, callback) => {
+	const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
+	/** @type {Map<string, number>} */
+	const activeModules = new Map();
+	const prefix = "/lazy-compilation-using-";
+
+	const isHttps =
+		options.protocol === "https" ||
+		(typeof options.server === "object" &&
+			("key" in options.server || "pfx" in options.server));
+
+	/** @type {CreateServerFunction} */
+	const createServer =
+		typeof options.server === "function"
+			? options.server
+			: (() => {
+					const http = isHttps ? require("https") : require("http");
+					return /** @type {(this: import("http") | import("https"), options: HttpServerOptions | HttpsServerOptions) => Server} */ (
+						http.createServer
+					).bind(
+						http,
+						/** @type {HttpServerOptions | HttpsServerOptions} */
+						(options.server)
+					);
+				})();
+	/** @type {Listen} */
+	const listen =
+		typeof options.listen === "function"
+			? options.listen
+			: (server) => {
+					let listen = options.listen;
+					if (typeof listen === "object" && !("port" in listen)) {
+						listen = { ...listen, port: undefined };
+					}
+					server.listen(listen);
+				};
+
+	const protocol = options.protocol || (isHttps ? "https" : "http");
+
+	/** @type {RequestListener} */
+	const requestListener = (req, res) => {
+		if (req.url === undefined) return;
+		const keys = req.url.slice(prefix.length).split("@");
+		req.socket.on("close", () => {
+			setTimeout(() => {
+				for (const key of keys) {
+					const oldValue = activeModules.get(key) || 0;
+					activeModules.set(key, oldValue - 1);
+					if (oldValue === 1) {
+						logger.log(
+							`${key} is no longer in use. Next compilation will skip this module.`
+						);
+					}
+				}
+			}, 120000);
+		});
+		req.socket.setNoDelay(true);
+		res.writeHead(200, {
+			"content-type": "text/event-stream",
+			"Access-Control-Allow-Origin": "*",
+			"Access-Control-Allow-Methods": "*",
+			"Access-Control-Allow-Headers": "*"
+		});
+		res.write("\n");
+		let moduleActivated = false;
+		for (const key of keys) {
+			const oldValue = activeModules.get(key) || 0;
+			activeModules.set(key, oldValue + 1);
+			if (oldValue === 0) {
+				logger.log(`${key} is now in use and will be compiled.`);
+				moduleActivated = true;
+			}
+		}
+		if (moduleActivated && compiler.watching) compiler.watching.invalidate();
+	};
+
+	const server = createServer();
+	server.on("request", requestListener);
+
+	let isClosing = false;
+	/** @type {Set<import("net").Socket>} */
+	const sockets = new Set();
+	server.on("connection", (socket) => {
+		sockets.add(socket);
+		socket.on("close", () => {
+			sockets.delete(socket);
+		});
+		if (isClosing) socket.destroy();
+	});
+	server.on("clientError", (e) => {
+		if (e.message !== "Server is disposing") logger.warn(e);
+	});
+
+	server.on(
+		"listening",
+		/**
+		 * Handles the callback logic for this hook.
+		 * @param {Error} err error
+		 * @returns {void}
+		 */
+		(err) => {
+			if (err) return callback(err);
+			const _addr = server.address();
+			if (typeof _addr === "string") {
+				throw new Error("addr must not be a string");
+			}
+			const addr = /** @type {AddressInfo} */ (_addr);
+			const urlBase =
+				addr.address === "::" || addr.address === "0.0.0.0"
+					? `${protocol}://localhost:${addr.port}`
+					: addr.family === "IPv6"
+						? `${protocol}://[${addr.address}]:${addr.port}`
+						: `${protocol}://${addr.address}:${addr.port}`;
+			logger.log(
+				`Server-Sent-Events server for lazy compilation open at ${urlBase}.`
+			);
+			callback(null, {
+				dispose(callback) {
+					isClosing = true;
+					// Removing the listener is a workaround for a memory leak in node.js
+					server.off("request", requestListener);
+					server.close((err) => {
+						callback(err);
+					});
+					for (const socket of sockets) {
+						socket.destroy(new Error("Server is disposing"));
+					}
+				},
+				module(originalModule) {
+					const key = `${encodeURIComponent(
+						originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_")
+					).replace(/%(2F|3A|24|26|2B|2C|3B|3D)/g, decodeURIComponent)}`;
+					const active = /** @type {number} */ (activeModules.get(key)) > 0;
+					return {
+						client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`,
+						data: key,
+						active
+					};
+				}
+			});
+		}
+	);
+	listen(server);
+};
Index: frontend/node_modules/webpack/lib/html/HtmlGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/html/HtmlGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/html/HtmlGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,379 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { RawSource, ReplaceSource } = require("webpack-sources");
+const ConcatenationScope = require("../ConcatenationScope");
+const Generator = require("../Generator");
+const {
+	HTML_TYPE,
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const CssUrlDependency = require("../dependencies/CssUrlDependency");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").HtmlGeneratorOptions} HtmlGeneratorOptions */
+/** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../util/Hash")} Hash */
+/**
+ * @template T
+ * @typedef {import("../InitFragment")<T>} InitFragment
+ */
+
+/**
+ * @type {ReadonlySet<"javascript" | "html">}
+ */
+const JAVASCRIPT_AND_HTML_TYPES = new Set([JAVASCRIPT_TYPE, HTML_TYPE]);
+
+class HtmlGenerator extends Generator {
+	/**
+	 * Creates an instance of HtmlGenerator.
+	 * @param {HtmlGeneratorOptions=} options generator options
+	 * @param {ModuleGraph=} moduleGraph the module graph; used to detect when an HTML module is reached as a compilation entry so `extract` can default to `true` for it
+	 */
+	constructor(options, moduleGraph) {
+		super();
+		this.options = options || {};
+		/** @type {ModuleGraph | undefined} */
+		this._moduleGraph = moduleGraph;
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		return undefined;
+	}
+
+	/**
+	 * Whether this HTML module is reached as a compilation entry. Entry
+	 * modules have at least one incoming connection without an
+	 * `originModule` (the EntryDependency added by `compilation.addEntry`).
+	 * @param {NormalModule} module module
+	 * @returns {boolean} true when the module is an entry
+	 */
+	_isEntryModule(module) {
+		if (!this._moduleGraph) return false;
+		for (const connection of this._moduleGraph.getIncomingConnections(module)) {
+			if (!connection.originModule) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Whether to emit the extracted `.html` file for this module.
+	 * `options.extract === true` always extracts; `false` never; when the
+	 * option is left unspecified, extraction defaults to on for HTML modules
+	 * used as compilation entries — that's the HTML-as-entry-point use case.
+	 * @param {NormalModule} module module
+	 * @returns {boolean} true when the `.html` file should be emitted
+	 */
+	_shouldExtract(module) {
+		const { extract } = this.options;
+		if (extract === true) return true;
+		if (extract === false) return false;
+		return this._isEntryModule(module);
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		if (this._shouldExtract(module)) {
+			return JAVASCRIPT_AND_HTML_TYPES;
+		}
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const originalSource = module.originalSource();
+		if (!originalSource) return 0;
+		if (type === HTML_TYPE) return originalSource.size();
+		return originalSource.size() + 10;
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {NormalModule} module the current module
+	 * @param {Dependency} dependency the dependency to generate
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext} generateContext the render context
+	 * @returns {void}
+	 */
+	sourceDependency(module, dependency, initFragments, source, generateContext) {
+		const constructor =
+			/** @type {DependencyConstructor} */
+			(dependency.constructor);
+		const template = generateContext.dependencyTemplates.get(constructor);
+		if (!template) {
+			throw new Error(
+				`No template for dependency: ${dependency.constructor.name}`
+			);
+		}
+
+		/** @type {DependencyTemplateContext} */
+		/** @type {InitFragment<GenerateContext>[] | undefined} */
+		let chunkInitFragments;
+		/** @type {DependencyTemplateContext} */
+		const templateContext = {
+			runtimeTemplate: generateContext.runtimeTemplate,
+			dependencyTemplates: generateContext.dependencyTemplates,
+			moduleGraph: generateContext.moduleGraph,
+			chunkGraph: generateContext.chunkGraph,
+			module,
+			runtime: generateContext.runtime,
+			runtimeRequirements: generateContext.runtimeRequirements,
+			concatenationScope: generateContext.concatenationScope,
+			codeGenerationResults:
+				/** @type {CodeGenerationResults} */
+				(generateContext.codeGenerationResults),
+			initFragments,
+			get chunkInitFragments() {
+				if (!chunkInitFragments) {
+					const data =
+						/** @type {NonNullable<GenerateContext["getData"]>} */
+						(generateContext.getData)();
+					chunkInitFragments = data.get("chunkInitFragments");
+					if (!chunkInitFragments) {
+						chunkInitFragments = [];
+						data.set("chunkInitFragments", chunkInitFragments);
+					}
+				}
+
+				return chunkInitFragments;
+			}
+		};
+
+		template.apply(dependency, source, templateContext);
+	}
+
+	/**
+	 * Processes the provided dependencies block.
+	 * @param {NormalModule} module the module to generate
+	 * @param {import("../DependenciesBlock")} block the dependencies block which will be processed
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext} generateContext the generateContext
+	 * @returns {void}
+	 */
+	sourceBlock(module, block, initFragments, source, generateContext) {
+		for (const dependency of block.dependencies) {
+			this.sourceDependency(
+				module,
+				dependency,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+
+		for (const childBlock of block.blocks) {
+			this.sourceBlock(
+				module,
+				childBlock,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {NormalModule} module the module to generate
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext} generateContext the generateContext
+	 * @returns {void}
+	 */
+	sourceModule(module, initFragments, source, generateContext) {
+		for (const dependency of module.dependencies) {
+			this.sourceDependency(
+				module,
+				dependency,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+
+		if (module.presentationalDependencies !== undefined) {
+			for (const dependency of module.presentationalDependencies) {
+				this.sourceDependency(
+					module,
+					dependency,
+					initFragments,
+					source,
+					generateContext
+				);
+			}
+		}
+
+		for (const childBlock of module.blocks) {
+			this.sourceBlock(
+				module,
+				childBlock,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+	}
+
+	/**
+	 * Run all HTML dependency templates against the original module source and
+	 * return the rewritten HTML. When `undoPath` is a string, `[webpack/auto]`
+	 * placeholders left in by asset/url dependencies are resolved to that
+	 * undo path (use `""` to make URLs root-relative). When `undoPath` is
+	 * `undefined`, the placeholders are preserved so the caller (typically
+	 * `HtmlModulesPlugin#renderManifest`, which only knows the final
+	 * `.html` filename after code generation) can resolve them itself.
+	 * @param {NormalModule} module the module to render
+	 * @param {GenerateContext} generateContext the generate context
+	 * @param {string=} undoPath value to substitute for `[webpack/auto]` placeholders
+	 * @returns {string} the rewritten HTML
+	 */
+	_renderHtml(module, generateContext, undoPath) {
+		const originalSource = /** @type {Source} */ (module.originalSource());
+		const source = new ReplaceSource(originalSource);
+		/** @type {InitFragment<GenerateContext>[]} */
+		const initFragments = [];
+
+		this.sourceModule(module, initFragments, source, generateContext);
+
+		if (undoPath === undefined) {
+			return /** @type {string} */ (source.source());
+		}
+
+		const moduleSourceContent = source.source();
+		const generatedSource = new ReplaceSource(source);
+
+		const autoPlaceholder = CssUrlDependency.PUBLIC_PATH_AUTO;
+		const autoPlaceholderLen = autoPlaceholder.length;
+		for (
+			let idx = moduleSourceContent.indexOf(autoPlaceholder);
+			idx !== -1;
+			idx = moduleSourceContent.indexOf(
+				autoPlaceholder,
+				idx + autoPlaceholderLen
+			)
+		) {
+			generatedSource.replace(idx, idx + autoPlaceholderLen - 1, undoPath);
+		}
+
+		// TODO handle `[fullhash]`
+
+		return /** @type {string} */ (generatedSource.source());
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const originalSource = module.originalSource();
+
+		if (!originalSource) {
+			return new RawSource("");
+		}
+
+		if (generateContext.type === HTML_TYPE) {
+			// Preserve `[webpack/auto]` placeholders here — the plugin's
+			// `renderManifest` hook knows the final `.html` filename and
+			// resolves them to an undo path relative to that location.
+			return new RawSource(
+				this._renderHtml(module, generateContext, undefined)
+			);
+		}
+
+		// JS export: the rewritten HTML is a string the consumer reads at
+		// runtime, so resolve placeholders to root-relative URLs.
+		const generated = this._renderHtml(module, generateContext, "");
+
+		/** @type {string} */
+		let sourceContent;
+		if (generateContext.concatenationScope) {
+			generateContext.concatenationScope.registerNamespaceExport(
+				ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+			);
+			sourceContent = `${generateContext.runtimeTemplate.renderConst()} ${
+				ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+			} = ${JSON.stringify(generated)};`;
+		} else {
+			generateContext.runtimeRequirements.add(RuntimeGlobals.module);
+			sourceContent = `${module.moduleArgument}.exports = ${JSON.stringify(
+				generated
+			)};`;
+		}
+
+		return new RawSource(sourceContent);
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		if (generateContext.type === HTML_TYPE) {
+			// The error message can contain arbitrary text (file paths, user
+			// input, dep request strings). Strip `<`, `>`, and `--` runs so a
+			// crafted message can't close the comment with `-->` (or open a
+			// fake nested comment) and inject HTML into the extracted page.
+			const safe = String(error.message)
+				.replace(/[<>]/g, "")
+				.replace(/-{2,}/g, (m) => `${"-".repeat(m.length - 1)} `);
+			return new RawSource(`<!-- webpack error: ${safe} -->`);
+		}
+		return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash that will be modified
+	 * @param {UpdateHashContext} updateHashContext context for updating hash
+	 */
+	updateHash(hash, updateHashContext) {
+		hash.update("html");
+		// Hash the *effective* extraction state, not just the raw option,
+		// so the module hash flips when a module becomes (or stops being)
+		// a compilation entry under the `extract: undefined` default — the
+		// generator's source-type set changes with it, so any cached
+		// HTML-type codegen result must be invalidated.
+		if (this._shouldExtract(updateHashContext.module)) {
+			hash.update("extract");
+		}
+	}
+}
+
+module.exports = HtmlGenerator;
Index: frontend/node_modules/webpack/lib/html/HtmlModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/html/HtmlModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/html/HtmlModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,429 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const EntryPlugin = require("../EntryPlugin");
+const HotUpdateChunk = require("../HotUpdateChunk");
+const { HTML_TYPE } = require("../ModuleSourceTypeConstants");
+const { HTML_MODULE_TYPE } = require("../ModuleTypeConstants");
+const NormalModule = require("../NormalModule");
+const ConstDependency = require("../dependencies/ConstDependency");
+const HtmlInlineScriptDependency = require("../dependencies/HtmlInlineScriptDependency");
+const HtmlInlineStyleDependency = require("../dependencies/HtmlInlineStyleDependency");
+const HtmlScriptSrcDependency = require("../dependencies/HtmlScriptSrcDependency");
+const HtmlSourceDependency = require("../dependencies/HtmlSourceDependency");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const { compareModulesByFullName } = require("../util/comparators");
+const removeBOM = require("../util/removeBOM");
+const HtmlGenerator = require("./HtmlGenerator");
+const HtmlParser = require("./HtmlParser");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {{ request: string, entryName: string, kind: "classic" | "esm-script" | "modulepreload" | "stylesheet" }} EntryScriptInfo */
+
+const PLUGIN_NAME = "HtmlModulesPlugin";
+
+/**
+ * @param {string} name definition name in `schemas/WebpackOptions.json`
+ * @returns {EXPECTED_OBJECT} a schema referencing `#/definitions/<name>`
+ */
+const getSchema = (name) => {
+	const { definitions } = require("../../schemas/WebpackOptions.json");
+
+	return {
+		definitions,
+		oneOf: [{ $ref: `#/definitions/${name}` }]
+	};
+};
+
+const generatorValidationOptions = {
+	name: "Html Modules Plugin",
+	baseDataPath: "generator"
+};
+
+class HtmlModulesPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		// `<script src>` and `<link rel="modulepreload">` references collected
+		// by HtmlParser become real compilation entries here. The classic
+		// and esm-script groups are chained via a leader-only dependOn so
+		// they share a runtime — the first entry of the group owns it and
+		// every subsequent entry sets `dependOn: [leader]`. Modulepreload
+		// entries are emitted as independent entries (no dependOn) so they
+		// can never be imported as a runtime leader by a later script —
+		// that's what keeps the "preload but don't execute" contract of
+		// `<link rel="modulepreload">` intact.
+		/** @type {WeakMap<import("../Compilation"), Set<string>>} */
+		const stylesheetEntriesPerCompilation = new WeakMap();
+		compiler.hooks.finishMake.tapAsync(PLUGIN_NAME, (compilation, callback) => {
+			/** @type {Promise<void>[]} */
+			const promises = [];
+			/** @type {Set<string>} */
+			const stylesheetEntries = new Set();
+			stylesheetEntriesPerCompilation.set(compilation, stylesheetEntries);
+
+			for (const module of compilation.modules) {
+				if (module.type !== HTML_MODULE_TYPE) continue;
+				const buildInfo = module.buildInfo;
+				const htmlEntryScripts =
+					buildInfo &&
+					/** @type {Record<string, EntryScriptInfo[]> | undefined} */
+					(buildInfo.htmlEntryScripts);
+				if (!htmlEntryScripts) continue;
+
+				const context = /** @type {string} */ (module.context);
+
+				for (const [groupKind, group] of Object.entries(htmlEntryScripts)) {
+					// Only the script chains (`classic`, `esm-script`) need a
+					// shared runtime via leader-only `dependOn` — the others
+					// either preload without executing (`modulepreload`) or
+					// produce CSS chunks (`stylesheet`) which have no runtime
+					// to share. CSS entries must NOT chain into a JS leader
+					// either, because the resulting chunk would mix a CSS
+					// stylesheet with a JS runtime.
+					const isChainGroup =
+						groupKind !== "modulepreload" && groupKind !== "stylesheet";
+					/** @type {string | undefined} */
+					let leaderName;
+					for (const entry of group) {
+						const dependOn =
+							isChainGroup && leaderName !== undefined
+								? [leaderName]
+								: undefined;
+						if (isChainGroup && leaderName === undefined) {
+							leaderName = entry.entryName;
+						}
+						if (groupKind === "stylesheet") {
+							stylesheetEntries.add(entry.entryName);
+						}
+						promises.push(
+							new Promise((resolve, reject) => {
+								compilation.addEntry(
+									context,
+									EntryPlugin.createDependency(entry.request, {
+										name: entry.entryName
+									}),
+									{
+										name: entry.entryName,
+										// Each script src / modulepreload entry gets its own
+										// filename derived from the synthetic entry name so it
+										// doesn't collide with the user's `output.filename`.
+										// For CSS entries the JS `filename` is irrelevant (no
+										// `.js` is emitted) — the CSS file's name is set on the
+										// chunk via `cssFilenameTemplate` in `afterChunks` below.
+										filename:
+											compilation.outputOptions.chunkFilename || "[name].js",
+										dependOn
+									},
+									(err) => {
+										if (err) reject(err);
+										else resolve();
+									}
+								);
+							})
+						);
+					}
+				}
+			}
+
+			Promise.all(promises).then(
+				() => callback(),
+				(err) => callback(err)
+			);
+		});
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				// CSS entries created by `<link rel="stylesheet">` in HTML need
+				// their `.css` filename set via `chunk.cssFilenameTemplate`
+				// (the field `CssModulesPlugin.getChunkFilenameTemplate` reads).
+				// Compilation only flows `options.filename` to `chunk.filenameTemplate`,
+				// which controls JS emit — there's no entry-level `cssFilename`.
+				// Set it ourselves after chunks are created so each stylesheet
+				// entry emits to a distinct file derived from `output.cssFilename`
+				// (or `output.cssChunkFilename` for non-initial CSS chunks).
+				compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
+					const stylesheetEntries =
+						stylesheetEntriesPerCompilation.get(compilation);
+					if (!stylesheetEntries || stylesheetEntries.size === 0) return;
+					for (const entryName of stylesheetEntries) {
+						const entrypoint = compilation.entrypoints.get(entryName);
+						if (!entrypoint) continue;
+						const chunk = entrypoint.getEntrypointChunk();
+						if (!chunk) continue;
+						// Each html-derived stylesheet entry uses the
+						// `cssChunkFilename` template — even though the entry
+						// chunk technically `canBeInitial()`, we deliberately
+						// avoid `cssFilename` here because that template often
+						// has no per-entry placeholder (it's derived from
+						// `output.filename`, which can be a literal like
+						// `bundle0.js`), and multiple `<link rel="stylesheet">`
+						// tags would then collide on the same emitted `.css`
+						// file. `cssChunkFilename` is derived from
+						// `output.chunkFilename` which webpack auto-extends
+						// with `[id].` when needed, guaranteeing uniqueness.
+						chunk.cssFilenameTemplate =
+							compilation.outputOptions.cssChunkFilename;
+					}
+				});
+				compilation.dependencyFactories.set(
+					HtmlSourceDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HtmlSourceDependency,
+					new HtmlSourceDependency.Template()
+				);
+				compilation.dependencyFactories.set(
+					HtmlScriptSrcDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HtmlScriptSrcDependency,
+					new HtmlScriptSrcDependency.Template()
+				);
+				// Inline `<script>` content is bundled as its own entry — the
+				// same pipeline that handles `<script src>` — via a
+				// `data:text/javascript,...` request. The dependency
+				// template rewrites the original tag to `<script src=…>`.
+				compilation.dependencyFactories.set(
+					HtmlInlineScriptDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HtmlInlineScriptDependency,
+					new HtmlInlineScriptDependency.Template()
+				);
+				// Inline `<style>` content is routed through the CSS pipeline
+				// as a `data:text/css` module. The dependency template reads
+				// the processed CSS text from the CSS module's code
+				// generation data (`css-text` channel set by CssGenerator
+				// when `exportType` is `"text"`).
+				compilation.dependencyFactories.set(
+					HtmlInlineStyleDependency,
+					normalModuleFactory
+				);
+				compilation.dependencyTemplates.set(
+					HtmlInlineStyleDependency,
+					new HtmlInlineStyleDependency.Template()
+				);
+				compilation.dependencyTemplates.set(
+					StaticExportsDependency,
+					new StaticExportsDependency.Template()
+				);
+				// `ConstDependency` is used by HtmlParser to insert
+				// ` type="module"` into the rewritten <script> tag when
+				// `output.module` is on. Register its template so the HTML
+				// generator runs the insertion.
+				compilation.dependencyTemplates.set(
+					ConstDependency,
+					new ConstDependency.Template()
+				);
+				const cssEnabled = Boolean(
+					compiler.options.experiments && compiler.options.experiments.css
+				);
+				normalModuleFactory.hooks.createParser
+					.for(HTML_MODULE_TYPE)
+					.tap(
+						PLUGIN_NAME,
+						() =>
+							new HtmlParser(
+								compilation.outputOptions.hashFunction,
+								compiler.context,
+								compilation.outputOptions.module,
+								cssEnabled
+							)
+					);
+
+				normalModuleFactory.hooks.createGenerator
+					.for(HTML_MODULE_TYPE)
+					.tap(PLUGIN_NAME, (generatorOptions) => {
+						compiler.validate(
+							() => getSchema("HtmlGeneratorOptions"),
+							generatorOptions,
+							generatorValidationOptions,
+							(options) =>
+								require("../../schemas/plugins/HtmlGeneratorOptions.check")(
+									options
+								)
+						);
+						return new HtmlGenerator(generatorOptions, compilation.moduleGraph);
+					});
+
+				NormalModule.getCompilationHooks(compilation).processResult.tap(
+					PLUGIN_NAME,
+					(result, module) => {
+						if (module.type === HTML_MODULE_TYPE) {
+							const [source, ...rest] = result;
+
+							return [removeBOM(source), ...rest];
+						}
+
+						return result;
+					}
+				);
+
+				// Emit extracted `.html` files for any HTML module that opted
+				// into extraction. The opt-in is computed by
+				// `HtmlGenerator#_shouldExtract`: `module.generator.html.extract:
+				// true` always extracts, `false` never extracts, and when
+				// `extract` is unset the generator extracts iff the HTML module
+				// is a compilation entry — the iteration below picks up only
+				// modules whose generator reported the `html` source type, so
+				// that decision is honored implicitly. The HTML content is read
+				// from the generator's secondary `"html"` source type (see
+				// HtmlGenerator#generate). The filename template comes from
+				// `output.htmlFilename` (initial chunks) or
+				// `output.htmlChunkFilename` (non-initial chunks), mirroring
+				// the CSS pipeline. Path data follows the asset-module pattern —
+				// `module` + a relative source `filename`, with `chunk`
+				// intentionally omitted so `[name]` resolves to the HTML
+				// source's basename (e.g. `page` for `./page.html`) rather
+				// than the importing chunk's name (e.g. `main`). A per-module
+				// content hash is computed from the rewritten HTML so the
+				// template's `[contenthash]` placeholder works; the
+				// compilation hash is also forwarded so `[fullhash]` /
+				// `[hash]` work in user-supplied templates.
+				const {
+					getUndoPath,
+					makePathsRelative
+				} = require("../util/identifier");
+				const createHash = require("../util/createHash");
+				const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
+				const CssUrlDependency = require("../dependencies/CssUrlDependency");
+
+				const autoPlaceholder = CssUrlDependency.PUBLIC_PATH_AUTO;
+
+				compilation.hooks.renderManifest.tap(
+					PLUGIN_NAME,
+					(result, { chunk, codeGenerationResults, hash: compilationHash }) => {
+						// HMR's `HotUpdateChunk`s flow through the same hook
+						// but aren't real output chunks — extracting `.html`
+						// for them would create stray hot-update HTML files.
+						// `CssModulesPlugin` early-returns for the same reason.
+						if (chunk instanceof HotUpdateChunk) return result;
+						const { chunkGraph } = compilation;
+						const modules =
+							chunkGraph.getOrderedChunkModulesIterableBySourceType(
+								chunk,
+								HTML_TYPE,
+								compareModulesByFullName(compilation.compiler)
+							);
+						if (!modules) return result;
+						const outputOptions = compilation.outputOptions;
+						for (const module of modules) {
+							const normalModule = /** @type {NormalModule} */ (module);
+							const codeGenResult = codeGenerationResults.get(
+								module,
+								chunk.runtime
+							);
+							const placeholderSource = codeGenResult.sources.get(HTML_TYPE);
+							if (!placeholderSource) continue;
+
+							const filenameTemplate = chunk.canBeInitial()
+								? outputOptions.htmlFilename
+								: outputOptions.htmlChunkFilename;
+
+							const sourceFilename = makePathsRelative(
+								compiler.context,
+								/** @type {string} */
+								(normalModule.getResource() || normalModule.resource),
+								compiler.root
+							).replace(/^\.\//, "");
+
+							const placeholderContent = /** @type {string} */ (
+								placeholderSource.source()
+							);
+							const hashInput = createHash(outputOptions.hashFunction);
+							if (outputOptions.hashSalt) {
+								hashInput.update(outputOptions.hashSalt);
+							}
+							hashInput.update(placeholderContent);
+							const fullContentHash = /** @type {string} */ (
+								hashInput.digest(outputOptions.hashDigest)
+							);
+							const contentHash = nonNumericOnlyHash(
+								fullContentHash,
+								outputOptions.hashDigestLength
+							);
+
+							const { path: filename, info } = compilation.getPathWithInfo(
+								/** @type {import("../TemplatedPathPlugin").TemplatePath} */
+								(filenameTemplate),
+								{
+									module,
+									runtime: chunk.runtime,
+									chunkGraph,
+									contentHash,
+									contentHashType: HTML_TYPE,
+									filename: sourceFilename,
+									hash: compilationHash
+								}
+							);
+
+							// Resolve any remaining `[webpack/auto]` placeholders to
+							// an undo path computed from the emitted HTML's location.
+							// Without this, an `output.htmlFilename` that emits into
+							// a subdirectory (e.g. `pages/[name].html`) would leave
+							// asset URLs like `image.png` and chunk URLs like
+							// `main.js` root-relative, so the browser would resolve
+							// them under the HTML's directory instead of the
+							// `output.path` root.
+							const undoPath = getUndoPath(
+								filename,
+								/** @type {string} */ (outputOptions.path),
+								false
+							);
+							const finalContent = placeholderContent
+								.split(autoPlaceholder)
+								.join(undoPath);
+							const finalSource = new RawSource(finalContent);
+							// The same HTML module can land in multiple chunks
+							// with different `output.htmlFilename` /
+							// `output.htmlChunkFilename` shapes, which means
+							// different `undoPath`s and therefore different
+							// final content for the same module id. Include
+							// the emitted filename in the asset cache key and
+							// the post-undo-path content in the hash, so the
+							// asset cache can't reuse one variant's bytes at
+							// another variant's URL.
+							const finalHash = createHash(outputOptions.hashFunction);
+							if (outputOptions.hashSalt) {
+								finalHash.update(outputOptions.hashSalt);
+							}
+							finalHash.update(finalContent);
+							const finalContentHash = nonNumericOnlyHash(
+								/** @type {string} */ (
+									finalHash.digest(outputOptions.hashDigest)
+								),
+								outputOptions.hashDigestLength
+							);
+
+							result.push({
+								render: () => finalSource,
+								filename,
+								info,
+								auxiliary: true,
+								identifier: `htmlModule${chunkGraph.getModuleId(
+									module
+								)}|${filename}`,
+								hash: finalContentHash
+							});
+						}
+						return result;
+					}
+				);
+			}
+		);
+	}
+}
+
+module.exports = HtmlModulesPlugin;
Index: frontend/node_modules/webpack/lib/html/HtmlParser.js
===================================================================
--- frontend/node_modules/webpack/lib/html/HtmlParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/html/HtmlParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1489 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const vm = require("vm");
+const Parser = require("../Parser");
+const ConstDependency = require("../dependencies/ConstDependency");
+const HtmlInlineScriptDependency = require("../dependencies/HtmlInlineScriptDependency");
+const HtmlInlineStyleDependency = require("../dependencies/HtmlInlineStyleDependency");
+const HtmlScriptSrcDependency = require("../dependencies/HtmlScriptSrcDependency");
+const HtmlSourceDependency = require("../dependencies/HtmlSourceDependency");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
+const ModuleDependencyError = require("../errors/ModuleDependencyError");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const WebpackError = require("../errors/WebpackError");
+const LocConverter = require("../util/LocConverter");
+const createHash = require("../util/createHash");
+const { contextify } = require("../util/identifier");
+const {
+	createMagicCommentContext,
+	webpackCommentRegExp
+} = require("../util/magicComment");
+const walkHtmlTokens = require("./walkHtmlTokens");
+
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+const HORIZONTAL_TAB = "\u0009".charCodeAt(0);
+const NEWLINE = "\u000A".charCodeAt(0);
+const FORM_FEED = "\u000C".charCodeAt(0);
+const CARRIAGE_RETURN = "\u000D".charCodeAt(0);
+const SPACE = "\u0020".charCodeAt(0);
+const COMMA = ",".charCodeAt(0);
+const LEFT_PARENTHESIS = "(".charCodeAt(0);
+const RIGHT_PARENTHESIS = ")".charCodeAt(0);
+const SMALL_LETTER_W = "w".charCodeAt(0);
+const SMALL_LETTER_X = "x".charCodeAt(0);
+const SMALL_LETTER_H = "h".charCodeAt(0);
+
+/**
+ * @param {number} char char
+ * @returns {boolean} true when ASCII whitespace, otherwise false
+ */
+function isASCIIWhitespace(char) {
+	return (
+		// Horizontal tab
+		char === HORIZONTAL_TAB ||
+		// New line
+		char === NEWLINE ||
+		// Form feed
+		char === FORM_FEED ||
+		// Carriage return
+		char === CARRIAGE_RETURN ||
+		// Space
+		char === SPACE
+	);
+}
+
+/** @typedef {[string, number, number]} ParsedSource */
+
+// eslint-disable-next-line no-control-regex
+const IGNORE_CHARS_REGEXP = /[\u0000-\u001F\u007F-\u009F\u00A0]/g;
+
+/**
+ * @param {string} input input
+ * @returns {ParsedSource[]} parsed src
+ */
+const parseSrc = (input) => {
+	const len = input.length;
+	if (len === 0) throw new Error("Must be non-empty");
+
+	let start = 0;
+	let end = len;
+
+	while (start < end) {
+		const code = input.charCodeAt(start);
+		if (code > 32 && code !== 160) break;
+		start++;
+	}
+
+	if (start === end) throw new Error("Must be non-empty");
+
+	while (end > start) {
+		const code = input.charCodeAt(end - 1);
+		if (code > 32 && code !== 160) break;
+		end--;
+	}
+
+	let value = input.slice(start, end);
+
+	if (IGNORE_CHARS_REGEXP.test(value)) {
+		value = value.replace(IGNORE_CHARS_REGEXP, "");
+		if (value.length === 0) throw new Error("Must be non-empty");
+	}
+
+	return [[value, start, end]];
+};
+
+// HTML `<style>` content is rawtext: it ends at the first `</style>`
+// where the tag name is followed by whitespace, `>` or `/`. The
+// lookahead (rather than a consuming character class) keeps the match
+// from running past the first `>` into a later tag — the
+// `[^>]*` only consumes any (rarely-seen) end-tag attributes before the
+// closing `>` of the end tag itself.
+const STYLE_END_REGEXP = /<\/style(?=[\s/>])[^>]*>/gi;
+
+// (Don't use \s, to avoid matching non-breaking space)
+// eslint-disable-next-line no-control-regex
+const LEADING_SPACES_REGEXP = /^[ \t\n\r\u000C]+/;
+// eslint-disable-next-line no-control-regex
+const LEADING_COMMAS_OR_SPACES_REGEXP = /^[, \t\n\r\u000C]+/;
+// eslint-disable-next-line no-control-regex
+const LEADING_NOT_SPACES = /^[^ \t\n\r\u000C]+/;
+const TRAILING_COMMAS_REGEXP = /[,]+$/;
+const NON_NEGATIVE_INTEGER_REGEXP = /^\d+$/;
+// ( Positive or negative or unsigned integers or decimals, without or without exponents.
+// Must include at least one digit.
+// According to spec tests any decimal point must be followed by a digit.
+// No leading plus sign is allowed.)
+// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number
+const FLOATING_POINT_REGEXP =
+	/^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
+
+/**
+ * @param {string} input input
+ * @returns {ParsedSource[]} parsed srcset
+ */
+const parseSrcset = (input) => {
+	// 1. Let input be the value passed to this algorithm.
+	const inputLength = input.length;
+
+	/** @type {string | undefined} */
+	let url;
+	/** @type {string[]} */
+	let descriptors;
+	/** @type {string} */
+	let currentDescriptor;
+	/** @type {string} */
+	let state;
+	/** @type {number} */
+	let charCode;
+	/** @type {number} */
+	let position = 0;
+	/** @type {number} */
+	let start;
+
+	/** @type {[string, number, number][]} */
+	const candidates = [];
+
+	/**
+	 * @param {RegExp} regExp reg exp to collect characters
+	 * @returns {string | undefined} characters
+	 */
+	function collectCharacters(regExp) {
+		/** @type {string} */
+		let chars;
+		const match = regExp.exec(input.slice(Math.max(0, position)));
+
+		if (match) {
+			[chars] = match;
+			position += chars.length;
+
+			return chars;
+		}
+	}
+
+	/**
+	 * @returns {void}
+	 */
+	function parseDescriptors() {
+		// 9. Descriptor parser: Let error be no.
+		let pError = false;
+
+		// 10. Let width be absent.
+		// 11. Let density be absent.
+		// 12. Let future-compat-h be absent. (We're implementing it now as h)
+		/** @type {number | undefined} */
+		let width;
+		/** @type {number | undefined} */
+		let density;
+		/** @type {number | undefined} */
+		let height;
+		/** @type {string | undefined} */
+		let desc;
+
+		// 13. For each descriptor in descriptors, run the appropriate set of steps
+		// from the following list:
+		for (let i = 0; i < descriptors.length; i++) {
+			desc = descriptors[i];
+
+			const lastChar = desc[desc.length - 1].charCodeAt(0);
+			const value = desc.slice(0, Math.max(0, desc.length - 1));
+
+			// If the descriptor consists of a valid non-negative integer followed by
+			// a U+0077 LATIN SMALL LETTER W character
+			if (
+				NON_NEGATIVE_INTEGER_REGEXP.test(value) &&
+				lastChar === SMALL_LETTER_W
+			) {
+				// If width and density are not both absent, then let error be yes.
+				if (width || density) {
+					pError = true;
+				}
+
+				const intVal = Number.parseInt(value, 10);
+
+				// Apply the rules for parsing non-negative integers to the descriptor.
+				// If the result is zero, let error be yes.
+				// Otherwise, let width be the result.
+				if (intVal === 0) {
+					pError = true;
+				} else {
+					width = intVal;
+				}
+			}
+			// If the descriptor consists of a valid floating-point number followed by
+			// a U+0078 LATIN SMALL LETTER X character
+			else if (
+				FLOATING_POINT_REGEXP.test(value) &&
+				lastChar === SMALL_LETTER_X
+			) {
+				// If width, density and future-compat-h are not all absent, then let error
+				// be yes.
+				if (width || density || height) {
+					pError = true;
+				}
+
+				const floatVal = Number.parseFloat(value);
+
+				// Apply the rules for parsing floating-point number values to the descriptor.
+				// If the result is less than zero, let error be yes. Otherwise, let density
+				// be the result.
+				if (floatVal < 0) {
+					pError = true;
+				} else {
+					density = floatVal;
+				}
+			}
+			// If the descriptor consists of a valid non-negative integer followed by
+			// a U+0068 LATIN SMALL LETTER H character
+			else if (
+				NON_NEGATIVE_INTEGER_REGEXP.test(value) &&
+				lastChar === SMALL_LETTER_H
+			) {
+				// If height and density are not both absent, then let error be yes.
+				if (height || density) {
+					pError = true;
+				}
+
+				const intVal = Number.parseInt(value, 10);
+
+				// Apply the rules for parsing non-negative integers to the descriptor.
+				// If the result is zero, let error be yes. Otherwise, let future-compat-h
+				// be the result.
+				if (intVal === 0) {
+					pError = true;
+				} else {
+					height = intVal;
+				}
+
+				// Anything else, Let error be yes.
+			} else {
+				pError = true;
+			}
+		}
+
+		// 15. If error is still no, then append a new image source to candidates whose
+		// URL is url, associated with a width width if not absent and a pixel
+		// density density if not absent. Otherwise, there is a parse error.
+		if (!pError) {
+			candidates.push([
+				/** @type {string} */ (url),
+				start,
+				start + /** @type {string} */ (url).length
+			]);
+		} else {
+			throw new Error(
+				`Invalid srcset descriptor found in '${input}' at '${desc}'`
+			);
+		}
+	}
+
+	/**
+	 * @returns {void}
+	 */
+	function tokenize() {
+		// 8.1. Descriptor tokenizer: Skip whitespace
+		collectCharacters(LEADING_SPACES_REGEXP);
+
+		// 8.2. Let current descriptor be the empty string.
+		currentDescriptor = "";
+
+		// 8.3. Let state be in descriptor.
+		state = "in descriptor";
+
+		while (true) {
+			// 8.4. Let charCode be the character at position.
+			charCode = input.charCodeAt(position);
+
+			//  Do the following depending on the value of state.
+			//  For the purpose of this step, "EOF" is a special character representing
+			//  that position is past the end of input.
+
+			// In descriptor
+			if (state === "in descriptor") {
+				// Do the following, depending on the value of charCode:
+
+				// Space character
+				// If current descriptor is not empty, append current descriptor to
+				// descriptors and let current descriptor be the empty string.
+				// Set state to after descriptor.
+				if (isASCIIWhitespace(charCode)) {
+					if (currentDescriptor) {
+						descriptors.push(currentDescriptor);
+						currentDescriptor = "";
+						state = "after descriptor";
+					}
+				}
+				// U+002C COMMA (,)
+				// Advance position to the next character in input. If current descriptor
+				// is not empty, append current descriptor to descriptors. Jump to the step
+				// labeled descriptor parser.
+				else if (charCode === COMMA) {
+					position += 1;
+
+					if (currentDescriptor) {
+						descriptors.push(currentDescriptor);
+					}
+
+					parseDescriptors();
+
+					return;
+				}
+				// U+0028 LEFT PARENTHESIS (()
+				// Append charCode to current descriptor. Set state to in parens.
+				else if (charCode === LEFT_PARENTHESIS) {
+					currentDescriptor += input.charAt(position);
+					state = "in parens";
+				}
+				// EOF
+				// If current descriptor is not empty, append current descriptor to
+				// descriptors. Jump to the step labeled descriptor parser.
+				else if (Number.isNaN(charCode)) {
+					if (currentDescriptor) {
+						descriptors.push(currentDescriptor);
+					}
+
+					parseDescriptors();
+
+					return;
+
+					// Anything else
+					// Append charCode to current descriptor.
+				} else {
+					currentDescriptor += input.charAt(position);
+				}
+			}
+			// In parens
+			else if (state === "in parens") {
+				// U+0029 RIGHT PARENTHESIS ())
+				// Append charCode to current descriptor. Set state to in descriptor.
+				if (charCode === RIGHT_PARENTHESIS) {
+					currentDescriptor += input.charAt(position);
+					state = "in descriptor";
+				}
+				// EOF
+				// Append current descriptor to descriptors. Jump to the step labeled
+				// descriptor parser.
+				else if (Number.isNaN(charCode)) {
+					descriptors.push(currentDescriptor);
+					parseDescriptors();
+					return;
+				}
+				// Anything else
+				// Append charCode to current descriptor.
+				else {
+					currentDescriptor += input.charAt(position);
+				}
+			}
+			// After descriptor
+			else if (state === "after descriptor") {
+				// Do the following, depending on the value of charCode:
+				if (isASCIIWhitespace(charCode)) {
+					// Space character: Stay in this state.
+				}
+				// EOF: Jump to the step labeled descriptor parser.
+				else if (Number.isNaN(charCode)) {
+					parseDescriptors();
+					return;
+				}
+				// Anything else
+				// Set state to in descriptor. Set position to the previous character in input.
+				else {
+					state = "in descriptor";
+					position -= 1;
+				}
+			}
+
+			// Advance position to the next character in input.
+			position += 1;
+		}
+	}
+
+	// 3. Let candidates be an initially empty source set.
+	// const candidates = []; // Moved to top
+
+	// 4. Splitting loop: Collect a sequence of characters that are space
+	//    characters or U+002C COMMA characters. If any U+002C COMMA characters
+	//    were collected, that is a parse error.
+
+	while (true) {
+		collectCharacters(LEADING_COMMAS_OR_SPACES_REGEXP);
+
+		// 5. If position is past the end of input, return candidates and abort these steps.
+		if (position >= inputLength) {
+			if (candidates.length === 0) {
+				throw new Error("Must contain one or more image candidate strings");
+			}
+
+			// (we're done, this is the sole return path)
+			return candidates;
+		}
+
+		// 6. Collect a sequence of characters that are not space characters,
+		//    and let that be url.
+		start = position;
+		url = collectCharacters(LEADING_NOT_SPACES);
+
+		// 7. Let descriptors be a new empty list.
+		descriptors = [];
+
+		// 8. If url ends with a U+002C COMMA character (,), follow these sub steps:
+		//		(1). Remove all trailing U+002C COMMA characters from url. If this removed
+		//         more than one character, that is a parse error.
+		if (url && url.charCodeAt(url.length - 1) === COMMA) {
+			url = url.replace(TRAILING_COMMAS_REGEXP, "");
+
+			// (Jump ahead to step 9 to skip tokenization and just push the candidate).
+			parseDescriptors();
+		}
+		//	Otherwise, follow these sub steps:
+		else {
+			tokenize();
+		}
+
+		// 16. Return to the step labeled splitting loop.
+	}
+};
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @param {string} name name
+ * @returns {string | undefined} attribute value
+ */
+const getAttributeValue = (attributes, name) => attributes.get(name);
+
+/** @type {Map<string, Set<string>>} */
+const META = new Map([
+	[
+		"name",
+		new Set([
+			// msapplication-TileImage
+			"msapplication-tileimage",
+			"msapplication-square70x70logo",
+			"msapplication-square150x150logo",
+			"msapplication-wide310x150logo",
+			"msapplication-square310x310logo",
+			"msapplication-config",
+			// TODO Do we need to parser it?
+			// "msapplication-task",
+			"twitter:image"
+		])
+	],
+	[
+		"property",
+		new Set([
+			"og:image",
+			"og:image:url",
+			"og:image:secure_url",
+			"og:audio",
+			"og:audio:secure_url",
+			"og:video",
+			"og:video:secure_url",
+			"vk:image"
+		])
+	],
+	[
+		"itemprop",
+		new Set([
+			"image",
+			"logo",
+			"screenshot",
+			"thumbnailurl",
+			"contenturl",
+			"downloadurl",
+			"duringmedia",
+			"embedurl",
+			"installurl",
+			"layoutimage"
+		])
+	]
+]);
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when need to parse, otherwise false
+ */
+const filterLinkItemprop = (attributes) => {
+	const value = getAttributeValue(attributes, "itemprop");
+	if (!value) return false;
+	const allowedAttributes = META.get("itemprop");
+	if (!allowedAttributes) return false;
+
+	return allowedAttributes.has(value.trim().toLowerCase());
+};
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when need to parse, otherwise false
+ */
+const filterLinkHref = (attributes) => {
+	const rel = getAttributeValue(attributes, "rel");
+	if (!rel) return false;
+	const usedRels = rel.trim().toLowerCase().split(" ").filter(Boolean);
+	const allowedRels = [
+		"stylesheet",
+		"icon",
+		"mask-icon",
+		"apple-touch-icon",
+		"apple-touch-icon-precomposed",
+		"apple-touch-startup-image",
+		"manifest",
+		"prefetch",
+		"preload",
+		"modulepreload"
+	];
+
+	return allowedRels.some((value) => usedRels.includes(value));
+};
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when need to parse, otherwise false
+ */
+const filterLinkUnion = (attributes) =>
+	filterLinkHref(attributes) || filterLinkItemprop(attributes);
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when need to parse, otherwise false
+ */
+const filterMetaContent = (attributes) => {
+	for (const item of META) {
+		const [key, allowedNames] = item;
+		const name = getAttributeValue(attributes, key);
+		if (!name) continue;
+
+		return allowedNames.has(name.trim().toLowerCase());
+	}
+
+	return false;
+};
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when the script element opts into ES module semantics
+ */
+const isModuleScript = (attributes) => {
+	const type = getAttributeValue(attributes, "type");
+	if (!type) return false;
+	return type.trim().toLowerCase() === "module";
+};
+
+// HTML `<script>` `type` values that the browser treats as executable
+// JavaScript. Anything outside this set (e.g. `application/ld+json`,
+// `importmap`, `application/wasm`) is a data block — webpack must not
+// try to bundle it as a JS entry; it should pass through as an asset URL.
+const JS_SCRIPT_TYPES = new Set([
+	"",
+	"module",
+	"text/javascript",
+	"application/javascript",
+	"text/ecmascript",
+	"application/ecmascript"
+]);
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when the script element's `type` is executable JS
+ */
+const isExecutableJsScript = (attributes) => {
+	const type = getAttributeValue(attributes, "type");
+	if (type === undefined) return true;
+	return JS_SCRIPT_TYPES.has(type.trim().toLowerCase());
+};
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when the link points at an ES module that should be bundled as an entry chunk
+ */
+const isLinkModulePreload = (attributes) => {
+	const rel = getAttributeValue(attributes, "rel");
+	if (!rel) return false;
+	return rel.trim().toLowerCase().split(/\s+/).includes("modulepreload");
+};
+
+/**
+ * @param {Map<string, string>} attributes attributes
+ * @returns {boolean} true when the link is a `<link rel="stylesheet">` that should be bundled as a CSS entry chunk
+ */
+const isLinkStylesheet = (attributes) => {
+	const rel = getAttributeValue(attributes, "rel");
+	if (!rel) return false;
+	return rel.trim().toLowerCase().split(/\s+/).includes("stylesheet");
+};
+
+/** @type {Map<string, Map<string, { parse: (input: string) => ParsedSource[] | undefined, filter?: (attributes: Map<string, string>) => boolean, entry?: boolean | ((attributes: Map<string, string>) => boolean), entryCategory?: string }>>} */
+const DEFAULT_SOURCES = new Map([
+	[
+		"audio",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	[
+		"embed",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	[
+		"img",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			],
+			[
+				"srcset",
+				{
+					parse: parseSrcset
+				}
+			]
+		])
+	],
+	[
+		"input",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	[
+		"link",
+		new Map([
+			[
+				"href",
+				{
+					parse: parseSrc,
+					filter: filterLinkUnion,
+					entry: isLinkModulePreload,
+					entryCategory: "esm"
+				}
+			],
+			[
+				"imagesrcset",
+				{
+					parse: parseSrcset,
+					filter: filterLinkHref
+				}
+			]
+		])
+	],
+	[
+		"meta",
+		new Map([
+			[
+				"content",
+				{
+					parse: parseSrc,
+					filter: filterMetaContent
+				}
+			]
+		])
+	],
+	[
+		"object",
+		new Map([
+			[
+				"data",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	[
+		"script",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc,
+					// Only executable-JS scripts become entries. Non-JS
+					// `<script>` types (e.g. `application/ld+json`,
+					// `importmap`) fall through to HtmlSourceDependency so
+					// the browser keeps seeing them as data blocks, with
+					// the asset URL rewritten like any other resource.
+					entry: isExecutableJsScript
+				}
+			]
+		])
+	],
+	[
+		"source",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			],
+			[
+				"srcset",
+				{
+					parse: parseSrcset
+				}
+			]
+		])
+	],
+	[
+		"track",
+		new Map([
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	[
+		"video",
+		new Map([
+			[
+				"poster",
+				{
+					parse: parseSrc
+				}
+			],
+			[
+				"src",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	// SVG
+	[
+		"image",
+		new Map([
+			[
+				"xlink:href",
+				{
+					parse: parseSrc
+				}
+			],
+			[
+				"href",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	],
+	[
+		"use",
+		new Map([
+			[
+				"xlink:href",
+				{
+					parse: parseSrc
+				}
+			],
+			[
+				"href",
+				{
+					parse: parseSrc
+				}
+			]
+		])
+	]
+]);
+
+class HtmlParser extends Parser {
+	/**
+	 * Creates an instance of HtmlParser.
+	 * @param {(string | typeof import("../util/Hash"))=} hashFunction algorithm or constructor used by `output.hashFunction`; falls back to the default when omitted
+	 * @param {string=} context compilation context used to contextify the HTML module's identifier when seeding the entry-name hash
+	 * @param {boolean=} outputModule whether `output.module` is enabled; when true, classic `<script src>` tags get `type="module"` auto-inserted so the rewritten src can load the emitted ES module chunk
+	 * @param {boolean=} css whether `experiments.css` is enabled; when true, inline `<style>` bodies are routed through the CSS pipeline as `data:text/css` modules
+	 */
+	constructor(hashFunction, context, outputModule, css) {
+		super();
+		this.magicCommentContext = createMagicCommentContext();
+		this.hashFunction = hashFunction;
+		this.context = context;
+		this.outputModule = outputModule;
+		this.css = css;
+	}
+
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (Buffer.isBuffer(source)) {
+			source = source.toString("utf8");
+		} else if (typeof source === "object") {
+			throw new Error("webpackAst is unexpected for the HtmlParser");
+		}
+		if (source[0] === "\uFEFF") {
+			source = source.slice(1);
+		}
+
+		const locConverter = new LocConverter(source);
+
+		const module = state.module;
+
+		// Stable, per-HTML-module prefix used when generating entry names for
+		// script src / modulepreload references so they don't collide across
+		// HTML modules in the same compilation. We hash the module's resource
+		// path (a plain absolute path) — going through `contextify` against
+		// the compilation root keeps the hash machine-stable for the same
+		// project layout. Note: `module.identifier()` returns `html|<path>`
+		// for HTML modules, which doesn't start with `/`, so contextify would
+		// leave it absolute. `module.resource` is the bare path.
+		/** @type {string} */
+		const resource =
+			/** @type {EXPECTED_ANY} */ (module).resource || module.identifier();
+		const moduleHash = createHash(this.hashFunction || "md4")
+			.update(this.context ? contextify(this.context, resource) : resource)
+			.digest("hex")
+			.slice(0, 8);
+
+		/** @typedef {{ nameStart: number, nameEnd: number, valueStart: number, valueEnd: number }} AttrToken */
+
+		/** @type {AttrToken[]} */
+		const pendingAttributes = [];
+
+		/**
+		 * Reconciles the rewritten `<script>` tag's `type` attribute with the
+		 * emitted chunk's actual format. Used by both the `<script src>` and
+		 * inline `<script>` paths so the two stay in sync.
+		 * @param {AttrToken | undefined} typeAttr existing `type` attribute, if any
+		 * @param {number} nameEnd position right after `<script` (for inserts)
+		 * @param {"classic" | "esm-script"} kind chunk kind decided by the parser
+		 * @param {string} input full source string
+		 * @returns {void}
+		 */
+		const reconcileScriptTypeAttr = (typeAttr, nameEnd, kind, input) => {
+			if (this.outputModule && kind === "classic") {
+				// Chunk is an ES module; upgrade the tag.
+				if (typeAttr && typeAttr.valueStart !== -1) {
+					module.addPresentationalDependency(
+						new ConstDependency("module", [
+							typeAttr.valueStart,
+							typeAttr.valueEnd
+						])
+					);
+				} else {
+					module.addPresentationalDependency(
+						new ConstDependency(' type="module"', nameEnd)
+					);
+				}
+			} else if (!this.outputModule && kind === "esm-script" && typeAttr) {
+				// Chunk is a classic IIFE; drop `type="module"` so the
+				// browser doesn't load it under module semantics.
+				let attrEnd;
+				if (typeAttr.valueStart === -1) {
+					attrEnd = typeAttr.nameEnd;
+				} else if (
+					input[typeAttr.valueEnd] === '"' ||
+					input[typeAttr.valueEnd] === "'"
+				) {
+					attrEnd = typeAttr.valueEnd + 1;
+				} else {
+					attrEnd = typeAttr.valueEnd;
+				}
+				// Consume one leading whitespace char so we don't leave a
+				// double space between `<script` and the next attribute.
+				let attrStart = typeAttr.nameStart;
+				if (
+					attrStart > 0 &&
+					isASCIIWhitespace(input.charCodeAt(attrStart - 1))
+				) {
+					attrStart -= 1;
+				}
+				module.addPresentationalDependency(
+					new ConstDependency("", [attrStart, attrEnd])
+				);
+			}
+		};
+
+		// Inline `<script>` body extraction is deferred to the matching
+		// `closeTag` event so the walker's script-data state machine
+		// (including its escaped/double-escaped sub-states) decides where
+		// the body ends. This is the spec-compliant way to find the close
+		// — a plain `</script>` regex would split too early inside
+		// `<!--<script>…</script>-->` patterns.
+		/** @type {null | { contentStart: number, attrs: Map<string, string>, typeAttr: AttrToken | undefined, nameEnd: number }} */
+		let pendingInlineScript = null;
+
+		// Script src / modulepreload references are collected per-category
+		// during the walk; HtmlModulesPlugin later turns them into real
+		// entries. Classic <script src> and <script type="module" src> are
+		// chained via a leader-only dependOn so they share a runtime.
+		// `<link rel="modulepreload">` entries are kept independent — they
+		// must preload without running, so they can never become a runtime
+		// leader that other entries would import.
+		/**
+		 * @typedef {object} EntryScriptInfo
+		 * @property {string} request
+		 * @property {string} entryName
+		 * @property {"classic" | "esm-script" | "modulepreload" | "stylesheet"} kind
+		 */
+		/** @type {EntryScriptInfo[]} */
+		const classicEntries = [];
+		/** @type {EntryScriptInfo[]} */
+		const esmScriptEntries = [];
+		/** @type {EntryScriptInfo[]} */
+		const modulePreloadEntries = [];
+		/** @type {EntryScriptInfo[]} */
+		const stylesheetEntries = [];
+
+		let nextEntryIndex = 0;
+
+		/**
+		 * Tracks the `webpackIgnore` value from the most recent comment that
+		 * appears before the next tag. Reset whenever a tag is emitted or a
+		 * comment without a `webpackIgnore` value is encountered.
+		 * @type {boolean | undefined}
+		 */
+		let pendingWebpackIgnore;
+
+		const magicCommentContext = this.magicCommentContext;
+
+		// TODO implement full HTML parser (WASM)
+		walkHtmlTokens(source, 0, {
+			comment: (input, start, end) => {
+				// Only proper `<!-- ... -->` comments carry magic comments.
+				// `walkHtmlTokens` also dispatches this callback for bogus
+				// comments such as `<!DOCTYPE …>` and `<?…>`, which must not
+				// be parsed as magic comments.
+				if (
+					end - start < 7 ||
+					input.charCodeAt(start) !== 0x3c /* < */ ||
+					input.charCodeAt(start + 1) !== 0x21 /* ! */ ||
+					input.charCodeAt(start + 2) !== 0x2d /* - */ ||
+					input.charCodeAt(start + 3) !== 0x2d /* - */ ||
+					input.charCodeAt(end - 1) !== 0x3e /* > */ ||
+					input.charCodeAt(end - 2) !== 0x2d /* - */ ||
+					input.charCodeAt(end - 3) !== 0x2d /* - */
+				) {
+					pendingWebpackIgnore = undefined;
+					return end;
+				}
+				const contentStart = start + 4;
+				const contentEnd = end - 3;
+				const value = input.slice(contentStart, contentEnd);
+				if (!webpackCommentRegExp.test(value)) {
+					pendingWebpackIgnore = undefined;
+					return end;
+				}
+				/** @type {Record<string, EXPECTED_ANY>} */
+				let options;
+				try {
+					options = vm.runInContext(
+						`(function(){return {${value}};})()`,
+						magicCommentContext
+					);
+				} catch (err) {
+					const { line: sl, column: sc } = locConverter.get(start);
+					const { line: el, column: ec } = locConverter.get(end);
+					module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${value}*/: ${
+								/** @type {Error} */ (err).message
+							}`,
+							{
+								start: { line: sl, column: sc },
+								end: { line: el, column: ec }
+							}
+						)
+					);
+					pendingWebpackIgnore = undefined;
+					return end;
+				}
+				if (options.webpackIgnore === undefined) {
+					pendingWebpackIgnore = undefined;
+					return end;
+				}
+				if (typeof options.webpackIgnore !== "boolean") {
+					const { line: sl, column: sc } = locConverter.get(start);
+					const { line: el, column: ec } = locConverter.get(end);
+					module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
+							{
+								start: { line: sl, column: sc },
+								end: { line: el, column: ec }
+							}
+						)
+					);
+					pendingWebpackIgnore = undefined;
+					return end;
+				}
+				pendingWebpackIgnore = options.webpackIgnore;
+				return end;
+			},
+			attribute: (
+				input,
+				nameStart,
+				nameEnd,
+				valueStart,
+				valueEnd,
+				quoteType
+			) => {
+				pendingAttributes.push({ nameStart, nameEnd, valueStart, valueEnd });
+				if (valueStart === -1) return nameEnd;
+				return quoteType !== walkHtmlTokens.QUOTE_NONE
+					? valueEnd + 1
+					: valueEnd;
+			},
+			closeTag: (input, start, end, nameStart, nameEnd) => {
+				pendingWebpackIgnore = undefined;
+				if (pendingInlineScript) {
+					const elName = input.slice(nameStart, nameEnd).toLowerCase();
+					if (elName === "script") {
+						const ps = pendingInlineScript;
+						pendingInlineScript = null;
+						const contentStart = ps.contentStart;
+						const contentEnd = start; // start of `</script>`
+						const jsContent = input.slice(contentStart, contentEnd);
+						if (jsContent.trim() === "") return end;
+
+						// Base64-encode the JS body so the data URI round-trips
+						// arbitrary JavaScript text, including non-ASCII source
+						// (`decodeDataURI` decodes non-base64 bodies as ASCII,
+						// which would corrupt Unicode string literals or
+						// identifiers).
+						const request = `data:text/javascript;base64,${Buffer.from(
+							jsContent,
+							"utf8"
+						).toString("base64")}`;
+
+						const useEsmEntry = isModuleScript(ps.attrs);
+						const entryName = `__html_${moduleHash}_${nextEntryIndex++}`;
+						/** @type {"classic" | "esm-script"} */
+						const kind = useEsmEntry ? "esm-script" : "classic";
+						const { line: sl, column: sc } = locConverter.get(contentStart);
+						const { line: el, column: ec } = locConverter.get(contentEnd);
+						const dep = new HtmlInlineScriptDependency(
+							request,
+							ps.nameEnd,
+							[contentStart, contentEnd],
+							entryName,
+							useEsmEntry ? "esm" : "commonjs"
+						);
+						dep.setLoc(sl, sc, el, ec);
+						module.addPresentationalDependency(dep);
+						reconcileScriptTypeAttr(ps.typeAttr, ps.nameEnd, kind, input);
+						const collection =
+							kind === "classic" ? classicEntries : esmScriptEntries;
+						collection.push({ request, entryName, kind });
+					}
+				}
+				return end;
+			},
+			openTag: (input, start, end, nameStart, nameEnd) => {
+				const ignore = pendingWebpackIgnore === true;
+				pendingWebpackIgnore = undefined;
+				if (ignore) {
+					// For `<script>` and `<style>` we don't emit a dependency,
+					// but we must NOT advance past the close tag either: the
+					// walker is already in script-data/rawtext state for
+					// those tags and will consume the body and emit the
+					// matching `closeTag` itself. Returning a position past
+					// `</script>`/`</style>` would leave the walker stuck in
+					// rawtext mode, swallowing later markup.
+					pendingAttributes.length = 0;
+					return end;
+				}
+				const elementName = input.slice(nameStart, nameEnd).toLowerCase();
+
+				// `<style>` is rawtext: capture the inline CSS and hand it to
+				// the CSS pipeline as a virtual `data:text/css` module with
+				// `exportType: "text"`. We use the regex only to discover the
+				// `</style>` position so we can slice the body; the walker is
+				// already in rawtext state for `<style>` and will emit the
+				// matching `closeTag` event itself, so we must return `end`
+				// (the position right after the opening tag's `>`) rather
+				// than advancing past `</style>`. Only `<style>` tags whose
+				// `type` attribute is absent, empty, or `text/css` are
+				// processed; other types are left untouched.
+				if (elementName === "style") {
+					/** @type {string | undefined} */
+					let typeValue;
+					for (const attr of pendingAttributes) {
+						const attrName = input
+							.slice(attr.nameStart, attr.nameEnd)
+							.toLowerCase();
+						if (attrName === "type") {
+							typeValue =
+								attr.valueStart !== -1
+									? input.slice(attr.valueStart, attr.valueEnd)
+									: "";
+							break;
+						}
+					}
+					pendingAttributes.length = 0;
+
+					STYLE_END_REGEXP.lastIndex = end;
+					const closeMatch = STYLE_END_REGEXP.exec(input);
+					if (!closeMatch) return end;
+					const contentStart = end;
+					const contentEnd = closeMatch.index;
+
+					const trimmedType =
+						typeValue !== undefined ? typeValue.trim().toLowerCase() : "";
+					if (
+						typeValue !== undefined &&
+						trimmedType !== "" &&
+						trimmedType !== "text/css"
+					) {
+						return end;
+					}
+
+					// Inline-style processing requires the CSS pipeline; when
+					// `experiments.css` is off, leave the body alone — the
+					// walker is in rawtext mode for `<style>` and will skip
+					// over the body to the matching `</style>` itself.
+					if (!this.css) {
+						return end;
+					}
+
+					const cssContent = input.slice(contentStart, contentEnd);
+					if (cssContent.trim() === "") {
+						return end;
+					}
+
+					// URL-encode the CSS body so the data URI parser's `(.*)$`
+					// body group matches even when the source has newlines or
+					// other characters that would otherwise break the regex.
+					const request = `data:text/css,${encodeURIComponent(cssContent)}`;
+
+					const { line: sl, column: sc } = locConverter.get(contentStart);
+					const { line: el, column: ec } = locConverter.get(contentEnd);
+					const dep = new HtmlInlineStyleDependency(request, [
+						contentStart,
+						contentEnd
+					]);
+					dep.setLoc(sl, sc, el, ec);
+					module.addDependency(dep);
+					module.addCodeGenerationDependency(dep);
+					return end;
+				}
+
+				const sources = DEFAULT_SOURCES.get(elementName);
+
+				if (!sources) {
+					pendingAttributes.length = 0;
+					return end;
+				}
+
+				/** @type {Map<string, string> | undefined} */
+				let attributesMap;
+				const getAttributesMap = () => {
+					if (attributesMap) return attributesMap;
+					attributesMap = new Map();
+					for (const attr of pendingAttributes) {
+						const name = input
+							.slice(attr.nameStart, attr.nameEnd)
+							.toLowerCase();
+						const value =
+							attr.valueStart !== -1
+								? input.slice(attr.valueStart, attr.valueEnd)
+								: "";
+						attributesMap.set(name, value);
+					}
+					return attributesMap;
+				};
+
+				for (const attr of pendingAttributes) {
+					const attributeName = input
+						.slice(attr.nameStart, attr.nameEnd)
+						.toLowerCase();
+					const sourceItem = sources.get(attributeName);
+
+					if (!sourceItem) continue;
+
+					// TODO(html-entities): We should ideally decode entities here using
+					// `walkHtmlTokens.decodeHtmlEntities(input.slice(...))` so that URLs
+					// like `image.png?a=1&amp;b=2` are correctly resolved as `&`.
+					// However, doing so currently breaks `srcset` parsing tests (e.g. `errors.js`)
+					// which explicitly expect whitespace entities like `&#x9;` to NOT be decoded
+					// before the srcset parser runs. A follow-up PR should implement selective
+					// decoding for specific URL attributes.
+					const attributeValue =
+						attr.valueStart !== -1
+							? input.slice(attr.valueStart, attr.valueEnd)
+							: "";
+
+					if (!attributeValue) continue;
+
+					if (
+						typeof sourceItem.filter === "function" &&
+						!sourceItem.filter(getAttributesMap())
+					) {
+						continue;
+					}
+
+					/** @type {ParsedSource[] | undefined} */
+					let parsedAttributeValue;
+
+					try {
+						parsedAttributeValue = sourceItem.parse(attributeValue);
+					} catch (err) {
+						const { line: sl, column: sc } = locConverter.get(attr.valueStart);
+						const { line: el, column: ec } = locConverter.get(attr.valueEnd);
+
+						module.addError(
+							new ModuleDependencyError(
+								module,
+								new WebpackError(
+									`Bad value for attribute "${attributeName}" on element "${elementName}": ${
+										/** @type {Error} */ (err).message
+									}`
+								),
+								{
+									start: { line: sl, column: sc },
+									end: { line: el, column: ec }
+								}
+							)
+						);
+					}
+
+					if (!parsedAttributeValue) continue;
+
+					// `<link rel="stylesheet">` is upgraded to an entry only when
+					// `experiments.css` is on — that's the mode where webpack can
+					// bundle the CSS into its own chunk. Without it, the
+					// stylesheet href stays a plain asset URL. Scope this to the
+					// `href` attribute only: `<link>` also exposes
+					// `imagesrcset` URLs which must continue to flow through
+					// the regular asset rewriting path even on a stylesheet
+					// link.
+					const isStylesheetEntry =
+						this.css &&
+						elementName === "link" &&
+						attributeName === "href" &&
+						isLinkStylesheet(getAttributesMap());
+					const isEntry =
+						isStylesheetEntry ||
+						sourceItem.entry === true ||
+						(typeof sourceItem.entry === "function" &&
+							sourceItem.entry(getAttributesMap()));
+
+					// `<script type="module" src>` and `<link rel="modulepreload">`
+					// reference ES modules; everything else under `<script src>` is a
+					// classic script. The category drives ESM vs CommonJS resolution
+					// of the entry — the chunk format is controlled by the user via
+					// `output.module` / `experiments.outputModule`.
+					const useEsmEntry =
+						(elementName === "script" && isModuleScript(getAttributesMap())) ||
+						sourceItem.entryCategory === "esm";
+
+					for (const parsedSource of parsedAttributeValue) {
+						const [value, innerStart, innerEnd] = parsedSource;
+						if (value.startsWith("#")) continue;
+						const sourceStart = attr.valueStart + innerStart;
+						const sourceEnd = attr.valueStart + innerEnd;
+						const { line: sl, column: sc } = locConverter.get(sourceStart);
+						const { line: el, column: ec } = locConverter.get(sourceEnd);
+						if (isEntry) {
+							const entryName = `__html_${moduleHash}_${nextEntryIndex++}`;
+							const isStylesheetLink =
+								elementName === "link" && isLinkStylesheet(getAttributesMap());
+							/** @type {"classic" | "esm-script" | "modulepreload" | "stylesheet"} */
+							const kind =
+								elementName === "link"
+									? isStylesheetLink
+										? "stylesheet"
+										: "modulepreload"
+									: useEsmEntry
+										? "esm-script"
+										: "classic";
+							// With `output.module` enabled, a classic `<script src>` is
+							// upgraded in place to `<script type="module" src>` (see the
+							// ConstDependency insertion below). Account for that in the
+							// dependency's `elementKind` so sibling tags emitted by the
+							// template for additional entry chunks (runtime / split chunks)
+							// also use `type="module"`.
+							const willBeModuleScript =
+								kind === "esm-script" ||
+								(this.outputModule &&
+									kind === "classic" &&
+									elementName === "script");
+							/** @type {"script-classic" | "script-module" | "modulepreload" | "stylesheet"} */
+							const elementKind =
+								kind === "modulepreload"
+									? "modulepreload"
+									: kind === "stylesheet"
+										? "stylesheet"
+										: willBeModuleScript
+											? "script-module"
+											: "script-classic";
+							const dep = new HtmlScriptSrcDependency(
+								value,
+								[sourceStart, sourceEnd],
+								entryName,
+								// `<link rel="stylesheet">` is bundled as a CSS entry —
+								// using a non-"url" category so the default `.css` rule
+								// (which gives the resolved module the CSS module type)
+								// wins over the `dependency: "url"` → asset rule.
+								kind === "stylesheet"
+									? "css-import"
+									: useEsmEntry
+										? "esm"
+										: sourceItem.entryCategory,
+								elementKind,
+								start,
+								end
+							);
+							dep.setLoc(sl, sc, el, ec);
+							module.addPresentationalDependency(dep);
+							// Reconcile the rewritten `<script>` tag's `type`
+							// attribute with the chunk's actual format. See
+							// `reconcileScriptTypeAttr` for the rules.
+							if (
+								elementName === "script" &&
+								(kind === "classic" || kind === "esm-script")
+							) {
+								/** @type {AttrToken | undefined} */
+								let typeAttr;
+								for (const a of pendingAttributes) {
+									if (
+										input.slice(a.nameStart, a.nameEnd).toLowerCase() === "type"
+									) {
+										typeAttr = a;
+										break;
+									}
+								}
+								reconcileScriptTypeAttr(typeAttr, nameEnd, kind, input);
+							}
+							const collection =
+								kind === "classic"
+									? classicEntries
+									: kind === "esm-script"
+										? esmScriptEntries
+										: kind === "stylesheet"
+											? stylesheetEntries
+											: modulePreloadEntries;
+							collection.push({ request: value, entryName, kind });
+						} else {
+							const dep = new HtmlSourceDependency(value, [
+								sourceStart,
+								sourceEnd
+							]);
+							dep.setLoc(sl, sc, el, ec);
+							module.addDependency(dep);
+							module.addCodeGenerationDependency(dep);
+						}
+					}
+				}
+
+				// `<script>` is rawtext (the "script data state" in the HTML
+				// tokenizer): its body must never be reparsed as HTML,
+				// regardless of whether the tag has a `src` attribute. The
+				// walker is already in script-data state for `<script>` and
+				// will emit the matching `closeTag` event itself, so we
+				// return `end` and defer body extraction to the closeTag
+				// callback (which gets the spec-correct `</script>` position
+				// even in escaped/double-escaped script-data sub-states).
+				// When the tag has no `src` and its body is non-empty, the
+				// closeTag handler bundles the inline JS as its own entry —
+				// the same pipeline that processes `<script src>` — by
+				// issuing a `data:text/javascript;base64,...` virtual request
+				// and adding a dependency that rewrites the tag to
+				// `<script src="…">` at render time. Only `<script>` tags
+				// whose `type` attribute is absent, empty, or a recognized
+				// JS mimetype are processed as JS; other types (e.g.
+				// `application/ld+json`, `importmap`) are left untouched.
+				if (elementName === "script") {
+					const attrs = getAttributesMap();
+					// Use attribute presence, not value: a `<script src>` with
+					// an empty or valueless `src` still ignores its inline
+					// body in the browser, so we must not bundle the body.
+					const hasSrc = attrs.has("src");
+
+					/** @type {AttrToken | undefined} */
+					let typeAttr;
+					for (const a of pendingAttributes) {
+						if (input.slice(a.nameStart, a.nameEnd).toLowerCase() === "type") {
+							typeAttr = a;
+							break;
+						}
+					}
+					pendingAttributes.length = 0;
+
+					if (hasSrc || !isExecutableJsScript(attrs)) {
+						// `<script src>` body is ignored by the browser, and
+						// non-JS `<script type>` (e.g. importmap, JSON-LD)
+						// passes through unchanged. Either way the walker
+						// consumes the body and emits the close tag itself.
+						return end;
+					}
+
+					pendingInlineScript = {
+						contentStart: end,
+						attrs,
+						typeAttr,
+						nameEnd
+					};
+					return end;
+				}
+
+				pendingAttributes.length = 0;
+				return end;
+			}
+		});
+
+		const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
+		buildInfo.strict = true;
+		// Hand off the collected entries to HtmlModulesPlugin; it creates the
+		// real compilation entries during the finishMake hook. The classic
+		// and esm-script groups are chained via a leader-only dependOn so
+		// they share a runtime; modulepreload entries are emitted as
+		// independent entries since `<link rel=modulepreload>` must preload
+		// without running.
+		if (
+			classicEntries.length > 0 ||
+			esmScriptEntries.length > 0 ||
+			modulePreloadEntries.length > 0 ||
+			stylesheetEntries.length > 0
+		) {
+			/** @type {Record<string, EntryScriptInfo[]>} */
+			(buildInfo.htmlEntryScripts) = {
+				classic: classicEntries,
+				"esm-script": esmScriptEntries,
+				modulepreload: modulePreloadEntries,
+				stylesheet: stylesheetEntries
+			};
+		}
+
+		const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
+		buildMeta.exportsType = "default";
+
+		state.module.addDependency(new StaticExportsDependency(["default"], true));
+
+		return state;
+	}
+}
+
+module.exports = HtmlParser;
Index: frontend/node_modules/webpack/lib/html/walkHtmlTokens.js
===================================================================
--- frontend/node_modules/webpack/lib/html/walkHtmlTokens.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/html/walkHtmlTokens.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3249 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Raj Aryan (based on SWC parser by Alexander Akait)
+*/
+
+"use strict";
+
+// cspell:ignore apos notpre noncharacters DFFF
+
+// #region html entities
+// The contents of this region are auto-generated by
+// `tooling/generate-html-entities.js` from `tooling/html-entities.json`.
+// Do not edit by hand — re-run the generator (via `yarn fix:special`) to refresh.
+//
+// WHATWG named character references. Keys are entity names WITHOUT the
+// leading `&` (some end with `;`, others omit it for legacy entities that
+// match without a closing semicolon). Values are the decoded character
+// strings (1–2 UTF-16 code units).
+// Built on a null prototype so bracket lookups (`HTML_ENTITIES[name]`)
+// can't be poisoned by inherited `Object.prototype` keys like `toString`,
+// `constructor`, or `__proto__` — without this, `&toString;` would falsely
+// look like a matched named character reference.
+// prettier-ignore
+// cspell:disable-next-line
+const HTML_ENTITIES = /** @type {Readonly<Record<string, string>>} */ (Object.freeze(Object.assign(Object.create(null), {"AElig":"Æ","AElig;":"Æ","AMP":"&","AMP;":"&","Aacute":"Á","Aacute;":"Á","Abreve;":"Ă","Acirc":"Â","Acirc;":"Â","Acy;":"А","Afr;":"𝔄","Agrave":"À","Agrave;":"À","Alpha;":"Α","Amacr;":"Ā","And;":"⩓","Aogon;":"Ą","Aopf;":"𝔸","ApplyFunction;":"⁡","Aring":"Å","Aring;":"Å","Ascr;":"𝒜","Assign;":"≔","Atilde":"Ã","Atilde;":"Ã","Auml":"Ä","Auml;":"Ä","Backslash;":"∖","Barv;":"⫧","Barwed;":"⌆","Bcy;":"Б","Because;":"∵","Bernoullis;":"ℬ","Beta;":"Β","Bfr;":"𝔅","Bopf;":"𝔹","Breve;":"˘","Bscr;":"ℬ","Bumpeq;":"≎","CHcy;":"Ч","COPY":"©","COPY;":"©","Cacute;":"Ć","Cap;":"⋒","CapitalDifferentialD;":"ⅅ","Cayleys;":"ℭ","Ccaron;":"Č","Ccedil":"Ç","Ccedil;":"Ç","Ccirc;":"Ĉ","Cconint;":"∰","Cdot;":"Ċ","Cedilla;":"¸","CenterDot;":"·","Cfr;":"ℭ","Chi;":"Χ","CircleDot;":"⊙","CircleMinus;":"⊖","CirclePlus;":"⊕","CircleTimes;":"⊗","ClockwiseContourIntegral;":"∲","CloseCurlyDoubleQuote;":"”","CloseCurlyQuote;":"’","Colon;":"∷","Colone;":"⩴","Congruent;":"≡","Conint;":"∯","ContourIntegral;":"∮","Copf;":"ℂ","Coproduct;":"∐","CounterClockwiseContourIntegral;":"∳","Cross;":"⨯","Cscr;":"𝒞","Cup;":"⋓","CupCap;":"≍","DD;":"ⅅ","DDotrahd;":"⤑","DJcy;":"Ђ","DScy;":"Ѕ","DZcy;":"Џ","Dagger;":"‡","Darr;":"↡","Dashv;":"⫤","Dcaron;":"Ď","Dcy;":"Д","Del;":"∇","Delta;":"Δ","Dfr;":"𝔇","DiacriticalAcute;":"´","DiacriticalDot;":"˙","DiacriticalDoubleAcute;":"˝","DiacriticalGrave;":"`","DiacriticalTilde;":"˜","Diamond;":"⋄","DifferentialD;":"ⅆ","Dopf;":"𝔻","Dot;":"¨","DotDot;":"⃜","DotEqual;":"≐","DoubleContourIntegral;":"∯","DoubleDot;":"¨","DoubleDownArrow;":"⇓","DoubleLeftArrow;":"⇐","DoubleLeftRightArrow;":"⇔","DoubleLeftTee;":"⫤","DoubleLongLeftArrow;":"⟸","DoubleLongLeftRightArrow;":"⟺","DoubleLongRightArrow;":"⟹","DoubleRightArrow;":"⇒","DoubleRightTee;":"⊨","DoubleUpArrow;":"⇑","DoubleUpDownArrow;":"⇕","DoubleVerticalBar;":"∥","DownArrow;":"↓","DownArrowBar;":"⤓","DownArrowUpArrow;":"⇵","DownBreve;":"̑","DownLeftRightVector;":"⥐","DownLeftTeeVector;":"⥞","DownLeftVector;":"↽","DownLeftVectorBar;":"⥖","DownRightTeeVector;":"⥟","DownRightVector;":"⇁","DownRightVectorBar;":"⥗","DownTee;":"⊤","DownTeeArrow;":"↧","Downarrow;":"⇓","Dscr;":"𝒟","Dstrok;":"Đ","ENG;":"Ŋ","ETH":"Ð","ETH;":"Ð","Eacute":"É","Eacute;":"É","Ecaron;":"Ě","Ecirc":"Ê","Ecirc;":"Ê","Ecy;":"Э","Edot;":"Ė","Efr;":"𝔈","Egrave":"È","Egrave;":"È","Element;":"∈","Emacr;":"Ē","EmptySmallSquare;":"◻","EmptyVerySmallSquare;":"▫","Eogon;":"Ę","Eopf;":"𝔼","Epsilon;":"Ε","Equal;":"⩵","EqualTilde;":"≂","Equilibrium;":"⇌","Escr;":"ℰ","Esim;":"⩳","Eta;":"Η","Euml":"Ë","Euml;":"Ë","Exists;":"∃","ExponentialE;":"ⅇ","Fcy;":"Ф","Ffr;":"𝔉","FilledSmallSquare;":"◼","FilledVerySmallSquare;":"▪","Fopf;":"𝔽","ForAll;":"∀","Fouriertrf;":"ℱ","Fscr;":"ℱ","GJcy;":"Ѓ","GT":">","GT;":">","Gamma;":"Γ","Gammad;":"Ϝ","Gbreve;":"Ğ","Gcedil;":"Ģ","Gcirc;":"Ĝ","Gcy;":"Г","Gdot;":"Ġ","Gfr;":"𝔊","Gg;":"⋙","Gopf;":"𝔾","GreaterEqual;":"≥","GreaterEqualLess;":"⋛","GreaterFullEqual;":"≧","GreaterGreater;":"⪢","GreaterLess;":"≷","GreaterSlantEqual;":"⩾","GreaterTilde;":"≳","Gscr;":"𝒢","Gt;":"≫","HARDcy;":"Ъ","Hacek;":"ˇ","Hat;":"^","Hcirc;":"Ĥ","Hfr;":"ℌ","HilbertSpace;":"ℋ","Hopf;":"ℍ","HorizontalLine;":"─","Hscr;":"ℋ","Hstrok;":"Ħ","HumpDownHump;":"≎","HumpEqual;":"≏","IEcy;":"Е","IJlig;":"Ĳ","IOcy;":"Ё","Iacute":"Í","Iacute;":"Í","Icirc":"Î","Icirc;":"Î","Icy;":"И","Idot;":"İ","Ifr;":"ℑ","Igrave":"Ì","Igrave;":"Ì","Im;":"ℑ","Imacr;":"Ī","ImaginaryI;":"ⅈ","Implies;":"⇒","Int;":"∬","Integral;":"∫","Intersection;":"⋂","InvisibleComma;":"⁣","InvisibleTimes;":"⁢","Iogon;":"Į","Iopf;":"𝕀","Iota;":"Ι","Iscr;":"ℐ","Itilde;":"Ĩ","Iukcy;":"І","Iuml":"Ï","Iuml;":"Ï","Jcirc;":"Ĵ","Jcy;":"Й","Jfr;":"𝔍","Jopf;":"𝕁","Jscr;":"𝒥","Jsercy;":"Ј","Jukcy;":"Є","KHcy;":"Х","KJcy;":"Ќ","Kappa;":"Κ","Kcedil;":"Ķ","Kcy;":"К","Kfr;":"𝔎","Kopf;":"𝕂","Kscr;":"𝒦","LJcy;":"Љ","LT":"<","LT;":"<","Lacute;":"Ĺ","Lambda;":"Λ","Lang;":"⟪","Laplacetrf;":"ℒ","Larr;":"↞","Lcaron;":"Ľ","Lcedil;":"Ļ","Lcy;":"Л","LeftAngleBracket;":"⟨","LeftArrow;":"←","LeftArrowBar;":"⇤","LeftArrowRightArrow;":"⇆","LeftCeiling;":"⌈","LeftDoubleBracket;":"⟦","LeftDownTeeVector;":"⥡","LeftDownVector;":"⇃","LeftDownVectorBar;":"⥙","LeftFloor;":"⌊","LeftRightArrow;":"↔","LeftRightVector;":"⥎","LeftTee;":"⊣","LeftTeeArrow;":"↤","LeftTeeVector;":"⥚","LeftTriangle;":"⊲","LeftTriangleBar;":"⧏","LeftTriangleEqual;":"⊴","LeftUpDownVector;":"⥑","LeftUpTeeVector;":"⥠","LeftUpVector;":"↿","LeftUpVectorBar;":"⥘","LeftVector;":"↼","LeftVectorBar;":"⥒","Leftarrow;":"⇐","Leftrightarrow;":"⇔","LessEqualGreater;":"⋚","LessFullEqual;":"≦","LessGreater;":"≶","LessLess;":"⪡","LessSlantEqual;":"⩽","LessTilde;":"≲","Lfr;":"𝔏","Ll;":"⋘","Lleftarrow;":"⇚","Lmidot;":"Ŀ","LongLeftArrow;":"⟵","LongLeftRightArrow;":"⟷","LongRightArrow;":"⟶","Longleftarrow;":"⟸","Longleftrightarrow;":"⟺","Longrightarrow;":"⟹","Lopf;":"𝕃","LowerLeftArrow;":"↙","LowerRightArrow;":"↘","Lscr;":"ℒ","Lsh;":"↰","Lstrok;":"Ł","Lt;":"≪","Map;":"⤅","Mcy;":"М","MediumSpace;":" ","Mellintrf;":"ℳ","Mfr;":"𝔐","MinusPlus;":"∓","Mopf;":"𝕄","Mscr;":"ℳ","Mu;":"Μ","NJcy;":"Њ","Nacute;":"Ń","Ncaron;":"Ň","Ncedil;":"Ņ","Ncy;":"Н","NegativeMediumSpace;":"​","NegativeThickSpace;":"​","NegativeThinSpace;":"​","NegativeVeryThinSpace;":"​","NestedGreaterGreater;":"≫","NestedLessLess;":"≪","NewLine;":"\n","Nfr;":"𝔑","NoBreak;":"⁠","NonBreakingSpace;":" ","Nopf;":"ℕ","Not;":"⫬","NotCongruent;":"≢","NotCupCap;":"≭","NotDoubleVerticalBar;":"∦","NotElement;":"∉","NotEqual;":"≠","NotEqualTilde;":"≂̸","NotExists;":"∄","NotGreater;":"≯","NotGreaterEqual;":"≱","NotGreaterFullEqual;":"≧̸","NotGreaterGreater;":"≫̸","NotGreaterLess;":"≹","NotGreaterSlantEqual;":"⩾̸","NotGreaterTilde;":"≵","NotHumpDownHump;":"≎̸","NotHumpEqual;":"≏̸","NotLeftTriangle;":"⋪","NotLeftTriangleBar;":"⧏̸","NotLeftTriangleEqual;":"⋬","NotLess;":"≮","NotLessEqual;":"≰","NotLessGreater;":"≸","NotLessLess;":"≪̸","NotLessSlantEqual;":"⩽̸","NotLessTilde;":"≴","NotNestedGreaterGreater;":"⪢̸","NotNestedLessLess;":"⪡̸","NotPrecedes;":"⊀","NotPrecedesEqual;":"⪯̸","NotPrecedesSlantEqual;":"⋠","NotReverseElement;":"∌","NotRightTriangle;":"⋫","NotRightTriangleBar;":"⧐̸","NotRightTriangleEqual;":"⋭","NotSquareSubset;":"⊏̸","NotSquareSubsetEqual;":"⋢","NotSquareSuperset;":"⊐̸","NotSquareSupersetEqual;":"⋣","NotSubset;":"⊂⃒","NotSubsetEqual;":"⊈","NotSucceeds;":"⊁","NotSucceedsEqual;":"⪰̸","NotSucceedsSlantEqual;":"⋡","NotSucceedsTilde;":"≿̸","NotSuperset;":"⊃⃒","NotSupersetEqual;":"⊉","NotTilde;":"≁","NotTildeEqual;":"≄","NotTildeFullEqual;":"≇","NotTildeTilde;":"≉","NotVerticalBar;":"∤","Nscr;":"𝒩","Ntilde":"Ñ","Ntilde;":"Ñ","Nu;":"Ν","OElig;":"Œ","Oacute":"Ó","Oacute;":"Ó","Ocirc":"Ô","Ocirc;":"Ô","Ocy;":"О","Odblac;":"Ő","Ofr;":"𝔒","Ograve":"Ò","Ograve;":"Ò","Omacr;":"Ō","Omega;":"Ω","Omicron;":"Ο","Oopf;":"𝕆","OpenCurlyDoubleQuote;":"“","OpenCurlyQuote;":"‘","Or;":"⩔","Oscr;":"𝒪","Oslash":"Ø","Oslash;":"Ø","Otilde":"Õ","Otilde;":"Õ","Otimes;":"⨷","Ouml":"Ö","Ouml;":"Ö","OverBar;":"‾","OverBrace;":"⏞","OverBracket;":"⎴","OverParenthesis;":"⏜","PartialD;":"∂","Pcy;":"П","Pfr;":"𝔓","Phi;":"Φ","Pi;":"Π","PlusMinus;":"±","Poincareplane;":"ℌ","Popf;":"ℙ","Pr;":"⪻","Precedes;":"≺","PrecedesEqual;":"⪯","PrecedesSlantEqual;":"≼","PrecedesTilde;":"≾","Prime;":"″","Product;":"∏","Proportion;":"∷","Proportional;":"∝","Pscr;":"𝒫","Psi;":"Ψ","QUOT":"\"","QUOT;":"\"","Qfr;":"𝔔","Qopf;":"ℚ","Qscr;":"𝒬","RBarr;":"⤐","REG":"®","REG;":"®","Racute;":"Ŕ","Rang;":"⟫","Rarr;":"↠","Rarrtl;":"⤖","Rcaron;":"Ř","Rcedil;":"Ŗ","Rcy;":"Р","Re;":"ℜ","ReverseElement;":"∋","ReverseEquilibrium;":"⇋","ReverseUpEquilibrium;":"⥯","Rfr;":"ℜ","Rho;":"Ρ","RightAngleBracket;":"⟩","RightArrow;":"→","RightArrowBar;":"⇥","RightArrowLeftArrow;":"⇄","RightCeiling;":"⌉","RightDoubleBracket;":"⟧","RightDownTeeVector;":"⥝","RightDownVector;":"⇂","RightDownVectorBar;":"⥕","RightFloor;":"⌋","RightTee;":"⊢","RightTeeArrow;":"↦","RightTeeVector;":"⥛","RightTriangle;":"⊳","RightTriangleBar;":"⧐","RightTriangleEqual;":"⊵","RightUpDownVector;":"⥏","RightUpTeeVector;":"⥜","RightUpVector;":"↾","RightUpVectorBar;":"⥔","RightVector;":"⇀","RightVectorBar;":"⥓","Rightarrow;":"⇒","Ropf;":"ℝ","RoundImplies;":"⥰","Rrightarrow;":"⇛","Rscr;":"ℛ","Rsh;":"↱","RuleDelayed;":"⧴","SHCHcy;":"Щ","SHcy;":"Ш","SOFTcy;":"Ь","Sacute;":"Ś","Sc;":"⪼","Scaron;":"Š","Scedil;":"Ş","Scirc;":"Ŝ","Scy;":"С","Sfr;":"𝔖","ShortDownArrow;":"↓","ShortLeftArrow;":"←","ShortRightArrow;":"→","ShortUpArrow;":"↑","Sigma;":"Σ","SmallCircle;":"∘","Sopf;":"𝕊","Sqrt;":"√","Square;":"□","SquareIntersection;":"⊓","SquareSubset;":"⊏","SquareSubsetEqual;":"⊑","SquareSuperset;":"⊐","SquareSupersetEqual;":"⊒","SquareUnion;":"⊔","Sscr;":"𝒮","Star;":"⋆","Sub;":"⋐","Subset;":"⋐","SubsetEqual;":"⊆","Succeeds;":"≻","SucceedsEqual;":"⪰","SucceedsSlantEqual;":"≽","SucceedsTilde;":"≿","SuchThat;":"∋","Sum;":"∑","Sup;":"⋑","Superset;":"⊃","SupersetEqual;":"⊇","Supset;":"⋑","THORN":"Þ","THORN;":"Þ","TRADE;":"™","TSHcy;":"Ћ","TScy;":"Ц","Tab;":"\t","Tau;":"Τ","Tcaron;":"Ť","Tcedil;":"Ţ","Tcy;":"Т","Tfr;":"𝔗","Therefore;":"∴","Theta;":"Θ","ThickSpace;":"  ","ThinSpace;":" ","Tilde;":"∼","TildeEqual;":"≃","TildeFullEqual;":"≅","TildeTilde;":"≈","Topf;":"𝕋","TripleDot;":"⃛","Tscr;":"𝒯","Tstrok;":"Ŧ","Uacute":"Ú","Uacute;":"Ú","Uarr;":"↟","Uarrocir;":"⥉","Ubrcy;":"Ў","Ubreve;":"Ŭ","Ucirc":"Û","Ucirc;":"Û","Ucy;":"У","Udblac;":"Ű","Ufr;":"𝔘","Ugrave":"Ù","Ugrave;":"Ù","Umacr;":"Ū","UnderBar;":"_","UnderBrace;":"⏟","UnderBracket;":"⎵","UnderParenthesis;":"⏝","Union;":"⋃","UnionPlus;":"⊎","Uogon;":"Ų","Uopf;":"𝕌","UpArrow;":"↑","UpArrowBar;":"⤒","UpArrowDownArrow;":"⇅","UpDownArrow;":"↕","UpEquilibrium;":"⥮","UpTee;":"⊥","UpTeeArrow;":"↥","Uparrow;":"⇑","Updownarrow;":"⇕","UpperLeftArrow;":"↖","UpperRightArrow;":"↗","Upsi;":"ϒ","Upsilon;":"Υ","Uring;":"Ů","Uscr;":"𝒰","Utilde;":"Ũ","Uuml":"Ü","Uuml;":"Ü","VDash;":"⊫","Vbar;":"⫫","Vcy;":"В","Vdash;":"⊩","Vdashl;":"⫦","Vee;":"⋁","Verbar;":"‖","Vert;":"‖","VerticalBar;":"∣","VerticalLine;":"|","VerticalSeparator;":"❘","VerticalTilde;":"≀","VeryThinSpace;":" ","Vfr;":"𝔙","Vopf;":"𝕍","Vscr;":"𝒱","Vvdash;":"⊪","Wcirc;":"Ŵ","Wedge;":"⋀","Wfr;":"𝔚","Wopf;":"𝕎","Wscr;":"𝒲","Xfr;":"𝔛","Xi;":"Ξ","Xopf;":"𝕏","Xscr;":"𝒳","YAcy;":"Я","YIcy;":"Ї","YUcy;":"Ю","Yacute":"Ý","Yacute;":"Ý","Ycirc;":"Ŷ","Ycy;":"Ы","Yfr;":"𝔜","Yopf;":"𝕐","Yscr;":"𝒴","Yuml;":"Ÿ","ZHcy;":"Ж","Zacute;":"Ź","Zcaron;":"Ž","Zcy;":"З","Zdot;":"Ż","ZeroWidthSpace;":"​","Zeta;":"Ζ","Zfr;":"ℨ","Zopf;":"ℤ","Zscr;":"𝒵","aacute":"á","aacute;":"á","abreve;":"ă","ac;":"∾","acE;":"∾̳","acd;":"∿","acirc":"â","acirc;":"â","acute":"´","acute;":"´","acy;":"а","aelig":"æ","aelig;":"æ","af;":"⁡","afr;":"𝔞","agrave":"à","agrave;":"à","alefsym;":"ℵ","aleph;":"ℵ","alpha;":"α","amacr;":"ā","amalg;":"⨿","amp":"&","amp;":"&","and;":"∧","andand;":"⩕","andd;":"⩜","andslope;":"⩘","andv;":"⩚","ang;":"∠","ange;":"⦤","angle;":"∠","angmsd;":"∡","angmsdaa;":"⦨","angmsdab;":"⦩","angmsdac;":"⦪","angmsdad;":"⦫","angmsdae;":"⦬","angmsdaf;":"⦭","angmsdag;":"⦮","angmsdah;":"⦯","angrt;":"∟","angrtvb;":"⊾","angrtvbd;":"⦝","angsph;":"∢","angst;":"Å","angzarr;":"⍼","aogon;":"ą","aopf;":"𝕒","ap;":"≈","apE;":"⩰","apacir;":"⩯","ape;":"≊","apid;":"≋","apos;":"'","approx;":"≈","approxeq;":"≊","aring":"å","aring;":"å","ascr;":"𝒶","ast;":"*","asymp;":"≈","asympeq;":"≍","atilde":"ã","atilde;":"ã","auml":"ä","auml;":"ä","awconint;":"∳","awint;":"⨑","bNot;":"⫭","backcong;":"≌","backepsilon;":"϶","backprime;":"‵","backsim;":"∽","backsimeq;":"⋍","barvee;":"⊽","barwed;":"⌅","barwedge;":"⌅","bbrk;":"⎵","bbrktbrk;":"⎶","bcong;":"≌","bcy;":"б","bdquo;":"„","becaus;":"∵","because;":"∵","bemptyv;":"⦰","bepsi;":"϶","bernou;":"ℬ","beta;":"β","beth;":"ℶ","between;":"≬","bfr;":"𝔟","bigcap;":"⋂","bigcirc;":"◯","bigcup;":"⋃","bigodot;":"⨀","bigoplus;":"⨁","bigotimes;":"⨂","bigsqcup;":"⨆","bigstar;":"★","bigtriangledown;":"▽","bigtriangleup;":"△","biguplus;":"⨄","bigvee;":"⋁","bigwedge;":"⋀","bkarow;":"⤍","blacklozenge;":"⧫","blacksquare;":"▪","blacktriangle;":"▴","blacktriangledown;":"▾","blacktriangleleft;":"◂","blacktriangleright;":"▸","blank;":"␣","blk12;":"▒","blk14;":"░","blk34;":"▓","block;":"█","bne;":"=⃥","bnequiv;":"≡⃥","bnot;":"⌐","bopf;":"𝕓","bot;":"⊥","bottom;":"⊥","bowtie;":"⋈","boxDL;":"╗","boxDR;":"╔","boxDl;":"╖","boxDr;":"╓","boxH;":"═","boxHD;":"╦","boxHU;":"╩","boxHd;":"╤","boxHu;":"╧","boxUL;":"╝","boxUR;":"╚","boxUl;":"╜","boxUr;":"╙","boxV;":"║","boxVH;":"╬","boxVL;":"╣","boxVR;":"╠","boxVh;":"╫","boxVl;":"╢","boxVr;":"╟","boxbox;":"⧉","boxdL;":"╕","boxdR;":"╒","boxdl;":"┐","boxdr;":"┌","boxh;":"─","boxhD;":"╥","boxhU;":"╨","boxhd;":"┬","boxhu;":"┴","boxminus;":"⊟","boxplus;":"⊞","boxtimes;":"⊠","boxuL;":"╛","boxuR;":"╘","boxul;":"┘","boxur;":"└","boxv;":"│","boxvH;":"╪","boxvL;":"╡","boxvR;":"╞","boxvh;":"┼","boxvl;":"┤","boxvr;":"├","bprime;":"‵","breve;":"˘","brvbar":"¦","brvbar;":"¦","bscr;":"𝒷","bsemi;":"⁏","bsim;":"∽","bsime;":"⋍","bsol;":"\\","bsolb;":"⧅","bsolhsub;":"⟈","bull;":"•","bullet;":"•","bump;":"≎","bumpE;":"⪮","bumpe;":"≏","bumpeq;":"≏","cacute;":"ć","cap;":"∩","capand;":"⩄","capbrcup;":"⩉","capcap;":"⩋","capcup;":"⩇","capdot;":"⩀","caps;":"∩︀","caret;":"⁁","caron;":"ˇ","ccaps;":"⩍","ccaron;":"č","ccedil":"ç","ccedil;":"ç","ccirc;":"ĉ","ccups;":"⩌","ccupssm;":"⩐","cdot;":"ċ","cedil":"¸","cedil;":"¸","cemptyv;":"⦲","cent":"¢","cent;":"¢","centerdot;":"·","cfr;":"𝔠","chcy;":"ч","check;":"✓","checkmark;":"✓","chi;":"χ","cir;":"○","cirE;":"⧃","circ;":"ˆ","circeq;":"≗","circlearrowleft;":"↺","circlearrowright;":"↻","circledR;":"®","circledS;":"Ⓢ","circledast;":"⊛","circledcirc;":"⊚","circleddash;":"⊝","cire;":"≗","cirfnint;":"⨐","cirmid;":"⫯","cirscir;":"⧂","clubs;":"♣","clubsuit;":"♣","colon;":":","colone;":"≔","coloneq;":"≔","comma;":",","commat;":"@","comp;":"∁","compfn;":"∘","complement;":"∁","complexes;":"ℂ","cong;":"≅","congdot;":"⩭","conint;":"∮","copf;":"𝕔","coprod;":"∐","copy":"©","copy;":"©","copysr;":"℗","crarr;":"↵","cross;":"✗","cscr;":"𝒸","csub;":"⫏","csube;":"⫑","csup;":"⫐","csupe;":"⫒","ctdot;":"⋯","cudarrl;":"⤸","cudarrr;":"⤵","cuepr;":"⋞","cuesc;":"⋟","cularr;":"↶","cularrp;":"⤽","cup;":"∪","cupbrcap;":"⩈","cupcap;":"⩆","cupcup;":"⩊","cupdot;":"⊍","cupor;":"⩅","cups;":"∪︀","curarr;":"↷","curarrm;":"⤼","curlyeqprec;":"⋞","curlyeqsucc;":"⋟","curlyvee;":"⋎","curlywedge;":"⋏","curren":"¤","curren;":"¤","curvearrowleft;":"↶","curvearrowright;":"↷","cuvee;":"⋎","cuwed;":"⋏","cwconint;":"∲","cwint;":"∱","cylcty;":"⌭","dArr;":"⇓","dHar;":"⥥","dagger;":"†","daleth;":"ℸ","darr;":"↓","dash;":"‐","dashv;":"⊣","dbkarow;":"⤏","dblac;":"˝","dcaron;":"ď","dcy;":"д","dd;":"ⅆ","ddagger;":"‡","ddarr;":"⇊","ddotseq;":"⩷","deg":"°","deg;":"°","delta;":"δ","demptyv;":"⦱","dfisht;":"⥿","dfr;":"𝔡","dharl;":"⇃","dharr;":"⇂","diam;":"⋄","diamond;":"⋄","diamondsuit;":"♦","diams;":"♦","die;":"¨","digamma;":"ϝ","disin;":"⋲","div;":"÷","divide":"÷","divide;":"÷","divideontimes;":"⋇","divonx;":"⋇","djcy;":"ђ","dlcorn;":"⌞","dlcrop;":"⌍","dollar;":"$","dopf;":"𝕕","dot;":"˙","doteq;":"≐","doteqdot;":"≑","dotminus;":"∸","dotplus;":"∔","dotsquare;":"⊡","doublebarwedge;":"⌆","downarrow;":"↓","downdownarrows;":"⇊","downharpoonleft;":"⇃","downharpoonright;":"⇂","drbkarow;":"⤐","drcorn;":"⌟","drcrop;":"⌌","dscr;":"𝒹","dscy;":"ѕ","dsol;":"⧶","dstrok;":"đ","dtdot;":"⋱","dtri;":"▿","dtrif;":"▾","duarr;":"⇵","duhar;":"⥯","dwangle;":"⦦","dzcy;":"џ","dzigrarr;":"⟿","eDDot;":"⩷","eDot;":"≑","eacute":"é","eacute;":"é","easter;":"⩮","ecaron;":"ě","ecir;":"≖","ecirc":"ê","ecirc;":"ê","ecolon;":"≕","ecy;":"э","edot;":"ė","ee;":"ⅇ","efDot;":"≒","efr;":"𝔢","eg;":"⪚","egrave":"è","egrave;":"è","egs;":"⪖","egsdot;":"⪘","el;":"⪙","elinters;":"⏧","ell;":"ℓ","els;":"⪕","elsdot;":"⪗","emacr;":"ē","empty;":"∅","emptyset;":"∅","emptyv;":"∅","emsp13;":" ","emsp14;":" ","emsp;":" ","eng;":"ŋ","ensp;":" ","eogon;":"ę","eopf;":"𝕖","epar;":"⋕","eparsl;":"⧣","eplus;":"⩱","epsi;":"ε","epsilon;":"ε","epsiv;":"ϵ","eqcirc;":"≖","eqcolon;":"≕","eqsim;":"≂","eqslantgtr;":"⪖","eqslantless;":"⪕","equals;":"=","equest;":"≟","equiv;":"≡","equivDD;":"⩸","eqvparsl;":"⧥","erDot;":"≓","erarr;":"⥱","escr;":"ℯ","esdot;":"≐","esim;":"≂","eta;":"η","eth":"ð","eth;":"ð","euml":"ë","euml;":"ë","euro;":"€","excl;":"!","exist;":"∃","expectation;":"ℰ","exponentiale;":"ⅇ","fallingdotseq;":"≒","fcy;":"ф","female;":"♀","ffilig;":"ﬃ","fflig;":"ﬀ","ffllig;":"ﬄ","ffr;":"𝔣","filig;":"ﬁ","fjlig;":"fj","flat;":"♭","fllig;":"ﬂ","fltns;":"▱","fnof;":"ƒ","fopf;":"𝕗","forall;":"∀","fork;":"⋔","forkv;":"⫙","fpartint;":"⨍","frac12":"½","frac12;":"½","frac13;":"⅓","frac14":"¼","frac14;":"¼","frac15;":"⅕","frac16;":"⅙","frac18;":"⅛","frac23;":"⅔","frac25;":"⅖","frac34":"¾","frac34;":"¾","frac35;":"⅗","frac38;":"⅜","frac45;":"⅘","frac56;":"⅚","frac58;":"⅝","frac78;":"⅞","frasl;":"⁄","frown;":"⌢","fscr;":"𝒻","gE;":"≧","gEl;":"⪌","gacute;":"ǵ","gamma;":"γ","gammad;":"ϝ","gap;":"⪆","gbreve;":"ğ","gcirc;":"ĝ","gcy;":"г","gdot;":"ġ","ge;":"≥","gel;":"⋛","geq;":"≥","geqq;":"≧","geqslant;":"⩾","ges;":"⩾","gescc;":"⪩","gesdot;":"⪀","gesdoto;":"⪂","gesdotol;":"⪄","gesl;":"⋛︀","gesles;":"⪔","gfr;":"𝔤","gg;":"≫","ggg;":"⋙","gimel;":"ℷ","gjcy;":"ѓ","gl;":"≷","glE;":"⪒","gla;":"⪥","glj;":"⪤","gnE;":"≩","gnap;":"⪊","gnapprox;":"⪊","gne;":"⪈","gneq;":"⪈","gneqq;":"≩","gnsim;":"⋧","gopf;":"𝕘","grave;":"`","gscr;":"ℊ","gsim;":"≳","gsime;":"⪎","gsiml;":"⪐","gt":">","gt;":">","gtcc;":"⪧","gtcir;":"⩺","gtdot;":"⋗","gtlPar;":"⦕","gtquest;":"⩼","gtrapprox;":"⪆","gtrarr;":"⥸","gtrdot;":"⋗","gtreqless;":"⋛","gtreqqless;":"⪌","gtrless;":"≷","gtrsim;":"≳","gvertneqq;":"≩︀","gvnE;":"≩︀","hArr;":"⇔","hairsp;":" ","half;":"½","hamilt;":"ℋ","hardcy;":"ъ","harr;":"↔","harrcir;":"⥈","harrw;":"↭","hbar;":"ℏ","hcirc;":"ĥ","hearts;":"♥","heartsuit;":"♥","hellip;":"…","hercon;":"⊹","hfr;":"𝔥","hksearow;":"⤥","hkswarow;":"⤦","hoarr;":"⇿","homtht;":"∻","hookleftarrow;":"↩","hookrightarrow;":"↪","hopf;":"𝕙","horbar;":"―","hscr;":"𝒽","hslash;":"ℏ","hstrok;":"ħ","hybull;":"⁃","hyphen;":"‐","iacute":"í","iacute;":"í","ic;":"⁣","icirc":"î","icirc;":"î","icy;":"и","iecy;":"е","iexcl":"¡","iexcl;":"¡","iff;":"⇔","ifr;":"𝔦","igrave":"ì","igrave;":"ì","ii;":"ⅈ","iiiint;":"⨌","iiint;":"∭","iinfin;":"⧜","iiota;":"℩","ijlig;":"ĳ","imacr;":"ī","image;":"ℑ","imagline;":"ℐ","imagpart;":"ℑ","imath;":"ı","imof;":"⊷","imped;":"Ƶ","in;":"∈","incare;":"℅","infin;":"∞","infintie;":"⧝","inodot;":"ı","int;":"∫","intcal;":"⊺","integers;":"ℤ","intercal;":"⊺","intlarhk;":"⨗","intprod;":"⨼","iocy;":"ё","iogon;":"į","iopf;":"𝕚","iota;":"ι","iprod;":"⨼","iquest":"¿","iquest;":"¿","iscr;":"𝒾","isin;":"∈","isinE;":"⋹","isindot;":"⋵","isins;":"⋴","isinsv;":"⋳","isinv;":"∈","it;":"⁢","itilde;":"ĩ","iukcy;":"і","iuml":"ï","iuml;":"ï","jcirc;":"ĵ","jcy;":"й","jfr;":"𝔧","jmath;":"ȷ","jopf;":"𝕛","jscr;":"𝒿","jsercy;":"ј","jukcy;":"є","kappa;":"κ","kappav;":"ϰ","kcedil;":"ķ","kcy;":"к","kfr;":"𝔨","kgreen;":"ĸ","khcy;":"х","kjcy;":"ќ","kopf;":"𝕜","kscr;":"𝓀","lAarr;":"⇚","lArr;":"⇐","lAtail;":"⤛","lBarr;":"⤎","lE;":"≦","lEg;":"⪋","lHar;":"⥢","lacute;":"ĺ","laemptyv;":"⦴","lagran;":"ℒ","lambda;":"λ","lang;":"⟨","langd;":"⦑","langle;":"⟨","lap;":"⪅","laquo":"«","laquo;":"«","larr;":"←","larrb;":"⇤","larrbfs;":"⤟","larrfs;":"⤝","larrhk;":"↩","larrlp;":"↫","larrpl;":"⤹","larrsim;":"⥳","larrtl;":"↢","lat;":"⪫","latail;":"⤙","late;":"⪭","lates;":"⪭︀","lbarr;":"⤌","lbbrk;":"❲","lbrace;":"{","lbrack;":"[","lbrke;":"⦋","lbrksld;":"⦏","lbrkslu;":"⦍","lcaron;":"ľ","lcedil;":"ļ","lceil;":"⌈","lcub;":"{","lcy;":"л","ldca;":"⤶","ldquo;":"“","ldquor;":"„","ldrdhar;":"⥧","ldrushar;":"⥋","ldsh;":"↲","le;":"≤","leftarrow;":"←","leftarrowtail;":"↢","leftharpoondown;":"↽","leftharpoonup;":"↼","leftleftarrows;":"⇇","leftrightarrow;":"↔","leftrightarrows;":"⇆","leftrightharpoons;":"⇋","leftrightsquigarrow;":"↭","leftthreetimes;":"⋋","leg;":"⋚","leq;":"≤","leqq;":"≦","leqslant;":"⩽","les;":"⩽","lescc;":"⪨","lesdot;":"⩿","lesdoto;":"⪁","lesdotor;":"⪃","lesg;":"⋚︀","lesges;":"⪓","lessapprox;":"⪅","lessdot;":"⋖","lesseqgtr;":"⋚","lesseqqgtr;":"⪋","lessgtr;":"≶","lesssim;":"≲","lfisht;":"⥼","lfloor;":"⌊","lfr;":"𝔩","lg;":"≶","lgE;":"⪑","lhard;":"↽","lharu;":"↼","lharul;":"⥪","lhblk;":"▄","ljcy;":"љ","ll;":"≪","llarr;":"⇇","llcorner;":"⌞","llhard;":"⥫","lltri;":"◺","lmidot;":"ŀ","lmoust;":"⎰","lmoustache;":"⎰","lnE;":"≨","lnap;":"⪉","lnapprox;":"⪉","lne;":"⪇","lneq;":"⪇","lneqq;":"≨","lnsim;":"⋦","loang;":"⟬","loarr;":"⇽","lobrk;":"⟦","longleftarrow;":"⟵","longleftrightarrow;":"⟷","longmapsto;":"⟼","longrightarrow;":"⟶","looparrowleft;":"↫","looparrowright;":"↬","lopar;":"⦅","lopf;":"𝕝","loplus;":"⨭","lotimes;":"⨴","lowast;":"∗","lowbar;":"_","loz;":"◊","lozenge;":"◊","lozf;":"⧫","lpar;":"(","lparlt;":"⦓","lrarr;":"⇆","lrcorner;":"⌟","lrhar;":"⇋","lrhard;":"⥭","lrm;":"‎","lrtri;":"⊿","lsaquo;":"‹","lscr;":"𝓁","lsh;":"↰","lsim;":"≲","lsime;":"⪍","lsimg;":"⪏","lsqb;":"[","lsquo;":"‘","lsquor;":"‚","lstrok;":"ł","lt":"<","lt;":"<","ltcc;":"⪦","ltcir;":"⩹","ltdot;":"⋖","lthree;":"⋋","ltimes;":"⋉","ltlarr;":"⥶","ltquest;":"⩻","ltrPar;":"⦖","ltri;":"◃","ltrie;":"⊴","ltrif;":"◂","lurdshar;":"⥊","luruhar;":"⥦","lvertneqq;":"≨︀","lvnE;":"≨︀","mDDot;":"∺","macr":"¯","macr;":"¯","male;":"♂","malt;":"✠","maltese;":"✠","map;":"↦","mapsto;":"↦","mapstodown;":"↧","mapstoleft;":"↤","mapstoup;":"↥","marker;":"▮","mcomma;":"⨩","mcy;":"м","mdash;":"—","measuredangle;":"∡","mfr;":"𝔪","mho;":"℧","micro":"µ","micro;":"µ","mid;":"∣","midast;":"*","midcir;":"⫰","middot":"·","middot;":"·","minus;":"−","minusb;":"⊟","minusd;":"∸","minusdu;":"⨪","mlcp;":"⫛","mldr;":"…","mnplus;":"∓","models;":"⊧","mopf;":"𝕞","mp;":"∓","mscr;":"𝓂","mstpos;":"∾","mu;":"μ","multimap;":"⊸","mumap;":"⊸","nGg;":"⋙̸","nGt;":"≫⃒","nGtv;":"≫̸","nLeftarrow;":"⇍","nLeftrightarrow;":"⇎","nLl;":"⋘̸","nLt;":"≪⃒","nLtv;":"≪̸","nRightarrow;":"⇏","nVDash;":"⊯","nVdash;":"⊮","nabla;":"∇","nacute;":"ń","nang;":"∠⃒","nap;":"≉","napE;":"⩰̸","napid;":"≋̸","napos;":"ŉ","napprox;":"≉","natur;":"♮","natural;":"♮","naturals;":"ℕ","nbsp":" ","nbsp;":" ","nbump;":"≎̸","nbumpe;":"≏̸","ncap;":"⩃","ncaron;":"ň","ncedil;":"ņ","ncong;":"≇","ncongdot;":"⩭̸","ncup;":"⩂","ncy;":"н","ndash;":"–","ne;":"≠","neArr;":"⇗","nearhk;":"⤤","nearr;":"↗","nearrow;":"↗","nedot;":"≐̸","nequiv;":"≢","nesear;":"⤨","nesim;":"≂̸","nexist;":"∄","nexists;":"∄","nfr;":"𝔫","ngE;":"≧̸","nge;":"≱","ngeq;":"≱","ngeqq;":"≧̸","ngeqslant;":"⩾̸","nges;":"⩾̸","ngsim;":"≵","ngt;":"≯","ngtr;":"≯","nhArr;":"⇎","nharr;":"↮","nhpar;":"⫲","ni;":"∋","nis;":"⋼","nisd;":"⋺","niv;":"∋","njcy;":"њ","nlArr;":"⇍","nlE;":"≦̸","nlarr;":"↚","nldr;":"‥","nle;":"≰","nleftarrow;":"↚","nleftrightarrow;":"↮","nleq;":"≰","nleqq;":"≦̸","nleqslant;":"⩽̸","nles;":"⩽̸","nless;":"≮","nlsim;":"≴","nlt;":"≮","nltri;":"⋪","nltrie;":"⋬","nmid;":"∤","nopf;":"𝕟","not":"¬","not;":"¬","notin;":"∉","notinE;":"⋹̸","notindot;":"⋵̸","notinva;":"∉","notinvb;":"⋷","notinvc;":"⋶","notni;":"∌","notniva;":"∌","notnivb;":"⋾","notnivc;":"⋽","npar;":"∦","nparallel;":"∦","nparsl;":"⫽⃥","npart;":"∂̸","npolint;":"⨔","npr;":"⊀","nprcue;":"⋠","npre;":"⪯̸","nprec;":"⊀","npreceq;":"⪯̸","nrArr;":"⇏","nrarr;":"↛","nrarrc;":"⤳̸","nrarrw;":"↝̸","nrightarrow;":"↛","nrtri;":"⋫","nrtrie;":"⋭","nsc;":"⊁","nsccue;":"⋡","nsce;":"⪰̸","nscr;":"𝓃","nshortmid;":"∤","nshortparallel;":"∦","nsim;":"≁","nsime;":"≄","nsimeq;":"≄","nsmid;":"∤","nspar;":"∦","nsqsube;":"⋢","nsqsupe;":"⋣","nsub;":"⊄","nsubE;":"⫅̸","nsube;":"⊈","nsubset;":"⊂⃒","nsubseteq;":"⊈","nsubseteqq;":"⫅̸","nsucc;":"⊁","nsucceq;":"⪰̸","nsup;":"⊅","nsupE;":"⫆̸","nsupe;":"⊉","nsupset;":"⊃⃒","nsupseteq;":"⊉","nsupseteqq;":"⫆̸","ntgl;":"≹","ntilde":"ñ","ntilde;":"ñ","ntlg;":"≸","ntriangleleft;":"⋪","ntrianglelefteq;":"⋬","ntriangleright;":"⋫","ntrianglerighteq;":"⋭","nu;":"ν","num;":"#","numero;":"№","numsp;":" ","nvDash;":"⊭","nvHarr;":"⤄","nvap;":"≍⃒","nvdash;":"⊬","nvge;":"≥⃒","nvgt;":">⃒","nvinfin;":"⧞","nvlArr;":"⤂","nvle;":"≤⃒","nvlt;":"<⃒","nvltrie;":"⊴⃒","nvrArr;":"⤃","nvrtrie;":"⊵⃒","nvsim;":"∼⃒","nwArr;":"⇖","nwarhk;":"⤣","nwarr;":"↖","nwarrow;":"↖","nwnear;":"⤧","oS;":"Ⓢ","oacute":"ó","oacute;":"ó","oast;":"⊛","ocir;":"⊚","ocirc":"ô","ocirc;":"ô","ocy;":"о","odash;":"⊝","odblac;":"ő","odiv;":"⨸","odot;":"⊙","odsold;":"⦼","oelig;":"œ","ofcir;":"⦿","ofr;":"𝔬","ogon;":"˛","ograve":"ò","ograve;":"ò","ogt;":"⧁","ohbar;":"⦵","ohm;":"Ω","oint;":"∮","olarr;":"↺","olcir;":"⦾","olcross;":"⦻","oline;":"‾","olt;":"⧀","omacr;":"ō","omega;":"ω","omicron;":"ο","omid;":"⦶","ominus;":"⊖","oopf;":"𝕠","opar;":"⦷","operp;":"⦹","oplus;":"⊕","or;":"∨","orarr;":"↻","ord;":"⩝","order;":"ℴ","orderof;":"ℴ","ordf":"ª","ordf;":"ª","ordm":"º","ordm;":"º","origof;":"⊶","oror;":"⩖","orslope;":"⩗","orv;":"⩛","oscr;":"ℴ","oslash":"ø","oslash;":"ø","osol;":"⊘","otilde":"õ","otilde;":"õ","otimes;":"⊗","otimesas;":"⨶","ouml":"ö","ouml;":"ö","ovbar;":"⌽","par;":"∥","para":"¶","para;":"¶","parallel;":"∥","parsim;":"⫳","parsl;":"⫽","part;":"∂","pcy;":"п","percnt;":"%","period;":".","permil;":"‰","perp;":"⊥","pertenk;":"‱","pfr;":"𝔭","phi;":"φ","phiv;":"ϕ","phmmat;":"ℳ","phone;":"☎","pi;":"π","pitchfork;":"⋔","piv;":"ϖ","planck;":"ℏ","planckh;":"ℎ","plankv;":"ℏ","plus;":"+","plusacir;":"⨣","plusb;":"⊞","pluscir;":"⨢","plusdo;":"∔","plusdu;":"⨥","pluse;":"⩲","plusmn":"±","plusmn;":"±","plussim;":"⨦","plustwo;":"⨧","pm;":"±","pointint;":"⨕","popf;":"𝕡","pound":"£","pound;":"£","pr;":"≺","prE;":"⪳","prap;":"⪷","prcue;":"≼","pre;":"⪯","prec;":"≺","precapprox;":"⪷","preccurlyeq;":"≼","preceq;":"⪯","precnapprox;":"⪹","precneqq;":"⪵","precnsim;":"⋨","precsim;":"≾","prime;":"′","primes;":"ℙ","prnE;":"⪵","prnap;":"⪹","prnsim;":"⋨","prod;":"∏","profalar;":"⌮","profline;":"⌒","profsurf;":"⌓","prop;":"∝","propto;":"∝","prsim;":"≾","prurel;":"⊰","pscr;":"𝓅","psi;":"ψ","puncsp;":" ","qfr;":"𝔮","qint;":"⨌","qopf;":"𝕢","qprime;":"⁗","qscr;":"𝓆","quaternions;":"ℍ","quatint;":"⨖","quest;":"?","questeq;":"≟","quot":"\"","quot;":"\"","rAarr;":"⇛","rArr;":"⇒","rAtail;":"⤜","rBarr;":"⤏","rHar;":"⥤","race;":"∽̱","racute;":"ŕ","radic;":"√","raemptyv;":"⦳","rang;":"⟩","rangd;":"⦒","range;":"⦥","rangle;":"⟩","raquo":"»","raquo;":"»","rarr;":"→","rarrap;":"⥵","rarrb;":"⇥","rarrbfs;":"⤠","rarrc;":"⤳","rarrfs;":"⤞","rarrhk;":"↪","rarrlp;":"↬","rarrpl;":"⥅","rarrsim;":"⥴","rarrtl;":"↣","rarrw;":"↝","ratail;":"⤚","ratio;":"∶","rationals;":"ℚ","rbarr;":"⤍","rbbrk;":"❳","rbrace;":"}","rbrack;":"]","rbrke;":"⦌","rbrksld;":"⦎","rbrkslu;":"⦐","rcaron;":"ř","rcedil;":"ŗ","rceil;":"⌉","rcub;":"}","rcy;":"р","rdca;":"⤷","rdldhar;":"⥩","rdquo;":"”","rdquor;":"”","rdsh;":"↳","real;":"ℜ","realine;":"ℛ","realpart;":"ℜ","reals;":"ℝ","rect;":"▭","reg":"®","reg;":"®","rfisht;":"⥽","rfloor;":"⌋","rfr;":"𝔯","rhard;":"⇁","rharu;":"⇀","rharul;":"⥬","rho;":"ρ","rhov;":"ϱ","rightarrow;":"→","rightarrowtail;":"↣","rightharpoondown;":"⇁","rightharpoonup;":"⇀","rightleftarrows;":"⇄","rightleftharpoons;":"⇌","rightrightarrows;":"⇉","rightsquigarrow;":"↝","rightthreetimes;":"⋌","ring;":"˚","risingdotseq;":"≓","rlarr;":"⇄","rlhar;":"⇌","rlm;":"‏","rmoust;":"⎱","rmoustache;":"⎱","rnmid;":"⫮","roang;":"⟭","roarr;":"⇾","robrk;":"⟧","ropar;":"⦆","ropf;":"𝕣","roplus;":"⨮","rotimes;":"⨵","rpar;":")","rpargt;":"⦔","rppolint;":"⨒","rrarr;":"⇉","rsaquo;":"›","rscr;":"𝓇","rsh;":"↱","rsqb;":"]","rsquo;":"’","rsquor;":"’","rthree;":"⋌","rtimes;":"⋊","rtri;":"▹","rtrie;":"⊵","rtrif;":"▸","rtriltri;":"⧎","ruluhar;":"⥨","rx;":"℞","sacute;":"ś","sbquo;":"‚","sc;":"≻","scE;":"⪴","scap;":"⪸","scaron;":"š","sccue;":"≽","sce;":"⪰","scedil;":"ş","scirc;":"ŝ","scnE;":"⪶","scnap;":"⪺","scnsim;":"⋩","scpolint;":"⨓","scsim;":"≿","scy;":"с","sdot;":"⋅","sdotb;":"⊡","sdote;":"⩦","seArr;":"⇘","searhk;":"⤥","searr;":"↘","searrow;":"↘","sect":"§","sect;":"§","semi;":";","seswar;":"⤩","setminus;":"∖","setmn;":"∖","sext;":"✶","sfr;":"𝔰","sfrown;":"⌢","sharp;":"♯","shchcy;":"щ","shcy;":"ш","shortmid;":"∣","shortparallel;":"∥","shy":"­","shy;":"­","sigma;":"σ","sigmaf;":"ς","sigmav;":"ς","sim;":"∼","simdot;":"⩪","sime;":"≃","simeq;":"≃","simg;":"⪞","simgE;":"⪠","siml;":"⪝","simlE;":"⪟","simne;":"≆","simplus;":"⨤","simrarr;":"⥲","slarr;":"←","smallsetminus;":"∖","smashp;":"⨳","smeparsl;":"⧤","smid;":"∣","smile;":"⌣","smt;":"⪪","smte;":"⪬","smtes;":"⪬︀","softcy;":"ь","sol;":"/","solb;":"⧄","solbar;":"⌿","sopf;":"𝕤","spades;":"♠","spadesuit;":"♠","spar;":"∥","sqcap;":"⊓","sqcaps;":"⊓︀","sqcup;":"⊔","sqcups;":"⊔︀","sqsub;":"⊏","sqsube;":"⊑","sqsubset;":"⊏","sqsubseteq;":"⊑","sqsup;":"⊐","sqsupe;":"⊒","sqsupset;":"⊐","sqsupseteq;":"⊒","squ;":"□","square;":"□","squarf;":"▪","squf;":"▪","srarr;":"→","sscr;":"𝓈","ssetmn;":"∖","ssmile;":"⌣","sstarf;":"⋆","star;":"☆","starf;":"★","straightepsilon;":"ϵ","straightphi;":"ϕ","strns;":"¯","sub;":"⊂","subE;":"⫅","subdot;":"⪽","sube;":"⊆","subedot;":"⫃","submult;":"⫁","subnE;":"⫋","subne;":"⊊","subplus;":"⪿","subrarr;":"⥹","subset;":"⊂","subseteq;":"⊆","subseteqq;":"⫅","subsetneq;":"⊊","subsetneqq;":"⫋","subsim;":"⫇","subsub;":"⫕","subsup;":"⫓","succ;":"≻","succapprox;":"⪸","succcurlyeq;":"≽","succeq;":"⪰","succnapprox;":"⪺","succneqq;":"⪶","succnsim;":"⋩","succsim;":"≿","sum;":"∑","sung;":"♪","sup1":"¹","sup1;":"¹","sup2":"²","sup2;":"²","sup3":"³","sup3;":"³","sup;":"⊃","supE;":"⫆","supdot;":"⪾","supdsub;":"⫘","supe;":"⊇","supedot;":"⫄","suphsol;":"⟉","suphsub;":"⫗","suplarr;":"⥻","supmult;":"⫂","supnE;":"⫌","supne;":"⊋","supplus;":"⫀","supset;":"⊃","supseteq;":"⊇","supseteqq;":"⫆","supsetneq;":"⊋","supsetneqq;":"⫌","supsim;":"⫈","supsub;":"⫔","supsup;":"⫖","swArr;":"⇙","swarhk;":"⤦","swarr;":"↙","swarrow;":"↙","swnwar;":"⤪","szlig":"ß","szlig;":"ß","target;":"⌖","tau;":"τ","tbrk;":"⎴","tcaron;":"ť","tcedil;":"ţ","tcy;":"т","tdot;":"⃛","telrec;":"⌕","tfr;":"𝔱","there4;":"∴","therefore;":"∴","theta;":"θ","thetasym;":"ϑ","thetav;":"ϑ","thickapprox;":"≈","thicksim;":"∼","thinsp;":" ","thkap;":"≈","thksim;":"∼","thorn":"þ","thorn;":"þ","tilde;":"˜","times":"×","times;":"×","timesb;":"⊠","timesbar;":"⨱","timesd;":"⨰","tint;":"∭","toea;":"⤨","top;":"⊤","topbot;":"⌶","topcir;":"⫱","topf;":"𝕥","topfork;":"⫚","tosa;":"⤩","tprime;":"‴","trade;":"™","triangle;":"▵","triangledown;":"▿","triangleleft;":"◃","trianglelefteq;":"⊴","triangleq;":"≜","triangleright;":"▹","trianglerighteq;":"⊵","tridot;":"◬","trie;":"≜","triminus;":"⨺","triplus;":"⨹","trisb;":"⧍","tritime;":"⨻","trpezium;":"⏢","tscr;":"𝓉","tscy;":"ц","tshcy;":"ћ","tstrok;":"ŧ","twixt;":"≬","twoheadleftarrow;":"↞","twoheadrightarrow;":"↠","uArr;":"⇑","uHar;":"⥣","uacute":"ú","uacute;":"ú","uarr;":"↑","ubrcy;":"ў","ubreve;":"ŭ","ucirc":"û","ucirc;":"û","ucy;":"у","udarr;":"⇅","udblac;":"ű","udhar;":"⥮","ufisht;":"⥾","ufr;":"𝔲","ugrave":"ù","ugrave;":"ù","uharl;":"↿","uharr;":"↾","uhblk;":"▀","ulcorn;":"⌜","ulcorner;":"⌜","ulcrop;":"⌏","ultri;":"◸","umacr;":"ū","uml":"¨","uml;":"¨","uogon;":"ų","uopf;":"𝕦","uparrow;":"↑","updownarrow;":"↕","upharpoonleft;":"↿","upharpoonright;":"↾","uplus;":"⊎","upsi;":"υ","upsih;":"ϒ","upsilon;":"υ","upuparrows;":"⇈","urcorn;":"⌝","urcorner;":"⌝","urcrop;":"⌎","uring;":"ů","urtri;":"◹","uscr;":"𝓊","utdot;":"⋰","utilde;":"ũ","utri;":"▵","utrif;":"▴","uuarr;":"⇈","uuml":"ü","uuml;":"ü","uwangle;":"⦧","vArr;":"⇕","vBar;":"⫨","vBarv;":"⫩","vDash;":"⊨","vangrt;":"⦜","varepsilon;":"ϵ","varkappa;":"ϰ","varnothing;":"∅","varphi;":"ϕ","varpi;":"ϖ","varpropto;":"∝","varr;":"↕","varrho;":"ϱ","varsigma;":"ς","varsubsetneq;":"⊊︀","varsubsetneqq;":"⫋︀","varsupsetneq;":"⊋︀","varsupsetneqq;":"⫌︀","vartheta;":"ϑ","vartriangleleft;":"⊲","vartriangleright;":"⊳","vcy;":"в","vdash;":"⊢","vee;":"∨","veebar;":"⊻","veeeq;":"≚","vellip;":"⋮","verbar;":"|","vert;":"|","vfr;":"𝔳","vltri;":"⊲","vnsub;":"⊂⃒","vnsup;":"⊃⃒","vopf;":"𝕧","vprop;":"∝","vrtri;":"⊳","vscr;":"𝓋","vsubnE;":"⫋︀","vsubne;":"⊊︀","vsupnE;":"⫌︀","vsupne;":"⊋︀","vzigzag;":"⦚","wcirc;":"ŵ","wedbar;":"⩟","wedge;":"∧","wedgeq;":"≙","weierp;":"℘","wfr;":"𝔴","wopf;":"𝕨","wp;":"℘","wr;":"≀","wreath;":"≀","wscr;":"𝓌","xcap;":"⋂","xcirc;":"◯","xcup;":"⋃","xdtri;":"▽","xfr;":"𝔵","xhArr;":"⟺","xharr;":"⟷","xi;":"ξ","xlArr;":"⟸","xlarr;":"⟵","xmap;":"⟼","xnis;":"⋻","xodot;":"⨀","xopf;":"𝕩","xoplus;":"⨁","xotime;":"⨂","xrArr;":"⟹","xrarr;":"⟶","xscr;":"𝓍","xsqcup;":"⨆","xuplus;":"⨄","xutri;":"△","xvee;":"⋁","xwedge;":"⋀","yacute":"ý","yacute;":"ý","yacy;":"я","ycirc;":"ŷ","ycy;":"ы","yen":"¥","yen;":"¥","yfr;":"𝔶","yicy;":"ї","yopf;":"𝕪","yscr;":"𝓎","yucy;":"ю","yuml":"ÿ","yuml;":"ÿ","zacute;":"ź","zcaron;":"ž","zcy;":"з","zdot;":"ż","zeetrf;":"ℨ","zeta;":"ζ","zfr;":"𝔷","zhcy;":"ж","zigrarr;":"⇝","zopf;":"𝕫","zscr;":"𝓏","zwj;":"‍","zwnj;":"‌"})));
+// #endregion
+
+const STATE_DATA = 0;
+const STATE_TAG_OPEN = 1;
+const STATE_END_TAG_OPEN = 2;
+const STATE_TAG_NAME = 3;
+const STATE_BEFORE_ATTRIBUTE_NAME = 4;
+const STATE_ATTRIBUTE_NAME = 5;
+const STATE_AFTER_ATTRIBUTE_NAME = 6;
+const STATE_BEFORE_ATTRIBUTE_VALUE = 7;
+const STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED = 8;
+const STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED = 9;
+const STATE_ATTRIBUTE_VALUE_UNQUOTED = 10;
+const STATE_AFTER_ATTRIBUTE_VALUE_QUOTED = 11;
+const STATE_SELF_CLOSING_START_TAG = 12;
+
+const STATE_MARKUP_DECLARATION_OPEN = 13;
+const STATE_COMMENT_START = 14;
+const STATE_COMMENT_START_DASH = 15;
+const STATE_COMMENT = 16;
+const STATE_COMMENT_END_DASH = 17;
+const STATE_COMMENT_END = 18;
+const STATE_COMMENT_END_BANG = 19;
+const STATE_BOGUS_COMMENT = 20;
+
+const STATE_COMMENT_LESS_THAN_SIGN = 21;
+const STATE_COMMENT_LESS_THAN_SIGN_BANG = 22;
+const STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH = 23;
+const STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH = 24;
+
+const STATE_DOCTYPE = 25;
+const STATE_BEFORE_DOCTYPE_NAME = 26;
+const STATE_DOCTYPE_NAME = 27;
+const STATE_AFTER_DOCTYPE_NAME = 28;
+const STATE_AFTER_DOCTYPE_PUBLIC_KEYWORD = 29;
+const STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER = 30;
+const STATE_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED = 31;
+const STATE_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED = 32;
+const STATE_AFTER_DOCTYPE_PUBLIC_IDENTIFIER = 33;
+const STATE_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS = 34;
+const STATE_AFTER_DOCTYPE_SYSTEM_KEYWORD = 35;
+const STATE_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER = 36;
+const STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED = 37;
+const STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED = 38;
+const STATE_AFTER_DOCTYPE_SYSTEM_IDENTIFIER = 39;
+const STATE_BOGUS_DOCTYPE = 40;
+
+const STATE_CDATA_SECTION = 41;
+const STATE_CDATA_SECTION_BRACKET = 42;
+const STATE_CDATA_SECTION_END = 43;
+
+const STATE_RCDATA = 44;
+const STATE_RCDATA_LESS_THAN_SIGN = 45;
+const STATE_RCDATA_END_TAG_OPEN = 46;
+const STATE_RCDATA_END_TAG_NAME = 47;
+
+const STATE_RAWTEXT = 48;
+const STATE_RAWTEXT_LESS_THAN_SIGN = 49;
+const STATE_RAWTEXT_END_TAG_OPEN = 50;
+const STATE_RAWTEXT_END_TAG_NAME = 51;
+
+const STATE_SCRIPT_DATA = 52;
+const STATE_SCRIPT_DATA_LESS_THAN_SIGN = 53;
+const STATE_SCRIPT_DATA_END_TAG_OPEN = 54;
+const STATE_SCRIPT_DATA_END_TAG_NAME = 55;
+const STATE_SCRIPT_DATA_ESCAPE_START = 56;
+const STATE_SCRIPT_DATA_ESCAPE_START_DASH = 57;
+const STATE_SCRIPT_DATA_ESCAPED = 58;
+const STATE_SCRIPT_DATA_ESCAPED_DASH = 59;
+const STATE_SCRIPT_DATA_ESCAPED_DASH_DASH = 60;
+const STATE_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN = 61;
+const STATE_SCRIPT_DATA_ESCAPED_END_TAG_OPEN = 62;
+const STATE_SCRIPT_DATA_ESCAPED_END_TAG_NAME = 63;
+const STATE_SCRIPT_DATA_DOUBLE_ESCAPE_START = 64;
+const STATE_SCRIPT_DATA_DOUBLE_ESCAPED = 65;
+const STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH = 66;
+const STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH = 67;
+const STATE_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN = 68;
+const STATE_SCRIPT_DATA_DOUBLE_ESCAPE_END = 69;
+
+const STATE_PLAINTEXT = 70;
+
+// https://html.spec.whatwg.org/multipage/parsing.html#character-reference-state
+const STATE_CHARACTER_REFERENCE = 71;
+// https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
+const STATE_NAMED_CHARACTER_REFERENCE = 72;
+// https://html.spec.whatwg.org/multipage/parsing.html#ambiguous-ampersand-state
+const STATE_AMBIGUOUS_AMPERSAND = 73;
+// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-state
+const STATE_NUMERIC_CHARACTER_REFERENCE = 74;
+// https://html.spec.whatwg.org/multipage/parsing.html#hexadecimal-character-reference-start-state
+const STATE_HEXADECIMAL_CHARACTER_REFERENCE_START = 75;
+// https://html.spec.whatwg.org/multipage/parsing.html#decimal-character-reference-start-state
+const STATE_DECIMAL_CHARACTER_REFERENCE_START = 76;
+// https://html.spec.whatwg.org/multipage/parsing.html#hexadecimal-character-reference-state
+const STATE_HEXADECIMAL_CHARACTER_REFERENCE = 77;
+// https://html.spec.whatwg.org/multipage/parsing.html#decimal-character-reference-state
+const STATE_DECIMAL_CHARACTER_REFERENCE = 78;
+// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
+const STATE_NUMERIC_CHARACTER_REFERENCE_END = 79;
+
+const CC_TAB = 0x09;
+const CC_LF = 0x0a;
+const CC_FF = 0x0c;
+const CC_SPACE = 0x20;
+const CC_EXCLAMATION_MARK = 0x21;
+const CC_QUOTATION_MARK = 0x22;
+const CC_NUMBER_SIGN = 0x23;
+const CC_AMPERSAND = 0x26;
+const CC_APOSTROPHE = 0x27;
+const CC_HYPHEN_MINUS = 0x2d;
+const CC_SOLIDUS = 0x2f;
+const CC_SEMICOLON = 0x3b;
+const CC_LESS_THAN = 0x3c;
+const CC_EQUALS = 0x3d;
+const CC_GREATER_THAN = 0x3e;
+const CC_QUESTION_MARK = 0x3f;
+const CC_LEFT_SQUARE_BRACKET = 0x5b;
+const CC_RIGHT_SQUARE_BRACKET = 0x5d;
+
+const QUOTE_DOUBLE = 1;
+const QUOTE_SINGLE = 2;
+const QUOTE_NONE = 0;
+
+// Longest WHATWG named entity name *including* the trailing `;` is 32 chars
+// (`CounterClockwiseContourIntegral;`); without the trailing `;` it's 31.
+// Used to cap both the tokenizer's named-character-reference run length and
+// the decoder's longest-prefix backtrack so pathological inputs (e.g. `&`
+// followed by thousands of alphanumerics) stay linear-time.
+const MAX_ENTITY_NAME_LEN = 32;
+
+/**
+ * @param {number} cc character code
+ * @returns {boolean} is ascii alpha
+ */
+const isAsciiAlpha = (cc) =>
+	(cc >= 0x41 && cc <= 0x5a) || (cc >= 0x61 && cc <= 0x7a);
+
+/**
+ * @param {number} cc character code
+ * @returns {boolean} is ascii alphanumeric
+ */
+const isAsciiAlphanumeric = (cc) =>
+	isAsciiAlpha(cc) || (cc >= 0x30 && cc <= 0x39);
+
+/**
+ * @param {number} cc character code
+ * @returns {boolean} is ascii digit
+ */
+const isAsciiDigit = (cc) => cc >= 0x30 && cc <= 0x39;
+
+/**
+ * @param {number} cc character code
+ * @returns {boolean} is ascii hex digit
+ */
+const isAsciiHexDigit = (cc) =>
+	(cc >= 0x30 && cc <= 0x39) ||
+	(cc >= 0x41 && cc <= 0x46) ||
+	(cc >= 0x61 && cc <= 0x66);
+
+/**
+ * @param {number} cc character code
+ * @returns {boolean} is space
+ */
+const isSpace = (cc) =>
+	cc === CC_TAB || cc === CC_LF || cc === CC_FF || cc === CC_SPACE;
+
+/**
+ * Severity of a tokenizer-detected parse error. `"warning"` is recoverable
+ * (the tokenizer continued and the emitted token is still well-formed, e.g.
+ * missing-attribute-value); `"error"` means the emitted token's offset
+ * range is incomplete or does not match what the spec would produce, e.g.
+ * eof-in-tag.
+ *
+ * Token offsets are JS string indices (UTF-16 code-unit offsets into
+ * `input`), not byte offsets — relevant for inputs containing non-BMP
+ * code points where one code point spans two indices.
+ * @typedef {"warning" | "error"} ParseErrorSeverity
+ */
+
+/**
+ * @typedef {object} HtmlTokenCallbacks
+ * @property {(input: string, start: number, end: number, nameStart: number, nameEnd: number, selfClosing: boolean) => number=} openTag
+ * @property {(input: string, start: number, end: number, nameStart: number, nameEnd: number) => number=} closeTag
+ * @property {(input: string, start: number, end: number) => number=} text
+ * @property {(input: string, nameStart: number, nameEnd: number, valueStart: number, valueEnd: number, quoteType: number) => number=} attribute
+ * @property {(input: string, start: number, end: number) => number=} comment
+ * @property {(input: string, start: number, end: number) => number=} doctype
+ * @property {(input: string, code: string, start: number, end: number, severity: ParseErrorSeverity) => void=} parseError
+ */
+
+/**
+ * @param {string} input input string
+ * @param {number} pos current position
+ * @param {HtmlTokenCallbacks} callbacks callbacks
+ * @returns {number} final position
+ */
+const walkHtmlTokens = (input, pos = 0, callbacks = {}) => {
+	const len = input.length;
+	let state = STATE_DATA;
+	let returnState = STATE_DATA;
+
+	let textStart = pos;
+	let tagStart = pos;
+	let tagNameStart = -1;
+	let tagNameEnd = -1;
+	let attrNameStart = -1;
+	let attrNameEnd = -1;
+	let attrValueStart = -1;
+	let attrQuoteType = QUOTE_NONE;
+	let commentStart = pos;
+	let lastOpenTagName = "";
+	// Counter used by SCRIPT_DATA_DOUBLE_ESCAPE_{START,END} to detect whether
+	// the ASCII-alpha run after `<` / `</` spells exactly `"script"`. Values
+	// 0..6 = number of chars matched so far; 7 = no longer matches (sentinel).
+	// Avoids growing a buffer for pathological inputs with long alpha runs.
+	let scriptMatch = 0;
+	let namedEntityConsumed = 0;
+	// Tracks whether the current tag has parsed any attributes — used to
+	// fire the `end-tag-with-attributes` parse error when an end tag emits.
+	let tagHasAttributes = false;
+
+	/**
+	 * Reports a tokenizer parse error to the consumer. The offset range and
+	 * severity follow the WHATWG spec naming. Severity is `"error"` for
+	 * cases where the emitted token is incomplete (EOF inside a tag or
+	 * comment); everything else is a `"warning"`. Offsets are JS string
+	 * indices (UTF-16 code-unit offsets into `input`).
+	 * @param {string} code WHATWG parse-error code (kebab-case)
+	 * @param {number} start string offset where the error starts
+	 * @param {number} end string offset where the error ends
+	 * @param {ParseErrorSeverity} severity error severity
+	 */
+	const reportError = (code, start, end, severity) => {
+		if (callbacks.parseError !== undefined) {
+			callbacks.parseError(input, code, start, end, severity);
+		}
+	};
+
+	/**
+	 * @param {number} cc character code
+	 * @returns {boolean} is ascii lower alpha
+	 */
+	const isAsciiLowerAlpha = (cc) => cc >= 0x61 && cc <= 0x7a;
+
+	/**
+	 * @param {number} cc character code
+	 * @returns {boolean} is ascii upper alpha
+	 */
+	const isAsciiUpperAlpha = (cc) => cc >= 0x41 && cc <= 0x5a;
+
+	/**
+	 * @param {string} name tag name (lowercase)
+	 * @returns {number} content mode state for this tag, or STATE_DATA
+	 */
+	const getContentModeForTag = (name) => {
+		switch (name) {
+			case "textarea":
+			case "title":
+				return STATE_RCDATA;
+			case "style":
+			case "xmp":
+			case "iframe":
+			case "noembed":
+			case "noframes":
+				return STATE_RAWTEXT;
+			case "script":
+				return STATE_SCRIPT_DATA;
+			case "plaintext":
+				return STATE_PLAINTEXT;
+			default:
+				return STATE_DATA;
+		}
+	};
+
+	/**
+	 * @param {number} endPos end position
+	 */
+	const flushText = (endPos) => {
+		if (textStart < endPos) {
+			if (callbacks.text !== undefined) {
+				callbacks.text(input, textStart, endPos);
+			}
+			// Advance `textStart` so a second `flushText` for the same span
+			// (e.g. from the EOF handler after a tag-open transition already
+			// flushed the pending text) is a no-op rather than a duplicate
+			// emit. emitOpenTag / emitCloseTag overwrite `textStart` with
+			// their own `nextPos` anyway, so this doesn't shift their start.
+			textStart = endPos;
+		}
+	};
+
+	/**
+	 * @param {number} endPos end position
+	 * @returns {number} next position
+	 */
+	const emitAttribute = (endPos) => {
+		// Default `nextPos` advances past the closing quote (if any) so the
+		// state machine can continue when no `attribute` callback is provided.
+		// When a callback IS provided, its return value overrides the default —
+		// the callback is expected to do the same advance based on the
+		// reported `quoteType`.
+		let nextPos = attrQuoteType === QUOTE_NONE ? endPos : endPos + 1;
+		if (callbacks.attribute !== undefined && attrNameStart !== -1) {
+			nextPos = callbacks.attribute(
+				input,
+				attrNameStart,
+				attrNameEnd,
+				attrValueStart,
+				attrValueStart === -1 ? -1 : endPos,
+				attrQuoteType
+			);
+		}
+		if (attrNameStart !== -1) tagHasAttributes = true;
+		attrNameStart = -1;
+		attrValueStart = -1;
+		attrQuoteType = QUOTE_NONE;
+		return nextPos;
+	};
+
+	/**
+	 * @param {number} endPos end position
+	 * @param {boolean} selfClosing is self closing
+	 * @returns {number} next position
+	 */
+	const emitOpenTag = (endPos, selfClosing) => {
+		let nextPos = endPos;
+		if (callbacks.openTag !== undefined) {
+			nextPos = callbacks.openTag(
+				input,
+				tagStart,
+				endPos,
+				tagNameStart,
+				tagNameEnd,
+				selfClosing
+			);
+		}
+		if (!selfClosing) {
+			lastOpenTagName = input.slice(tagNameStart, tagNameEnd).toLowerCase();
+		}
+		tagHasAttributes = false;
+		textStart = nextPos;
+		return nextPos;
+	};
+
+	/**
+	 * @param {number} endPos end position
+	 * @returns {number} next position
+	 */
+	const emitCloseTag = (endPos) => {
+		// Per WHATWG: an end tag emitted with attributes is a parse error.
+		if (tagHasAttributes) {
+			reportError("end-tag-with-attributes", tagStart, endPos, "warning");
+		}
+		let nextPos = endPos;
+		if (callbacks.closeTag !== undefined) {
+			nextPos = callbacks.closeTag(
+				input,
+				tagStart,
+				endPos,
+				tagNameStart,
+				tagNameEnd
+			);
+		}
+		tagHasAttributes = false;
+		textStart = nextPos;
+		return nextPos;
+	};
+
+	while (pos < len) {
+		const cc = input.charCodeAt(pos);
+
+		// TODO: We don't handle all states here yet. In the future we will need to handle
+		// all of them, and when we move all the tokenizer we will remove it.
+		switch (state) {
+			// https://html.spec.whatwg.org/multipage/parsing.html#data-state
+			case STATE_DATA:
+				// Consume the next input character:
+				// U+003C LESS-THAN SIGN (<)
+				// Set the return state to the data state. Switch to the tag open state.
+				if (cc === CC_LESS_THAN) {
+					tagStart = pos;
+					state = STATE_TAG_OPEN;
+					pos++;
+				} else if (cc === CC_AMPERSAND) {
+					// U+0026 AMPERSAND (&)
+					// Set the return state to the data state. Switch to the
+					// character reference state.
+					returnState = STATE_DATA;
+					state = STATE_CHARACTER_REFERENCE;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
+			case STATE_TAG_OPEN:
+				// Consume the next input character:
+				// U+002F SOLIDUS (/)
+				// Switch to the end tag open state.
+				if (cc === CC_SOLIDUS) {
+					state = STATE_END_TAG_OPEN;
+					pos++;
+				} else if (cc === CC_EXCLAMATION_MARK) {
+					// U+0021 EXCLAMATION MARK (!)
+					// Switch to the markup declaration open state.
+					flushText(tagStart);
+					commentStart = tagStart;
+					state = STATE_MARKUP_DECLARATION_OPEN;
+					pos++;
+				} else if (isAsciiAlpha(cc)) {
+					// ASCII alpha
+					// Create a new start tag token, set its tag name to the empty string.
+					// Reconsume in the tag name state.
+					flushText(tagStart);
+					tagNameStart = pos;
+					state = STATE_TAG_NAME;
+					// Reconsume
+				} else if (cc === CC_QUESTION_MARK) {
+					// U+003F QUESTION MARK (?)
+					// This is an unexpected-question-mark-instead-of-tag-name parse error.
+					// Create a comment token whose data is the empty string. Reconsume in the
+					// bogus comment state.
+					reportError(
+						"unexpected-question-mark-instead-of-tag-name",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					flushText(tagStart);
+					commentStart = tagStart;
+					state = STATE_BOGUS_COMMENT;
+					// Reconsume — let the bogus-comment state consume the `?`
+					// itself, matching the spec.
+				} else {
+					// Anything else
+					// This is an invalid-first-character-of-tag-name parse error. Emit a U+003C
+					// LESS-THAN SIGN character token. Reconsume in the data state.
+					reportError(
+						"invalid-first-character-of-tag-name",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
+			case STATE_END_TAG_OPEN:
+				// Consume the next input character:
+				// ASCII alpha
+				// Create a new end tag token, set its tag name to the empty string.
+				// Reconsume in the tag name state.
+				if (isAsciiAlpha(cc)) {
+					flushText(tagStart);
+					tagNameStart = pos;
+					state = STATE_TAG_NAME;
+					// Reconsume
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-end-tag-name parse error. Switch to the data state.
+					reportError("missing-end-tag-name", pos, pos + 1, "warning");
+					state = STATE_DATA;
+					pos++;
+				} else {
+					// Anything else
+					// This is an invalid-first-character-of-tag-name parse error. Create a
+					// comment token whose data is the empty string. Reconsume in the bogus
+					// comment state.
+					reportError(
+						"invalid-first-character-of-tag-name",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					flushText(tagStart);
+					commentStart = tagStart;
+					state = STATE_BOGUS_COMMENT;
+					// Reconsume — let bogus-comment consume this char itself.
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
+			case STATE_TAG_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Switch to the before attribute name state.
+				if (isSpace(cc)) {
+					tagNameEnd = pos;
+					state = STATE_BEFORE_ATTRIBUTE_NAME;
+					pos++;
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// Switch to the self-closing start tag state.
+					tagNameEnd = pos;
+					state = STATE_SELF_CLOSING_START_TAG;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current tag token.
+					tagNameEnd = pos;
+					if (input.charCodeAt(tagStart + 1) === CC_SOLIDUS) {
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						const nextPos = emitOpenTag(pos + 1, false);
+						state =
+							nextPos > pos + 1
+								? STATE_DATA
+								: getContentModeForTag(lastOpenTagName);
+						pos = nextPos;
+					}
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state
+			case STATE_BEFORE_ATTRIBUTE_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Ignore the character.
+				// Reconsume so space is handled in BEFORE_ATTRIBUTE_NAME
+				if (isSpace(cc)) {
+					pos++;
+				} else if (cc === CC_SOLIDUS || cc === CC_GREATER_THAN) {
+					// U+002F SOLIDUS (/)
+					// U+003E GREATER-THAN SIGN (>)
+					// EOF
+					// Reconsume in the after attribute name state.
+					state = STATE_AFTER_ATTRIBUTE_NAME;
+					// Reconsume
+				} else if (cc === CC_EQUALS) {
+					// U+003D EQUALS SIGN (=)
+					// This is an unexpected-equals-sign-before-attribute-name parse
+					// error. Start a new attribute. Switch to the attribute name state.
+					reportError(
+						"unexpected-equals-sign-before-attribute-name",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					attrNameStart = pos;
+					state = STATE_ATTRIBUTE_NAME;
+					pos++;
+				} else {
+					// Anything else
+					// Start a new attribute in the current tag token. Set that attribute name
+					// and value to the empty string. Reconsume in the attribute name state.
+					attrNameStart = pos;
+					state = STATE_ATTRIBUTE_NAME;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
+			case STATE_ATTRIBUTE_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// U+002F SOLIDUS (/)
+				// U+003E GREATER-THAN SIGN (>)
+				// EOF
+				// Reconsume in the after attribute name state.
+				if (isSpace(cc) || cc === CC_SOLIDUS || cc === CC_GREATER_THAN) {
+					attrNameEnd = pos;
+					state = STATE_AFTER_ATTRIBUTE_NAME;
+					// Reconsume
+				} else if (cc === CC_EQUALS) {
+					attrNameEnd = pos;
+					state = STATE_BEFORE_ATTRIBUTE_VALUE;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-attribute-name-state
+			case STATE_AFTER_ATTRIBUTE_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Ignore the character.
+				if (isSpace(cc)) {
+					pos++;
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// Switch to the self-closing start tag state.
+					emitAttribute(pos);
+					state = STATE_SELF_CLOSING_START_TAG;
+					pos++;
+				} else if (cc === CC_EQUALS) {
+					// U+003D EQUALS SIGN (=)
+					// Switch to the before attribute value state.
+					state = STATE_BEFORE_ATTRIBUTE_VALUE;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current tag token.
+					emitAttribute(pos);
+					if (input.charCodeAt(tagStart + 1) === CC_SOLIDUS) {
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						const nextPos = emitOpenTag(pos + 1, false);
+						state =
+							nextPos > pos + 1
+								? STATE_DATA
+								: getContentModeForTag(lastOpenTagName);
+						pos = nextPos;
+					}
+				} else {
+					// Anything else
+					// Start a new attribute in the current tag token.
+					emitAttribute(pos);
+					attrNameStart = pos;
+					state = STATE_ATTRIBUTE_NAME;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-value-state
+			case STATE_BEFORE_ATTRIBUTE_VALUE:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Ignore the character.
+				if (isSpace(cc)) {
+					pos++;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// Switch to the attribute value (double-quoted) state.
+					attrValueStart = pos + 1;
+					attrQuoteType = QUOTE_DOUBLE;
+					state = STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// Switch to the attribute value (single-quoted) state.
+					attrValueStart = pos + 1;
+					attrQuoteType = QUOTE_SINGLE;
+					state = STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-attribute-value parse error. Switch to the data
+					// state. Emit the current tag token. The attribute is reported with
+					// an empty value range pointing at the `>` so the open-tag offset range
+					// still includes the `>`.
+					reportError("missing-attribute-value", pos, pos + 1, "warning");
+					attrValueStart = pos;
+					attrQuoteType = QUOTE_NONE;
+					pos = emitAttribute(pos);
+					if (input.charCodeAt(tagStart + 1) === CC_SOLIDUS) {
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						const nextPos = emitOpenTag(pos + 1, false);
+						state =
+							nextPos > pos + 1
+								? STATE_DATA
+								: getContentModeForTag(lastOpenTagName);
+						pos = nextPos;
+					}
+				} else {
+					// Anything else
+					// Reconsume in the attribute value (unquoted) state.
+					attrValueStart = pos;
+					attrQuoteType = QUOTE_NONE;
+					state = STATE_ATTRIBUTE_VALUE_UNQUOTED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(double-quoted)-state
+			case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+				// Consume the next input character:
+				// U+0022 QUOTATION MARK (")
+				// Switch to the after attribute value (quoted) state.
+				if (cc === CC_QUOTATION_MARK) {
+					pos = emitAttribute(pos);
+					state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED;
+				} else if (cc === CC_AMPERSAND) {
+					// U+0026 AMPERSAND (&)
+					// Set the return state to the attribute value (double-quoted)
+					// state. Switch to the character reference state.
+					returnState = STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
+					state = STATE_CHARACTER_REFERENCE;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(single-quoted)-state
+			case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED:
+				// Consume the next input character:
+				// U+0027 APOSTROPHE (')
+				// Switch to the after attribute value (quoted) state.
+				if (cc === CC_APOSTROPHE) {
+					pos = emitAttribute(pos);
+					state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED;
+				} else if (cc === CC_AMPERSAND) {
+					// U+0026 AMPERSAND (&)
+					// Set the return state to the attribute value (single-quoted)
+					// state. Switch to the character reference state.
+					returnState = STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED;
+					state = STATE_CHARACTER_REFERENCE;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(unquoted)-state
+			case STATE_ATTRIBUTE_VALUE_UNQUOTED:
+				if (isSpace(cc)) {
+					pos = emitAttribute(pos);
+					state = STATE_BEFORE_ATTRIBUTE_NAME;
+					// Reconsume so space is handled in BEFORE_ATTRIBUTE_NAME
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-attribute-value parse error. Switch to the data state.
+					// Emit the current tag token.
+					pos = emitAttribute(pos);
+					if (input.charCodeAt(tagStart + 1) === CC_SOLIDUS) {
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						const nextPos = emitOpenTag(pos + 1, false);
+						state =
+							nextPos > pos + 1
+								? STATE_DATA
+								: getContentModeForTag(lastOpenTagName);
+						pos = nextPos;
+					}
+				} else if (cc === CC_AMPERSAND) {
+					// U+0026 AMPERSAND (&)
+					// Set the return state to the attribute value (unquoted)
+					// state. Switch to the character reference state.
+					returnState = STATE_ATTRIBUTE_VALUE_UNQUOTED;
+					state = STATE_CHARACTER_REFERENCE;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-attribute-value-(quoted)-state
+			case STATE_AFTER_ATTRIBUTE_VALUE_QUOTED:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Switch to the before attribute name state.
+				if (isSpace(cc)) {
+					state = STATE_BEFORE_ATTRIBUTE_NAME;
+					pos++;
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// Switch to the self-closing start tag state.
+					state = STATE_SELF_CLOSING_START_TAG;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					if (input.charCodeAt(tagStart + 1) === CC_SOLIDUS) {
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						const nextPos = emitOpenTag(pos + 1, false);
+						state =
+							nextPos > pos + 1
+								? STATE_DATA
+								: getContentModeForTag(lastOpenTagName);
+						pos = nextPos;
+					}
+				} else {
+					// Anything else
+					// This is a missing-whitespace-between-attributes parse error. Reconsume in
+					// the before attribute name state.
+					reportError(
+						"missing-whitespace-between-attributes",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BEFORE_ATTRIBUTE_NAME;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#self-closing-start-tag-state
+			case STATE_SELF_CLOSING_START_TAG:
+				// Consume the next input character:
+				// U+003E GREATER-THAN SIGN (>)
+				// Set the self-closing flag of the current tag token. Switch to the data
+				// state. Emit the current tag token.
+				if (cc === CC_GREATER_THAN) {
+					if (input.charCodeAt(tagStart + 1) === CC_SOLIDUS) {
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						pos = emitOpenTag(pos + 1, true);
+						state = STATE_DATA;
+					}
+				} else {
+					// Anything else
+					// This is an unexpected-solidus-in-tag parse error. Reconsume in the before
+					// attribute name state.
+					reportError("unexpected-solidus-in-tag", pos, pos + 1, "warning");
+					state = STATE_BEFORE_ATTRIBUTE_NAME;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
+			case STATE_MARKUP_DECLARATION_OPEN:
+				// If the next few characters are:
+				// Two U+002D HYPHEN-MINUS characters (-)
+				// Consume those two characters, create a comment token whose data
+				// is the empty string, and switch to the comment start state.
+				if (
+					cc === CC_HYPHEN_MINUS &&
+					input.charCodeAt(pos + 1) === CC_HYPHEN_MINUS
+				) {
+					pos += 2;
+					commentStart = tagStart;
+					state = STATE_COMMENT_START;
+				} else if (
+					// ASCII case-insensitive match for the word "DOCTYPE"
+					// Consume those characters and switch to the DOCTYPE state.
+					(cc === 0x44 || cc === 0x64) /* D or d */ &&
+					(input.charCodeAt(pos + 1) | 0x20) === 0x6f /* o */ &&
+					(input.charCodeAt(pos + 2) | 0x20) === 0x63 /* c */ &&
+					(input.charCodeAt(pos + 3) | 0x20) === 0x74 /* t */ &&
+					(input.charCodeAt(pos + 4) | 0x20) === 0x79 /* y */ &&
+					(input.charCodeAt(pos + 5) | 0x20) === 0x70 /* p */ &&
+					(input.charCodeAt(pos + 6) | 0x20) === 0x65 /* e */
+				) {
+					pos += 7;
+					commentStart = tagStart;
+					state = STATE_DOCTYPE;
+				} else if (
+					// The string "[CDATA[" (the five uppercase letters "CDATA" with a
+					// U+005B LEFT SQUARE BRACKET character before and after)
+					// Consume those characters and switch to the CDATA section state.
+					cc === CC_LEFT_SQUARE_BRACKET &&
+					input.charCodeAt(pos + 1) === 0x43 /* C */ &&
+					input.charCodeAt(pos + 2) === 0x44 /* D */ &&
+					input.charCodeAt(pos + 3) === 0x41 /* A */ &&
+					input.charCodeAt(pos + 4) === 0x54 /* T */ &&
+					input.charCodeAt(pos + 5) === 0x41 /* A */ &&
+					input.charCodeAt(pos + 6) === CC_LEFT_SQUARE_BRACKET
+				) {
+					pos += 7;
+					commentStart = tagStart;
+					state = STATE_CDATA_SECTION;
+				} else {
+					// Anything else
+					// This is an incorrectly-opened-comment parse error. Create a comment token
+					// whose data is the empty string. Switch to the bogus comment state (don't
+					// consume anything in the current state).
+					reportError("incorrectly-opened-comment", tagStart, pos, "warning");
+					commentStart = tagStart;
+					state = STATE_BOGUS_COMMENT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-start-state
+			case STATE_COMMENT_START:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the comment start dash state.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_COMMENT_START_DASH;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an abrupt-closing-of-empty-comment parse error. Switch to the
+					// data state. Emit the current comment token.
+					reportError(
+						"abrupt-closing-of-empty-comment",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.comment !== undefined) {
+						nextPos = callbacks.comment(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Reconsume in the comment state.
+					state = STATE_COMMENT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-start-dash-state
+			case STATE_COMMENT_START_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the comment end state.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_COMMENT_END;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an abrupt-closing-of-empty-comment parse error. Switch to the
+					// data state. Emit the current comment token.
+					reportError(
+						"abrupt-closing-of-empty-comment",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.comment !== undefined) {
+						nextPos = callbacks.comment(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Append a U+002D HYPHEN-MINUS character (-) to the comment token's data.
+					// Reconsume in the comment state.
+					state = STATE_COMMENT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-state
+			case STATE_COMMENT:
+				// Consume the next input character:
+				// U+003C LESS-THAN SIGN (<)
+				// Append a U+003C LESS-THAN SIGN character to the comment token's data. Switch to the comment less-than sign state.
+				if (cc === CC_LESS_THAN) {
+					state = STATE_COMMENT_LESS_THAN_SIGN;
+					pos++;
+				} else if (cc === CC_HYPHEN_MINUS) {
+					// Consume the next input character:
+					// U+002D HYPHEN-MINUS (-)
+					// Switch to the comment end dash state.
+					state = STATE_COMMENT_END_DASH;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-end-dash-state
+			case STATE_COMMENT_END_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the comment end state.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_COMMENT_END;
+					pos++;
+				} else {
+					// Anything else
+					// Append a U+002D HYPHEN-MINUS character (-) to the comment token's data.
+					// Reconsume in the comment state.
+					state = STATE_COMMENT;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-end-state
+			case STATE_COMMENT_END:
+				// Consume the next input character:
+				// U+003E GREATER-THAN SIGN (>)
+				// Switch to the data state. Emit the current comment token.
+				if (cc === CC_GREATER_THAN) {
+					let nextPos = pos + 1;
+					if (callbacks.comment !== undefined) {
+						nextPos = callbacks.comment(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else if (cc === CC_EXCLAMATION_MARK) {
+					// U+0021 EXCLAMATION MARK (!)
+					// Switch to the comment end bang state.
+					state = STATE_COMMENT_END_BANG;
+					pos++;
+				} else if (cc === CC_HYPHEN_MINUS) {
+					pos++;
+				} else {
+					// Anything else
+					// Append two U+002D HYPHEN-MINUS characters (-) to the comment token's
+					// data. Reconsume in the comment state.
+					state = STATE_COMMENT;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-end-bang-state
+			case STATE_COMMENT_END_BANG:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Append two U+002D HYPHEN-MINUS characters (-) and a U+0021 EXCLAMATION
+				// MARK character (!) to the comment token's data. Switch to the comment end
+				// dash state.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_COMMENT_END_DASH;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an incorrectly-closed-comment parse error. Switch to the data
+					// state. Emit the current comment token.
+					reportError("incorrectly-closed-comment", pos, pos + 1, "warning");
+					let nextPos = pos + 1;
+					if (callbacks.comment !== undefined) {
+						nextPos = callbacks.comment(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Append two U+002D HYPHEN-MINUS characters (-) and a U+0021 EXCLAMATION
+					// MARK character (!) to the comment token's data. Reconsume in the comment
+					// state.
+					state = STATE_COMMENT;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#bogus-comment-state
+			case STATE_BOGUS_COMMENT:
+				// Consume the next input character:
+				// U+003E GREATER-THAN SIGN (>)
+				// Switch to the data state. Emit the current comment token.
+				if (cc === CC_GREATER_THAN) {
+					let nextPos = pos + 1;
+					if (callbacks.comment !== undefined) {
+						nextPos = callbacks.comment(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-less-than-sign-state
+			case STATE_COMMENT_LESS_THAN_SIGN:
+				// Consume the next input character:
+				// U+0021 EXCLAMATION MARK (!)
+				// Append the current input character to the comment token's data. Switch to
+				// the comment less-than sign bang state.
+				if (cc === CC_EXCLAMATION_MARK) {
+					state = STATE_COMMENT_LESS_THAN_SIGN_BANG;
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Append the current input character to the comment token's data.
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the comment state.
+					state = STATE_COMMENT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-less-than-sign-bang-state
+			case STATE_COMMENT_LESS_THAN_SIGN_BANG:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the comment less-than sign bang dash state.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH;
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the comment state.
+					state = STATE_COMMENT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-less-than-sign-bang-dash-state
+			case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the comment less-than sign bang dash dash state.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH;
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the comment end dash state.
+					state = STATE_COMMENT_END_DASH;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#comment-less-than-sign-bang-dash-dash-state
+			case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH:
+				// Consume the next input character:
+				// U+003E GREATER-THAN SIGN (>)
+				// EOF
+				// Reconsume in the comment end state.
+				// Anything else
+				// This is a nested-comment parse error. Reconsume in the comment end state.
+				if (cc !== CC_GREATER_THAN) {
+					reportError("nested-comment", pos, pos + 1, "warning");
+				}
+				state = STATE_COMMENT_END;
+				// Reconsume
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#doctype-state
+			case STATE_DOCTYPE:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Switch to the before DOCTYPE name state.
+				if (isSpace(cc)) {
+					state = STATE_BEFORE_DOCTYPE_NAME;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Reconsume in the before DOCTYPE name state.
+					state = STATE_BEFORE_DOCTYPE_NAME;
+				} else {
+					// Anything else
+					// This is a missing-whitespace-before-doctype-name parse error. Reconsume
+					// in the before DOCTYPE name state.
+					reportError(
+						"missing-whitespace-before-doctype-name",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BEFORE_DOCTYPE_NAME;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#before-doctype-name-state
+			case STATE_BEFORE_DOCTYPE_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Ignore the character.
+				if (isSpace(cc)) {
+					pos++;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Create a new DOCTYPE
+					// token. Set the token's name to a U+FFFD REPLACEMENT CHARACTER character.
+					// Switch to the DOCTYPE name state.
+					state = STATE_DOCTYPE_NAME;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-doctype-name parse error. Create a new DOCTYPE token.
+					// Set its force-quirks flag to on. Switch to the data state. Emit the
+					// current token.
+					reportError("missing-doctype-name", pos, pos + 1, "warning");
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// ASCII upper alpha
+					// Create a new DOCTYPE token. Set the token's name to the lowercase version
+					// of the current input character (add 0x0020 to the character's code
+					// point). Switch to the DOCTYPE name state.
+					// Anything else
+					// Create a new DOCTYPE token. Set the token's name to the current input
+					// character. Switch to the DOCTYPE name state.
+					state = STATE_DOCTYPE_NAME;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#doctype-name-state
+			case STATE_DOCTYPE_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// Switch to the after DOCTYPE name state.
+				if (isSpace(cc)) {
+					state = STATE_AFTER_DOCTYPE_NAME;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current DOCTYPE token.
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Append a U+FFFD
+					// REPLACEMENT CHARACTER character to the current DOCTYPE token's name.
+					pos++;
+				} else {
+					// ASCII upper alpha
+					// Append the lowercase version of the current input character (add 0x0020
+					// to the character's code point) to the current DOCTYPE token's name.
+					// Anything else
+					// Append the current input character to the current DOCTYPE token's name.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-doctype-name-state
+			case STATE_AFTER_DOCTYPE_NAME:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Ignore the character.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current DOCTYPE token.
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else if (
+					pos + 5 < len &&
+					(cc === 0x50 || cc === 0x70) /* P or p */ &&
+					(input.charCodeAt(pos + 1) | 0x20) === 0x75 /* u */ &&
+					(input.charCodeAt(pos + 2) | 0x20) === 0x62 /* b */ &&
+					(input.charCodeAt(pos + 3) | 0x20) === 0x6c /* l */ &&
+					(input.charCodeAt(pos + 4) | 0x20) === 0x69 /* i */ &&
+					(input.charCodeAt(pos + 5) | 0x20) === 0x63 /* c */
+				) {
+					// ASCII case-insensitive match for the word "PUBLIC"
+					pos += 6;
+					state = STATE_AFTER_DOCTYPE_PUBLIC_KEYWORD;
+				} else if (
+					pos + 5 < len &&
+					(cc === 0x53 || cc === 0x73) /* S or s */ &&
+					(input.charCodeAt(pos + 1) | 0x20) === 0x79 /* y */ &&
+					(input.charCodeAt(pos + 2) | 0x20) === 0x73 /* s */ &&
+					(input.charCodeAt(pos + 3) | 0x20) === 0x74 /* t */ &&
+					(input.charCodeAt(pos + 4) | 0x20) === 0x65 /* e */ &&
+					(input.charCodeAt(pos + 5) | 0x20) === 0x6d /* m */
+				) {
+					// ASCII case-insensitive match for the word "SYSTEM"
+					pos += 6;
+					state = STATE_AFTER_DOCTYPE_SYSTEM_KEYWORD;
+				} else {
+					// Anything else
+					// This is an invalid-character-sequence-after-doctype-name parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"invalid-character-sequence-after-doctype-name",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-doctype-public-keyword-state
+			case STATE_AFTER_DOCTYPE_PUBLIC_KEYWORD:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Switch to the before DOCTYPE public identifier state.
+					state = STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
+					pos++;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// This is a missing-whitespace-after-doctype-public-keyword parse error.
+					// Set the current DOCTYPE token's public identifier to the empty string
+					// (not missing), then switch to the DOCTYPE public identifier
+					// (double-quoted) state.
+					reportError(
+						"missing-whitespace-after-doctype-public-keyword",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// This is a missing-whitespace-after-doctype-public-keyword parse error.
+					// Set the current DOCTYPE token's public identifier to the empty string
+					// (not missing), then switch to the DOCTYPE public identifier
+					// (single-quoted) state.
+					reportError(
+						"missing-whitespace-after-doctype-public-keyword",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-doctype-public-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"missing-doctype-public-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// This is a missing-quote-before-doctype-public-identifier parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"missing-quote-before-doctype-public-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#before-doctype-public-identifier-state
+			case STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Ignore the character.
+					pos++;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// Set the current DOCTYPE token's public identifier to the empty string
+					// (not missing), then switch to the DOCTYPE public identifier
+					// (double-quoted) state.
+					state = STATE_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// Set the current DOCTYPE token's public identifier to the empty string
+					// (not missing), then switch to the DOCTYPE public identifier
+					// (single-quoted) state.
+					state = STATE_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-doctype-public-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"missing-doctype-public-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// This is a missing-quote-before-doctype-public-identifier parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"missing-quote-before-doctype-public-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#doctype-public-identifier-(double-quoted)-state
+			case STATE_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+				// Consume the next input character:
+				if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// Switch to the after DOCTYPE public identifier state.
+					state = STATE_AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
+					pos++;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Append a U+FFFD
+					// REPLACEMENT CHARACTER character to the current DOCTYPE token's public
+					// identifier.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an abrupt-doctype-public-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"abrupt-doctype-public-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Append the current input character to the current DOCTYPE token's public
+					// identifier.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#doctype-public-identifier-(single-quoted)-state
+			case STATE_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
+				// Consume the next input character:
+				if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// Switch to the after DOCTYPE public identifier state.
+					state = STATE_AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
+					pos++;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Append a U+FFFD
+					// REPLACEMENT CHARACTER character to the current DOCTYPE token's public
+					// identifier.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an abrupt-doctype-public-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"abrupt-doctype-public-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Append the current input character to the current DOCTYPE token's public
+					// identifier.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-doctype-public-identifier-state
+			case STATE_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Switch to the between DOCTYPE public and system identifiers state.
+					state = STATE_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current DOCTYPE token.
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// This is a missing-whitespace-between-doctype-public-and-system-identifiers
+					// parse error. Set the current DOCTYPE token's system
+					// identifier to the empty string (not missing), then switch
+					// to the DOCTYPE system identifier (double-quoted) state.
+					reportError(
+						"missing-whitespace-between-doctype-public-and-system-identifiers",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// This is a missing-whitespace-between-doctype-public-and-system-identifiers
+					// parse error. Set the current DOCTYPE token's system
+					// identifier to the empty string (not missing), then switch
+					// to the DOCTYPE system identifier (single-quoted) state.
+					reportError(
+						"missing-whitespace-between-doctype-public-and-system-identifiers",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
+					pos++;
+				} else {
+					// Anything else
+					// This is a missing-quote-before-doctype-system-identifier parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"missing-quote-before-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#between-doctype-public-and-system-identifiers-state
+			case STATE_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Ignore the character.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current DOCTYPE token.
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// Set the current DOCTYPE token's system identifier to the empty string
+					// (not missing), then switch to the DOCTYPE system identifier
+					// (double-quoted) state.
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// Set the current DOCTYPE token's system identifier to the empty string
+					// (not missing), then switch to the DOCTYPE system identifier
+					// (single-quoted) state.
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
+					pos++;
+				} else {
+					// Anything else
+					// This is a missing-quote-before-doctype-system-identifier parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"missing-quote-before-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-doctype-system-keyword-state
+			case STATE_AFTER_DOCTYPE_SYSTEM_KEYWORD:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Switch to the before DOCTYPE system identifier state.
+					state = STATE_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;
+					pos++;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// This is a missing-whitespace-after-doctype-system-keyword parse error.
+					// Set the current DOCTYPE token's system identifier to the empty string
+					// (not missing), then switch to the DOCTYPE system identifier
+					// (double-quoted) state.
+					reportError(
+						"missing-whitespace-after-doctype-system-keyword",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// This is a missing-whitespace-after-doctype-system-keyword parse error.
+					// Set the current DOCTYPE token's system identifier to the empty string
+					// (not missing), then switch to the DOCTYPE system identifier
+					// (single-quoted) state.
+					reportError(
+						"missing-whitespace-after-doctype-system-keyword",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-doctype-system-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"missing-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// This is a missing-quote-before-doctype-system-identifier parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"missing-quote-before-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#before-doctype-system-identifier-state
+			case STATE_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Ignore the character.
+					pos++;
+				} else if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// Set the current DOCTYPE token's system identifier to the empty string
+					// (not missing), then switch to the DOCTYPE system identifier
+					// (double-quoted) state.
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
+					pos++;
+				} else if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// Set the current DOCTYPE token's system identifier to the empty string
+					// (not missing), then switch to the DOCTYPE system identifier
+					// (single-quoted) state.
+					state = STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is a missing-doctype-system-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"missing-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// This is a missing-quote-before-doctype-system-identifier parse error. Set
+					// the current DOCTYPE token's force-quirks flag to on. Reconsume in the
+					// bogus DOCTYPE state.
+					reportError(
+						"missing-quote-before-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#doctype-system-identifier-(double-quoted)-state
+			case STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+				// Consume the next input character:
+				if (cc === CC_QUOTATION_MARK) {
+					// U+0022 QUOTATION MARK (")
+					// Switch to the after DOCTYPE system identifier state.
+					state = STATE_AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
+					pos++;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Append a U+FFFD
+					// REPLACEMENT CHARACTER character to the current DOCTYPE token's system
+					// identifier.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an abrupt-doctype-system-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"abrupt-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Append the current input character to the current DOCTYPE token's system
+					// identifier.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#doctype-system-identifier-(single-quoted)-state
+			case STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
+				// Consume the next input character:
+				if (cc === CC_APOSTROPHE) {
+					// U+0027 APOSTROPHE (')
+					// Switch to the after DOCTYPE system identifier state.
+					state = STATE_AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
+					pos++;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Append a U+FFFD
+					// REPLACEMENT CHARACTER character to the current DOCTYPE token's system
+					// identifier.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// This is an abrupt-doctype-system-identifier parse error. Set the current
+					// DOCTYPE token's force-quirks flag to on. Switch to the data state. Emit
+					// the current DOCTYPE token.
+					reportError(
+						"abrupt-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Append the current input character to the current DOCTYPE token's system
+					// identifier.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#after-doctype-system-identifier-state
+			case STATE_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
+				// Consume the next input character:
+				if (isSpace(cc)) {
+					// U+0009 CHARACTER TABULATION (tab)
+					// U+000A LINE FEED (LF)
+					// U+000C FORM FEED (FF)
+					// U+0020 SPACE
+					// Ignore the character.
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the current DOCTYPE token.
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// This is an unexpected-character-after-doctype-system-identifier parse
+					// error. Reconsume in the bogus DOCTYPE state. (This does not set the
+					// current DOCTYPE token's force-quirks flag to on.)
+					reportError(
+						"unexpected-character-after-doctype-system-identifier",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_BOGUS_DOCTYPE;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#bogus-doctype-state
+			case STATE_BOGUS_DOCTYPE:
+				// Consume the next input character:
+				if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state. Emit the DOCTYPE token.
+					let nextPos = pos + 1;
+					if (callbacks.doctype !== undefined) {
+						nextPos = callbacks.doctype(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else if (cc === 0x00) {
+					// U+0000 NULL
+					// This is an unexpected-null-character parse error. Ignore the character.
+					pos++;
+				} else {
+					// Anything else
+					// Ignore the character.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#cdata-section-state
+			case STATE_CDATA_SECTION:
+				// Consume the next input character:
+				// U+005D RIGHT SQUARE BRACKET (])
+				// Switch to the CDATA section bracket state.
+				if (cc === CC_RIGHT_SQUARE_BRACKET) {
+					state = STATE_CDATA_SECTION_BRACKET;
+					pos++;
+				} else {
+					// Anything else
+					// Emit the current input character as a character token.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#cdata-section-bracket-state
+			case STATE_CDATA_SECTION_BRACKET:
+				// Consume the next input character:
+				// U+005D RIGHT SQUARE BRACKET (])
+				// Switch to the CDATA section end state.
+				if (cc === CC_RIGHT_SQUARE_BRACKET) {
+					state = STATE_CDATA_SECTION_END;
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+005D RIGHT SQUARE BRACKET character token. Reconsume in the
+					// CDATA section state.
+					state = STATE_CDATA_SECTION;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#cdata-section-end-state
+			case STATE_CDATA_SECTION_END:
+				// Consume the next input character:
+				// U+005D RIGHT SQUARE BRACKET (])
+				// Emit a U+005D RIGHT SQUARE BRACKET character token.
+				if (cc === CC_RIGHT_SQUARE_BRACKET) {
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the data state.
+					let nextPos = pos + 1;
+					if (callbacks.comment !== undefined) {
+						nextPos = callbacks.comment(input, commentStart, pos + 1);
+					}
+					state = STATE_DATA;
+					textStart = nextPos;
+					pos = nextPos;
+				} else {
+					// Anything else
+					// Emit two U+005D RIGHT SQUARE BRACKET character tokens. Reconsume in the
+					// CDATA section state.
+					state = STATE_CDATA_SECTION;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rcdata-state
+			case STATE_RCDATA:
+				// Consume the next input character:
+				// U+003C LESS-THAN SIGN (<)
+				// Switch to the RCDATA less-than sign state.
+				if (cc === CC_LESS_THAN) {
+					tagStart = pos;
+					state = STATE_RCDATA_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					// Anything else
+					// Emit the current input character as a character token.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rcdata-less-than-sign-state
+			case STATE_RCDATA_LESS_THAN_SIGN:
+				// Consume the next input character:
+				// U+002F SOLIDUS (/)
+				// Switch to the RCDATA end tag open state. (Spec sets a
+				// temporary buffer here; we track the would-be content via
+				// offset ranges instead.)
+				if (cc === CC_SOLIDUS) {
+					state = STATE_RCDATA_END_TAG_OPEN;
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token. Reconsume in the RCDATA
+					// state.
+					state = STATE_RCDATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rcdata-end-tag-open-state
+			case STATE_RCDATA_END_TAG_OPEN:
+				// Consume the next input character:
+				// ASCII alpha
+				// Create a new end tag token, set its tag name to the empty string.
+				// Reconsume in the RCDATA end tag name state.
+				if (isAsciiAlpha(cc)) {
+					tagNameStart = pos;
+					state = STATE_RCDATA_END_TAG_NAME;
+					// Reconsume
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS
+					// character token. Reconsume in the RCDATA state.
+					state = STATE_RCDATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rcdata-end-tag-name-state
+			case STATE_RCDATA_END_TAG_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// If the current end tag token is an appropriate end tag token, then switch
+				// to the before attribute name state. Otherwise, treat it as per the
+				// "anything else" entry below.
+				if (isSpace(cc)) {
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_BEFORE_ATTRIBUTE_NAME;
+						pos++;
+					} else {
+						state = STATE_RCDATA;
+						// Reconsume
+					}
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the self-closing start tag state. Otherwise, treat it as per the
+					// "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_SELF_CLOSING_START_TAG;
+						pos++;
+					} else {
+						state = STATE_RCDATA;
+						// Reconsume
+					}
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the data state and emit the current tag token. Otherwise, treat it as
+					// per the "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						state = STATE_RCDATA;
+						// Reconsume
+					}
+				} else if (isAsciiAlpha(cc)) {
+					// ASCII upper alpha / ASCII lower alpha
+					// Append the lowercase version of the current input character to the
+					// current tag token's tag name. Append the current input character to
+					// the temporary buffer.
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token, a U+002F SOLIDUS character
+					// token, and a character token for each of the characters in the temporary
+					// buffer (in the order they were added to the buffer). Reconsume in the
+					// RCDATA state.
+					state = STATE_RCDATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rawtext-state
+			case STATE_RAWTEXT:
+				// Consume the next input character:
+				// U+003C LESS-THAN SIGN (<)
+				// Switch to the RAWTEXT less-than sign state.
+				if (cc === CC_LESS_THAN) {
+					tagStart = pos;
+					state = STATE_RAWTEXT_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rawtext-less-than-sign-state
+			case STATE_RAWTEXT_LESS_THAN_SIGN:
+				// Consume the next input character:
+				// U+002F SOLIDUS (/)
+				// Switch to the RAWTEXT end tag open state. (Spec sets a
+				// temporary buffer here; we track via offset ranges instead.)
+				if (cc === CC_SOLIDUS) {
+					state = STATE_RAWTEXT_END_TAG_OPEN;
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token. Reconsume in the RAWTEXT
+					// state.
+					state = STATE_RAWTEXT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rawtext-end-tag-open-state
+			case STATE_RAWTEXT_END_TAG_OPEN:
+				// Consume the next input character:
+				// ASCII alpha
+				// Create a new end tag token, set its tag name to the empty string.
+				// Reconsume in the RAWTEXT end tag name state.
+				if (isAsciiAlpha(cc)) {
+					tagNameStart = pos;
+					state = STATE_RAWTEXT_END_TAG_NAME;
+					// Reconsume
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS
+					// character token. Reconsume in the RAWTEXT state.
+					state = STATE_RAWTEXT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#rawtext-end-tag-name-state
+			case STATE_RAWTEXT_END_TAG_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// If the current end tag token is an appropriate end tag token, then switch
+				// to the before attribute name state. Otherwise, treat it as per the
+				// "anything else" entry below.
+				if (isSpace(cc)) {
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_BEFORE_ATTRIBUTE_NAME;
+						pos++;
+					} else {
+						state = STATE_RAWTEXT;
+					}
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the self-closing start tag state. Otherwise, treat it as per the
+					// "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_SELF_CLOSING_START_TAG;
+						pos++;
+					} else {
+						state = STATE_RAWTEXT;
+					}
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the data state and emit the current tag token. Otherwise, treat it as
+					// per the "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						state = STATE_RAWTEXT;
+					}
+				} else if (isAsciiAlpha(cc)) {
+					// ASCII upper alpha / ASCII lower alpha
+					// Append the lowercase version of the current input character to the
+					// current tag token's tag name. Append the current input character to
+					// the temporary buffer.
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token, a U+002F SOLIDUS character
+					// token, and a character token for each of the characters in the temporary
+					// buffer (in the order they were added to the buffer). Reconsume in the
+					// RAWTEXT state.
+					state = STATE_RAWTEXT;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-state
+			case STATE_SCRIPT_DATA:
+				// Consume the next input character:
+				// U+003C LESS-THAN SIGN (<)
+				// Switch to the script data less-than sign state.
+				if (cc === CC_LESS_THAN) {
+					tagStart = pos;
+					state = STATE_SCRIPT_DATA_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-less-than-sign-state
+			case STATE_SCRIPT_DATA_LESS_THAN_SIGN:
+				// Consume the next input character:
+				// U+002F SOLIDUS (/)
+				// Switch to the script data end tag open state. (Spec sets a
+				// temporary buffer here; we track via offset ranges instead.)
+				if (cc === CC_SOLIDUS) {
+					state = STATE_SCRIPT_DATA_END_TAG_OPEN;
+					pos++;
+				} else if (cc === CC_EXCLAMATION_MARK) {
+					// U+0021 EXCLAMATION MARK (!)
+					// Switch to the script data escape start state. Emit a U+003C LESS-THAN
+					// SIGN character token and a U+0021 EXCLAMATION MARK character token.
+					state = STATE_SCRIPT_DATA_ESCAPE_START;
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token. Reconsume in the script
+					// data state.
+					state = STATE_SCRIPT_DATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-end-tag-open-state
+			case STATE_SCRIPT_DATA_END_TAG_OPEN:
+				// Consume the next input character:
+				// ASCII alpha
+				// Create a new end tag token, set its tag name to the empty string.
+				// Reconsume in the script data end tag name state.
+				if (isAsciiAlpha(cc)) {
+					tagNameStart = pos;
+					state = STATE_SCRIPT_DATA_END_TAG_NAME;
+					// Reconsume
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS
+					// character token. Reconsume in the script data state.
+					state = STATE_SCRIPT_DATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-end-tag-name-state
+			case STATE_SCRIPT_DATA_END_TAG_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// If the current end tag token is an appropriate end tag token, then switch
+				// to the before attribute name state. Otherwise, treat it as per the
+				// "anything else" entry below.
+				if (isSpace(cc)) {
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_BEFORE_ATTRIBUTE_NAME;
+						pos++;
+					} else {
+						state = STATE_SCRIPT_DATA;
+					}
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the self-closing start tag state. Otherwise, treat it as per the
+					// "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_SELF_CLOSING_START_TAG;
+						pos++;
+					} else {
+						state = STATE_SCRIPT_DATA;
+					}
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the data state and emit the current tag token. Otherwise, treat it as
+					// per the "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						state = STATE_SCRIPT_DATA;
+					}
+				} else if (isAsciiAlpha(cc)) {
+					// ASCII upper alpha / ASCII lower alpha
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token, a U+002F SOLIDUS character
+					// token, and a character token for each of the characters in the temporary
+					// buffer (in the order they were added to the buffer). Reconsume in the
+					// script data state.
+					state = STATE_SCRIPT_DATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escape-start-state
+			case STATE_SCRIPT_DATA_ESCAPE_START:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the script data escape start dash state. Emit a U+002D
+				// HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_SCRIPT_DATA_ESCAPE_START_DASH;
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the script data state.
+					state = STATE_SCRIPT_DATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escape-start-dash-state
+			case STATE_SCRIPT_DATA_ESCAPE_START_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the script data escaped dash dash state. Emit a U+002D
+				// HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_SCRIPT_DATA_ESCAPED_DASH_DASH;
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the script data state.
+					state = STATE_SCRIPT_DATA;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-state
+			case STATE_SCRIPT_DATA_ESCAPED:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the script data escaped dash state. Emit a U+002D HYPHEN-MINUS
+				// character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_SCRIPT_DATA_ESCAPED_DASH;
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Switch to the script data escaped less-than sign state.
+					tagStart = pos;
+					state = STATE_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					// Anything else
+					// Emit the current input character as a character token.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-dash-state
+			case STATE_SCRIPT_DATA_ESCAPED_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the script data escaped dash dash state. Emit a U+002D
+				// HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_SCRIPT_DATA_ESCAPED_DASH_DASH;
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Switch to the script data escaped less-than sign state.
+					tagStart = pos;
+					state = STATE_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					// Anything else
+					// Switch to the script data escaped state. Emit the current input character
+					// as a character token.
+					state = STATE_SCRIPT_DATA_ESCAPED;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-dash-dash-state
+			case STATE_SCRIPT_DATA_ESCAPED_DASH_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Emit a U+002D HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Switch to the script data escaped less-than sign state.
+					tagStart = pos;
+					state = STATE_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the script data state. Emit a U+003E GREATER-THAN SIGN
+					// character token.
+					state = STATE_SCRIPT_DATA;
+					pos++;
+				} else {
+					// Anything else
+					// Switch to the script data escaped state. Emit the current input character
+					// as a character token.
+					state = STATE_SCRIPT_DATA_ESCAPED;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-less-than-sign-state
+			case STATE_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
+				// Consume the next input character:
+				// U+002F SOLIDUS (/)
+				// Switch to the script data escaped end tag open state.
+				// (Spec sets a temporary buffer; we track via offset ranges.)
+				if (cc === CC_SOLIDUS) {
+					state = STATE_SCRIPT_DATA_ESCAPED_END_TAG_OPEN;
+					pos++;
+				} else if (isAsciiAlpha(cc)) {
+					// ASCII alpha
+					// Set the temporary buffer to the empty string. Emit a U+003C LESS-THAN
+					// SIGN character token. Reconsume in the script data double escape start
+					// state.
+					scriptMatch = 0;
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPE_START;
+					// Reconsume
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token. Reconsume in the script
+					// data escaped state.
+					state = STATE_SCRIPT_DATA_ESCAPED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-end-tag-open-state
+			case STATE_SCRIPT_DATA_ESCAPED_END_TAG_OPEN:
+				// Consume the next input character:
+				// ASCII alpha
+				// Create a new end tag token, set its tag name to the empty string.
+				// Reconsume in the script data escaped end tag name state.
+				if (isAsciiAlpha(cc)) {
+					tagNameStart = pos;
+					state = STATE_SCRIPT_DATA_ESCAPED_END_TAG_NAME;
+					// Reconsume
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS
+					// character token. Reconsume in the script data escaped state.
+					state = STATE_SCRIPT_DATA_ESCAPED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-escaped-end-tag-name-state
+			case STATE_SCRIPT_DATA_ESCAPED_END_TAG_NAME:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// If the current end tag token is an appropriate end tag token, then switch
+				// to the before attribute name state. Otherwise, treat it as per the
+				// "anything else" entry below.
+				if (isSpace(cc)) {
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_BEFORE_ATTRIBUTE_NAME;
+						pos++;
+					} else {
+						state = STATE_SCRIPT_DATA_ESCAPED;
+					}
+				} else if (cc === CC_SOLIDUS) {
+					// U+002F SOLIDUS (/)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the self-closing start tag state. Otherwise, treat it as per the
+					// "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_SELF_CLOSING_START_TAG;
+						pos++;
+					} else {
+						state = STATE_SCRIPT_DATA_ESCAPED;
+					}
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// If the current end tag token is an appropriate end tag token, then switch
+					// to the data state and emit the current tag token. Otherwise, treat it as
+					// per the "anything else" entry below.
+					tagNameEnd = pos;
+					if (
+						input.slice(tagNameStart, tagNameEnd).toLowerCase() ===
+						lastOpenTagName
+					) {
+						flushText(tagStart);
+						state = STATE_DATA;
+						pos = emitCloseTag(pos + 1);
+					} else {
+						state = STATE_SCRIPT_DATA_ESCAPED;
+					}
+				} else if (isAsciiAlpha(cc)) {
+					// ASCII upper alpha / ASCII lower alpha
+					pos++;
+				} else {
+					// Anything else
+					// Emit a U+003C LESS-THAN SIGN character token, a U+002F SOLIDUS character
+					// token, and a character token for each of the characters in the temporary
+					// buffer (in the order they were added to the buffer). Reconsume in the
+					// script data escaped state.
+					state = STATE_SCRIPT_DATA_ESCAPED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escape-start-state
+			case STATE_SCRIPT_DATA_DOUBLE_ESCAPE_START:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// U+002F SOLIDUS (/)
+				// U+003E GREATER-THAN SIGN (>)
+				// If the temporary buffer is the string "script", then switch to the script
+				// data double escaped state. Otherwise, switch to the script data escaped
+				// state. Emit the current input character as a character token.
+				if (isSpace(cc) || cc === CC_SOLIDUS || cc === CC_GREATER_THAN) {
+					state =
+						scriptMatch === 6
+							? STATE_SCRIPT_DATA_DOUBLE_ESCAPED
+							: STATE_SCRIPT_DATA_ESCAPED;
+					pos++;
+				} else if (isAsciiUpperAlpha(cc) || isAsciiLowerAlpha(cc)) {
+					// ASCII alpha — advance the `"script"` match counter if the
+					// lowercase form matches the next expected char, otherwise
+					// snap to the sentinel so further chars can't revive a
+					// match. No buffer allocation.
+					const lower = isAsciiUpperAlpha(cc) ? cc + 0x20 : cc;
+					if (scriptMatch < 6 && lower === "script".charCodeAt(scriptMatch)) {
+						scriptMatch++;
+					} else {
+						scriptMatch = 7;
+					}
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the script data escaped state.
+					state = STATE_SCRIPT_DATA_ESCAPED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escaped-state
+			case STATE_SCRIPT_DATA_DOUBLE_ESCAPED:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the script data double escaped dash state. Emit a U+002D
+				// HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH;
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Switch to the script data double escaped less-than sign state. Emit a
+					// U+003C LESS-THAN SIGN character token.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					// Anything else
+					// Emit the current input character as a character token.
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escaped-dash-state
+			case STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Switch to the script data double escaped dash dash state. Emit a U+002D
+				// HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH;
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Switch to the script data double escaped less-than sign state. Emit a
+					// U+003C LESS-THAN SIGN character token.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
+					pos++;
+				} else {
+					// Anything else
+					// Switch to the script data double escaped state. Emit the current input
+					// character as a character token.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escaped-dash-dash-state
+			case STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
+				// Consume the next input character:
+				// U+002D HYPHEN-MINUS (-)
+				// Emit a U+002D HYPHEN-MINUS character token.
+				if (cc === CC_HYPHEN_MINUS) {
+					pos++;
+				} else if (cc === CC_LESS_THAN) {
+					// U+003C LESS-THAN SIGN (<)
+					// Switch to the script data double escaped less-than sign state. Emit a
+					// U+003C LESS-THAN SIGN character token.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
+					pos++;
+				} else if (cc === CC_GREATER_THAN) {
+					// U+003E GREATER-THAN SIGN (>)
+					// Switch to the script data state. Emit a U+003E GREATER-THAN SIGN
+					// character token.
+					state = STATE_SCRIPT_DATA;
+					pos++;
+				} else {
+					// Anything else
+					// Switch to the script data double escaped state. Emit the current input
+					// character as a character token.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED;
+					pos++;
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escaped-less-than-sign-state
+			case STATE_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
+				// Consume the next input character:
+				// U+002F SOLIDUS (/)
+				// Set the temporary buffer to the empty string. Switch to the script data
+				// double escape end state. Emit a U+002F SOLIDUS character token.
+				if (cc === CC_SOLIDUS) {
+					scriptMatch = 0;
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPE_END;
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the script data double escaped state.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escape-end-state
+			case STATE_SCRIPT_DATA_DOUBLE_ESCAPE_END:
+				// Consume the next input character:
+				// U+0009 CHARACTER TABULATION (tab)
+				// U+000A LINE FEED (LF)
+				// U+000C FORM FEED (FF)
+				// U+0020 SPACE
+				// U+002F SOLIDUS (/)
+				// U+003E GREATER-THAN SIGN (>)
+				// If the temporary buffer is the string "script", then switch to the script
+				// data escaped state. Otherwise, switch to the script data double escaped
+				// state. Emit the current input character as a character token.
+				if (isSpace(cc) || cc === CC_SOLIDUS || cc === CC_GREATER_THAN) {
+					state =
+						scriptMatch === 6
+							? STATE_SCRIPT_DATA_ESCAPED
+							: STATE_SCRIPT_DATA_DOUBLE_ESCAPED;
+					pos++;
+				} else if (isAsciiUpperAlpha(cc) || isAsciiLowerAlpha(cc)) {
+					// ASCII alpha — advance the `"script"` match counter if the
+					// lowercase form matches the next expected char, otherwise
+					// snap to the sentinel so further chars can't revive a
+					// match. No buffer allocation.
+					const lower = isAsciiUpperAlpha(cc) ? cc + 0x20 : cc;
+					if (scriptMatch < 6 && lower === "script".charCodeAt(scriptMatch)) {
+						scriptMatch++;
+					} else {
+						scriptMatch = 7;
+					}
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the script data double escaped state.
+					state = STATE_SCRIPT_DATA_DOUBLE_ESCAPED;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#plaintext-state
+			case STATE_PLAINTEXT:
+				// Consume the next input character:
+				// Anything else
+				// Emit the current input character as a character token.
+				pos++;
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#character-reference-state
+			case STATE_CHARACTER_REFERENCE:
+				// Set the temporary buffer to the empty string. Append a U+0026
+				// AMPERSAND (&) character to the temporary buffer.
+				// Consume the next input character:
+				if (isAsciiAlphanumeric(cc)) {
+					// ASCII alphanumeric
+					// Reconsume in the named character reference state.
+					state = STATE_NAMED_CHARACTER_REFERENCE;
+					// Reconsume
+				} else if (cc === CC_NUMBER_SIGN) {
+					// U+0023 NUMBER SIGN (#)
+					// Append the current input character to the temporary buffer.
+					// Switch to the numeric character reference state.
+					state = STATE_NUMERIC_CHARACTER_REFERENCE;
+					pos++;
+				} else {
+					// Anything else
+					// Flush code points consumed as a character reference.
+					// Reconsume in the return state.
+					state = returnState;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
+			case STATE_NAMED_CHARACTER_REFERENCE: {
+				// Consume the maximum number of characters possible where the
+				// consumed characters are one of the identifiers in the first
+				// column of the named character references table.
+				//
+				// We measure the longest run of ASCII alphanumeric characters
+				// (capped at MAX_ENTITY_NAME_LEN - 1 since the optional `;` is
+				// handled separately), then walk that run from longest to
+				// shortest looking for the first prefix that exists in the
+				// entity table (with a trailing `;` if present, otherwise the
+				// legacy bare form).
+				let runLen = 0;
+				while (
+					pos + runLen < len &&
+					isAsciiAlphanumeric(input.charCodeAt(pos + runLen)) &&
+					runLen < MAX_ENTITY_NAME_LEN - 1
+				) {
+					runLen++;
+				}
+				const hasSemicolon =
+					pos + runLen < len && input.charCodeAt(pos + runLen) === CC_SEMICOLON;
+				namedEntityConsumed = 0;
+				for (let n = runLen; n > 0; n--) {
+					// Try with trailing `;` first if one is present after the run.
+					if (n === runLen && hasSemicolon) {
+						const withSemi = `${input.slice(pos, pos + n)};`;
+						if (HTML_ENTITIES[withSemi] !== undefined) {
+							namedEntityConsumed = n + 1;
+							break;
+						}
+					}
+					const bare = input.slice(pos, pos + n);
+					if (HTML_ENTITIES[bare] !== undefined) {
+						namedEntityConsumed = n;
+						break;
+					}
+				}
+				if (namedEntityConsumed > 0) {
+					pos += namedEntityConsumed;
+					state = returnState;
+				} else {
+					// No match — flush code points consumed as a character
+					// reference. Switch to the ambiguous ampersand state.
+					state = STATE_AMBIGUOUS_AMPERSAND;
+				}
+				break;
+			}
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#ambiguous-ampersand-state
+			case STATE_AMBIGUOUS_AMPERSAND:
+				// Consume the next input character:
+				if (isAsciiAlphanumeric(cc)) {
+					// ASCII alphanumeric
+					// If the character reference was consumed as part of an
+					// attribute, then append the current input character to the
+					// current attribute's value. Otherwise, emit the current
+					// input character as a character token.
+					pos++;
+				} else if (cc === CC_SEMICOLON) {
+					// U+003B SEMICOLON (;)
+					// This is an unknown-named-character-reference parse error.
+					// Reconsume in the return state.
+					reportError(
+						"unknown-named-character-reference",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = returnState;
+					// Reconsume
+				} else {
+					// Anything else
+					// Reconsume in the return state.
+					state = returnState;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-state
+			case STATE_NUMERIC_CHARACTER_REFERENCE:
+				// Set the character reference code to zero (0).
+				// Consume the next input character:
+				if (cc === 0x78 || cc === 0x58) {
+					// U+0078 LATIN SMALL LETTER X
+					// U+0058 LATIN CAPITAL LETTER X
+					// Append the current input character to the temporary
+					// buffer. Switch to the hexadecimal character reference
+					// start state.
+					state = STATE_HEXADECIMAL_CHARACTER_REFERENCE_START;
+					pos++;
+				} else {
+					// Anything else
+					// Reconsume in the decimal character reference start state.
+					state = STATE_DECIMAL_CHARACTER_REFERENCE_START;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#hexadecimal-character-reference-start-state
+			case STATE_HEXADECIMAL_CHARACTER_REFERENCE_START:
+				// Consume the next input character:
+				// ASCII hex digit: reconsume in the hexadecimal character reference state.
+				// Anything else: absence-of-digits-in-numeric-character-reference parse
+				// error. Flush code points consumed as a character reference. Reconsume
+				// in the return state.
+				if (isAsciiHexDigit(cc)) {
+					state = STATE_HEXADECIMAL_CHARACTER_REFERENCE;
+				} else {
+					reportError(
+						"absence-of-digits-in-numeric-character-reference",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = returnState;
+				}
+				// Reconsume
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#decimal-character-reference-start-state
+			case STATE_DECIMAL_CHARACTER_REFERENCE_START:
+				// Consume the next input character:
+				// ASCII digit: reconsume in the decimal character reference state.
+				// Anything else: absence-of-digits-in-numeric-character-reference parse
+				// error. Flush code points consumed as a character reference. Reconsume
+				// in the return state.
+				if (isAsciiDigit(cc)) {
+					state = STATE_DECIMAL_CHARACTER_REFERENCE;
+				} else {
+					reportError(
+						"absence-of-digits-in-numeric-character-reference",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = returnState;
+				}
+				// Reconsume
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#hexadecimal-character-reference-state
+			case STATE_HEXADECIMAL_CHARACTER_REFERENCE:
+				// Consume the next input character:
+				if (isAsciiHexDigit(cc)) {
+					// ASCII digit / upper hex / lower hex
+					// Multiply the character reference code by 16. Add a numeric
+					// version of the current input character to the character
+					// reference code.
+					pos++;
+				} else if (cc === CC_SEMICOLON) {
+					// U+003B SEMICOLON
+					// Switch to the numeric character reference end state.
+					state = STATE_NUMERIC_CHARACTER_REFERENCE_END;
+					pos++;
+				} else {
+					// Anything else
+					// This is a missing-semicolon-after-character-reference
+					// parse error. Reconsume in the numeric character reference
+					// end state.
+					reportError(
+						"missing-semicolon-after-character-reference",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_NUMERIC_CHARACTER_REFERENCE_END;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#decimal-character-reference-state
+			case STATE_DECIMAL_CHARACTER_REFERENCE:
+				// Consume the next input character:
+				if (isAsciiDigit(cc)) {
+					// ASCII digit
+					// Multiply the character reference code by 10. Add a numeric
+					// version of the current input character (subtract 0x0030
+					// from the character's code point) to the character reference
+					// code.
+					pos++;
+				} else if (cc === CC_SEMICOLON) {
+					// U+003B SEMICOLON
+					// Switch to the numeric character reference end state.
+					state = STATE_NUMERIC_CHARACTER_REFERENCE_END;
+					pos++;
+				} else {
+					// Anything else
+					// This is a missing-semicolon-after-character-reference
+					// parse error. Reconsume in the numeric character reference
+					// end state.
+					reportError(
+						"missing-semicolon-after-character-reference",
+						pos,
+						pos + 1,
+						"warning"
+					);
+					state = STATE_NUMERIC_CHARACTER_REFERENCE_END;
+					// Reconsume
+				}
+				break;
+
+			// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
+			case STATE_NUMERIC_CHARACTER_REFERENCE_END:
+				// Check the character reference code (validation omitted for
+				// the scanner — we don't decode, just skip past the entity).
+				// Flush code points consumed as a character reference.
+				// Switch to the return state.
+				state = returnState;
+				// Reconsume
+				break;
+
+			/* istanbul ignore next -- @preserve: defensive fallback, all states are explicit above */
+			default:
+				pos++;
+		}
+	}
+
+	// Handle EOF in non-data states per the WHATWG spec.
+	//
+	// Each in-progress comment / doctype / cdata / tag emits its partial
+	// token range plus a corresponding `eof-in-X` parse error. Severity is
+	// `"error"` because the emitted token offset range is incomplete (missing
+	// trailing `-->`, `>`, `]]>`, etc.). For data / `<` / `</` / `<!`-only
+	// inputs we emit `eof-before-tag-name` and fall through to flush the
+	// pending text span (which still contains the lone `<`).
+	// If EOF caught us inside a character-reference state, flush whatever the
+	// scanner had consumed and resume in the return state so any in-progress
+	// tag/comment is handled correctly by the branches below.
+	if (
+		state >= STATE_CHARACTER_REFERENCE &&
+		state <= STATE_NUMERIC_CHARACTER_REFERENCE_END
+	) {
+		state = returnState;
+	}
+
+	if (
+		(state >= STATE_TAG_NAME && state <= STATE_SELF_CLOSING_START_TAG) ||
+		state === STATE_RCDATA_END_TAG_NAME ||
+		state === STATE_RAWTEXT_END_TAG_NAME ||
+		state === STATE_SCRIPT_DATA_END_TAG_NAME ||
+		state === STATE_SCRIPT_DATA_ESCAPED_END_TAG_NAME
+	) {
+		// EOF mid-tag — emit the partial open/close tag at EOF so the
+		// consumer still sees the tag. This is a deliberate deviation
+		// from the spec's per-character emission model: rather than
+		// dropping the in-progress tag, we emit its offset range up to EOF.
+		reportError("eof-in-tag", len, len, "error");
+		// If we hit EOF mid-attribute-name, the name runs to EOF. Set
+		// attrNameEnd here so the emitted attribute range is valid.
+		if (state === STATE_ATTRIBUTE_NAME && attrNameStart !== -1) {
+			attrNameEnd = len;
+		}
+		if (attrNameStart !== -1) emitAttribute(len);
+		// If we hit EOF before the tag-name end was recorded, the name runs
+		// to EOF. `tagNameEnd` may carry over from a previously emitted tag,
+		// so reset it whenever it's missing or stale (less than `tagNameStart`)
+		// — covers `<div` open-tag EOFs as well as `<title>x</tit` and other
+		// content-mode end-tag-name EOFs.
+		if (tagNameStart !== -1 && tagNameEnd < tagNameStart) {
+			tagNameEnd = len;
+		}
+		flushText(tagStart);
+		pos =
+			input.charCodeAt(tagStart + 1) === CC_SOLIDUS
+				? emitCloseTag(len)
+				: emitOpenTag(len, false);
+	} else if (
+		(state >= STATE_COMMENT_START && state <= STATE_BOGUS_COMMENT) ||
+		(state >= STATE_COMMENT_LESS_THAN_SIGN &&
+			state <= STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH) ||
+		state === STATE_MARKUP_DECLARATION_OPEN
+	) {
+		// Bogus comments at EOF are normal per spec (no parse error).
+		if (state !== STATE_BOGUS_COMMENT) {
+			reportError("eof-in-comment", len, len, "error");
+		}
+		if (callbacks.comment !== undefined) {
+			pos = callbacks.comment(input, commentStart, len);
+		}
+	} else if (state >= STATE_CDATA_SECTION && state <= STATE_CDATA_SECTION_END) {
+		reportError("eof-in-cdata", len, len, "error");
+		if (callbacks.comment !== undefined) {
+			pos = callbacks.comment(input, commentStart, len);
+		}
+	} else if (state >= STATE_DOCTYPE && state <= STATE_BOGUS_DOCTYPE) {
+		reportError("eof-in-doctype", len, len, "error");
+		if (callbacks.doctype !== undefined) {
+			pos = callbacks.doctype(input, commentStart, len);
+		}
+	} else {
+		if (
+			state === STATE_SCRIPT_DATA_ESCAPED ||
+			state === STATE_SCRIPT_DATA_ESCAPED_DASH ||
+			state === STATE_SCRIPT_DATA_ESCAPED_DASH_DASH ||
+			state === STATE_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN ||
+			state === STATE_SCRIPT_DATA_DOUBLE_ESCAPED ||
+			state === STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH ||
+			state === STATE_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH ||
+			state === STATE_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN ||
+			state === STATE_SCRIPT_DATA_DOUBLE_ESCAPE_END
+		) {
+			// Inside `<script><!-- … ` at EOF — spec calls this an
+			// eof-in-script-html-comment-like-text parse error. The
+			// less-than-sign and double-escape-end states reconsume back
+			// into the (double-)escaped state on EOF per spec, which then
+			// hits this same error.
+			reportError("eof-in-script-html-comment-like-text", len, len, "error");
+		} else if (state === STATE_TAG_OPEN || state === STATE_END_TAG_OPEN) {
+			// `<` or `</` with nothing after; spec calls this
+			// eof-before-tag-name. The lone `<` / `</` is preserved in the
+			// pending text span which is flushed below.
+			reportError("eof-before-tag-name", len, len, "warning");
+		}
+		if (textStart < len && callbacks.text !== undefined) {
+			callbacks.text(input, textStart, len);
+		}
+	}
+
+	return pos;
+};
+
+walkHtmlTokens.QUOTE_NONE = QUOTE_NONE;
+walkHtmlTokens.QUOTE_SINGLE = QUOTE_SINGLE;
+walkHtmlTokens.QUOTE_DOUBLE = QUOTE_DOUBLE;
+
+// WHATWG numeric-character-reference-end Windows-1252 remap table for the
+// 0x80-0x9F range. Per spec these C1 control code points decode to the
+// corresponding Windows-1252 glyph (with a parse error) rather than to the
+// raw C1 control character.
+const NUMERIC_C1_REMAP = {
+	0x80: "€",
+	0x82: "‚",
+	0x83: "ƒ",
+	0x84: "„",
+	0x85: "…",
+	0x86: "†",
+	0x87: "‡",
+	0x88: "ˆ",
+	0x89: "‰",
+	0x8a: "Š",
+	0x8b: "‹",
+	0x8c: "Œ",
+	0x8e: "Ž",
+	0x91: "‘",
+	0x92: "’",
+	0x93: "“",
+	0x94: "”",
+	0x95: "•",
+	0x96: "–",
+	0x97: "—",
+	0x98: "˜",
+	0x99: "™",
+	0x9a: "š",
+	0x9b: "›",
+	0x9c: "œ",
+	0x9e: "ž",
+	0x9f: "Ÿ"
+};
+
+/**
+ * @param {number} code numeric character reference code point
+ * @returns {string} decoded character per WHATWG remap rules
+ */
+const decodeNumericReference = (code) => {
+	// Per WHATWG numeric-character-reference-end-state:
+	//   - 0x00, > 0x10FFFF, or surrogate (0xD800-0xDFFF) -> U+FFFD.
+	//   - 0x80-0x9F -> Windows-1252 remap (above).
+	//   - Anything else (including noncharacters and C0 controls) -> the
+	//     code point itself; we don't surface the spec's parse-error
+	//     classes here since decoding is happening after the scanner ran.
+	if (code === 0 || code > 0x10ffff || (code >= 0xd800 && code <= 0xdfff)) {
+		return "�";
+	}
+	if (code >= 0x80 && code <= 0x9f) {
+		const remapped = /** @type {Record<number, string>} */ (NUMERIC_C1_REMAP)[
+			code
+		];
+		if (remapped !== undefined) return remapped;
+	}
+	return String.fromCodePoint(code);
+};
+
+/**
+ * Decode HTML character references in a string. Handles all numeric
+ * references (with WHATWG remap of 0x00, surrogates, out-of-range, and the
+ * C1 Windows-1252 table) and the full WHATWG named character references
+ * table. Unknown or malformed references are left as literal text.
+ *
+ * When `isAttribute` is `true`, applies the WHATWG
+ * "consumed-as-part-of-an-attribute" rule: a named reference without a
+ * trailing `;` whose next character is `=` or ASCII alphanumeric is left
+ * undecoded, so e.g. `&amp=foo` stays literal in an attribute value but
+ * decodes to `&=foo` in text.
+ * @param {string} str the raw string from the token slice
+ * @param {boolean=} isAttribute true if `str` came from an attribute value
+ * @returns {string} decoded string
+ */
+walkHtmlTokens.decodeHtmlEntities = (str, isAttribute) => {
+	if (!str.includes("&")) return str;
+
+	// Match one of three forms (each with an optional trailing `;`):
+	//   `&#x<hex>` - hex numeric reference (requires the `x`/`X`).
+	//   `&#<dec>`  - decimal numeric reference (digits only).
+	//   `&<name>`  - named reference (letter followed by alphanumerics).
+	// The three alternatives are kept separate so a decimal reference like
+	// `&#65b` doesn't greedily eat the trailing `b` as if it were hex.
+	return str.replace(
+		/&(?:#[xX][0-9a-fA-F]+|#[0-9]+|[a-zA-Z][a-zA-Z0-9]*);?/g,
+		(match, offset, source) => {
+			// Numeric reference: &#65; or &#x41;
+			if (match.charCodeAt(1) === 0x23 /* # */) {
+				const lastChar = match.charAt(match.length - 1);
+				const isHex =
+					match.charCodeAt(2) === 0x78 || match.charCodeAt(2) === 0x58;
+				const body = isHex
+					? lastChar === ";"
+						? match.slice(3, -1)
+						: match.slice(3)
+					: lastChar === ";"
+						? match.slice(2, -1)
+						: match.slice(2);
+				// The regex above guarantees at least one digit in `body`,
+				// so `parseInt` always returns a finite number here.
+				return decodeNumericReference(Number.parseInt(body, isHex ? 16 : 10));
+			}
+
+			// Named reference. Try the full captured name first, then
+			// progressively shorter prefixes - this handles direct matches
+			// like `&amp;` as well as WHATWG longest-prefix semantics where
+			// e.g. `&notpre;` decodes as `&not` (a legacy bare entity)
+			// followed by `pre;` as literal text.
+			const name = match.slice(1);
+			const matchEndsWithSemi = name.charCodeAt(name.length - 1) === 0x3b;
+
+			// Attribute-context guard: if the entity match didn't end with `;`
+			// and the next character in the source is `=` or ASCII
+			// alphanumeric, the WHATWG spec says to flush the literal text
+			// rather than decode. The greedy regex already absorbed any
+			// trailing alphanumerics, so the only candidate "next char" here
+			// is `=` (or any non-alphanumeric).
+			if (isAttribute && !matchEndsWithSemi) {
+				const after = source.charCodeAt(offset + match.length);
+				if (after === 0x3d /* = */) return match;
+			}
+
+			// Cap the longest-prefix search at MAX_ENTITY_NAME_LEN so pathological
+			// inputs like `&` + thousands of alphanumerics stay linear-time.
+			// Anything past that cap can't possibly match and is appended
+			// verbatim as part of `name.slice(i)`.
+			const searchLen =
+				name.length > MAX_ENTITY_NAME_LEN ? MAX_ENTITY_NAME_LEN : name.length;
+			for (let i = searchLen; i > 0; i--) {
+				const prefix = name.slice(0, i);
+				if (HTML_ENTITIES[prefix] !== undefined) {
+					// Attribute-context longest-prefix guard: if the matched
+					// prefix doesn't end with `;` and the leftover starts with
+					// an alphanumeric character, leave literal per WHATWG.
+					// (The regex greedy-consumes alphanumerics, so any leftover
+					// within `name` is itself alphanumeric — we only need to
+					// check non-empty leftover here; the `=` case is handled
+					// above against the source character after the match.)
+					if (
+						isAttribute &&
+						i < name.length &&
+						prefix.charCodeAt(prefix.length - 1) !== 0x3b
+					) {
+						return match;
+					}
+					return HTML_ENTITIES[prefix] + name.slice(i);
+				}
+			}
+			return match;
+		}
+	);
+};
+
+module.exports = walkHtmlTokens;
Index: frontend/node_modules/webpack/lib/ids/ChunkModuleIdRangePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/ChunkModuleIdRangePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/ChunkModuleIdRangePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,96 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { find } = require("../util/SetHelpers");
+const {
+	compareModulesByPostOrderIndexOrIdentifier,
+	compareModulesByPreOrderIndexOrIdentifier
+} = require("../util/comparators");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ChunkGraph").ModuleComparator} ModuleComparator */
+
+/**
+ * Defines the chunk module id range plugin options type used by this module.
+ * @typedef {object} ChunkModuleIdRangePluginOptions
+ * @property {string} name the chunk name
+ * @property {("index" | "index2" | "preOrderIndex" | "postOrderIndex")=} order order
+ * @property {number=} start start id
+ * @property {number=} end end id
+ */
+
+const PLUGIN_NAME = "ChunkModuleIdRangePlugin";
+
+class ChunkModuleIdRangePlugin {
+	/**
+	 * Creates an instance of ChunkModuleIdRangePlugin.
+	 * @param {ChunkModuleIdRangePluginOptions} options options object
+	 */
+	constructor(options) {
+		/** @type {ChunkModuleIdRangePluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			compilation.hooks.moduleIds.tap(PLUGIN_NAME, (modules) => {
+				const chunkGraph = compilation.chunkGraph;
+				const chunk = find(
+					compilation.chunks,
+					(chunk) => chunk.name === this.options.name
+				);
+				if (!chunk) {
+					throw new Error(
+						`${PLUGIN_NAME}: Chunk with name '${this.options.name}"' was not found`
+					);
+				}
+
+				/** @type {Module[]} */
+				let chunkModules;
+				if (this.options.order) {
+					/** @type {ModuleComparator} */
+					let cmpFn;
+					switch (this.options.order) {
+						case "index":
+						case "preOrderIndex":
+							cmpFn = compareModulesByPreOrderIndexOrIdentifier(moduleGraph);
+							break;
+						case "index2":
+						case "postOrderIndex":
+							cmpFn = compareModulesByPostOrderIndexOrIdentifier(moduleGraph);
+							break;
+						default:
+							throw new Error(`${PLUGIN_NAME}: unexpected value of order`);
+					}
+					chunkModules = chunkGraph.getOrderedChunkModules(chunk, cmpFn);
+				} else {
+					chunkModules = [...modules]
+						.filter((m) => chunkGraph.isModuleInChunk(m, chunk))
+						.sort(compareModulesByPreOrderIndexOrIdentifier(moduleGraph));
+				}
+
+				let currentId = this.options.start || 0;
+				for (let i = 0; i < chunkModules.length; i++) {
+					const m = chunkModules[i];
+					if (m.needId && chunkGraph.getModuleId(m) === null) {
+						chunkGraph.setModuleId(m, currentId++);
+					}
+					if (this.options.end && currentId > this.options.end) break;
+				}
+			});
+		});
+	}
+}
+
+module.exports = ChunkModuleIdRangePlugin;
Index: frontend/node_modules/webpack/lib/ids/DeterministicChunkIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/DeterministicChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/DeterministicChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const { compareChunksNatural } = require("../util/comparators");
+const {
+	assignDeterministicIds,
+	getFullChunkName,
+	getUsedChunkIds
+} = require("./IdHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the deterministic chunk ids plugin options type used by this module.
+ * @typedef {object} DeterministicChunkIdsPluginOptions
+ * @property {string=} context context for ids
+ * @property {number=} maxLength maximum length of ids
+ */
+
+const PLUGIN_NAME = "DeterministicChunkIdsPlugin";
+
+class DeterministicChunkIdsPlugin {
+	/**
+	 * Creates an instance of DeterministicChunkIdsPlugin.
+	 * @param {DeterministicChunkIdsPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {DeterministicChunkIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.chunkIds.tap(PLUGIN_NAME, (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+				const context = this.options.context
+					? this.options.context
+					: compiler.context;
+				const maxLength = this.options.maxLength || 3;
+
+				const compareNatural = compareChunksNatural(chunkGraph);
+
+				const usedIds = getUsedChunkIds(compilation);
+				assignDeterministicIds(
+					[...chunks].filter((chunk) => chunk.id === null),
+					(chunk) =>
+						getFullChunkName(chunk, chunkGraph, context, compiler.root),
+					compareNatural,
+					(chunk, id) => {
+						const size = usedIds.size;
+						usedIds.add(`${id}`);
+						if (size === usedIds.size) return false;
+						chunk.id = id;
+						chunk.ids = [id];
+						return true;
+					},
+					[10 ** maxLength],
+					10,
+					usedIds.size
+				);
+			});
+		});
+	}
+}
+
+module.exports = DeterministicChunkIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/DeterministicModuleIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/DeterministicModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/DeterministicModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const {
+	compareModulesByPreOrderIndexOrIdentifier
+} = require("../util/comparators");
+const {
+	assignDeterministicIds,
+	getFullModuleName,
+	getUsedModuleIdsAndModules
+} = require("./IdHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+/**
+ * Defines the deterministic module ids plugin options type used by this module.
+ * @typedef {object} DeterministicModuleIdsPluginOptions
+ * @property {string=} context context relative to which module identifiers are computed
+ * @property {((module: Module) => boolean)=} test selector function for modules
+ * @property {number=} maxLength maximum id length in digits (used as starting point)
+ * @property {number=} salt hash salt for ids
+ * @property {boolean=} fixedLength do not increase the maxLength to find an optimal id space size
+ * @property {boolean=} failOnConflict throw an error when id conflicts occur (instead of rehashing)
+ */
+
+const PLUGIN_NAME = "DeterministicModuleIdsPlugin";
+
+class DeterministicModuleIdsPlugin {
+	/**
+	 * Creates an instance of DeterministicModuleIdsPlugin.
+	 * @param {DeterministicModuleIdsPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {DeterministicModuleIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
+				const chunkGraph = compilation.chunkGraph;
+				const context = this.options.context
+					? this.options.context
+					: compiler.context;
+				const maxLength = this.options.maxLength || 3;
+				const failOnConflict = this.options.failOnConflict || false;
+				const fixedLength = this.options.fixedLength || false;
+				const salt = this.options.salt || 0;
+				let conflicts = 0;
+
+				const [usedIds, modules] = getUsedModuleIdsAndModules(
+					compilation,
+					this.options.test
+				);
+				assignDeterministicIds(
+					modules,
+					(module) => getFullModuleName(module, context, compiler.root),
+					failOnConflict
+						? () => 0
+						: compareModulesByPreOrderIndexOrIdentifier(
+								compilation.moduleGraph
+							),
+					(module, id) => {
+						const size = usedIds.size;
+						usedIds.add(`${id}`);
+						if (size === usedIds.size) {
+							conflicts++;
+							return false;
+						}
+						chunkGraph.setModuleId(module, id);
+						return true;
+					},
+					[10 ** maxLength],
+					fixedLength ? 0 : 10,
+					usedIds.size,
+					salt
+				);
+				if (failOnConflict && conflicts) {
+					throw new Error(
+						`Assigning deterministic module ids has lead to ${conflicts} conflict${
+							conflicts > 1 ? "s" : ""
+						}.\nIncrease the 'maxLength' to increase the id space and make conflicts less likely (recommended when there are many conflicts or application is expected to grow), or add an 'salt' number to try another hash starting value in the same id space (recommended when there is only a single conflict).`
+					);
+				}
+			});
+		});
+	}
+}
+
+module.exports = DeterministicModuleIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/HashedModuleIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/HashedModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/HashedModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,84 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { DEFAULTS } = require("../config/defaults");
+const {
+	compareModulesByPreOrderIndexOrIdentifier
+} = require("../util/comparators");
+const createHash = require("../util/createHash");
+const {
+	getFullModuleName,
+	getUsedModuleIdsAndModules
+} = require("./IdHelpers");
+
+/** @typedef {import("../../declarations/plugins/ids/HashedModuleIdsPlugin").HashedModuleIdsPluginOptions} HashedModuleIdsPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "HashedModuleIdsPlugin";
+
+class HashedModuleIdsPlugin {
+	/**
+	 * Creates an instance of HashedModuleIdsPlugin.
+	 * @param {HashedModuleIdsPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {HashedModuleIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/ids/HashedModuleIdsPlugin.json"),
+				this.options,
+				{
+					name: "Hashed Module Ids Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/ids/HashedModuleIdsPlugin.check")(
+						options
+					)
+			);
+		});
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
+				const chunkGraph = compilation.chunkGraph;
+				const context = this.options.context
+					? this.options.context
+					: compiler.context;
+
+				const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
+				const modulesInNaturalOrder = modules.sort(
+					compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
+				);
+				for (const module of modulesInNaturalOrder) {
+					const ident = getFullModuleName(module, context, compiler.root);
+					const hash = createHash(
+						this.options.hashFunction || DEFAULTS.HASH_FUNCTION
+					);
+					hash.update(ident || "");
+					const hashId = hash.digest(this.options.hashDigest || "base64");
+					let len = this.options.hashDigestLength || 4;
+					while (usedIds.has(hashId.slice(0, len))) {
+						/** @type {number} */ (len)++;
+					}
+					const moduleId = hashId.slice(0, len);
+					chunkGraph.setModuleId(module, moduleId);
+					usedIds.add(moduleId);
+				}
+			});
+		});
+	}
+}
+
+module.exports = HashedModuleIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/IdHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/IdHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/IdHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,513 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const createHash = require("../util/createHash");
+const { makePathsRelative } = require("../util/identifier");
+const numberHash = require("../util/numberHash");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+/** @typedef {import("../util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+
+/**
+ * Returns hash.
+ * @param {string} str string to hash
+ * @param {number} len max length of the hash
+ * @param {HashFunction} hashFunction hash function to use
+ * @returns {string} hash
+ */
+const getHash = (str, len, hashFunction) => {
+	const hash = createHash(hashFunction);
+	hash.update(str);
+	const digest = hash.digest("hex");
+	return digest.slice(0, len);
+};
+
+/**
+ * Returns string prefixed by an underscore if it is a number.
+ * @param {string} str the string
+ * @returns {string} string prefixed by an underscore if it is a number
+ */
+const avoidNumber = (str) => {
+	// max length of a number is 21 chars, bigger numbers a written as "...e+xx"
+	if (str.length > 21) return str;
+	const firstChar = str.charCodeAt(0);
+	// skip everything that doesn't look like a number
+	// charCodes: "-": 45, "1": 49, "9": 57
+	if (firstChar < 49) {
+		if (firstChar !== 45) return str;
+	} else if (firstChar > 57) {
+		return str;
+	}
+	if (str === String(Number(str))) {
+		return `_${str}`;
+	}
+	return str;
+};
+
+/**
+ * Returns id representation.
+ * @param {string} request the request
+ * @returns {string} id representation
+ */
+const requestToId = (request) =>
+	request.replace(/^(\.\.?\/)+/, "").replace(/(^[.-]|[^a-z0-9_-])+/gi, "_");
+
+/**
+ * Shorten long string.
+ * @param {string} string the string
+ * @param {string} delimiter separator for string and hash
+ * @param {HashFunction} hashFunction hash function to use
+ * @returns {string} string with limited max length to 100 chars
+ */
+const shortenLongString = (string, delimiter, hashFunction) => {
+	if (string.length < 100) return string;
+	return (
+		string.slice(0, 100 - 6 - delimiter.length) +
+		delimiter +
+		getHash(string, 6, hashFunction)
+	);
+};
+
+/**
+ * Gets short module name.
+ * @param {Module} module the module
+ * @param {string} context context directory
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} short module name
+ */
+const getShortModuleName = (module, context, associatedObjectForCache) => {
+	const libIdent = module.libIdent({ context, associatedObjectForCache });
+	if (libIdent) return avoidNumber(libIdent);
+	const nameForCondition = module.nameForCondition();
+	if (nameForCondition) {
+		return avoidNumber(
+			makePathsRelative(context, nameForCondition, associatedObjectForCache)
+		);
+	}
+	return "";
+};
+
+/**
+ * Gets long module name.
+ * @param {string} shortName the short name
+ * @param {Module} module the module
+ * @param {string} context context directory
+ * @param {HashFunction} hashFunction hash function to use
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} long module name
+ */
+const getLongModuleName = (
+	shortName,
+	module,
+	context,
+	hashFunction,
+	associatedObjectForCache
+) => {
+	const fullName = getFullModuleName(module, context, associatedObjectForCache);
+	return `${shortName}?${getHash(fullName, 4, hashFunction)}`;
+};
+
+/**
+ * Gets full module name.
+ * @param {Module} module the module
+ * @param {string} context context directory
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} full module name
+ */
+const getFullModuleName = (module, context, associatedObjectForCache) =>
+	makePathsRelative(context, module.identifier(), associatedObjectForCache);
+
+/**
+ * Gets short chunk name.
+ * @param {Chunk} chunk the chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {string} context context directory
+ * @param {string} delimiter delimiter for names
+ * @param {HashFunction} hashFunction hash function to use
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} short chunk name
+ */
+const getShortChunkName = (
+	chunk,
+	chunkGraph,
+	context,
+	delimiter,
+	hashFunction,
+	associatedObjectForCache
+) => {
+	const modules = chunkGraph.getChunkRootModules(chunk);
+	const shortModuleNames = modules.map((m) =>
+		requestToId(getShortModuleName(m, context, associatedObjectForCache))
+	);
+	chunk.idNameHints.sort();
+	const chunkName = [...chunk.idNameHints, ...shortModuleNames]
+		.filter(Boolean)
+		.join(delimiter);
+	return shortenLongString(chunkName, delimiter, hashFunction);
+};
+
+/**
+ * Gets long chunk name.
+ * @param {Chunk} chunk the chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {string} context context directory
+ * @param {string} delimiter delimiter for names
+ * @param {HashFunction} hashFunction hash function to use
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} short chunk name
+ */
+const getLongChunkName = (
+	chunk,
+	chunkGraph,
+	context,
+	delimiter,
+	hashFunction,
+	associatedObjectForCache
+) => {
+	const modules = chunkGraph.getChunkRootModules(chunk);
+	const shortModuleNames = modules.map((m) =>
+		requestToId(getShortModuleName(m, context, associatedObjectForCache))
+	);
+	const longModuleNames = modules.map((m) =>
+		requestToId(
+			getLongModuleName("", m, context, hashFunction, associatedObjectForCache)
+		)
+	);
+	chunk.idNameHints.sort();
+	const chunkName = [
+		...chunk.idNameHints,
+		...shortModuleNames,
+		...longModuleNames
+	]
+		.filter(Boolean)
+		.join(delimiter);
+	return shortenLongString(chunkName, delimiter, hashFunction);
+};
+
+/**
+ * Gets full chunk name.
+ * @param {Chunk} chunk the chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {string} context context directory
+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached
+ * @returns {string} full chunk name
+ */
+const getFullChunkName = (
+	chunk,
+	chunkGraph,
+	context,
+	associatedObjectForCache
+) => {
+	if (chunk.name) return chunk.name;
+	const modules = chunkGraph.getChunkRootModules(chunk);
+	const fullModuleNames = modules.map((m) =>
+		makePathsRelative(context, m.identifier(), associatedObjectForCache)
+	);
+	return fullModuleNames.join();
+};
+
+/**
+ * Adds to map of items.
+ * @template K
+ * @template V
+ * @param {Map<K, V[]>} map a map from key to values
+ * @param {K} key key
+ * @param {V} value value
+ * @returns {void}
+ */
+const addToMapOfItems = (map, key, value) => {
+	let array = map.get(key);
+	if (array === undefined) {
+		array = [];
+		map.set(key, array);
+	}
+	array.push(value);
+};
+
+/** @typedef {Set<string>} UsedModuleIds */
+
+/**
+ * Gets used module ids and modules.
+ * @param {Compilation} compilation the compilation
+ * @param {((module: Module) => boolean)=} filter filter modules
+ * @returns {[UsedModuleIds, Module[]]} used module ids as strings and modules without id matching the filter
+ */
+const getUsedModuleIdsAndModules = (compilation, filter) => {
+	const chunkGraph = compilation.chunkGraph;
+	/** @type {Module[]} */
+	const modules = [];
+
+	/** @type {UsedModuleIds} */
+	const usedIds = new Set();
+	if (compilation.usedModuleIds) {
+		for (const id of compilation.usedModuleIds) {
+			usedIds.add(String(id));
+		}
+	}
+
+	for (const module of compilation.modules) {
+		if (!module.needId) continue;
+		const moduleId = chunkGraph.getModuleId(module);
+		if (moduleId !== null) {
+			usedIds.add(String(moduleId));
+		} else if (
+			(!filter || filter(module)) &&
+			(chunkGraph.getNumberOfModuleChunks(module) !== 0 ||
+				// CSS modules need IDs even when not in chunks, for generating CSS class names(i.e. [id]-[local])
+				/** @type {BuildMeta} */ (module.buildMeta).isCssModule ||
+				/** @type {BuildMeta} */ (module.buildMeta).needIdInConcatenation)
+		) {
+			modules.push(module);
+		}
+	}
+
+	return [usedIds, modules];
+};
+
+/** @typedef {Set<string>} UsedChunkIds */
+
+/**
+ * Gets used chunk ids.
+ * @param {Compilation} compilation the compilation
+ * @returns {UsedChunkIds} used chunk ids as strings
+ */
+const getUsedChunkIds = (compilation) => {
+	/** @type {UsedChunkIds} */
+	const usedIds = new Set();
+	if (compilation.usedChunkIds) {
+		for (const id of compilation.usedChunkIds) {
+			usedIds.add(String(id));
+		}
+	}
+
+	for (const chunk of compilation.chunks) {
+		const chunkId = chunk.id;
+		if (chunkId !== null) {
+			usedIds.add(String(chunkId));
+		}
+	}
+
+	return usedIds;
+};
+
+/**
+ * Returns list of items without a name.
+ * @template T
+ * @param {Iterable<T>} items list of items to be named
+ * @param {(item: T) => string} getShortName get a short name for an item
+ * @param {(item: T, name: string) => string} getLongName get a long name for an item
+ * @param {(a: T, b: T) => -1 | 0 | 1} comparator order of items
+ * @param {Set<string>} usedIds already used ids, will not be assigned
+ * @param {(item: T, name: string) => void} assignName assign a name to an item
+ * @returns {T[]} list of items without a name
+ */
+const assignNames = (
+	items,
+	getShortName,
+	getLongName,
+	comparator,
+	usedIds,
+	assignName
+) => {
+	/**
+	 * Defines the map to item type used by this module.
+	 * @template T
+	 * @typedef {Map<string, T[]>} MapToItem
+	 */
+
+	/** @type {MapToItem<T>} */
+	const nameToItems = new Map();
+
+	for (const item of items) {
+		const name = getShortName(item);
+		addToMapOfItems(nameToItems, name, item);
+	}
+
+	/** @type {MapToItem<T>} */
+	const nameToItems2 = new Map();
+
+	for (const [name, items] of nameToItems) {
+		if (items.length > 1 || !name) {
+			for (const item of items) {
+				const longName = getLongName(item, name);
+				addToMapOfItems(nameToItems2, longName, item);
+			}
+		} else {
+			addToMapOfItems(nameToItems2, name, items[0]);
+		}
+	}
+
+	/** @type {T[]} */
+	const unnamedItems = [];
+
+	for (const [name, items] of nameToItems2) {
+		if (!name) {
+			for (const item of items) {
+				unnamedItems.push(item);
+			}
+		} else if (items.length === 1 && !usedIds.has(name)) {
+			assignName(items[0], name);
+			usedIds.add(name);
+		} else {
+			items.sort(comparator);
+			let i = 0;
+			for (const item of items) {
+				while (nameToItems2.has(name + i) && usedIds.has(name + i)) i++;
+				assignName(item, name + i);
+				usedIds.add(name + i);
+				i++;
+			}
+		}
+	}
+
+	unnamedItems.sort(comparator);
+	return unnamedItems;
+};
+
+/**
+ * Assign deterministic ids.
+ * @template T
+ * @param {T[]} items list of items to be named
+ * @param {(item: T) => string} getName get a name for an item
+ * @param {(a: T, n: T) => -1 | 0 | 1} comparator order of items
+ * @param {(item: T, id: number) => boolean} assignId assign an id to an item
+ * @param {number[]} ranges usable ranges for ids
+ * @param {number} expandFactor factor to create more ranges
+ * @param {number} extraSpace extra space to allocate, i. e. when some ids are already used
+ * @param {number} salt salting number to initialize hashing
+ * @returns {void}
+ */
+const assignDeterministicIds = (
+	items,
+	getName,
+	comparator,
+	assignId,
+	ranges = [10],
+	expandFactor = 10,
+	extraSpace = 0,
+	salt = 0
+) => {
+	items.sort(comparator);
+
+	// max 5% fill rate
+	const optimalRange = Math.min(
+		items.length * 20 + extraSpace,
+		Number.MAX_SAFE_INTEGER
+	);
+
+	let i = 0;
+	let range = ranges[i];
+	while (range < optimalRange) {
+		i++;
+		if (i < ranges.length) {
+			range = Math.min(ranges[i], Number.MAX_SAFE_INTEGER);
+		} else if (expandFactor) {
+			range = Math.min(range * expandFactor, Number.MAX_SAFE_INTEGER);
+		} else {
+			break;
+		}
+	}
+
+	for (const item of items) {
+		const ident = getName(item);
+		/** @type {number} */
+		let id;
+		let i = salt;
+		do {
+			id = numberHash(ident + i++, range);
+		} while (!assignId(item, id));
+	}
+};
+
+/**
+ * Assign ascending module ids.
+ * @param {UsedModuleIds} usedIds used ids
+ * @param {Iterable<Module>} modules the modules
+ * @param {Compilation} compilation the compilation
+ * @returns {void}
+ */
+const assignAscendingModuleIds = (usedIds, modules, compilation) => {
+	const chunkGraph = compilation.chunkGraph;
+
+	let nextId = 0;
+	/** @type {(mod: Module) => void} */
+	let assignId;
+	if (usedIds.size > 0) {
+		/**
+		 * Processes the provided module.
+		 * @param {Module} module the module
+		 */
+		assignId = (module) => {
+			if (chunkGraph.getModuleId(module) === null) {
+				while (usedIds.has(String(nextId))) nextId++;
+				chunkGraph.setModuleId(module, nextId++);
+			}
+		};
+	} else {
+		/**
+		 * Processes the provided module.
+		 * @param {Module} module the module
+		 */
+		assignId = (module) => {
+			if (chunkGraph.getModuleId(module) === null) {
+				chunkGraph.setModuleId(module, nextId++);
+			}
+		};
+	}
+	for (const module of modules) {
+		assignId(module);
+	}
+};
+
+/**
+ * Assign ascending chunk ids.
+ * @param {Iterable<Chunk>} chunks the chunks
+ * @param {Compilation} compilation the compilation
+ * @returns {void}
+ */
+const assignAscendingChunkIds = (chunks, compilation) => {
+	const usedIds = getUsedChunkIds(compilation);
+
+	let nextId = 0;
+	if (usedIds.size > 0) {
+		for (const chunk of chunks) {
+			if (chunk.id === null) {
+				while (usedIds.has(String(nextId))) nextId++;
+				chunk.id = nextId;
+				chunk.ids = [nextId];
+				nextId++;
+			}
+		}
+	} else {
+		for (const chunk of chunks) {
+			if (chunk.id === null) {
+				chunk.id = nextId;
+				chunk.ids = [nextId];
+				nextId++;
+			}
+		}
+	}
+};
+
+module.exports.assignAscendingChunkIds = assignAscendingChunkIds;
+module.exports.assignAscendingModuleIds = assignAscendingModuleIds;
+module.exports.assignDeterministicIds = assignDeterministicIds;
+module.exports.assignNames = assignNames;
+module.exports.getFullChunkName = getFullChunkName;
+module.exports.getFullModuleName = getFullModuleName;
+module.exports.getLongChunkName = getLongChunkName;
+module.exports.getLongModuleName = getLongModuleName;
+module.exports.getShortChunkName = getShortChunkName;
+module.exports.getShortModuleName = getShortModuleName;
+module.exports.getUsedChunkIds = getUsedChunkIds;
+module.exports.getUsedModuleIdsAndModules = getUsedModuleIdsAndModules;
+module.exports.requestToId = requestToId;
Index: frontend/node_modules/webpack/lib/ids/NamedChunkIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/NamedChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/NamedChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,94 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { compareChunksNatural } = require("../util/comparators");
+const {
+	assignAscendingChunkIds,
+	assignNames,
+	getLongChunkName,
+	getShortChunkName,
+	getUsedChunkIds
+} = require("./IdHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the named chunk ids plugin options type used by this module.
+ * @typedef {object} NamedChunkIdsPluginOptions
+ * @property {string=} context context
+ * @property {string=} delimiter delimiter
+ */
+
+const PLUGIN_NAME = "NamedChunkIdsPlugin";
+
+class NamedChunkIdsPlugin {
+	/**
+	 * Creates an instance of NamedChunkIdsPlugin.
+	 * @param {NamedChunkIdsPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {NamedChunkIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const hashFunction = compilation.outputOptions.hashFunction;
+			compilation.hooks.chunkIds.tap(PLUGIN_NAME, (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+				const context = this.options.context
+					? this.options.context
+					: compiler.context;
+				const delimiter = this.options.delimiter || "-";
+
+				const unnamedChunks = assignNames(
+					[...chunks].filter((chunk) => {
+						if (chunk.name) {
+							chunk.id = chunk.name;
+							chunk.ids = [chunk.name];
+						}
+						return chunk.id === null;
+					}),
+					(chunk) =>
+						getShortChunkName(
+							chunk,
+							chunkGraph,
+							context,
+							delimiter,
+							hashFunction,
+							compiler.root
+						),
+					(chunk) =>
+						getLongChunkName(
+							chunk,
+							chunkGraph,
+							context,
+							delimiter,
+							hashFunction,
+							compiler.root
+						),
+					compareChunksNatural(chunkGraph),
+					getUsedChunkIds(compilation),
+					(chunk, name) => {
+						chunk.id = name;
+						chunk.ids = [name];
+					}
+				);
+				if (unnamedChunks.length > 0) {
+					assignAscendingChunkIds(unnamedChunks, compilation);
+				}
+			});
+		});
+	}
+}
+
+module.exports = NamedChunkIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/NamedModuleIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/NamedModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/NamedModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { compareModulesByIdentifier } = require("../util/comparators");
+const {
+	assignAscendingModuleIds,
+	assignNames,
+	getLongModuleName,
+	getShortModuleName,
+	getUsedModuleIdsAndModules
+} = require("./IdHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the named module ids plugin options type used by this module.
+ * @typedef {object} NamedModuleIdsPluginOptions
+ * @property {string=} context context
+ */
+
+const PLUGIN_NAME = "NamedModuleIdsPlugin";
+
+class NamedModuleIdsPlugin {
+	/**
+	 * Creates an instance of NamedModuleIdsPlugin.
+	 * @param {NamedModuleIdsPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {NamedModuleIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { root } = compiler;
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const hashFunction = compilation.outputOptions.hashFunction;
+			compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
+				const chunkGraph = compilation.chunkGraph;
+				const context = this.options.context
+					? this.options.context
+					: compiler.context;
+
+				const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
+				const unnamedModules = assignNames(
+					modules,
+					(m) => getShortModuleName(m, context, root),
+					(m, shortName) =>
+						getLongModuleName(shortName, m, context, hashFunction, root),
+					compareModulesByIdentifier,
+					usedIds,
+					(m, name) => chunkGraph.setModuleId(m, name)
+				);
+				if (unnamedModules.length > 0) {
+					assignAscendingModuleIds(usedIds, unnamedModules, compilation);
+				}
+			});
+		});
+	}
+}
+
+module.exports = NamedModuleIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/NaturalChunkIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/NaturalChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/NaturalChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { compareChunksNatural } = require("../util/comparators");
+const { assignAscendingChunkIds } = require("./IdHelpers");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "NaturalChunkIdsPlugin";
+
+class NaturalChunkIdsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.chunkIds.tap(PLUGIN_NAME, (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+				const compareNatural = compareChunksNatural(chunkGraph);
+				/** @type {Chunk[]} */
+				const chunksInNaturalOrder = [...chunks].sort(compareNatural);
+				assignAscendingChunkIds(chunksInNaturalOrder, compilation);
+			});
+		});
+	}
+}
+
+module.exports = NaturalChunkIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/NaturalModuleIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/NaturalModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/NaturalModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Florent Cailhol @ooflorent
+*/
+
+"use strict";
+
+const {
+	compareModulesByPreOrderIndexOrIdentifier
+} = require("../util/comparators");
+const {
+	assignAscendingModuleIds,
+	getUsedModuleIdsAndModules
+} = require("./IdHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "NaturalModuleIdsPlugin";
+
+class NaturalModuleIdsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
+				const [usedIds, modulesInNaturalOrder] =
+					getUsedModuleIdsAndModules(compilation);
+				modulesInNaturalOrder.sort(
+					compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
+				);
+				assignAscendingModuleIds(usedIds, modulesInNaturalOrder, compilation);
+			});
+		});
+	}
+}
+
+module.exports = NaturalModuleIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/OccurrenceChunkIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/OccurrenceChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/OccurrenceChunkIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { compareChunksNatural } = require("../util/comparators");
+const { assignAscendingChunkIds } = require("./IdHelpers");
+
+/** @typedef {import("../../declarations/plugins/ids/OccurrenceChunkIdsPlugin").OccurrenceChunkIdsPluginOptions} OccurrenceChunkIdsPluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "OccurrenceChunkIdsPlugin";
+
+class OccurrenceChunkIdsPlugin {
+	/**
+	 * Creates an instance of OccurrenceChunkIdsPlugin.
+	 * @param {OccurrenceChunkIdsPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {OccurrenceChunkIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.json"),
+				this.options,
+				{
+					name: "Occurrence Order Chunk Ids Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.check")(
+						options
+					)
+			);
+		});
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.chunkIds.tap(PLUGIN_NAME, (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+
+				/** @type {Map<Chunk, number>} */
+				const occursInInitialChunksMap = new Map();
+
+				const compareNatural = compareChunksNatural(chunkGraph);
+
+				for (const c of chunks) {
+					let occurs = 0;
+					for (const chunkGroup of c.groupsIterable) {
+						for (const parent of chunkGroup.parentsIterable) {
+							if (parent.isInitial()) occurs++;
+						}
+					}
+					occursInInitialChunksMap.set(c, occurs);
+				}
+
+				/** @type {Chunk[]} */
+				const chunksInOccurrenceOrder = [...chunks].sort((a, b) => {
+					if (this.options.prioritiseInitial) {
+						const aEntryOccurs =
+							/** @type {number} */
+							(occursInInitialChunksMap.get(a));
+						const bEntryOccurs =
+							/** @type {number} */
+							(occursInInitialChunksMap.get(b));
+						if (aEntryOccurs > bEntryOccurs) return -1;
+						if (aEntryOccurs < bEntryOccurs) return 1;
+					}
+					const aOccurs = a.getNumberOfGroups();
+					const bOccurs = b.getNumberOfGroups();
+					if (aOccurs > bOccurs) return -1;
+					if (aOccurs < bOccurs) return 1;
+					return compareNatural(a, b);
+				});
+				assignAscendingChunkIds(chunksInOccurrenceOrder, compilation);
+			});
+		});
+	}
+}
+
+module.exports = OccurrenceChunkIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/OccurrenceModuleIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/OccurrenceModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/OccurrenceModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,175 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+	compareModulesByPreOrderIndexOrIdentifier
+} = require("../util/comparators");
+const {
+	assignAscendingModuleIds,
+	getUsedModuleIdsAndModules
+} = require("./IdHelpers");
+
+/** @typedef {import("../../declarations/plugins/ids/OccurrenceModuleIdsPlugin").OccurrenceModuleIdsPluginOptions} OccurrenceModuleIdsPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+const PLUGIN_NAME = "OccurrenceModuleIdsPlugin";
+
+class OccurrenceModuleIdsPlugin {
+	/**
+	 * Creates an instance of OccurrenceModuleIdsPlugin.
+	 * @param {OccurrenceModuleIdsPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {OccurrenceModuleIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/ids/OccurrenceModuleIdsPlugin.json"),
+				this.options,
+				{
+					name: "Occurrence Order Module Ids Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/ids/OccurrenceModuleIdsPlugin.check")(
+						options
+					)
+			);
+		});
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+
+			compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
+				const chunkGraph = compilation.chunkGraph;
+
+				const [usedIds, modulesInOccurrenceOrder] =
+					getUsedModuleIdsAndModules(compilation);
+
+				/** @type {Map<Module, number>} */
+				const occursInInitialChunksMap = new Map();
+				/** @type {Map<Module, number>} */
+				const occursInAllChunksMap = new Map();
+
+				/** @type {Map<Module, number>} */
+				const initialChunkChunkMap = new Map();
+				/** @type {Map<Module, number>} */
+				const entryCountMap = new Map();
+				for (const m of modulesInOccurrenceOrder) {
+					let initial = 0;
+					let entry = 0;
+					for (const c of chunkGraph.getModuleChunksIterable(m)) {
+						if (c.canBeInitial()) initial++;
+						if (chunkGraph.isEntryModuleInChunk(m, c)) entry++;
+					}
+					initialChunkChunkMap.set(m, initial);
+					entryCountMap.set(m, entry);
+				}
+
+				/**
+				 * Count occurs in entry.
+				 * @param {Module} module module
+				 * @returns {number} count of occurs
+				 */
+				const countOccursInEntry = (module) => {
+					let sum = 0;
+					for (const [
+						originModule,
+						connections
+					] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
+						if (!originModule) continue;
+						if (!connections.some((c) => c.isTargetActive(undefined))) continue;
+						sum += initialChunkChunkMap.get(originModule) || 0;
+					}
+					return sum;
+				};
+
+				/**
+				 * Returns count of occurs.
+				 * @param {Module} module module
+				 * @returns {number} count of occurs
+				 */
+				const countOccurs = (module) => {
+					let sum = 0;
+					for (const [
+						originModule,
+						connections
+					] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
+						if (!originModule) continue;
+						const chunkModules =
+							chunkGraph.getNumberOfModuleChunks(originModule);
+						for (const c of connections) {
+							if (!c.isTargetActive(undefined)) continue;
+							if (!c.dependency) continue;
+							const factor = c.dependency.getNumberOfIdOccurrences();
+							if (factor === 0) continue;
+							sum += factor * chunkModules;
+						}
+					}
+					return sum;
+				};
+
+				if (this.options.prioritiseInitial) {
+					for (const m of modulesInOccurrenceOrder) {
+						const result =
+							countOccursInEntry(m) +
+							/** @type {number} */ (initialChunkChunkMap.get(m)) +
+							/** @type {number} */ (entryCountMap.get(m));
+						occursInInitialChunksMap.set(m, result);
+					}
+				}
+
+				for (const m of modulesInOccurrenceOrder) {
+					const result =
+						countOccurs(m) +
+						chunkGraph.getNumberOfModuleChunks(m) +
+						/** @type {number} */ (entryCountMap.get(m));
+					occursInAllChunksMap.set(m, result);
+				}
+
+				const naturalCompare = compareModulesByPreOrderIndexOrIdentifier(
+					compilation.moduleGraph
+				);
+
+				modulesInOccurrenceOrder.sort((a, b) => {
+					if (this.options.prioritiseInitial) {
+						const aEntryOccurs =
+							/** @type {number} */
+							(occursInInitialChunksMap.get(a));
+						const bEntryOccurs =
+							/** @type {number} */
+							(occursInInitialChunksMap.get(b));
+						if (aEntryOccurs > bEntryOccurs) return -1;
+						if (aEntryOccurs < bEntryOccurs) return 1;
+					}
+					const aOccurs = /** @type {number} */ (occursInAllChunksMap.get(a));
+					const bOccurs = /** @type {number} */ (occursInAllChunksMap.get(b));
+					if (aOccurs > bOccurs) return -1;
+					if (aOccurs < bOccurs) return 1;
+					return naturalCompare(a, b);
+				});
+
+				assignAscendingModuleIds(
+					usedIds,
+					modulesInOccurrenceOrder,
+					compilation
+				);
+			});
+		});
+	}
+}
+
+module.exports = OccurrenceModuleIdsPlugin;
Index: frontend/node_modules/webpack/lib/ids/SyncModuleIdsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/ids/SyncModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/ids/SyncModuleIdsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,163 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { WebpackError } = require("..");
+const { getUsedModuleIdsAndModules } = require("./IdHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").ModuleId} ModuleId */
+/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
+
+/** @typedef {{ [key: string]: ModuleId }} JSONContent */
+
+const plugin = "SyncModuleIdsPlugin";
+
+/**
+ * Represents the sync module ids plugin runtime component.
+ * @typedef {object} SyncModuleIdsPluginOptions
+ * @property {string} path path to file
+ * @property {string=} context context for module names
+ * @property {((module: Module) => boolean)=} test selector for modules
+ * @property {"read" | "create" | "merge" | "update"=} mode operation mode (defaults to merge)
+ */
+
+class SyncModuleIdsPlugin {
+	/**
+	 * Creates an instance of SyncModuleIdsPlugin.
+	 * @param {SyncModuleIdsPluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {SyncModuleIdsPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		/** @type {Map<string, ModuleId>} */
+		let data;
+		let dataChanged = false;
+
+		const readAndWrite =
+			!this.options.mode ||
+			this.options.mode === "merge" ||
+			this.options.mode === "update";
+
+		const needRead = readAndWrite || this.options.mode === "read";
+		const needWrite = readAndWrite || this.options.mode === "create";
+		const needPrune = this.options.mode === "update";
+
+		if (needRead) {
+			compiler.hooks.readRecords.tapAsync(plugin, (callback) => {
+				const fs =
+					/** @type {IntermediateFileSystem} */
+					(compiler.intermediateFileSystem);
+				fs.readFile(this.options.path, (err, buffer) => {
+					if (err) {
+						if (err.code !== "ENOENT") {
+							return callback(err);
+						}
+						return callback();
+					}
+					/** @type {JSONContent} */
+					const json = JSON.parse(/** @type {Buffer} */ (buffer).toString());
+					/** @type {Map<string, string | number | null>} */
+					data = new Map();
+					for (const key of Object.keys(json)) {
+						data.set(key, json[key]);
+					}
+					dataChanged = false;
+					return callback();
+				});
+			});
+		}
+		if (needWrite) {
+			compiler.hooks.emitRecords.tapAsync(plugin, (callback) => {
+				if (!data || !dataChanged) return callback();
+				/** @type {JSONContent} */
+				const json = {};
+				const sorted = [...data].sort(([a], [b]) => (a < b ? -1 : 1));
+				for (const [key, value] of sorted) {
+					json[key] = value;
+				}
+				const fs =
+					/** @type {IntermediateFileSystem} */
+					(compiler.intermediateFileSystem);
+				fs.writeFile(this.options.path, JSON.stringify(json), callback);
+			});
+		}
+		compiler.hooks.thisCompilation.tap(plugin, (compilation) => {
+			const associatedObjectForCache = compiler.root;
+			const context = this.options.context || compiler.context;
+			const test = this.options.test || (() => true);
+			if (needRead) {
+				compilation.hooks.reviveModules.tap(plugin, (_1, _2) => {
+					if (!data) return;
+					const { chunkGraph } = compilation;
+					const [usedIds, modules] = getUsedModuleIdsAndModules(
+						compilation,
+						test
+					);
+					for (const module of modules) {
+						const name = module.libIdent({
+							context,
+							associatedObjectForCache
+						});
+						if (!name) continue;
+						const id = data.get(name);
+						const idAsString = `${id}`;
+						if (usedIds.has(idAsString)) {
+							const err = new WebpackError(
+								`SyncModuleIdsPlugin: Unable to restore id '${id}' from '${this.options.path}' as it's already used.`
+							);
+							err.module = module;
+							compilation.errors.push(err);
+						}
+						chunkGraph.setModuleId(module, /** @type {ModuleId} */ (id));
+						usedIds.add(idAsString);
+					}
+				});
+			}
+			if (needWrite) {
+				compilation.hooks.recordModules.tap(plugin, (modules) => {
+					const { chunkGraph } = compilation;
+					let oldData = data;
+					if (!oldData) {
+						oldData = data = new Map();
+					} else if (needPrune) {
+						data = new Map();
+					}
+					for (const module of modules) {
+						if (test(module)) {
+							const name = module.libIdent({
+								context,
+								associatedObjectForCache
+							});
+							if (!name) continue;
+							const id = chunkGraph.getModuleId(module);
+							if (id === null) continue;
+							const oldId = oldData.get(name);
+							if (oldId !== id) {
+								dataChanged = true;
+							} else if (data === oldData) {
+								continue;
+							}
+							data.set(name, id);
+						}
+					}
+					if (data.size !== oldData.size) dataChanged = true;
+				});
+			}
+		});
+	}
+}
+
+module.exports = SyncModuleIdsPlugin;
Index: frontend/node_modules/webpack/lib/index.js
===================================================================
--- frontend/node_modules/webpack/lib/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,707 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("../declarations/WebpackOptions").Entry} Entry */
+/** @typedef {import("../declarations/WebpackOptions").EntryNormalized} EntryNormalized */
+/** @typedef {import("../declarations/WebpackOptions").EntryObject} EntryObject */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItem} ExternalItem */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemFunction} ExternalItemFunction */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectKnown} ExternalItemObjectKnown */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectUnknown} ExternalItemObjectUnknown */
+/** @typedef {import("../declarations/WebpackOptions").ExternalItemValue} ExternalItemValue */
+/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
+/** @typedef {import("../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */
+/** @typedef {import("../declarations/WebpackOptions").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */
+/** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../declarations/WebpackOptions").MemoryCacheOptions} MemoryCacheOptions */
+/** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */
+/** @typedef {import("../declarations/WebpackOptions").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */
+/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetCondition} RuleSetCondition */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetConditionAbsolute} RuleSetConditionAbsolute */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetUse} RuleSetUse */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetUseFunction} RuleSetUseFunction */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */
+/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
+/** @typedef {import("../declarations/WebpackOptions").WebpackOptions} Configuration */
+/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */
+/** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */
+/** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */
+/** @typedef {import("./ChunkGroup")} ChunkGroup */
+/** @typedef {import("./Compiler").AssetEmittedInfo} AssetEmittedInfo */
+/** @typedef {import("./Compilation").Asset} Asset */
+/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("./Compilation").EntryOptions} EntryOptions */
+/** @typedef {import("./Compilation").PathData} PathData */
+/** @typedef {import("./Compilation").PathDataChunk} PathDataChunk */
+/** @typedef {import("./Compilation").PathDataModule} PathDataModule */
+/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("./Entrypoint")} Entrypoint */
+/** @typedef {import("./ExternalModuleFactoryPlugin").ExternalItemFunctionCallback} ExternalItemFunctionCallback */
+/** @typedef {import("./ExternalModuleFactoryPlugin").ExternalItemFunctionData} ExternalItemFunctionData */
+/** @typedef {import("./ExternalModuleFactoryPlugin").ExternalItemFunctionDataGetResolve} ExternalItemFunctionDataGetResolve */
+/** @typedef {import("./ExternalModuleFactoryPlugin").ExternalItemFunctionDataGetResolveCallbackResult} ExternalItemFunctionDataGetResolveCallbackResult */
+/** @typedef {import("./ExternalModuleFactoryPlugin").ExternalItemFunctionDataGetResolveResult} ExternalItemFunctionDataGetResolveResult */
+/** @typedef {import("./ExternalModuleFactoryPlugin").ExternalItemFunctionPromise} ExternalItemFunctionPromise */
+/** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */
+/** @typedef {import("./MultiCompiler").MultiWebpackOptions} MultiConfiguration */
+/** @typedef {import("./MultiStats")} MultiStats */
+/** @typedef {import("./MultiStats").MultiStatsOptions} MultiStatsOptions */
+/** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */
+/** @typedef {import("./Parser").ParserState} ParserState */
+/** @typedef {import("./ResolverFactory").ResolvePluginInstance} ResolvePluginInstance */
+/** @typedef {import("./ResolverFactory").Resolver} Resolver */
+/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */
+/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions */
+/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
+/** @typedef {import("./Watching")} Watching */
+/** @typedef {import("./cli").Argument} Argument */
+/** @typedef {import("./cli").Problem} Problem */
+/** @typedef {import("./cli").Colors} Colors */
+/** @typedef {import("./cli").ColorsOptions} ColorsOptions */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsChunk} StatsChunk */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsChunkGroup} StatsChunkGroup */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsChunkOrigin} StatsChunkOrigin */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsLogging} StatsLogging */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsLoggingEntry} StatsLoggingEntry */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleIssuer} StatsModuleIssuer */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleTraceDependency} StatsModuleTraceDependency */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleTraceItem} StatsModuleTraceItem */
+/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsProfile} StatsProfile */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
+
+/**
+ * Returns function.
+ * @template {EXPECTED_FUNCTION} T
+ * @param {() => T} factory factory function
+ * @returns {T} function
+ */
+const lazyFunction = (factory) => {
+	const fac = memoize(factory);
+	const f = /** @type {unknown} */ (
+		/**
+		 * Handles the callback logic for this hook.
+		 * @param {...EXPECTED_ANY} args args
+		 * @returns {T} result
+		 */
+		(...args) => fac()(...args)
+	);
+	return /** @type {T} */ (f);
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @template A
+ * @template B
+ * @param {A} obj input a
+ * @param {B} exports input b
+ * @returns {A & B} merged
+ */
+const mergeExports = (obj, exports) => {
+	const descriptors = Object.getOwnPropertyDescriptors(exports);
+	for (const name of Object.keys(descriptors)) {
+		const descriptor = descriptors[name];
+		if (descriptor.get) {
+			const fn = descriptor.get;
+			Object.defineProperty(obj, name, {
+				configurable: false,
+				enumerable: true,
+				get: memoize(fn)
+			});
+		} else if (typeof descriptor.value === "object") {
+			Object.defineProperty(obj, name, {
+				configurable: false,
+				enumerable: true,
+				writable: false,
+				value: mergeExports({}, descriptor.value)
+			});
+		} else {
+			throw new Error(
+				"Exposed values must be either a getter or an nested object"
+			);
+		}
+	}
+	return /** @type {A & B} */ (Object.freeze(obj));
+};
+
+const fn = lazyFunction(() => require("./webpack"));
+
+module.exports = mergeExports(fn, {
+	get webpack() {
+		return require("./webpack");
+	},
+	/**
+	 * Returns validate fn.
+	 * @returns {(configuration: Configuration | MultiConfiguration) => void} validate fn
+	 */
+	get validate() {
+		const webpackOptionsSchemaCheck =
+			/** @type {(configuration: Configuration | MultiConfiguration) => boolean} */
+			(require("../schemas/WebpackOptions.check"));
+
+		const getRealValidate = memoize(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @returns {(configuration: Configuration | MultiConfiguration) => void} validate fn
+			 */
+			() => {
+				const validateSchema = require("./validateSchema");
+				const webpackOptionsSchema =
+					/** @type {EXPECTED_ANY} */
+					(require("../schemas/WebpackOptions.json"));
+
+				return (options) => validateSchema(webpackOptionsSchema, options);
+			}
+		);
+		return (options) => {
+			if (!webpackOptionsSchemaCheck(options)) {
+				getRealValidate()(options);
+			}
+		};
+	},
+	get validateSchema() {
+		const validateSchema = require("./validateSchema");
+
+		return validateSchema;
+	},
+	get version() {
+		return /** @type {string} */ (require("../package.json").version);
+	},
+
+	get cli() {
+		return require("./cli");
+	},
+	get AutomaticPrefetchPlugin() {
+		return require("./AutomaticPrefetchPlugin");
+	},
+	get AsyncDependenciesBlock() {
+		return require("./AsyncDependenciesBlock");
+	},
+	get BannerPlugin() {
+		return require("./BannerPlugin");
+	},
+	get Cache() {
+		return require("./Cache");
+	},
+	get Chunk() {
+		return require("./Chunk");
+	},
+	get ChunkGraph() {
+		return require("./ChunkGraph");
+	},
+	get CleanPlugin() {
+		return require("./CleanPlugin");
+	},
+	get Compilation() {
+		return require("./Compilation");
+	},
+	get Compiler() {
+		return require("./Compiler");
+	},
+	get ConcatenationScope() {
+		return require("./ConcatenationScope");
+	},
+	get ContextExclusionPlugin() {
+		return require("./ContextExclusionPlugin");
+	},
+	get ContextReplacementPlugin() {
+		return require("./ContextReplacementPlugin");
+	},
+	get DefinePlugin() {
+		return require("./DefinePlugin");
+	},
+	get Dependency() {
+		return require("./Dependency");
+	},
+	get DynamicEntryPlugin() {
+		return require("./DynamicEntryPlugin");
+	},
+	get DotenvPlugin() {
+		return require("./DotenvPlugin");
+	},
+	get EntryOptionPlugin() {
+		return require("./EntryOptionPlugin");
+	},
+	get EntryPlugin() {
+		return require("./EntryPlugin");
+	},
+	get EnvironmentPlugin() {
+		return require("./EnvironmentPlugin");
+	},
+	get EvalDevToolModulePlugin() {
+		return require("./EvalDevToolModulePlugin");
+	},
+	get EvalSourceMapDevToolPlugin() {
+		return require("./EvalSourceMapDevToolPlugin");
+	},
+	get ExternalModule() {
+		return require("./ExternalModule");
+	},
+	get ExternalsPlugin() {
+		return require("./ExternalsPlugin");
+	},
+	get Generator() {
+		return require("./Generator");
+	},
+	get HotUpdateChunk() {
+		return require("./HotUpdateChunk");
+	},
+	get HotModuleReplacementPlugin() {
+		return require("./HotModuleReplacementPlugin");
+	},
+	get InitFragment() {
+		return require("./InitFragment");
+	},
+	get IgnorePlugin() {
+		return require("./IgnorePlugin");
+	},
+	get JavascriptModulesPlugin() {
+		return util.deprecate(
+			() => require("./javascript/JavascriptModulesPlugin"),
+			"webpack.JavascriptModulesPlugin has moved to webpack.javascript.JavascriptModulesPlugin",
+			"DEP_WEBPACK_JAVASCRIPT_MODULES_PLUGIN"
+		)();
+	},
+	get LibraryTemplatePlugin() {
+		return util.deprecate(
+			() => require("./LibraryTemplatePlugin"),
+			"webpack.LibraryTemplatePlugin is deprecated and has been replaced by compilation.outputOptions.library or compilation.addEntry + passing a library option",
+			"DEP_WEBPACK_LIBRARY_TEMPLATE_PLUGIN"
+		)();
+	},
+	get LoaderOptionsPlugin() {
+		return require("./LoaderOptionsPlugin");
+	},
+	get LoaderTargetPlugin() {
+		return require("./LoaderTargetPlugin");
+	},
+	get Module() {
+		return require("./Module");
+	},
+	get ModuleFactory() {
+		return require("./ModuleFactory");
+	},
+	get ModuleFilenameHelpers() {
+		return require("./ModuleFilenameHelpers");
+	},
+	get ModuleGraph() {
+		return require("./ModuleGraph");
+	},
+	get ModuleGraphConnection() {
+		return require("./ModuleGraphConnection");
+	},
+	get NoEmitOnErrorsPlugin() {
+		return require("./NoEmitOnErrorsPlugin");
+	},
+	get NormalModule() {
+		return require("./NormalModule");
+	},
+	get NormalModuleReplacementPlugin() {
+		return require("./NormalModuleReplacementPlugin");
+	},
+	get MultiCompiler() {
+		return require("./MultiCompiler");
+	},
+	get OptimizationStages() {
+		return require("./OptimizationStages");
+	},
+	get Parser() {
+		return require("./Parser");
+	},
+	get PlatformPlugin() {
+		return require("./PlatformPlugin");
+	},
+	get PrefetchPlugin() {
+		return require("./PrefetchPlugin");
+	},
+	get ProgressPlugin() {
+		return require("./ProgressPlugin");
+	},
+	get ProvidePlugin() {
+		return require("./ProvidePlugin");
+	},
+	get RuntimeGlobals() {
+		return require("./RuntimeGlobals");
+	},
+	get RuntimeModule() {
+		return require("./RuntimeModule");
+	},
+	get SingleEntryPlugin() {
+		return util.deprecate(
+			() => require("./EntryPlugin"),
+			"SingleEntryPlugin was renamed to EntryPlugin",
+			"DEP_WEBPACK_SINGLE_ENTRY_PLUGIN"
+		)();
+	},
+	get SourceMapDevToolPlugin() {
+		return require("./SourceMapDevToolPlugin");
+	},
+	get Stats() {
+		return require("./Stats");
+	},
+	get ManifestPlugin() {
+		return require("./ManifestPlugin");
+	},
+	get Template() {
+		return require("./Template");
+	},
+	get UsageState() {
+		return require("./ExportsInfo").UsageState;
+	},
+	get WatchIgnorePlugin() {
+		return require("./WatchIgnorePlugin");
+	},
+	get WebpackError() {
+		return require("./errors/WebpackError");
+	},
+	get WebpackOptionsApply() {
+		return require("./WebpackOptionsApply");
+	},
+	get WebpackOptionsDefaulter() {
+		return util.deprecate(
+			() => require("./WebpackOptionsDefaulter"),
+			"webpack.WebpackOptionsDefaulter is deprecated and has been replaced by webpack.config.getNormalizedWebpackOptions and webpack.config.applyWebpackOptionsDefaults",
+			"DEP_WEBPACK_OPTIONS_DEFAULTER"
+		)();
+	},
+	// TODO webpack 6 remove
+	get WebpackOptionsValidationError() {
+		return require("schema-utils").ValidationError;
+	},
+	get ValidationError() {
+		return require("schema-utils").ValidationError;
+	},
+
+	cache: {
+		get MemoryCachePlugin() {
+			return require("./cache/MemoryCachePlugin");
+		}
+	},
+
+	config: {
+		get getNormalizedWebpackOptions() {
+			return require("./config/normalization").getNormalizedWebpackOptions;
+		},
+		get applyWebpackOptionsDefaults() {
+			return require("./config/defaults").applyWebpackOptionsDefaults;
+		}
+	},
+
+	dependencies: {
+		get ModuleDependency() {
+			return require("./dependencies/ModuleDependency");
+		},
+		get HarmonyImportDependency() {
+			return require("./dependencies/HarmonyImportDependency");
+		},
+		get ConstDependency() {
+			return require("./dependencies/ConstDependency");
+		},
+		get NullDependency() {
+			return require("./dependencies/NullDependency");
+		}
+	},
+
+	ids: {
+		get ChunkModuleIdRangePlugin() {
+			return require("./ids/ChunkModuleIdRangePlugin");
+		},
+		get NaturalModuleIdsPlugin() {
+			return require("./ids/NaturalModuleIdsPlugin");
+		},
+		get OccurrenceModuleIdsPlugin() {
+			return require("./ids/OccurrenceModuleIdsPlugin");
+		},
+		get NamedModuleIdsPlugin() {
+			return require("./ids/NamedModuleIdsPlugin");
+		},
+		get DeterministicChunkIdsPlugin() {
+			return require("./ids/DeterministicChunkIdsPlugin");
+		},
+		get DeterministicModuleIdsPlugin() {
+			return require("./ids/DeterministicModuleIdsPlugin");
+		},
+		get NamedChunkIdsPlugin() {
+			return require("./ids/NamedChunkIdsPlugin");
+		},
+		get OccurrenceChunkIdsPlugin() {
+			return require("./ids/OccurrenceChunkIdsPlugin");
+		},
+		get HashedModuleIdsPlugin() {
+			return require("./ids/HashedModuleIdsPlugin");
+		}
+	},
+
+	javascript: {
+		get EnableChunkLoadingPlugin() {
+			return require("./javascript/EnableChunkLoadingPlugin");
+		},
+		get JavascriptModulesPlugin() {
+			return require("./javascript/JavascriptModulesPlugin");
+		},
+		get JavascriptParser() {
+			return require("./javascript/JavascriptParser");
+		}
+	},
+
+	optimize: {
+		get AggressiveMergingPlugin() {
+			return require("./optimize/AggressiveMergingPlugin");
+		},
+		get AggressiveSplittingPlugin() {
+			return util.deprecate(
+				() => require("./optimize/AggressiveSplittingPlugin"),
+				"AggressiveSplittingPlugin is deprecated in favor of SplitChunksPlugin",
+				"DEP_WEBPACK_AGGRESSIVE_SPLITTING_PLUGIN"
+			)();
+		},
+		get InnerGraph() {
+			return require("./optimize/InnerGraph");
+		},
+		get LimitChunkCountPlugin() {
+			return require("./optimize/LimitChunkCountPlugin");
+		},
+		get MergeDuplicateChunksPlugin() {
+			return require("./optimize/MergeDuplicateChunksPlugin");
+		},
+		get MinChunkSizePlugin() {
+			return require("./optimize/MinChunkSizePlugin");
+		},
+		get ModuleConcatenationPlugin() {
+			return require("./optimize/ModuleConcatenationPlugin");
+		},
+		get RealContentHashPlugin() {
+			return require("./optimize/RealContentHashPlugin");
+		},
+		get RuntimeChunkPlugin() {
+			return require("./optimize/RuntimeChunkPlugin");
+		},
+		get SideEffectsFlagPlugin() {
+			return require("./optimize/SideEffectsFlagPlugin");
+		},
+		get SplitChunksPlugin() {
+			return require("./optimize/SplitChunksPlugin");
+		}
+	},
+
+	runtime: {
+		get GetChunkFilenameRuntimeModule() {
+			return require("./runtime/GetChunkFilenameRuntimeModule");
+		},
+		get LoadScriptRuntimeModule() {
+			return require("./runtime/LoadScriptRuntimeModule");
+		}
+	},
+
+	prefetch: {
+		get ChunkPrefetchPreloadPlugin() {
+			return require("./prefetch/ChunkPrefetchPreloadPlugin");
+		}
+	},
+
+	web: {
+		get FetchCompileWasmPlugin() {
+			return require("./web/FetchCompileWasmPlugin");
+		},
+		get FetchCompileAsyncWasmPlugin() {
+			return require("./web/FetchCompileAsyncWasmPlugin");
+		},
+		get JsonpChunkLoadingRuntimeModule() {
+			return require("./web/JsonpChunkLoadingRuntimeModule");
+		},
+		get JsonpTemplatePlugin() {
+			return require("./web/JsonpTemplatePlugin");
+		},
+		get CssLoadingRuntimeModule() {
+			return require("./css/CssLoadingRuntimeModule");
+		}
+	},
+
+	esm: {
+		get ModuleChunkLoadingRuntimeModule() {
+			return require("./esm/ModuleChunkLoadingRuntimeModule");
+		}
+	},
+
+	webworker: {
+		get WebWorkerTemplatePlugin() {
+			return require("./webworker/WebWorkerTemplatePlugin");
+		}
+	},
+
+	node: {
+		get NodeEnvironmentPlugin() {
+			return require("./node/NodeEnvironmentPlugin");
+		},
+		get NodeSourcePlugin() {
+			return require("./node/NodeSourcePlugin");
+		},
+		get NodeTargetPlugin() {
+			return require("./node/NodeTargetPlugin");
+		},
+		get NodeTemplatePlugin() {
+			return require("./node/NodeTemplatePlugin");
+		},
+		get ReadFileCompileWasmPlugin() {
+			return require("./node/ReadFileCompileWasmPlugin");
+		},
+		get ReadFileCompileAsyncWasmPlugin() {
+			return require("./node/ReadFileCompileAsyncWasmPlugin");
+		}
+	},
+
+	electron: {
+		get ElectronTargetPlugin() {
+			return require("./electron/ElectronTargetPlugin");
+		}
+	},
+
+	wasm: {
+		get AsyncWebAssemblyModulesPlugin() {
+			return require("./wasm-async/AsyncWebAssemblyModulesPlugin");
+		},
+		get EnableWasmLoadingPlugin() {
+			return require("./wasm/EnableWasmLoadingPlugin");
+		}
+	},
+
+	css: {
+		get CssModulesPlugin() {
+			return require("./css/CssModulesPlugin");
+		}
+	},
+
+	library: {
+		get AbstractLibraryPlugin() {
+			return require("./library/AbstractLibraryPlugin");
+		},
+		get EnableLibraryPlugin() {
+			return require("./library/EnableLibraryPlugin");
+		}
+	},
+
+	// TODO remove in webpack 6 in favor of `dll` scope
+	get DelegatedPlugin() {
+		return require("./dll/DelegatedPlugin");
+	},
+	get DllPlugin() {
+		return require("./dll/DllPlugin");
+	},
+	get DllReferencePlugin() {
+		return require("./dll/DllReferencePlugin");
+	},
+	get LibManifestPlugin() {
+		return require("./dll/LibManifestPlugin");
+	},
+
+	dll: {
+		get DelegatedPlugin() {
+			return require("./dll/DelegatedPlugin");
+		},
+		get DllPlugin() {
+			return require("./dll/DllPlugin");
+		},
+		get DllReferencePlugin() {
+			return require("./dll/DllReferencePlugin");
+		},
+		get LibManifestPlugin() {
+			return require("./dll/LibManifestPlugin");
+		}
+	},
+
+	container: {
+		get ContainerPlugin() {
+			return require("./container/ContainerPlugin");
+		},
+		get ContainerReferencePlugin() {
+			return require("./container/ContainerReferencePlugin");
+		},
+		get ModuleFederationPlugin() {
+			return require("./container/ModuleFederationPlugin");
+		},
+		get scope() {
+			return require("./container/options").scope;
+		}
+	},
+
+	sharing: {
+		get ConsumeSharedPlugin() {
+			return require("./sharing/ConsumeSharedPlugin");
+		},
+		get ProvideSharedPlugin() {
+			return require("./sharing/ProvideSharedPlugin");
+		},
+		get SharePlugin() {
+			return require("./sharing/SharePlugin");
+		},
+		get scope() {
+			return require("./container/options").scope;
+		}
+	},
+
+	debug: {
+		get ProfilingPlugin() {
+			return require("./debug/ProfilingPlugin");
+		}
+	},
+
+	util: {
+		get createHash() {
+			return require("./util/createHash");
+		},
+		get comparators() {
+			return require("./util/comparators");
+		},
+		get runtime() {
+			return require("./util/runtime");
+		},
+		get serialization() {
+			return require("./util/serialization");
+		},
+		get cleverMerge() {
+			return require("./util/cleverMerge").cachedCleverMerge;
+		},
+		get LazySet() {
+			return require("./util/LazySet");
+		},
+		get compileBooleanMatcher() {
+			return require("./util/compileBooleanMatcher");
+		}
+	},
+
+	get sources() {
+		return require("webpack-sources");
+	},
+
+	experiments: {
+		schemes: {
+			get HttpUriPlugin() {
+				return require("./schemes/HttpUriPlugin");
+			},
+			get VirtualUrlPlugin() {
+				return require("./schemes/VirtualUrlPlugin");
+			}
+		},
+		ids: {
+			get SyncModuleIdsPlugin() {
+				return require("./ids/SyncModuleIdsPlugin");
+			}
+		}
+	}
+});
Index: frontend/node_modules/webpack/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,150 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, PrefixSource, RawSource } = require("webpack-sources");
+const { RuntimeGlobals } = require("..");
+const HotUpdateChunk = require("../HotUpdateChunk");
+const Template = require("../Template");
+const { getCompilationHooks } = require("./JavascriptModulesPlugin");
+const {
+	generateEntryStartup,
+	updateHashForEntryStartup
+} = require("./StartupHelpers");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+
+const PLUGIN_NAME = "ArrayPushCallbackChunkFormatPlugin";
+
+class ArrayPushCallbackChunkFormatPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.additionalChunkRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph }) => {
+					if (chunk.hasRuntime()) return;
+					if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
+						set.add(RuntimeGlobals.onChunksLoaded);
+						set.add(RuntimeGlobals.exports);
+						set.add(RuntimeGlobals.require);
+					}
+					set.add(RuntimeGlobals.chunkCallback);
+				}
+			);
+			const hooks = getCompilationHooks(compilation);
+			hooks.renderChunk.tap(PLUGIN_NAME, (modules, renderContext) => {
+				const { chunk, chunkGraph, runtimeTemplate } = renderContext;
+				const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
+				const globalObject = runtimeTemplate.globalObject;
+				const source = new ConcatSource();
+				const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder(chunk);
+				if (hotUpdateChunk) {
+					const hotUpdateGlobal = runtimeTemplate.outputOptions.hotUpdateGlobal;
+					source.add(`${globalObject}[${JSON.stringify(hotUpdateGlobal)}](`);
+					source.add(`${JSON.stringify(chunk.id)},`);
+					source.add(modules);
+					if (runtimeModules.length > 0) {
+						source.add(",\n");
+						const runtimePart = Template.renderChunkRuntimeModules(
+							runtimeModules,
+							renderContext
+						);
+						source.add(runtimePart);
+					}
+					source.add(")");
+				} else {
+					const chunkLoadingGlobal =
+						runtimeTemplate.outputOptions.chunkLoadingGlobal;
+					source.add(
+						`(${globalObject}[${JSON.stringify(
+							chunkLoadingGlobal
+						)}] = ${globalObject}[${JSON.stringify(
+							chunkLoadingGlobal
+						)}] || []).push([`
+					);
+					source.add(`${JSON.stringify(chunk.ids)},`);
+					source.add(modules);
+					/** @type {EntryModuleWithChunkGroup[]} */
+					const entries = [
+						...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
+					];
+					if (runtimeModules.length > 0 || entries.length > 0) {
+						const runtime = new ConcatSource(
+							`${
+								runtimeTemplate.supportsArrowFunction()
+									? `${RuntimeGlobals.require} =>`
+									: `function(${RuntimeGlobals.require})`
+							} { // webpackRuntimeModules\n`
+						);
+						if (runtimeModules.length > 0) {
+							runtime.add(
+								Template.renderRuntimeModules(runtimeModules, {
+									...renderContext,
+									codeGenerationResults:
+										/** @type {CodeGenerationResults} */
+										(compilation.codeGenerationResults)
+								})
+							);
+						}
+						if (entries.length > 0) {
+							const startupSource = new RawSource(
+								generateEntryStartup(
+									chunkGraph,
+									runtimeTemplate,
+									entries,
+									chunk,
+									true
+								)
+							);
+							runtime.add(
+								hooks.renderStartup.call(
+									startupSource,
+									entries[entries.length - 1][0],
+									renderContext
+								)
+							);
+							if (
+								chunkGraph
+									.getChunkRuntimeRequirements(chunk)
+									.has(RuntimeGlobals.returnExportsFromRuntime)
+							) {
+								runtime.add(`return ${RuntimeGlobals.exports};\n`);
+							}
+						}
+						runtime.add("}\n");
+						source.add(",\n");
+						source.add(new PrefixSource("/******/ ", runtime));
+					}
+					source.add("])");
+				}
+				return source;
+			});
+			hooks.chunkHash.tap(
+				PLUGIN_NAME,
+				(chunk, hash, { chunkGraph, runtimeTemplate }) => {
+					if (chunk.hasRuntime()) return;
+					hash.update(
+						`${PLUGIN_NAME}1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.globalObject}`
+					);
+					/** @type {EntryModuleWithChunkGroup[]} */
+					const entries = [
+						...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
+					];
+					updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
+				}
+			);
+		});
+	}
+}
+
+module.exports = ArrayPushCallbackChunkFormatPlugin;
Index: frontend/node_modules/webpack/lib/javascript/BasicEvaluatedExpression.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/BasicEvaluatedExpression.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/BasicEvaluatedExpression.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,605 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("estree").Node} Node */
+/** @typedef {import("./JavascriptParser").Range} Range */
+/** @typedef {import("./JavascriptParser").VariableInfo} VariableInfo */
+/** @typedef {import("./JavascriptParser").Members} Members */
+/** @typedef {import("./JavascriptParser").MembersOptionals} MembersOptionals */
+/** @typedef {import("./JavascriptParser").MemberRanges} MemberRanges */
+
+const TypeUnknown = 0;
+const TypeUndefined = 1;
+const TypeNull = 2;
+const TypeString = 3;
+const TypeNumber = 4;
+const TypeBoolean = 5;
+const TypeRegExp = 6;
+const TypeConditional = 7;
+const TypeArray = 8;
+const TypeConstArray = 9;
+const TypeIdentifier = 10;
+const TypeWrapped = 11;
+const TypeTemplateString = 12;
+const TypeBigInt = 13;
+
+/** @typedef {() => Members} GetMembers */
+/** @typedef {() => MembersOptionals} GetMembersOptionals */
+/** @typedef {() => MemberRanges} GetMemberRanges */
+
+class BasicEvaluatedExpression {
+	constructor() {
+		this.type = TypeUnknown;
+		/** @type {Range | undefined} */
+		this.range = undefined;
+		/** @type {boolean} */
+		this.falsy = false;
+		/** @type {boolean} */
+		this.truthy = false;
+		/** @type {boolean | undefined} */
+		this.nullish = undefined;
+		/** @type {boolean} */
+		this.sideEffects = true;
+		/** @type {boolean | undefined} */
+		this.bool = undefined;
+		/** @type {number | undefined} */
+		this.number = undefined;
+		/** @type {bigint | undefined} */
+		this.bigint = undefined;
+		/** @type {RegExp | undefined} */
+		this.regExp = undefined;
+		/** @type {string | undefined} */
+		this.string = undefined;
+		/** @type {BasicEvaluatedExpression[] | undefined} */
+		this.quasis = undefined;
+		/** @type {BasicEvaluatedExpression[] | undefined} */
+		this.parts = undefined;
+		/** @type {EXPECTED_ANY[] | undefined} */
+		this.array = undefined;
+		/** @type {BasicEvaluatedExpression[] | undefined} */
+		this.items = undefined;
+		/** @type {BasicEvaluatedExpression[] | undefined} */
+		this.options = undefined;
+		/** @type {BasicEvaluatedExpression | undefined | null} */
+		this.prefix = undefined;
+		/** @type {BasicEvaluatedExpression | undefined | null} */
+		this.postfix = undefined;
+		/** @type {BasicEvaluatedExpression[] | undefined} */
+		this.wrappedInnerExpressions = undefined;
+		/** @type {string | VariableInfo | undefined} */
+		this.identifier = undefined;
+		/** @type {string | VariableInfo | undefined} */
+		this.rootInfo = undefined;
+		/** @type {GetMembers | undefined} */
+		this.getMembers = undefined;
+		/** @type {GetMembersOptionals | undefined} */
+		this.getMembersOptionals = undefined;
+		/** @type {GetMemberRanges | undefined} */
+		this.getMemberRanges = undefined;
+		/** @type {Node | undefined} */
+		this.expression = undefined;
+	}
+
+	isUnknown() {
+		return this.type === TypeUnknown;
+	}
+
+	isNull() {
+		return this.type === TypeNull;
+	}
+
+	isUndefined() {
+		return this.type === TypeUndefined;
+	}
+
+	isString() {
+		return this.type === TypeString;
+	}
+
+	isNumber() {
+		return this.type === TypeNumber;
+	}
+
+	isBigInt() {
+		return this.type === TypeBigInt;
+	}
+
+	isBoolean() {
+		return this.type === TypeBoolean;
+	}
+
+	isRegExp() {
+		return this.type === TypeRegExp;
+	}
+
+	isConditional() {
+		return this.type === TypeConditional;
+	}
+
+	isArray() {
+		return this.type === TypeArray;
+	}
+
+	isConstArray() {
+		return this.type === TypeConstArray;
+	}
+
+	isIdentifier() {
+		return this.type === TypeIdentifier;
+	}
+
+	isWrapped() {
+		return this.type === TypeWrapped;
+	}
+
+	isTemplateString() {
+		return this.type === TypeTemplateString;
+	}
+
+	/**
+	 * Is expression a primitive or an object type value?
+	 * @returns {boolean | undefined} true: primitive type, false: object type, undefined: unknown/runtime-defined
+	 */
+	isPrimitiveType() {
+		switch (this.type) {
+			case TypeUndefined:
+			case TypeNull:
+			case TypeString:
+			case TypeNumber:
+			case TypeBoolean:
+			case TypeBigInt:
+			case TypeWrapped:
+			case TypeTemplateString:
+				return true;
+			case TypeRegExp:
+			case TypeArray:
+			case TypeConstArray:
+				return false;
+			default:
+				return undefined;
+		}
+	}
+
+	/**
+	 * Is expression a runtime or compile-time value?
+	 * @returns {boolean} true: compile time value, false: runtime value
+	 */
+	isCompileTimeValue() {
+		switch (this.type) {
+			case TypeUndefined:
+			case TypeNull:
+			case TypeString:
+			case TypeNumber:
+			case TypeBoolean:
+			case TypeRegExp:
+			case TypeConstArray:
+			case TypeBigInt:
+				return true;
+			default:
+				return false;
+		}
+	}
+
+	/**
+	 * As compile time value.
+	 * @returns {undefined | null | string | number | boolean | RegExp | EXPECTED_ANY[] | bigint} the javascript value
+	 */
+	asCompileTimeValue() {
+		switch (this.type) {
+			case TypeUndefined:
+				return;
+			case TypeNull:
+				return null;
+			case TypeString:
+				return this.string;
+			case TypeNumber:
+				return this.number;
+			case TypeBoolean:
+				return this.bool;
+			case TypeRegExp:
+				return this.regExp;
+			case TypeConstArray:
+				return this.array;
+			case TypeBigInt:
+				return this.bigint;
+			default:
+				throw new Error(
+					"asCompileTimeValue must only be called for compile-time values"
+				);
+		}
+	}
+
+	isTruthy() {
+		return this.truthy;
+	}
+
+	isFalsy() {
+		return this.falsy;
+	}
+
+	isNullish() {
+		return this.nullish;
+	}
+
+	/**
+	 * Can this expression have side effects?
+	 * @returns {boolean} false: never has side effects
+	 */
+	couldHaveSideEffects() {
+		return this.sideEffects;
+	}
+
+	/**
+	 * Creates a boolean representation of this evaluated expression.
+	 * @returns {boolean | undefined} true: truthy, false: falsy, undefined: unknown
+	 */
+	asBool() {
+		if (this.truthy) return true;
+		if (this.falsy || this.nullish) return false;
+		if (this.isBoolean()) return this.bool;
+		if (this.isNull()) return false;
+		if (this.isUndefined()) return false;
+		if (this.isString()) return this.string !== "";
+		if (this.isNumber()) return this.number !== 0;
+		if (this.isBigInt()) return this.bigint !== BigInt(0);
+		if (this.isRegExp()) return true;
+		if (this.isArray()) return true;
+		if (this.isConstArray()) return true;
+		if (this.isWrapped()) {
+			return (this.prefix && this.prefix.asBool()) ||
+				(this.postfix && this.postfix.asBool())
+				? true
+				: undefined;
+		}
+		if (this.isTemplateString()) {
+			const str = this.asString();
+			if (typeof str === "string") return str !== "";
+		}
+	}
+
+	/**
+	 * Creates a nullish coalescing representation of this evaluated expression.
+	 * @returns {boolean | undefined} true: nullish, false: not nullish, undefined: unknown
+	 */
+	asNullish() {
+		const nullish = this.isNullish();
+
+		if (nullish === true || this.isNull() || this.isUndefined()) return true;
+
+		if (nullish === false) return false;
+		if (this.isTruthy()) return false;
+		if (this.isBoolean()) return false;
+		if (this.isString()) return false;
+		if (this.isNumber()) return false;
+		if (this.isBigInt()) return false;
+		if (this.isRegExp()) return false;
+		if (this.isArray()) return false;
+		if (this.isConstArray()) return false;
+		if (this.isTemplateString()) return false;
+		if (this.isRegExp()) return false;
+	}
+
+	/**
+	 * Creates a string representation of this evaluated expression.
+	 * @returns {string | undefined} the string representation or undefined if not possible
+	 */
+	asString() {
+		if (this.isBoolean()) return `${this.bool}`;
+		if (this.isNull()) return "null";
+		if (this.isUndefined()) return "undefined";
+		if (this.isString()) return this.string;
+		if (this.isNumber()) return `${this.number}`;
+		if (this.isBigInt()) return `${this.bigint}`;
+		if (this.isRegExp()) return `${this.regExp}`;
+		if (this.isArray()) {
+			/** @type {string[]} */
+			const array = [];
+			for (const item of /** @type {BasicEvaluatedExpression[]} */ (
+				this.items
+			)) {
+				const itemStr = item.asString();
+				if (itemStr === undefined) return;
+				array.push(itemStr);
+			}
+			return `${array}`;
+		}
+		if (this.isConstArray()) return `${this.array}`;
+		if (this.isTemplateString()) {
+			let str = "";
+			for (const part of /** @type {BasicEvaluatedExpression[]} */ (
+				this.parts
+			)) {
+				const partStr = part.asString();
+				if (partStr === undefined) return;
+				str += partStr;
+			}
+			return str;
+		}
+	}
+
+	/**
+	 * Updates string using the provided string.
+	 * @param {string} string value
+	 * @returns {BasicEvaluatedExpression} basic evaluated expression
+	 */
+	setString(string) {
+		this.type = TypeString;
+		this.string = string;
+		this.sideEffects = false;
+		return this;
+	}
+
+	setUndefined() {
+		this.type = TypeUndefined;
+		this.sideEffects = false;
+		return this;
+	}
+
+	setNull() {
+		this.type = TypeNull;
+		this.sideEffects = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to a number
+	 * @param {number} number number to set
+	 * @returns {this} this
+	 */
+	setNumber(number) {
+		this.type = TypeNumber;
+		this.number = number;
+		this.sideEffects = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to a BigInt
+	 * @param {bigint} bigint bigint to set
+	 * @returns {this} this
+	 */
+	setBigInt(bigint) {
+		this.type = TypeBigInt;
+		this.bigint = bigint;
+		this.sideEffects = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to a boolean
+	 * @param {boolean} bool boolean to set
+	 * @returns {this} this
+	 */
+	setBoolean(bool) {
+		this.type = TypeBoolean;
+		this.bool = bool;
+		this.sideEffects = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to a regular expression
+	 * @param {RegExp} regExp regular expression to set
+	 * @returns {this} this
+	 */
+	setRegExp(regExp) {
+		this.type = TypeRegExp;
+		this.regExp = regExp;
+		this.sideEffects = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to a particular identifier and its members.
+	 * @param {string | VariableInfo} identifier identifier to set
+	 * @param {string | VariableInfo} rootInfo root info
+	 * @param {GetMembers} getMembers members
+	 * @param {GetMembersOptionals=} getMembersOptionals optional members
+	 * @param {GetMemberRanges=} getMemberRanges ranges of progressively increasing sub-expressions
+	 * @returns {this} this
+	 */
+	setIdentifier(
+		identifier,
+		rootInfo,
+		getMembers,
+		getMembersOptionals,
+		getMemberRanges
+	) {
+		this.type = TypeIdentifier;
+		this.identifier = identifier;
+		this.rootInfo = rootInfo;
+		this.getMembers = getMembers;
+		this.getMembersOptionals = getMembersOptionals;
+		this.getMemberRanges = getMemberRanges;
+		this.sideEffects = true;
+		return this;
+	}
+
+	/**
+	 * Wraps an array of expressions with a prefix and postfix expression.
+	 * @param {BasicEvaluatedExpression | null | undefined} prefix Expression to be added before the innerExpressions
+	 * @param {BasicEvaluatedExpression | null | undefined} postfix Expression to be added after the innerExpressions
+	 * @param {BasicEvaluatedExpression[] | undefined} innerExpressions Expressions to be wrapped
+	 * @returns {this} this
+	 */
+	setWrapped(prefix, postfix, innerExpressions) {
+		this.type = TypeWrapped;
+		this.prefix = prefix;
+		this.postfix = postfix;
+		this.wrappedInnerExpressions = innerExpressions;
+		this.sideEffects = true;
+		return this;
+	}
+
+	/**
+	 * Stores the options of a conditional expression.
+	 * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be set
+	 * @returns {this} this
+	 */
+	setOptions(options) {
+		this.type = TypeConditional;
+		this.options = options;
+		this.sideEffects = true;
+		return this;
+	}
+
+	/**
+	 * Adds the provided basic evaluated expression to the basic evaluated expression.
+	 * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be added
+	 * @returns {this} this
+	 */
+	addOptions(options) {
+		if (!this.options) {
+			this.type = TypeConditional;
+			this.options = [];
+			this.sideEffects = true;
+		}
+		for (const item of options) {
+			this.options.push(item);
+		}
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to an array of expressions.
+	 * @param {BasicEvaluatedExpression[]} items expressions to set
+	 * @returns {this} this
+	 */
+	setItems(items) {
+		this.type = TypeArray;
+		this.items = items;
+		this.sideEffects = items.some((i) => i.couldHaveSideEffects());
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to an array of strings.
+	 * @param {string[]} array array to set
+	 * @returns {this} this
+	 */
+	setArray(array) {
+		this.type = TypeConstArray;
+		this.array = array;
+		this.sideEffects = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of this expression to a processed/unprocessed template string. Used
+	 * for evaluating TemplateLiteral expressions in the JavaScript Parser.
+	 * @param {BasicEvaluatedExpression[]} quasis template string quasis
+	 * @param {BasicEvaluatedExpression[]} parts template string parts
+	 * @param {"cooked" | "raw"} kind template string kind
+	 * @returns {this} this
+	 */
+	setTemplateString(quasis, parts, kind) {
+		this.type = TypeTemplateString;
+		this.quasis = quasis;
+		this.parts = parts;
+		this.templateStringKind = kind;
+		this.sideEffects = parts.some((p) => p.sideEffects);
+		return this;
+	}
+
+	setTruthy() {
+		this.falsy = false;
+		this.truthy = true;
+		this.nullish = false;
+		return this;
+	}
+
+	setFalsy() {
+		this.falsy = true;
+		this.truthy = false;
+		return this;
+	}
+
+	/**
+	 * Set's the value of the expression to nullish.
+	 * @param {boolean} value true, if the expression is nullish
+	 * @returns {this} this
+	 */
+	setNullish(value) {
+		this.nullish = value;
+
+		if (value) return this.setFalsy();
+
+		return this;
+	}
+
+	/**
+	 * Set's the range for the expression.
+	 * @param {Range} range range to set
+	 * @returns {this} this
+	 */
+	setRange(range) {
+		this.range = range;
+		return this;
+	}
+
+	/**
+	 * Set whether or not the expression has side effects.
+	 * @param {boolean} sideEffects true, if the expression has side effects
+	 * @returns {this} this
+	 */
+	setSideEffects(sideEffects = true) {
+		this.sideEffects = sideEffects;
+		return this;
+	}
+
+	/**
+	 * Set the expression node for the expression.
+	 * @param {Node | undefined} expression expression
+	 * @returns {this} this
+	 */
+	setExpression(expression) {
+		this.expression = expression;
+		return this;
+	}
+}
+
+/**
+ * Returns is valid flags.
+ * @param {string} flags regexp flags
+ * @returns {boolean} is valid flags
+ */
+BasicEvaluatedExpression.isValidRegExpFlags = (flags) => {
+	const len = flags.length;
+
+	if (len === 0) return true;
+	if (len > 4) return false;
+
+	// cspell:word gimy
+	let remaining = 0b0000; // bit per RegExp flag: gimy
+
+	for (let i = 0; i < len; i++) {
+		switch (flags.charCodeAt(i)) {
+			case 103 /* g */:
+				if (remaining & 0b1000) return false;
+				remaining |= 0b1000;
+				break;
+			case 105 /* i */:
+				if (remaining & 0b0100) return false;
+				remaining |= 0b0100;
+				break;
+			case 109 /* m */:
+				if (remaining & 0b0010) return false;
+				remaining |= 0b0010;
+				break;
+			case 121 /* y */:
+				if (remaining & 0b0001) return false;
+				remaining |= 0b0001;
+				break;
+			default:
+				return false;
+		}
+	}
+
+	return true;
+};
+
+module.exports = BasicEvaluatedExpression;
Index: frontend/node_modules/webpack/lib/javascript/ChunkFormatHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/ChunkFormatHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/ChunkFormatHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+const { updateHashForEntryStartup } = require("./StartupHelpers");
+
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+
+/**
+ * Returns } Object containing chunk entries and runtime chunk.
+ * @param {Chunk} chunk The chunk to get information for
+ * @param {ChunkGraph} chunkGraph The chunk graph containing the chunk
+ * @returns {{ entries: [Module, Entrypoint | undefined][], runtimeChunk: Chunk | null }} Object containing chunk entries and runtime chunk
+ */
+function getChunkInfo(chunk, chunkGraph) {
+	const entries = [
+		...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
+	];
+	const runtimeChunk =
+		entries.length > 0
+			? /** @type {Entrypoint[][]} */
+				(entries)[0][1].getRuntimeChunk()
+			: null;
+
+	return {
+		entries,
+		runtimeChunk
+	};
+}
+
+/**
+ * Creates a chunk hash handler
+ * @param {string} name The name of the chunk
+ * @returns {(chunk: Chunk, hash: Hash, { chunkGraph }: ChunkHashContext) => void} The chunk hash handler
+ */
+function createChunkHashHandler(name) {
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk The chunk to get information for
+	 * @param {Hash} hash The hash to update
+	 * @param {ChunkHashContext} chunkHashContext The chunk hash context
+	 * @returns {void}
+	 */
+	return (chunk, hash, { chunkGraph }) => {
+		if (chunk.hasRuntime()) return;
+		const { entries, runtimeChunk } = getChunkInfo(chunk, chunkGraph);
+		hash.update(name);
+		hash.update("1");
+		if (runtimeChunk && runtimeChunk.hash) {
+			// https://github.com/webpack/webpack/issues/19439
+			// Any change to runtimeChunk should trigger a hash update,
+			// we shouldn't depend on or inspect its internal implementation.
+			// import __webpack_require__ from "./runtime-main.e9400aee33633a3973bd.js";
+			hash.update(runtimeChunk.hash);
+		}
+		updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
+	};
+}
+
+module.exports = {
+	createChunkHashHandler,
+	getChunkInfo
+};
Index: frontend/node_modules/webpack/lib/javascript/ChunkHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/ChunkHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/ChunkHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,46 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Entrypoint = require("../Entrypoint");
+
+/** @typedef {import("../Chunk")} Chunk */
+
+/**
+ * Returns chunks.
+ * @param {Entrypoint} entrypoint a chunk group
+ * @param {(Chunk | null)=} excludedChunk1 current chunk which is excluded
+ * @param {(Chunk | null)=} excludedChunk2 runtime chunk which is excluded
+ * @returns {Set<Chunk>} chunks
+ */
+const getAllChunks = (entrypoint, excludedChunk1, excludedChunk2) => {
+	/** @type {Set<Entrypoint>} */
+	const queue = new Set([entrypoint]);
+	/** @type {Set<Entrypoint>} */
+	const groups = new Set();
+	for (const group of queue) {
+		if (group !== entrypoint) {
+			groups.add(group);
+		}
+		for (const parent of group.parentsIterable) {
+			if (parent instanceof Entrypoint) queue.add(parent);
+		}
+	}
+	groups.add(entrypoint);
+
+	/** @type {Set<Chunk>} */
+	const chunks = new Set();
+	for (const group of groups) {
+		for (const chunk of group.chunks) {
+			if (chunk === excludedChunk1) continue;
+			if (chunk === excludedChunk2) continue;
+			chunks.add(chunk);
+		}
+	}
+	return chunks;
+};
+
+module.exports.getAllChunks = getAllChunks;
Index: frontend/node_modules/webpack/lib/javascript/CommonJsChunkFormatPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/CommonJsChunkFormatPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/CommonJsChunkFormatPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,145 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, RawSource } = require("webpack-sources");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const { getUndoPath } = require("../util/identifier");
+const {
+	createChunkHashHandler,
+	getChunkInfo
+} = require("./ChunkFormatHelpers");
+const {
+	getChunkFilenameTemplate,
+	getCompilationHooks
+} = require("./JavascriptModulesPlugin");
+const { generateEntryStartup } = require("./StartupHelpers");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "CommonJsChunkFormatPlugin";
+
+class CommonJsChunkFormatPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.additionalChunkRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph }) => {
+					if (chunk.hasRuntime()) return;
+					if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
+						set.add(RuntimeGlobals.require);
+						set.add(RuntimeGlobals.startupEntrypoint);
+						set.add(RuntimeGlobals.externalInstallChunk);
+					}
+				}
+			);
+			const hooks = getCompilationHooks(compilation);
+			hooks.renderChunk.tap(PLUGIN_NAME, (modules, renderContext) => {
+				const { chunk, chunkGraph, runtimeTemplate } = renderContext;
+				const source = new ConcatSource();
+				source.add(`exports.id = ${JSON.stringify(chunk.id)};\n`);
+				source.add(`exports.ids = ${JSON.stringify(chunk.ids)};\n`);
+				source.add("exports.modules = ");
+				source.add(modules);
+				source.add(";\n");
+				const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder(chunk);
+				if (runtimeModules.length > 0) {
+					source.add("exports.runtime =\n");
+					source.add(
+						Template.renderChunkRuntimeModules(runtimeModules, renderContext)
+					);
+				}
+				const { entries, runtimeChunk } = getChunkInfo(chunk, chunkGraph);
+				if (runtimeChunk) {
+					const currentOutputName = compilation
+						.getPath(
+							getChunkFilenameTemplate(chunk, compilation.outputOptions),
+							{
+								chunk,
+								contentHashType: "javascript"
+							}
+						)
+						.replace(/^\/+/g, "")
+						.split("/");
+					const runtimeOutputName = compilation
+						.getPath(
+							getChunkFilenameTemplate(
+								/** @type {Chunk} */
+								(runtimeChunk),
+								compilation.outputOptions
+							),
+							{
+								chunk: /** @type {Chunk} */ (runtimeChunk),
+								contentHashType: "javascript"
+							}
+						)
+						.replace(/^\/+/g, "")
+						.split("/");
+
+					// remove common parts
+					while (
+						currentOutputName.length > 1 &&
+						runtimeOutputName.length > 1 &&
+						currentOutputName[0] === runtimeOutputName[0]
+					) {
+						currentOutputName.shift();
+						runtimeOutputName.shift();
+					}
+					const last = runtimeOutputName.join("/");
+					// create final path
+					const runtimePath =
+						getUndoPath(currentOutputName.join("/"), last, true) + last;
+
+					const entrySource = new ConcatSource();
+					entrySource.add(
+						`(${
+							runtimeTemplate.supportsArrowFunction() ? "() => " : "function() "
+						}{\n`
+					);
+					entrySource.add("var exports = {};\n");
+					entrySource.add(source);
+					entrySource.add(";\n\n// load runtime\n");
+					entrySource.add(
+						`var ${RuntimeGlobals.require} = require(${JSON.stringify(
+							runtimePath
+						)});\n`
+					);
+					entrySource.add(`${RuntimeGlobals.externalInstallChunk}(exports);\n`);
+					const startupSource = new RawSource(
+						generateEntryStartup(
+							chunkGraph,
+							runtimeTemplate,
+							entries,
+							chunk,
+							false
+						)
+					);
+					entrySource.add(
+						hooks.renderStartup.call(
+							startupSource,
+							entries[entries.length - 1][0],
+							renderContext
+						)
+					);
+					entrySource.add("\n})()");
+					return entrySource;
+				}
+				return source;
+			});
+
+			hooks.chunkHash.tap(PLUGIN_NAME, createChunkHashHandler(PLUGIN_NAME));
+		});
+	}
+}
+
+module.exports = CommonJsChunkFormatPlugin;
Index: frontend/node_modules/webpack/lib/javascript/EnableChunkLoadingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/EnableChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/EnableChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,130 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").ChunkLoadingType} ChunkLoadingType */
+/** @typedef {import("../Compiler")} Compiler */
+
+/** @typedef {Set<ChunkLoadingType>} ChunkLoadingTypes */
+
+/** @type {WeakMap<Compiler, ChunkLoadingTypes>} */
+const enabledTypes = new WeakMap();
+
+/**
+ * Returns enabled types.
+ * @param {Compiler} compiler compiler
+ * @returns {ChunkLoadingTypes} enabled types
+ */
+const getEnabledTypes = (compiler) => {
+	let set = enabledTypes.get(compiler);
+	if (set === undefined) {
+		/** @type {ChunkLoadingTypes} */
+		set = new Set();
+		enabledTypes.set(compiler, set);
+	}
+	return set;
+};
+
+class EnableChunkLoadingPlugin {
+	/**
+	 * Creates an instance of EnableChunkLoadingPlugin.
+	 * @param {ChunkLoadingType} type library type that should be available
+	 */
+	constructor(type) {
+		this.type = type;
+	}
+
+	/**
+	 * Updates enabled using the provided compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @param {ChunkLoadingType} type type of library
+	 * @returns {void}
+	 */
+	static setEnabled(compiler, type) {
+		getEnabledTypes(compiler).add(type);
+	}
+
+	/**
+	 * Checks enabled.
+	 * @param {Compiler} compiler the compiler instance
+	 * @param {ChunkLoadingType} type type of library
+	 * @returns {void}
+	 */
+	static checkEnabled(compiler, type) {
+		if (!getEnabledTypes(compiler).has(type)) {
+			throw new Error(
+				`Chunk loading type "${type}" is not enabled. ` +
+					"EnableChunkLoadingPlugin need to be used to enable this type of chunk loading. " +
+					'This usually happens through the "output.enabledChunkLoadingTypes" option. ' +
+					'If you are using a function as entry which sets "chunkLoading", you need to add all potential chunk loading types to "output.enabledChunkLoadingTypes". ' +
+					`These types are enabled: ${[...getEnabledTypes(compiler)].join(", ")}`
+			);
+		}
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { type } = this;
+
+		// Only enable once
+		const enabled = getEnabledTypes(compiler);
+		if (enabled.has(type)) return;
+		enabled.add(type);
+
+		if (typeof type === "string") {
+			switch (type) {
+				case "jsonp": {
+					const JsonpChunkLoadingPlugin = require("../web/JsonpChunkLoadingPlugin");
+
+					new JsonpChunkLoadingPlugin().apply(compiler);
+					break;
+				}
+				case "import-scripts": {
+					const ImportScriptsChunkLoadingPlugin = require("../webworker/ImportScriptsChunkLoadingPlugin");
+
+					new ImportScriptsChunkLoadingPlugin().apply(compiler);
+					break;
+				}
+				case "require": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const CommonJsChunkLoadingPlugin = require("../node/CommonJsChunkLoadingPlugin");
+
+					new CommonJsChunkLoadingPlugin({
+						asyncChunkLoading: false
+					}).apply(compiler);
+					break;
+				}
+				case "async-node": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const CommonJsChunkLoadingPlugin = require("../node/CommonJsChunkLoadingPlugin");
+
+					new CommonJsChunkLoadingPlugin({
+						asyncChunkLoading: true
+					}).apply(compiler);
+					break;
+				}
+				case "import": {
+					const ModuleChunkLoadingPlugin = require("../esm/ModuleChunkLoadingPlugin");
+
+					new ModuleChunkLoadingPlugin().apply(compiler);
+					break;
+				}
+				default:
+					throw new Error(`Unsupported chunk loading type ${type}.
+Plugins which provide custom chunk loading types must call EnableChunkLoadingPlugin.setEnabled(compiler, type) to disable this error.`);
+			}
+		} else {
+			// TODO support plugin instances here
+			// apply them to the compiler
+		}
+	}
+}
+
+module.exports = EnableChunkLoadingPlugin;
Index: frontend/node_modules/webpack/lib/javascript/JavascriptGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/JavascriptGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/JavascriptGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,287 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const { RawSource, ReplaceSource } = require("webpack-sources");
+const Generator = require("../Generator");
+const InitFragment = require("../InitFragment");
+const { JAVASCRIPT_TYPES } = require("../ModuleSourceTypeConstants");
+const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
+/** @typedef {import("../DependenciesBlock")} DependenciesBlock */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplate")} DependencyTemplate */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+const DEFAULT_SOURCE = {
+	source() {
+		return new RawSource("throw new Error('No source available');");
+	},
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @returns {number} size of the DEFAULT_SOURCE.source()
+	 */
+	size() {
+		return 39;
+	}
+};
+
+// TODO: clean up this file
+// replace with newer constructs
+
+const deprecatedGetInitFragments = util.deprecate(
+	/**
+	 * Handles the callback logic for this hook.
+	 * @param {DependencyTemplate} template template
+	 * @param {Dependency} dependency dependency
+	 * @param {DependencyTemplateContext} templateContext template context
+	 * @returns {InitFragment<GenerateContext>[]} init fragments
+	 */
+	(template, dependency, templateContext) =>
+		/** @type {DependencyTemplate & { getInitFragments: (dependency: Dependency, dependencyTemplateContext: DependencyTemplateContext) => InitFragment<GenerateContext>[] }} */
+		(template).getInitFragments(dependency, templateContext),
+	"DependencyTemplate.getInitFragment is deprecated (use apply(dep, source, { initFragments }) instead)",
+	"DEP_WEBPACK_JAVASCRIPT_GENERATOR_GET_INIT_FRAGMENTS"
+);
+
+class JavascriptGenerator extends Generator {
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const originalSource = module.originalSource();
+		if (!originalSource) {
+			return DEFAULT_SOURCE.size();
+		}
+		return originalSource.size();
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		// Only harmony modules are valid for optimization
+		if (
+			!module.buildMeta ||
+			module.buildMeta.exportsType !== "namespace" ||
+			module.presentationalDependencies === undefined ||
+			!module.presentationalDependencies.some(
+				(d) => d instanceof HarmonyCompatibilityDependency
+			)
+		) {
+			return "Module is not an ECMAScript module";
+		}
+
+		// Some expressions are not compatible with module concatenation
+		// because they may produce unexpected results. The plugin bails out
+		// if some were detected upfront.
+		if (module.buildInfo && module.buildInfo.moduleConcatenationBailout) {
+			return `Module uses ${module.buildInfo.moduleConcatenationBailout}`;
+		}
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module the current module
+	 * @param {Dependency} dependency the dependency to generate
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext} generateContext the render context
+	 * @returns {void}
+	 */
+	sourceDependency(module, dependency, initFragments, source, generateContext) {
+		const constructor =
+			/** @type {DependencyConstructor} */
+			(dependency.constructor);
+		const template = generateContext.dependencyTemplates.get(constructor);
+		if (!template) {
+			throw new Error(
+				`No template for dependency: ${dependency.constructor.name}`
+			);
+		}
+
+		/** @type {InitFragment<GenerateContext>[] | undefined} */
+		let chunkInitFragments;
+
+		/** @type {DependencyTemplateContext} */
+		const templateContext = {
+			runtimeTemplate: generateContext.runtimeTemplate,
+			dependencyTemplates: generateContext.dependencyTemplates,
+			moduleGraph: generateContext.moduleGraph,
+			chunkGraph: generateContext.chunkGraph,
+			module,
+			runtime: generateContext.runtime,
+			runtimeRequirements: generateContext.runtimeRequirements,
+			concatenationScope: generateContext.concatenationScope,
+			codeGenerationResults:
+				/** @type {NonNullable<GenerateContext["codeGenerationResults"]>} */
+				(generateContext.codeGenerationResults),
+			initFragments,
+			get chunkInitFragments() {
+				if (!chunkInitFragments) {
+					const data =
+						/** @type {NonNullable<GenerateContext["getData"]>} */
+						(generateContext.getData)();
+					chunkInitFragments = data.get("chunkInitFragments");
+					if (!chunkInitFragments) {
+						chunkInitFragments = [];
+						data.set("chunkInitFragments", chunkInitFragments);
+					}
+				}
+
+				return chunkInitFragments;
+			}
+		};
+
+		template.apply(dependency, source, templateContext);
+
+		// TODO remove in webpack 6
+		if ("getInitFragments" in template) {
+			const fragments = deprecatedGetInitFragments(
+				template,
+				dependency,
+				templateContext
+			);
+
+			if (fragments) {
+				for (const fragment of fragments) {
+					initFragments.push(fragment);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module the module to generate
+	 * @param {DependenciesBlock} block the dependencies block which will be processed
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext} generateContext the generateContext
+	 * @returns {void}
+	 */
+	sourceBlock(module, block, initFragments, source, generateContext) {
+		for (const dependency of block.dependencies) {
+			this.sourceDependency(
+				module,
+				dependency,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+
+		for (const childBlock of block.blocks) {
+			this.sourceBlock(
+				module,
+				childBlock,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module the module to generate
+	 * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
+	 * @param {ReplaceSource} source the current replace source which can be modified
+	 * @param {GenerateContext} generateContext the generateContext
+	 * @returns {void}
+	 */
+	sourceModule(module, initFragments, source, generateContext) {
+		for (const dependency of module.dependencies) {
+			this.sourceDependency(
+				module,
+				dependency,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+
+		if (module.presentationalDependencies !== undefined) {
+			for (const dependency of module.presentationalDependencies) {
+				this.sourceDependency(
+					module,
+					dependency,
+					initFragments,
+					source,
+					generateContext
+				);
+			}
+		}
+
+		for (const childBlock of module.blocks) {
+			this.sourceBlock(
+				module,
+				childBlock,
+				initFragments,
+				source,
+				generateContext
+			);
+		}
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const originalSource = module.originalSource();
+		if (!originalSource) {
+			return DEFAULT_SOURCE.source();
+		}
+
+		const source = new ReplaceSource(originalSource);
+		/** @type {InitFragment<GenerateContext>[]} */
+		const initFragments = [];
+
+		this.sourceModule(module, initFragments, source, generateContext);
+
+		return InitFragment.addToSource(source, initFragments, generateContext);
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
+	}
+}
+
+module.exports = JavascriptGenerator;
Index: frontend/node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2034 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const vm = require("vm");
+const eslintScope = require("eslint-scope");
+const { SyncBailHook, SyncHook, SyncWaterfallHook } = require("tapable");
+const {
+	CachedSource,
+	ConcatSource,
+	OriginalSource,
+	PrefixSource,
+	RawSource,
+	ReplaceSource
+} = require("webpack-sources");
+const Compilation = require("../Compilation");
+const HotUpdateChunk = require("../HotUpdateChunk");
+const InitFragment = require("../InitFragment");
+const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM,
+	WEBPACK_MODULE_TYPE_RUNTIME
+} = require("../ModuleTypeConstants");
+const NormalModule = require("../NormalModule");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const { tryRunOrWebpackError } = require("../errors/HookWebpackError");
+const { last, someInIterable } = require("../util/IterableHelpers");
+const StringXor = require("../util/StringXor");
+const { compareModulesByFullName } = require("../util/comparators");
+const {
+	RESERVED_NAMES,
+	addScopeSymbols,
+	findNewName,
+	getAllReferences,
+	getPathInAst,
+	getUsedNamesInScopeInfo
+} = require("../util/concatenate");
+const createHash = require("../util/createHash");
+const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
+const removeBOM = require("../util/removeBOM");
+const { intersectRuntime } = require("../util/runtime");
+const JavascriptGenerator = require("./JavascriptGenerator");
+const JavascriptParser = require("./JavascriptParser");
+
+/** @typedef {import("estree").Program} Program */
+/** @typedef {import("estree").Node} Node */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("estree").CatchClause} CatchClause */
+/** @typedef {import("estree").ClassDeclaration} ClassDeclaration */
+/** @typedef {import("estree").ClassExpression} ClassExpression */
+/** @typedef {import("estree").FunctionDeclaration} FunctionDeclaration */
+/** @typedef {import("estree").FunctionExpression} FunctionExpression */
+/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */
+/** @typedef {import("estree").VariableDeclarator} VariableDeclarator */
+/** @typedef {import("estree").VariableDeclaration} VariableDeclaration */
+/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */
+/** @typedef {import("estree").ImportSpecifier} ImportSpecifier */
+/** @typedef {import("estree").ImportDefaultSpecifier} ImportDefaultSpecifier */
+/** @typedef {import("estree").ImportNamespaceSpecifier} ImportNamespaceSpecifier */
+/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
+/** @typedef {import("estree").ForInStatement} ForInStatement */
+/** @typedef {import("estree").ForOfStatement} ForOfStatement */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../Compilation").ExecuteModuleObject} ExecuteModuleObject */
+/** @typedef {import("../Compilation").WebpackRequire} WebpackRequire */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../Chunk").ChunkFilenameTemplate} ChunkFilenameTemplate */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/concatenate").ScopeSet} ScopeSet */
+/** @typedef {import("../util/concatenate").UsedNamesInScopeInfo} UsedNamesInScopeInfo */
+
+// TODO remove these types when we will update `eslint-scope` to the latest version and import them from `eslint-scope`
+/**
+ * @typedef {object} Scope
+ * @property {"block" | "catch" | "class" | "class-field-initializer" | "class-static-block" | "for" | "function" | "function-expression-name" | "global" | "module" | "switch" | "with" | "TDZ"} type
+ * @property {boolean} isStrict
+ * @property {Scope | null} upper
+ * @property {Scope[]} childScopes
+ * @property {Scope} variableScope
+ * @property {Node} block
+ * @property {Variable[]} variables
+ * @property {Map<string, Variable>} set
+ * @property {Reference[]} references
+ * @property {Reference[]} through
+ * @property {boolean} functionExpressionScope
+ * @property {{ variables: Variable[], set: Map<string, Variable> }=} implicit
+ */
+
+/**
+ * @typedef {
+ * | { type: "CatchClause", node: CatchClause, parent: null }
+ * | { type: "ClassName", node: ClassDeclaration | ClassExpression, parent: null }
+ * | { type: "FunctionName", node: FunctionDeclaration | FunctionExpression, parent: null }
+ * | { type: "ImplicitGlobalVariable", node: AssignmentExpression | ForInStatement | ForOfStatement, parent: null }
+ * | { type: "ImportBinding", node: ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier, parent: ImportDeclaration }
+ * | { type: "Parameter", node: FunctionDeclaration | FunctionExpression | ArrowFunctionExpression, parent: null }
+ * | { type: "TDZ", node: any, parent: null }
+ * | { type: "Variable", node: VariableDeclarator, parent: VariableDeclaration }
+ * } DefinitionType
+ */
+
+/** @typedef {DefinitionType & { name: Identifier }} Definition */
+
+/**
+ * @typedef {object} Variable
+ * @property {string} name
+ * @property {Scope} scope
+ * @property {Identifier[]} identifiers
+ * @property {Reference[]} references
+ * @property {Definition[]} defs
+ */
+
+/**
+ * @typedef {object} Reference
+ * @property {Identifier} identifier
+ * @property {Scope} from
+ * @property {Variable | null} resolved
+ * @property {Node | null} writeExpr
+ * @property {boolean} init
+ * @property {() => boolean} isWrite
+ * @property {() => boolean} isRead
+ * @property {() => boolean} isWriteOnly
+ * @property {() => boolean} isReadOnly
+ * @property {() => boolean} isReadWrite
+ */
+
+/** @type {WeakMap<ChunkGraph, WeakMap<Chunk, boolean>>} */
+const chunkHasJsCache = new WeakMap();
+
+/**
+ * Returns true, when a JS file is needed for this chunk.
+ * @param {Chunk} chunk a chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @returns {boolean} true, when a JS file is needed for this chunk
+ */
+const _chunkHasJs = (chunk, chunkGraph) => {
+	if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
+		for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
+			if (chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
+				return true;
+			}
+		}
+	}
+
+	return Boolean(
+		chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
+	);
+};
+
+/**
+ * Returns true, when a JS file is needed for this chunk.
+ * @param {Chunk} chunk a chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @returns {boolean} true, when a JS file is needed for this chunk
+ */
+const chunkHasJs = (chunk, chunkGraph) => {
+	let innerCache = chunkHasJsCache.get(chunkGraph);
+	if (innerCache === undefined) {
+		innerCache = new WeakMap();
+		chunkHasJsCache.set(chunkGraph, innerCache);
+	}
+
+	const cachedResult = innerCache.get(chunk);
+	if (cachedResult !== undefined) {
+		return cachedResult;
+	}
+
+	const result = _chunkHasJs(chunk, chunkGraph);
+	innerCache.set(chunk, result);
+	return result;
+};
+
+/**
+ * Chunk has runtime or js.
+ * @param {Chunk} chunk a chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @returns {boolean} true, when a JS file is needed for this chunk
+ */
+const chunkHasRuntimeOrJs = (chunk, chunkGraph) => {
+	if (chunkHasJs(chunk, chunkGraph)) {
+		return true;
+	}
+
+	if (
+		chunkGraph.getChunkModulesIterableBySourceType(
+			chunk,
+			WEBPACK_MODULE_TYPE_RUNTIME
+		)
+	) {
+		for (const chunkGroup of chunk.groupsIterable) {
+			for (const c of chunkGroup.chunks) {
+				if (chunkHasJs(c, chunkGraph)) return true;
+			}
+		}
+		return false;
+	}
+
+	return false;
+};
+
+/**
+ * Print generated code for stack.
+ * @param {Module} module a module
+ * @param {string} code the code
+ * @returns {string} generated code for the stack
+ */
+const printGeneratedCodeForStack = (module, code) => {
+	const lines = code.split("\n");
+	const n = `${lines.length}`.length;
+	return `\n\nGenerated code for ${module.identifier()}\n${lines
+		.map(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {string} line the line
+			 * @param {number} i the index
+			 * @param {string[]} _lines the lines
+			 * @returns {string} the line with line number
+			 */
+			(line, i, _lines) => {
+				const iStr = `${i + 1}`;
+				return `${" ".repeat(n - iStr.length)}${iStr} | ${line}`;
+			}
+		)
+		.join("\n")}`;
+};
+
+/**
+ * Defines the render context type used by this module.
+ * @typedef {object} RenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {boolean | undefined} strictMode rendering in strict context
+ */
+
+/**
+ * Defines the main render context type used by this module.
+ * @typedef {object} MainRenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {string} hash hash to be used for render call
+ * @property {boolean | undefined} strictMode rendering in strict context
+ */
+
+/**
+ * Defines the chunk render context type used by this module.
+ * @typedef {object} ChunkRenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
+ * @property {boolean | undefined} strictMode rendering in strict context
+ */
+
+/**
+ * Defines the render bootstrap context type used by this module.
+ * @typedef {object} RenderBootstrapContext
+ * @property {Chunk} chunk the chunk
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {string} hash hash to be used for render call
+ */
+
+/**
+ * Defines the startup render context type used by this module.
+ * @typedef {object} StartupRenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {boolean | undefined} strictMode rendering in strict context
+ * @property {boolean=} inlined inlined
+ * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE
+ * @property {boolean=} needExportsDeclaration whether the top-level exports declaration needs to be generated
+ */
+
+/**
+ * Defines the module render context type used by this module.
+ * @typedef {object} ModuleRenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
+ * @property {boolean | undefined} strictMode rendering in strict context
+ * @property {boolean} factory true: renders as factory method, false: pure module content
+ * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE, existing only when `factory` is set to false
+ * @property {boolean=} renderInObject render module in object container
+ */
+
+/**
+ * Defines the compilation hooks type used by this module.
+ * @typedef {object} CompilationHooks
+ * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContent
+ * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContainer
+ * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModulePackage
+ * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk
+ * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain
+ * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent
+ * @property {SyncWaterfallHook<[Source, RenderContext]>} render
+ * @property {SyncWaterfallHook<[Source, Module, StartupRenderContext]>} renderStartup
+ * @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire
+ * @property {SyncBailHook<[Module, Partial<RenderBootstrapContext>], string | void>} inlineInRuntimeBailout
+ * @property {SyncBailHook<[Module, RenderContext], string | void>} embedInRuntimeBailout
+ * @property {SyncBailHook<[RenderContext], string | void>} strictRuntimeBailout
+ * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
+ * @property {SyncBailHook<[Chunk, RenderContext], boolean | void>} useSourceMap
+ */
+
+/** @type {WeakMap<Compilation, CompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+const PLUGIN_NAME = "JavascriptModulesPlugin";
+
+/** @typedef {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} Bootstrap */
+
+class JavascriptModulesPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CompilationHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				renderModuleContent: new SyncWaterfallHook([
+					"source",
+					"module",
+					"moduleRenderContext"
+				]),
+				renderModuleContainer: new SyncWaterfallHook([
+					"source",
+					"module",
+					"moduleRenderContext"
+				]),
+				renderModulePackage: new SyncWaterfallHook([
+					"source",
+					"module",
+					"moduleRenderContext"
+				]),
+				render: new SyncWaterfallHook(["source", "renderContext"]),
+				renderContent: new SyncWaterfallHook(["source", "renderContext"]),
+				renderStartup: new SyncWaterfallHook([
+					"source",
+					"module",
+					"startupRenderContext"
+				]),
+				renderChunk: new SyncWaterfallHook(["source", "renderContext"]),
+				renderMain: new SyncWaterfallHook(["source", "renderContext"]),
+				renderRequire: new SyncWaterfallHook(["code", "renderContext"]),
+				inlineInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
+				embedInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
+				strictRuntimeBailout: new SyncBailHook(["renderContext"]),
+				chunkHash: new SyncHook(["chunk", "hash", "context"]),
+				useSourceMap: new SyncBailHook(["chunk", "renderContext"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	constructor(options = {}) {
+		this.options = options;
+		/** @type {WeakMap<Source, { source: Source, needModule: boolean, needExports: boolean, needRequire: boolean, needThisAsExports: boolean, needStrict: boolean | undefined, renderShorthand: boolean }>} */
+		this._moduleFactoryCache = new WeakMap();
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
+
+				for (const type of [
+					JAVASCRIPT_MODULE_TYPE_AUTO,
+					JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+					JAVASCRIPT_MODULE_TYPE_ESM
+				]) {
+					normalModuleFactory.hooks.createParser
+						.for(type)
+						.tap(PLUGIN_NAME, (options) => {
+							switch (type) {
+								case JAVASCRIPT_MODULE_TYPE_AUTO: {
+									return new JavascriptParser("auto", {
+										parse: options.parse,
+										typescript: options.typescript
+									});
+								}
+								case JAVASCRIPT_MODULE_TYPE_DYNAMIC: {
+									return new JavascriptParser("script", {
+										parse: options.parse,
+										typescript: options.typescript
+									});
+								}
+								case JAVASCRIPT_MODULE_TYPE_ESM: {
+									return new JavascriptParser("module", {
+										parse: options.parse,
+										typescript: options.typescript
+									});
+								}
+							}
+						});
+					normalModuleFactory.hooks.createGenerator
+						.for(type)
+						.tap(PLUGIN_NAME, () => new JavascriptGenerator());
+
+					NormalModule.getCompilationHooks(compilation).processResult.tap(
+						PLUGIN_NAME,
+						(result, module) => {
+							if (module.type === type) {
+								const [source, ...rest] = result;
+
+								return [removeBOM(source), ...rest];
+							}
+
+							return result;
+						}
+					);
+				}
+
+				compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
+					const {
+						hash,
+						chunk,
+						chunkGraph,
+						moduleGraph,
+						runtimeTemplate,
+						dependencyTemplates,
+						outputOptions,
+						codeGenerationResults
+					} = options;
+
+					const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
+					const filenameTemplate =
+						JavascriptModulesPlugin.getChunkFilenameTemplate(
+							chunk,
+							outputOptions
+						);
+
+					/** @type {() => Source} */
+					let render;
+
+					if (hotUpdateChunk) {
+						render = () =>
+							this.renderChunk(
+								{
+									chunk,
+									dependencyTemplates,
+									runtimeTemplate,
+									moduleGraph,
+									chunkGraph,
+									codeGenerationResults,
+									strictMode: runtimeTemplate.isModule()
+								},
+								hooks
+							);
+					} else if (chunk.hasRuntime()) {
+						if (!chunkHasRuntimeOrJs(chunk, chunkGraph)) {
+							return result;
+						}
+
+						render = () =>
+							this.renderMain(
+								{
+									hash,
+									chunk,
+									dependencyTemplates,
+									runtimeTemplate,
+									moduleGraph,
+									chunkGraph,
+									codeGenerationResults,
+									strictMode: runtimeTemplate.isModule()
+								},
+								hooks,
+								compilation
+							);
+					} else {
+						if (!chunkHasJs(chunk, chunkGraph)) {
+							return result;
+						}
+
+						render = () =>
+							this.renderChunk(
+								{
+									chunk,
+									dependencyTemplates,
+									runtimeTemplate,
+									moduleGraph,
+									chunkGraph,
+									codeGenerationResults,
+									strictMode: runtimeTemplate.isModule()
+								},
+								hooks
+							);
+					}
+
+					result.push({
+						render,
+						filenameTemplate,
+						pathOptions: {
+							hash,
+							runtime: chunk.runtime,
+							chunk,
+							contentHashType: "javascript"
+						},
+						info: {
+							javascriptModule: compilation.runtimeTemplate.isModule()
+						},
+						identifier: hotUpdateChunk
+							? `hotupdatechunk${chunk.id}`
+							: `chunk${chunk.id}`,
+						hash: chunk.contentHash.javascript
+					});
+
+					return result;
+				});
+				compilation.hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash, context) => {
+					hooks.chunkHash.call(chunk, hash, context);
+					if (chunk.hasRuntime()) {
+						this.updateHashWithBootstrap(
+							hash,
+							{
+								hash: "0000",
+								chunk,
+								codeGenerationResults: context.codeGenerationResults,
+								chunkGraph: context.chunkGraph,
+								moduleGraph: context.moduleGraph,
+								runtimeTemplate: context.runtimeTemplate
+							},
+							hooks
+						);
+					}
+				});
+				compilation.hooks.contentHash.tap(PLUGIN_NAME, (chunk) => {
+					const {
+						chunkGraph,
+						moduleGraph,
+						runtimeTemplate,
+						outputOptions: {
+							hashSalt,
+							hashDigest,
+							hashDigestLength,
+							hashFunction
+						}
+					} = compilation;
+					const codeGenerationResults =
+						/** @type {CodeGenerationResults} */
+						(compilation.codeGenerationResults);
+					const hash = createHash(hashFunction);
+					if (hashSalt) hash.update(hashSalt);
+					if (chunk.hasRuntime()) {
+						this.updateHashWithBootstrap(
+							hash,
+							{
+								hash: "0000",
+								chunk,
+								codeGenerationResults,
+								chunkGraph: compilation.chunkGraph,
+								moduleGraph: compilation.moduleGraph,
+								runtimeTemplate: compilation.runtimeTemplate
+							},
+							hooks
+						);
+					} else {
+						hash.update(`${chunk.id} `);
+						hash.update(chunk.ids ? chunk.ids.join(",") : "");
+					}
+					hooks.chunkHash.call(chunk, hash, {
+						chunkGraph,
+						codeGenerationResults,
+						moduleGraph,
+						runtimeTemplate
+					});
+					const modules = chunkGraph.getChunkModulesIterableBySourceType(
+						chunk,
+						JAVASCRIPT_TYPE
+					);
+					if (modules) {
+						const xor = new StringXor();
+						for (const m of modules) {
+							xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
+						}
+						xor.updateHash(hash);
+					}
+					const runtimeModules = chunkGraph.getChunkModulesIterableBySourceType(
+						chunk,
+						WEBPACK_MODULE_TYPE_RUNTIME
+					);
+					if (runtimeModules) {
+						const xor = new StringXor();
+						for (const m of runtimeModules) {
+							xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
+						}
+						xor.updateHash(hash);
+					}
+					const digest = hash.digest(hashDigest);
+					chunk.contentHash.javascript = nonNumericOnlyHash(
+						digest,
+						hashDigestLength
+					);
+				});
+				compilation.hooks.additionalTreeRuntimeRequirements.tap(
+					PLUGIN_NAME,
+					(chunk, set, { chunkGraph }) => {
+						if (
+							!set.has(RuntimeGlobals.startupNoDefault) &&
+							chunkGraph.hasChunkEntryDependentChunks(chunk)
+						) {
+							set.add(RuntimeGlobals.onChunksLoaded);
+							set.add(RuntimeGlobals.exports);
+							set.add(RuntimeGlobals.require);
+						}
+					}
+				);
+				compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => {
+					const source =
+						options.codeGenerationResult.sources.get(JAVASCRIPT_TYPE);
+					if (source === undefined) return;
+					const { module } = options;
+					const code = source.source();
+
+					/** @type {(this: ExecuteModuleObject["exports"], exports: ExecuteModuleObject["exports"], moduleObject: ExecuteModuleObject, webpackRequire: WebpackRequire) => void} */
+					const fn = vm.runInThisContext(
+						`(function(${module.moduleArgument}, ${module.exportsArgument}, ${RuntimeGlobals.require}) {\n${code}\n/**/})`,
+						{
+							filename: module.identifier(),
+							lineOffset: -1
+						}
+					);
+
+					const moduleObject =
+						/** @type {ExecuteModuleObject} */
+						(options.moduleObject);
+
+					try {
+						fn.call(
+							moduleObject.exports,
+							moduleObject,
+							moduleObject.exports,
+							/** @type {WebpackRequire} */
+							(context.__webpack_require__)
+						);
+					} catch (err) {
+						/** @type {Error} */
+						(err).stack += printGeneratedCodeForStack(
+							options.module,
+							/** @type {string} */ (code)
+						);
+						throw err;
+					}
+				});
+				compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => {
+					const source = options.codeGenerationResult.sources.get("runtime");
+					if (source === undefined) return;
+					let code = source.source();
+					if (typeof code !== "string") code = code.toString();
+
+					/** @type {(this: null, webpackRequire: WebpackRequire) => void} */
+					const fn = vm.runInThisContext(
+						`(function(${RuntimeGlobals.require}) {\n${code}\n/**/})`,
+						{
+							filename: options.module.identifier(),
+							lineOffset: -1
+						}
+					);
+					try {
+						// eslint-disable-next-line no-useless-call
+						fn.call(
+							null,
+							/** @type {WebpackRequire} */
+							(context.__webpack_require__)
+						);
+					} catch (err) {
+						/** @type {Error} */
+						(err).stack += printGeneratedCodeForStack(options.module, code);
+						throw err;
+					}
+				});
+			}
+		);
+	}
+
+	/**
+	 * Gets chunk filename template.
+	 * @param {Chunk} chunk chunk
+	 * @param {OutputOptions} outputOptions output options
+	 * @returns {ChunkFilenameTemplate} used filename template
+	 */
+	static getChunkFilenameTemplate(chunk, outputOptions) {
+		if (chunk.filenameTemplate) {
+			return chunk.filenameTemplate;
+		} else if (chunk instanceof HotUpdateChunk) {
+			return outputOptions.hotUpdateChunkFilename;
+		} else if (chunk.canBeInitial()) {
+			return outputOptions.filename;
+		}
+		return outputOptions.chunkFilename;
+	}
+
+	/**
+	 * Renders the newly generated source from rendering.
+	 * @param {Module} module the rendered module
+	 * @param {ModuleRenderContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {Source | null} the newly generated source from rendering
+	 */
+	renderModule(module, renderContext, hooks) {
+		const {
+			chunk,
+			chunkGraph,
+			runtimeTemplate,
+			codeGenerationResults,
+			strictMode,
+			factory,
+			renderInObject
+		} = renderContext;
+		try {
+			const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
+			const moduleSource = codeGenResult.sources.get(JAVASCRIPT_TYPE);
+			if (!moduleSource) return null;
+			if (codeGenResult.data !== undefined) {
+				const chunkInitFragments = codeGenResult.data.get("chunkInitFragments");
+				if (chunkInitFragments) {
+					for (const i of chunkInitFragments) {
+						renderContext.chunkInitFragments.push(i);
+					}
+				}
+			}
+			const moduleSourcePostContent = tryRunOrWebpackError(
+				() =>
+					hooks.renderModuleContent.call(moduleSource, module, renderContext),
+				"JavascriptModulesPlugin.getCompilationHooks().renderModuleContent"
+			);
+			/** @type {Source} */
+			let moduleSourcePostContainer;
+			if (factory) {
+				const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
+					module,
+					chunk.runtime
+				);
+				const needModule = runtimeRequirements.has(RuntimeGlobals.module);
+				const needExports = runtimeRequirements.has(RuntimeGlobals.exports);
+				const needRequire =
+					runtimeRequirements.has(RuntimeGlobals.require) ||
+					runtimeRequirements.has(RuntimeGlobals.requireScope);
+				const needThisAsExports = runtimeRequirements.has(
+					RuntimeGlobals.thisAsExports
+				);
+				const needStrict =
+					/** @type {BuildInfo} */
+					(module.buildInfo).strict && !strictMode;
+				const cacheEntry = this._moduleFactoryCache.get(
+					moduleSourcePostContent
+				);
+				const renderShorthand =
+					renderInObject === true && runtimeTemplate.supportsMethodShorthand();
+				/** @type {Source} */
+				let source;
+				if (
+					cacheEntry &&
+					cacheEntry.needModule === needModule &&
+					cacheEntry.needExports === needExports &&
+					cacheEntry.needRequire === needRequire &&
+					cacheEntry.needThisAsExports === needThisAsExports &&
+					cacheEntry.needStrict === needStrict &&
+					cacheEntry.renderShorthand === renderShorthand
+				) {
+					source = cacheEntry.source;
+				} else {
+					const factorySource = new ConcatSource();
+					/** @type {string[]} */
+					const args = [];
+					if (needExports || needRequire || needModule) {
+						args.push(
+							needModule
+								? module.moduleArgument
+								: `__unused_webpack_${module.moduleArgument}`
+						);
+					}
+					if (needExports || needRequire) {
+						args.push(
+							needExports
+								? module.exportsArgument
+								: `__unused_webpack_${module.exportsArgument}`
+						);
+					}
+					if (needRequire) args.push(RuntimeGlobals.require);
+
+					if (renderShorthand) {
+						// we can optimize function to methodShorthand if render module factory in object
+						factorySource.add(`(${args.join(", ")}) {\n\n`);
+					} else if (
+						!needThisAsExports &&
+						runtimeTemplate.supportsArrowFunction()
+					) {
+						factorySource.add(`/***/ ((${args.join(", ")}) => {\n\n`);
+					} else {
+						factorySource.add(`/***/ (function(${args.join(", ")}) {\n\n`);
+					}
+
+					if (needStrict) {
+						factorySource.add('"use strict";\n');
+					}
+					factorySource.add(moduleSourcePostContent);
+					factorySource.add(`\n\n/***/ }${renderShorthand ? "" : ")"}`);
+					source = new CachedSource(factorySource);
+					this._moduleFactoryCache.set(moduleSourcePostContent, {
+						source,
+						needModule,
+						needExports,
+						needRequire,
+						needThisAsExports,
+						needStrict,
+						renderShorthand
+					});
+				}
+				moduleSourcePostContainer = tryRunOrWebpackError(
+					() => hooks.renderModuleContainer.call(source, module, renderContext),
+					"JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer"
+				);
+			} else {
+				moduleSourcePostContainer = moduleSourcePostContent;
+			}
+			return tryRunOrWebpackError(
+				() =>
+					hooks.renderModulePackage.call(
+						moduleSourcePostContainer,
+						module,
+						renderContext
+					),
+				"JavascriptModulesPlugin.getCompilationHooks().renderModulePackage"
+			);
+		} catch (err) {
+			/** @type {WebpackError} */
+			(err).module = module;
+			throw err;
+		}
+	}
+
+	/**
+	 * Renders the rendered source.
+	 * @param {RenderContext} renderContext the render context
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {Source} the rendered source
+	 */
+	renderChunk(renderContext, hooks) {
+		const { chunk, chunkGraph, runtimeTemplate } = renderContext;
+		const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
+			chunk,
+			JAVASCRIPT_TYPE,
+			compareModulesByFullName(runtimeTemplate.compilation.compiler)
+		);
+		const allModules = modules ? [...modules] : [];
+		/** @type {undefined | string} */
+		let strictHeader;
+		let allStrict = renderContext.strictMode;
+		if (
+			!allStrict &&
+			allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict)
+		) {
+			const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
+			strictHeader = strictBailout
+				? `// runtime can't be in strict mode because ${strictBailout}.\n`
+				: '"use strict";\n';
+			if (!strictBailout) allStrict = true;
+		}
+		/** @type {ChunkRenderContext} */
+		const chunkRenderContext = {
+			...renderContext,
+			chunkInitFragments: [],
+			strictMode: allStrict
+		};
+		const moduleSources =
+			Template.renderChunkModules(
+				chunkRenderContext,
+				allModules,
+				(module, renderInObject) =>
+					this.renderModule(
+						module,
+						{ ...chunkRenderContext, factory: true, renderInObject },
+						hooks
+					)
+			) || new RawSource("{}");
+		let source = tryRunOrWebpackError(
+			() => hooks.renderChunk.call(moduleSources, chunkRenderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().renderChunk"
+		);
+		source = tryRunOrWebpackError(
+			() => hooks.renderContent.call(source, chunkRenderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().renderContent"
+		);
+		if (!source) {
+			throw new Error(
+				"JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
+			);
+		}
+		source = InitFragment.addToSource(
+			source,
+			chunkRenderContext.chunkInitFragments,
+			chunkRenderContext
+		);
+		source = tryRunOrWebpackError(
+			() => hooks.render.call(source, chunkRenderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().render"
+		);
+		if (!source) {
+			throw new Error(
+				"JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
+			);
+		}
+		chunk.rendered = true;
+		return strictHeader
+			? new ConcatSource(strictHeader, source, ";")
+			: renderContext.runtimeTemplate.isModule()
+				? source
+				: new ConcatSource(source, ";");
+	}
+
+	/**
+	 * Renders the newly generated source from rendering.
+	 * @param {MainRenderContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 * @param {Compilation} compilation the compilation
+	 * @returns {Source} the newly generated source from rendering
+	 */
+	renderMain(renderContext, hooks, compilation) {
+		const { chunk, chunkGraph, runtimeTemplate } = renderContext;
+
+		const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
+		const iife = runtimeTemplate.isIIFE();
+
+		const bootstrap = this.renderBootstrap(renderContext, hooks);
+		const useSourceMap = hooks.useSourceMap.call(chunk, renderContext);
+
+		/** @type {Module[]} */
+		const allModules = [
+			...(chunkGraph.getOrderedChunkModulesIterableBySourceType(
+				chunk,
+				JAVASCRIPT_TYPE,
+				compareModulesByFullName(runtimeTemplate.compilation.compiler)
+			) || [])
+		];
+
+		const hasEntryModules = chunkGraph.getNumberOfEntryModules(chunk) > 0;
+		/** @type {Set<Module> | undefined} */
+		let inlinedModules;
+		if (bootstrap.allowInlineStartup && hasEntryModules) {
+			inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk));
+		}
+
+		const source = new ConcatSource();
+		/** @type {string} */
+		let prefix;
+		if (iife) {
+			if (runtimeTemplate.supportsArrowFunction()) {
+				source.add("/******/ (() => { // webpackBootstrap\n");
+			} else {
+				source.add("/******/ (function() { // webpackBootstrap\n");
+			}
+			prefix = "/******/ \t";
+		} else {
+			prefix = "/******/ ";
+		}
+		let allStrict = renderContext.strictMode;
+		if (
+			!allStrict &&
+			allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict)
+		) {
+			const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
+			if (strictBailout) {
+				source.add(
+					`${
+						prefix
+					}// runtime can't be in strict mode because ${strictBailout}.\n`
+				);
+			} else {
+				allStrict = true;
+				source.add(`${prefix}"use strict";\n`);
+			}
+		}
+
+		/** @type {ChunkRenderContext} */
+		const chunkRenderContext = {
+			...renderContext,
+			chunkInitFragments: [],
+			strictMode: allStrict
+		};
+
+		const chunkModules = Template.renderChunkModules(
+			chunkRenderContext,
+			inlinedModules
+				? allModules.filter(
+						(m) => !(/** @type {Set<Module>} */ (inlinedModules).has(m))
+					)
+				: allModules,
+			(module, renderInObject) =>
+				this.renderModule(
+					module,
+					{ ...chunkRenderContext, factory: true, renderInObject },
+					hooks
+				),
+			prefix
+		);
+		if (
+			chunkModules ||
+			runtimeRequirements.has(RuntimeGlobals.moduleFactories) ||
+			runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) ||
+			runtimeRequirements.has(RuntimeGlobals.require)
+		) {
+			source.add(`${prefix}var __webpack_modules__ = (`);
+			source.add(chunkModules || "{}");
+			source.add(");\n");
+			source.add(
+				"/************************************************************************/\n"
+			);
+		}
+
+		if (bootstrap.header.length > 0) {
+			const header = `${Template.asString(bootstrap.header)}\n`;
+			source.add(
+				new PrefixSource(
+					prefix,
+					useSourceMap
+						? new OriginalSource(header, "webpack/bootstrap")
+						: new RawSource(header)
+				)
+			);
+			source.add(
+				"/************************************************************************/\n"
+			);
+		}
+
+		const runtimeModules =
+			renderContext.chunkGraph.getChunkRuntimeModulesInOrder(chunk);
+
+		if (runtimeModules.length > 0) {
+			source.add(
+				new PrefixSource(
+					prefix,
+					Template.renderRuntimeModules(runtimeModules, chunkRenderContext)
+				)
+			);
+			source.add(
+				"/************************************************************************/\n"
+			);
+			// runtimeRuntimeModules calls codeGeneration
+			for (const module of runtimeModules) {
+				compilation.codeGeneratedModules.add(module);
+			}
+		}
+		if (inlinedModules) {
+			if (bootstrap.beforeStartup.length > 0) {
+				const beforeStartup = `${Template.asString(bootstrap.beforeStartup)}\n`;
+				source.add(
+					new PrefixSource(
+						prefix,
+						useSourceMap
+							? new OriginalSource(beforeStartup, "webpack/before-startup")
+							: new RawSource(beforeStartup)
+					)
+				);
+			}
+			const lastInlinedModule = /** @type {Module} */ (last(inlinedModules));
+			const startupSource = new ConcatSource();
+
+			const avoidEntryIife = compilation.options.optimization.avoidEntryIife;
+			/** @type {Map<Module, Source> | false} */
+			let renamedInlinedModule = false;
+			let inlinedInIIFE = false;
+
+			if (avoidEntryIife) {
+				renamedInlinedModule = this._getRenamedInlineModule(
+					compilation,
+					allModules,
+					renderContext,
+					inlinedModules,
+					chunkRenderContext,
+					hooks,
+					allStrict,
+					Boolean(chunkModules)
+				);
+			}
+
+			for (const m of inlinedModules) {
+				const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
+					m,
+					chunk.runtime
+				);
+				const exports = runtimeRequirements.has(RuntimeGlobals.exports);
+				const webpackExports =
+					exports && m.exportsArgument === RuntimeGlobals.exports;
+
+				const innerStrict =
+					!allStrict && /** @type {BuildInfo} */ (m.buildInfo).strict;
+
+				const iife = innerStrict
+					? "it needs to be in strict mode."
+					: inlinedModules.size > 1
+						? // TODO check globals and top-level declarations of other entries and chunk modules
+							// to make a better decision
+							"it needs to be isolated against other entry modules."
+						: chunkModules && !renamedInlinedModule
+							? "it needs to be isolated against other modules in the chunk."
+							: exports && !webpackExports
+								? `it uses a non-standard name for the exports (${m.exportsArgument}).`
+								: hooks.embedInRuntimeBailout.call(m, renderContext);
+
+				if (iife) {
+					inlinedInIIFE = true;
+				}
+
+				const renderedModule = renamedInlinedModule
+					? renamedInlinedModule.get(m)
+					: this.renderModule(
+							m,
+							{
+								...chunkRenderContext,
+								factory: false,
+								inlinedInIIFE
+							},
+							hooks
+						);
+
+				if (renderedModule) {
+					/** @type {string} */
+					let footer;
+					if (iife !== undefined) {
+						startupSource.add(
+							`// This entry needs to be wrapped in an IIFE because ${iife}\n`
+						);
+						const arrow = runtimeTemplate.supportsArrowFunction();
+						if (arrow) {
+							startupSource.add("(() => {\n");
+							footer = "\n})();\n\n";
+						} else {
+							startupSource.add("!function() {\n");
+							footer = "\n}();\n";
+						}
+						if (innerStrict) startupSource.add('"use strict";\n');
+					} else {
+						footer = "\n";
+					}
+					if (exports) {
+						if (m !== lastInlinedModule) {
+							startupSource.add(`var ${m.exportsArgument} = {};\n`);
+						} else if (m.exportsArgument !== RuntimeGlobals.exports) {
+							startupSource.add(
+								`var ${m.exportsArgument} = ${RuntimeGlobals.exports};\n`
+							);
+						}
+					}
+					startupSource.add(renderedModule);
+					startupSource.add(footer);
+				}
+			}
+			if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
+				startupSource.add(
+					`${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});\n`
+				);
+			}
+			/** @type {StartupRenderContext} */
+			const startupRenderContext = {
+				...renderContext,
+				inlined: true,
+				inlinedInIIFE,
+				needExportsDeclaration: runtimeRequirements.has(RuntimeGlobals.exports)
+			};
+			let renderedStartup = hooks.renderStartup.call(
+				startupSource,
+				lastInlinedModule,
+				startupRenderContext
+			);
+			const lastInlinedModuleRequirements =
+				chunkGraph.getModuleRuntimeRequirements(
+					lastInlinedModule,
+					chunk.runtime
+				);
+			if (
+				// `onChunksLoaded` reads and reassigns `__webpack_exports__`
+				runtimeRequirements.has(RuntimeGlobals.onChunksLoaded) ||
+				// Top-level `__webpack_exports__` will be returned
+				runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime) ||
+				// Custom exports argument aliases from `__webpack_exports__`
+				(lastInlinedModuleRequirements.has(RuntimeGlobals.exports) &&
+					lastInlinedModule.exportsArgument !== RuntimeGlobals.exports)
+			) {
+				startupRenderContext.needExportsDeclaration = true;
+			}
+			if (startupRenderContext.needExportsDeclaration) {
+				renderedStartup = new ConcatSource(
+					`var ${RuntimeGlobals.exports} = {};\n`,
+					renderedStartup
+				);
+			}
+			source.add(renderedStartup);
+			if (bootstrap.afterStartup.length > 0) {
+				const afterStartup = `${Template.asString(bootstrap.afterStartup)}\n`;
+				source.add(
+					new PrefixSource(
+						prefix,
+						useSourceMap
+							? new OriginalSource(afterStartup, "webpack/after-startup")
+							: new RawSource(afterStartup)
+					)
+				);
+			}
+		} else {
+			const lastEntryModule =
+				/** @type {Module} */
+				(last(chunkGraph.getChunkEntryModulesIterable(chunk)));
+			/** @type {(content: string[], name: string) => Source} */
+			const toSource = useSourceMap
+				? (content, name) =>
+						new OriginalSource(Template.asString(content), name)
+				: (content) => new RawSource(Template.asString(content));
+			source.add(
+				new PrefixSource(
+					prefix,
+					new ConcatSource(
+						toSource(bootstrap.beforeStartup, "webpack/before-startup"),
+						"\n",
+						hooks.renderStartup.call(
+							toSource([...bootstrap.startup, ""], "webpack/startup"),
+							lastEntryModule,
+							{
+								...renderContext,
+								inlined: false,
+								needExportsDeclaration: true
+							}
+						),
+						toSource(bootstrap.afterStartup, "webpack/after-startup"),
+						"\n"
+					)
+				)
+			);
+		}
+		if (
+			hasEntryModules &&
+			runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)
+		) {
+			source.add(`${prefix}return ${RuntimeGlobals.exports};\n`);
+		}
+		if (iife) {
+			source.add("/******/ })()\n");
+		}
+
+		/** @type {Source} */
+		let finalSource = tryRunOrWebpackError(
+			() => hooks.renderMain.call(source, renderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().renderMain"
+		);
+		if (!finalSource) {
+			throw new Error(
+				"JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderMain plugins should return something"
+			);
+		}
+		finalSource = tryRunOrWebpackError(
+			() => hooks.renderContent.call(finalSource, renderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().renderContent"
+		);
+		if (!finalSource) {
+			throw new Error(
+				"JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
+			);
+		}
+
+		finalSource = InitFragment.addToSource(
+			finalSource,
+			chunkRenderContext.chunkInitFragments,
+			chunkRenderContext
+		);
+		finalSource = tryRunOrWebpackError(
+			() => hooks.render.call(finalSource, renderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().render"
+		);
+		if (!finalSource) {
+			throw new Error(
+				"JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
+			);
+		}
+		chunk.rendered = true;
+		return iife ? new ConcatSource(finalSource, ";") : finalSource;
+	}
+
+	/**
+	 * Updates hash with bootstrap.
+	 * @param {Hash} hash the hash to be updated
+	 * @param {RenderBootstrapContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 */
+	updateHashWithBootstrap(hash, renderContext, hooks) {
+		const bootstrap = this.renderBootstrap(renderContext, hooks);
+		for (const _k of Object.keys(bootstrap)) {
+			const key = /** @type {keyof Bootstrap} */ (_k);
+			hash.update(key);
+			if (Array.isArray(bootstrap[key])) {
+				for (const line of bootstrap[key]) {
+					hash.update(line);
+				}
+			} else {
+				hash.update(JSON.stringify(bootstrap[key]));
+			}
+		}
+	}
+
+	/**
+	 * Renders the generated source of the bootstrap code.
+	 * @param {RenderBootstrapContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {Bootstrap} the generated source of the bootstrap code
+	 */
+	renderBootstrap(renderContext, hooks) {
+		const {
+			chunkGraph,
+			codeGenerationResults,
+			moduleGraph,
+			chunk,
+			runtimeTemplate
+		} = renderContext;
+
+		const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
+
+		const requireFunction = runtimeRequirements.has(RuntimeGlobals.require);
+		const moduleCache = runtimeRequirements.has(RuntimeGlobals.moduleCache);
+		const moduleFactories = runtimeRequirements.has(
+			RuntimeGlobals.moduleFactories
+		);
+		const moduleUsed = runtimeRequirements.has(RuntimeGlobals.module);
+		const requireScopeUsed = runtimeRequirements.has(
+			RuntimeGlobals.requireScope
+		);
+		const interceptModuleExecution = runtimeRequirements.has(
+			RuntimeGlobals.interceptModuleExecution
+		);
+
+		const useRequire =
+			requireFunction || interceptModuleExecution || moduleUsed;
+
+		/**
+		 * @type {{ startup: string[], beforeStartup: string[], header: string[], afterStartup: string[], allowInlineStartup: boolean }}
+		 */
+		const result = {
+			header: [],
+			beforeStartup: [],
+			startup: [],
+			afterStartup: [],
+			allowInlineStartup: true
+		};
+
+		const { header: buf, startup, beforeStartup, afterStartup } = result;
+
+		if (result.allowInlineStartup && moduleFactories) {
+			startup.push(
+				"// module factories are used so entry inlining is disabled"
+			);
+			result.allowInlineStartup = false;
+		}
+		if (result.allowInlineStartup && moduleCache) {
+			startup.push("// module cache are used so entry inlining is disabled");
+			result.allowInlineStartup = false;
+		}
+		if (result.allowInlineStartup && interceptModuleExecution) {
+			startup.push(
+				"// module execution is intercepted so entry inlining is disabled"
+			);
+			result.allowInlineStartup = false;
+		}
+
+		if (useRequire || moduleCache) {
+			buf.push("// The module cache");
+			buf.push("var __webpack_module_cache__ = {};");
+			buf.push("");
+		}
+
+		if (runtimeRequirements.has(RuntimeGlobals.makeDeferredNamespaceObject)) {
+			// in order to optimize of DeferredNamespaceObject, we remove all proxy handlers after the module initialize
+			// (see MakeDeferredNamespaceObjectRuntimeModule)
+			// This requires all deferred imports to a module can get the module export object before the module
+			// is evaluated.
+			buf.push("// The deferred module cache");
+			buf.push("var __webpack_module_deferred_exports__ = {};");
+			// Per the TC39 import-defer spec, every defer-import call site for
+			// the same module must yield the same Deferred Module Namespace
+			// Exotic Object (and a distinct one from any eager namespace).
+			// Cache the deferred namespace proxy here so calls from different
+			// files share identity.
+			buf.push("// The deferred namespace cache");
+			buf.push("var __webpack_module_deferred_namespace_cache__ = {};");
+			buf.push("");
+		}
+
+		if (useRequire) {
+			buf.push("// The require function");
+			buf.push(`function ${RuntimeGlobals.require}(moduleId) {`);
+			buf.push(Template.indent(this.renderRequire(renderContext, hooks)));
+			buf.push("}");
+			buf.push("");
+		} else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) {
+			buf.push("// The require scope");
+			buf.push(`var ${RuntimeGlobals.require} = {};`);
+			buf.push("");
+		}
+
+		if (
+			moduleFactories ||
+			runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly)
+		) {
+			buf.push("// expose the modules object (__webpack_modules__)");
+			buf.push(`${RuntimeGlobals.moduleFactories} = __webpack_modules__;`);
+			buf.push("");
+		}
+
+		if (moduleCache) {
+			buf.push("// expose the module cache");
+			buf.push(`${RuntimeGlobals.moduleCache} = __webpack_module_cache__;`);
+			buf.push("");
+		}
+
+		if (interceptModuleExecution) {
+			buf.push("// expose the module execution interceptor");
+			buf.push(`${RuntimeGlobals.interceptModuleExecution} = [];`);
+			buf.push("");
+		}
+
+		if (!runtimeRequirements.has(RuntimeGlobals.startupNoDefault)) {
+			if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
+				/** @type {string[]} */
+				const buf2 = [];
+				const runtimeRequirements =
+					chunkGraph.getTreeRuntimeRequirements(chunk);
+				buf2.push("// Load entry module and return exports");
+
+				/** @type {EntryModuleWithChunkGroup[]} */
+				const jsEntries = [];
+				for (const [
+					entryModule,
+					entrypoint
+				] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) {
+					if (
+						chunkGraph.getModuleSourceTypes(entryModule).has(JAVASCRIPT_TYPE)
+					) {
+						jsEntries.push([entryModule, entrypoint]);
+						continue;
+					}
+				}
+				let i = jsEntries.length;
+				for (const [entryModule, entrypoint] of jsEntries) {
+					const chunks =
+						/** @type {Entrypoint} */
+						(entrypoint).chunks.filter((c) => c !== chunk);
+					if (result.allowInlineStartup && chunks.length > 0) {
+						buf2.push(
+							"// This entry module depends on other loaded chunks and execution need to be delayed"
+						);
+						result.allowInlineStartup = false;
+					}
+					if (
+						result.allowInlineStartup &&
+						someInIterable(
+							moduleGraph.getIncomingConnectionsByOriginModule(entryModule),
+							([originModule, connections]) =>
+								originModule &&
+								connections.some((c) => c.isTargetActive(chunk.runtime)) &&
+								someInIterable(
+									chunkGraph.getModuleRuntimes(originModule),
+									(runtime) =>
+										intersectRuntime(runtime, chunk.runtime) !== undefined
+								)
+						)
+					) {
+						buf2.push(
+							"// This entry module is referenced by other modules so it can't be inlined"
+						);
+						result.allowInlineStartup = false;
+					}
+
+					/** @type {undefined | CodeGenerationResultData} */
+					let data;
+					if (codeGenerationResults.has(entryModule, chunk.runtime)) {
+						const result = codeGenerationResults.get(
+							entryModule,
+							chunk.runtime
+						);
+						data = result.data;
+					}
+					if (
+						result.allowInlineStartup &&
+						(!data || !data.get("topLevelDeclarations")) &&
+						(!entryModule.buildInfo ||
+							!entryModule.buildInfo.topLevelDeclarations)
+					) {
+						buf2.push(
+							"// This entry module doesn't tell about it's top-level declarations so it can't be inlined"
+						);
+						result.allowInlineStartup = false;
+					}
+					if (result.allowInlineStartup) {
+						const bailout = hooks.inlineInRuntimeBailout.call(
+							entryModule,
+							renderContext
+						);
+						if (bailout !== undefined) {
+							buf2.push(
+								`// This entry module can't be inlined because ${bailout}`
+							);
+							result.allowInlineStartup = false;
+						}
+					}
+					i--;
+					const moduleId = chunkGraph.getModuleId(entryModule);
+					const entryRuntimeRequirements =
+						chunkGraph.getModuleRuntimeRequirements(entryModule, chunk.runtime);
+					let moduleIdExpr = JSON.stringify(moduleId);
+					if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) {
+						moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`;
+					}
+					if (
+						result.allowInlineStartup &&
+						entryRuntimeRequirements.has(RuntimeGlobals.module)
+					) {
+						result.allowInlineStartup = false;
+						buf2.push(
+							"// This entry module used 'module' so it can't be inlined"
+						);
+					}
+					if (
+						result.allowInlineStartup &&
+						entryRuntimeRequirements.has(RuntimeGlobals.thisAsExports)
+					) {
+						buf2.push(
+							"// This entry module used `this` as exports so it can't be inlined"
+						);
+						result.allowInlineStartup = false;
+					}
+
+					if (chunks.length > 0) {
+						buf2.push(
+							`${i === 0 ? `var ${RuntimeGlobals.exports} = ` : ""}${
+								RuntimeGlobals.onChunksLoaded
+							}(undefined, ${JSON.stringify(
+								chunks.map((c) => c.id)
+							)}, ${runtimeTemplate.returningFunction(
+								`${RuntimeGlobals.require}(${moduleIdExpr})`
+							)})`
+						);
+					} else if (useRequire) {
+						buf2.push(
+							`${i === 0 ? `var ${RuntimeGlobals.exports} = ` : ""}${
+								RuntimeGlobals.require
+							}(${moduleIdExpr});`
+						);
+					} else {
+						if (i === 0) buf2.push(`var ${RuntimeGlobals.exports} = {};`);
+						const needThisAsExports = entryRuntimeRequirements.has(
+							RuntimeGlobals.thisAsExports
+						);
+
+						/** @type {string[]} */
+						const args = [];
+						if (
+							requireScopeUsed ||
+							entryRuntimeRequirements.has(RuntimeGlobals.exports)
+						) {
+							const exportsArg = i === 0 ? RuntimeGlobals.exports : "{}";
+							args.push("0", exportsArg);
+							if (requireScopeUsed) {
+								args.push(RuntimeGlobals.require);
+							}
+						}
+						buf2.push(
+							Template.asString(
+								(() => {
+									if (needThisAsExports) {
+										const comma = args.length ? "," : "";
+										return `__webpack_modules__[${moduleIdExpr}].call(${RuntimeGlobals.exports}${comma}${args.join(",")});`;
+									}
+									return `__webpack_modules__[${moduleIdExpr}](${args.join(",")});`;
+								})()
+							)
+						);
+					}
+				}
+				if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
+					buf2.push(
+						`${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});`
+					);
+				}
+				if (
+					runtimeRequirements.has(RuntimeGlobals.startup) ||
+					(runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) &&
+						runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter))
+				) {
+					result.allowInlineStartup = false;
+					buf.push("// the startup function");
+					buf.push(
+						`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction("", [
+							...buf2,
+							`return ${RuntimeGlobals.exports};`
+						])};`
+					);
+					buf.push("");
+					startup.push("// run startup");
+					startup.push(
+						`var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();`
+					);
+				} else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) {
+					buf.push("// the startup function");
+					buf.push(
+						`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
+					);
+					beforeStartup.push("// run runtime startup");
+					beforeStartup.push(`${RuntimeGlobals.startup}();`);
+					startup.push("// startup");
+					startup.push(Template.asString(buf2));
+				} else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)) {
+					buf.push("// the startup function");
+					buf.push(
+						`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
+					);
+					startup.push("// startup");
+					startup.push(Template.asString(buf2));
+					afterStartup.push("// run runtime startup");
+					afterStartup.push(`${RuntimeGlobals.startup}();`);
+				} else {
+					startup.push("// startup");
+					startup.push(Template.asString(buf2));
+				}
+			} else if (
+				runtimeRequirements.has(RuntimeGlobals.startup) ||
+				runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
+				runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
+			) {
+				buf.push(
+					"// the startup function",
+					"// It's empty as no entry modules are in this chunk",
+					`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`,
+					""
+				);
+			}
+		} else if (
+			runtimeRequirements.has(RuntimeGlobals.startup) ||
+			runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
+			runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
+		) {
+			result.allowInlineStartup = false;
+			buf.push(
+				"// the startup function",
+				"// It's empty as some runtime module handles the default behavior",
+				`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
+			);
+			startup.push("// run startup");
+			startup.push(
+				`var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();`
+			);
+		}
+		return result;
+	}
+
+	/**
+	 * Renders the generated source of the require function.
+	 * @param {RenderBootstrapContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {string} the generated source of the require function
+	 */
+	renderRequire(renderContext, hooks) {
+		const {
+			chunk,
+			chunkGraph,
+			runtimeTemplate: { outputOptions }
+		} = renderContext;
+		const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
+
+		/**
+		 * Renders missing module error.
+		 * @param {string} condition guard expression
+		 * @returns {string[]} source
+		 */
+		const renderMissingModuleError = (condition) =>
+			outputOptions.pathinfo
+				? [
+						`if (${condition}) {`,
+						Template.indent([
+							"delete __webpack_module_cache__[moduleId];",
+							'var e = new Error("Cannot find module \'" + moduleId + "\'");',
+							"e.code = 'MODULE_NOT_FOUND';",
+							"throw e;"
+						]),
+						"}"
+					]
+				: [];
+
+		const moduleExecution = runtimeRequirements.has(
+			RuntimeGlobals.interceptModuleExecution
+		)
+			? Template.asString([
+					`var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: ${RuntimeGlobals.require} };`,
+					`${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
+					...renderMissingModuleError("!execOptions.factory"),
+					"module = execOptions.module;",
+					"execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
+				])
+			: runtimeRequirements.has(RuntimeGlobals.thisAsExports)
+				? Template.asString([
+						...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
+						`__webpack_modules__[moduleId].call(module.exports, module, module.exports, ${RuntimeGlobals.require});`
+					])
+				: Template.asString([
+						...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
+						`__webpack_modules__[moduleId](module, module.exports, ${RuntimeGlobals.require});`
+					]);
+		const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId);
+		const needModuleLoaded = runtimeRequirements.has(
+			RuntimeGlobals.moduleLoaded
+		);
+		const needModuleDefer = runtimeRequirements.has(
+			RuntimeGlobals.makeDeferredNamespaceObject
+		);
+		const content = Template.asString([
+			"// Check if module is in cache",
+			"var cachedModule = __webpack_module_cache__[moduleId];",
+			"if (cachedModule !== undefined) {",
+			outputOptions.strictModuleErrorHandling
+				? Template.indent([
+						"if (cachedModule.error !== undefined) throw cachedModule.error;",
+						"return cachedModule.exports;"
+					])
+				: Template.indent("return cachedModule.exports;"),
+			"}",
+			"// Create a new module (and put it into the cache)",
+			"var module = __webpack_module_cache__[moduleId] = {",
+			Template.indent([
+				needModuleId ? "id: moduleId," : "// no module.id needed",
+				needModuleLoaded ? "loaded: false," : "// no module.loaded needed",
+				needModuleDefer
+					? "exports: __webpack_module_deferred_exports__[moduleId] || {}"
+					: "exports: {}"
+			]),
+			"};",
+			"",
+			outputOptions.strictModuleExceptionHandling
+				? Template.asString([
+						"// Execute the module function",
+						"var threw = true;",
+						"try {",
+						Template.indent([
+							moduleExecution,
+							"threw = false;",
+							...(needModuleDefer
+								? ["delete __webpack_module_deferred_exports__[moduleId];"]
+								: [])
+						]),
+						"} finally {",
+						Template.indent([
+							"if(threw) delete __webpack_module_cache__[moduleId];"
+						]),
+						"}"
+					])
+				: outputOptions.strictModuleErrorHandling
+					? Template.asString([
+							"// Execute the module function",
+							"try {",
+							Template.indent(
+								needModuleDefer
+									? [
+											moduleExecution,
+											"delete __webpack_module_deferred_exports__[moduleId];"
+										]
+									: moduleExecution
+							),
+							"} catch(e) {",
+							Template.indent(["module.error = e;", "throw e;"]),
+							"}"
+						])
+					: Template.asString([
+							"// Execute the module function",
+							moduleExecution,
+							...(needModuleDefer
+								? ["delete __webpack_module_deferred_exports__[moduleId];"]
+								: [])
+						]),
+			needModuleLoaded
+				? Template.asString([
+						"",
+						"// Flag the module as loaded",
+						`${RuntimeGlobals.moduleLoaded} = true;`,
+						""
+					])
+				: "",
+			"// Return the exports of the module",
+			"return module.exports;"
+		]);
+		return tryRunOrWebpackError(
+			() => hooks.renderRequire.call(content, renderContext),
+			"JavascriptModulesPlugin.getCompilationHooks().renderRequire"
+		);
+	}
+
+	/**
+	 * Get renamed inline module.
+	 * @param {Compilation} compilation compilation
+	 * @param {Module[]} allModules allModules
+	 * @param {MainRenderContext} renderContext renderContext
+	 * @param {Set<Module>} inlinedModules inlinedModules
+	 * @param {ChunkRenderContext} chunkRenderContext chunkRenderContext
+	 * @param {CompilationHooks} hooks hooks
+	 * @param {boolean | undefined} allStrict allStrict
+	 * @param {boolean} hasChunkModules hasChunkModules
+	 * @returns {Map<Module, Source> | false} renamed inlined modules
+	 */
+	_getRenamedInlineModule(
+		compilation,
+		allModules,
+		renderContext,
+		inlinedModules,
+		chunkRenderContext,
+		hooks,
+		allStrict,
+		hasChunkModules
+	) {
+		const innerStrict =
+			!allStrict &&
+			allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict);
+		const isMultipleEntries = inlinedModules.size > 1;
+		const singleEntryWithModules = inlinedModules.size === 1 && hasChunkModules;
+		// TODO:
+		// This step is before the IIFE reason calculation. Ideally, it should only be executed when this function can optimize the
+		// IIFE reason. Otherwise, it should directly return false. There are four reasons now, we have skipped two already, the left
+		// one is 'it uses a non-standard name for the exports'.
+		if (isMultipleEntries || innerStrict || !singleEntryWithModules) {
+			return false;
+		}
+
+		/** @type {Map<Module, Source>} */
+		const renamedInlinedModules = new Map();
+		const { runtimeTemplate } = renderContext;
+
+		/** @typedef {{ source: Source, module: Module, ast: Program, variables: Set<Variable>, through: Set<Reference>, usedInNonInlined: Set<Variable>, moduleScope: Scope }} Info */
+		/** @type {Map<Module, Info>} */
+		const inlinedModulesToInfo = new Map();
+		/** @type {Set<string>} */
+		const nonInlinedModuleThroughIdentifiers = new Set();
+
+		for (const m of allModules) {
+			const isInlinedModule = inlinedModules && inlinedModules.has(m);
+			const moduleSource = this.renderModule(
+				m,
+				{
+					...chunkRenderContext,
+					factory: !isInlinedModule,
+					inlinedInIIFE: false
+				},
+				hooks
+			);
+
+			if (!moduleSource) continue;
+			const code = /** @type {string} */ (moduleSource.source());
+
+			const { ast } = JavascriptParser._parse(
+				code,
+				{
+					sourceType: "auto",
+					ranges: true
+				},
+				JavascriptParser._getModuleParseFunction(compilation, m)
+			);
+
+			const scopeManager = eslintScope.analyze(ast, {
+				ecmaVersion: 6,
+				sourceType: "module",
+				optimistic: true,
+				ignoreEval: true
+			});
+
+			const globalScope = /** @type {Scope} */ (scopeManager.acquire(ast));
+			if (inlinedModules && inlinedModules.has(m)) {
+				const moduleScope = globalScope.childScopes[0];
+				inlinedModulesToInfo.set(m, {
+					source: moduleSource,
+					ast,
+					module: m,
+					variables: new Set(moduleScope.variables),
+					through: new Set(moduleScope.through),
+					usedInNonInlined: new Set(),
+					moduleScope
+				});
+			} else {
+				for (const ref of globalScope.through) {
+					nonInlinedModuleThroughIdentifiers.add(ref.identifier.name);
+				}
+			}
+		}
+
+		for (const [, { variables, usedInNonInlined }] of inlinedModulesToInfo) {
+			for (const variable of variables) {
+				if (
+					nonInlinedModuleThroughIdentifiers.has(variable.name) ||
+					RESERVED_NAMES.has(variable.name)
+				) {
+					usedInNonInlined.add(variable);
+				}
+			}
+		}
+
+		for (const [m, moduleInfo] of inlinedModulesToInfo) {
+			const { ast, source: _source, usedInNonInlined } = moduleInfo;
+			const source = new ReplaceSource(_source);
+			if (usedInNonInlined.size === 0) {
+				renamedInlinedModules.set(m, source);
+				continue;
+			}
+
+			const info = /** @type {Info} */ (inlinedModulesToInfo.get(m));
+			const allUsedNames = new Set(
+				Array.from(info.through, (v) => v.identifier.name)
+			);
+
+			for (const variable of usedInNonInlined) {
+				allUsedNames.add(variable.name);
+			}
+
+			for (const variable of info.variables) {
+				/** @type {UsedNamesInScopeInfo} */
+				const usedNamesInScopeInfo = new Map();
+				/** @type {ScopeSet} */
+				const ignoredScopes = new Set();
+
+				const name = variable.name;
+				const { usedNames, alreadyCheckedScopes } = getUsedNamesInScopeInfo(
+					usedNamesInScopeInfo,
+					info.module.identifier(),
+					name
+				);
+
+				if (allUsedNames.has(name) || usedNames.has(name)) {
+					const references = getAllReferences(variable);
+					const allIdentifiers = new Set([
+						...references.map((r) => r.identifier),
+						...variable.identifiers
+					]);
+					for (const ref of references) {
+						addScopeSymbols(
+							ref.from,
+							usedNames,
+							alreadyCheckedScopes,
+							ignoredScopes
+						);
+					}
+
+					const newName = findNewName(
+						variable.name,
+						allUsedNames,
+						usedNames,
+						m.readableIdentifier(runtimeTemplate.requestShortener)
+					);
+					allUsedNames.add(newName);
+					for (const identifier of allIdentifiers) {
+						const r = /** @type {Range} */ (identifier.range);
+						const path = getPathInAst(ast, identifier);
+						if (path && path.length > 1) {
+							const maybeProperty =
+								path[1].type === "AssignmentPattern" && path[1].left === path[0]
+									? path[2]
+									: path[1];
+							if (
+								maybeProperty.type === "Property" &&
+								maybeProperty.shorthand
+							) {
+								source.insert(r[1], `: ${newName}`);
+								continue;
+							}
+						}
+						source.replace(r[0], r[1] - 1, newName);
+					}
+				}
+				allUsedNames.add(name);
+			}
+
+			renamedInlinedModules.set(m, source);
+		}
+
+		return renamedInlinedModules;
+	}
+}
+
+module.exports = JavascriptModulesPlugin;
+module.exports.chunkHasJs = chunkHasJs;
Index: frontend/node_modules/webpack/lib/javascript/JavascriptParser.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/JavascriptParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/JavascriptParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,5822 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const vm = require("vm");
+const { Parser: AcornParser, tokTypes } = require("acorn");
+const { HookMap, SyncBailHook } = require("tapable");
+const NormalModule = require("../NormalModule");
+const Parser = require("../Parser");
+const StackedMap = require("../util/StackedMap");
+const binarySearchBounds = require("../util/binarySearchBounds");
+const {
+	CompilerHintNotationRegExp,
+	createMagicCommentContext,
+	webpackCommentRegExp
+} = require("../util/magicComment");
+const memoize = require("../util/memoize");
+const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
+
+/** @typedef {import("acorn").Options} AcornOptions */
+/** @typedef {import("acorn").ecmaVersion} EcmaVersion */
+/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
+/** @typedef {import("estree").BinaryExpression} BinaryExpression */
+/** @typedef {import("estree").BlockStatement} BlockStatement */
+/** @typedef {import("estree").SequenceExpression} SequenceExpression */
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("estree").StaticBlock} StaticBlock */
+/** @typedef {import("estree").ClassDeclaration} ClassDeclaration */
+/** @typedef {import("estree").ForStatement} ForStatement */
+/** @typedef {import("estree").SwitchStatement} SwitchStatement */
+/** @typedef {import("estree").ClassExpression} ClassExpression */
+/** @typedef {import("estree").SourceLocation} SourceLocation */
+/** @typedef {import("estree").Comment & { start: number, end: number, loc: SourceLocation }} Comment */
+/** @typedef {import("estree").ConditionalExpression} ConditionalExpression */
+/** @typedef {import("estree").Declaration} Declaration */
+/** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
+/** @typedef {import("estree").PropertyDefinition} PropertyDefinition */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").ImportAttribute} ImportAttribute */
+/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */
+/** @typedef {import("estree").Identifier} Identifier */
+/** @typedef {import("estree").VariableDeclaration} VariableDeclaration */
+/** @typedef {import("estree").IfStatement} IfStatement */
+/** @typedef {import("estree").LabeledStatement} LabeledStatement */
+/** @typedef {import("estree").Literal} Literal */
+/** @typedef {import("estree").LogicalExpression} LogicalExpression */
+/** @typedef {import("estree").ChainExpression} ChainExpression */
+/** @typedef {import("estree").MemberExpression} MemberExpression */
+/** @typedef {import("estree").YieldExpression} YieldExpression */
+/** @typedef {import("estree").MetaProperty} MetaProperty */
+/** @typedef {import("estree").Property} Property */
+/** @typedef {import("estree").AssignmentPattern} AssignmentPattern */
+/** @typedef {import("estree").Pattern} Pattern */
+/** @typedef {import("estree").UpdateExpression} UpdateExpression */
+/** @typedef {import("estree").ObjectExpression} ObjectExpression */
+/** @typedef {import("estree").UnaryExpression} UnaryExpression */
+/** @typedef {import("estree").ArrayExpression} ArrayExpression */
+/** @typedef {import("estree").ArrayPattern} ArrayPattern */
+/** @typedef {import("estree").AwaitExpression} AwaitExpression */
+/** @typedef {import("estree").ThisExpression} ThisExpression */
+/** @typedef {import("estree").RestElement} RestElement */
+/** @typedef {import("estree").ObjectPattern} ObjectPattern */
+/** @typedef {import("estree").SwitchCase} SwitchCase */
+/** @typedef {import("estree").CatchClause} CatchClause */
+/** @typedef {import("estree").VariableDeclarator} VariableDeclarator */
+/** @typedef {import("estree").ForInStatement} ForInStatement */
+/** @typedef {import("estree").ForOfStatement} ForOfStatement */
+/** @typedef {import("estree").ReturnStatement} ReturnStatement */
+/** @typedef {import("estree").WithStatement} WithStatement */
+/** @typedef {import("estree").ThrowStatement} ThrowStatement */
+/** @typedef {import("estree").MethodDefinition} MethodDefinition */
+/** @typedef {import("estree").NewExpression} NewExpression */
+/** @typedef {import("estree").SpreadElement} SpreadElement */
+/** @typedef {import("estree").FunctionExpression} FunctionExpression */
+/** @typedef {import("estree").WhileStatement} WhileStatement */
+/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */
+/** @typedef {import("estree").ExpressionStatement} ExpressionStatement */
+/** @typedef {import("estree").ExportAllDeclaration} ExportAllDeclaration */
+/** @typedef {import("estree").ExportNamedDeclaration} ExportNamedDeclaration */
+/** @typedef {import("estree").FunctionDeclaration} FunctionDeclaration */
+/** @typedef {import("estree").DoWhileStatement} DoWhileStatement */
+/** @typedef {import("estree").TryStatement} TryStatement */
+/** @typedef {import("estree").Node} Node */
+/** @typedef {import("estree").Program} Program */
+/** @typedef {import("estree").Directive} Directive */
+/** @typedef {import("estree").Statement} Statement */
+/** @typedef {import("estree").ExportDefaultDeclaration} ExportDefaultDeclaration */
+/** @typedef {import("estree").Super} Super */
+/** @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpression */
+/** @typedef {import("estree").TemplateLiteral} TemplateLiteral */
+/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */
+/** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
+/** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("tapable").AsArray<T>} AsArray<T>
+ */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+/** @typedef {import("../dependencies/LocalModule")} LocalModule */
+/** @typedef {import("../dependencies/HarmonyExportImportedSpecifierDependency").HarmonyStarExportsList} HarmonyStarExportsList */
+
+/**
+ * Defines the known javascript parser state type used by this module.
+ * @typedef {object} KnownJavascriptParserState
+ * @property {Set<string>=} harmonyNamedExports
+ * @property {HarmonyStarExportsList=} harmonyStarExports
+ * @property {number=} lastHarmonyImportOrder
+ * @property {LocalModule[]=} localModules
+ */
+
+/** @typedef {ParserState & KnownJavascriptParserState} JavascriptParserState */
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+
+/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} GetInfoResult */
+/** @typedef {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} StatementPathItem */
+/** @typedef {(ident: string) => void} OnIdentString */
+/** @typedef {(ident: string, identifier: Identifier) => void} OnIdent */
+/** @typedef {StatementPathItem[]} StatementPath */
+
+/** @typedef {Set<DestructuringAssignmentProperty>} DestructuringAssignmentProperties */
+
+// TODO remove cast when @types/estree has been updated to import assertions
+/** @typedef {import("estree").ImportExpression & { phase?: "defer" | "source" }} ImportExpression */
+
+/** @type {string[]} */
+const EMPTY_ARRAY = [];
+const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
+const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10;
+const ALLOWED_MEMBER_TYPES_ALL = 0b11;
+
+const LEGACY_ASSERT_ATTRIBUTES = Symbol("assert");
+
+/** @type {(BaseParser: typeof AcornParser) => typeof AcornParser} */
+const importAssertions = (Parser) =>
+	class extends Parser {
+		/**
+		 * Parses with clause.
+		 * @this {InstanceType<AcornParser>}
+		 * @returns {ImportAttribute[]} import attributes
+		 */
+		parseWithClause() {
+			/** @type {ImportAttribute[]} */
+			const nodes = [];
+
+			const isAssertLegacy = this.value === "assert";
+
+			if (isAssertLegacy) {
+				if (!this.eat(tokTypes.name)) {
+					return nodes;
+				}
+			} else if (!this.eat(tokTypes._with)) {
+				return nodes;
+			}
+
+			this.expect(tokTypes.braceL);
+
+			/** @type {Record<string, boolean>} */
+			const attributeKeys = {};
+			let first = true;
+
+			while (!this.eat(tokTypes.braceR)) {
+				if (!first) {
+					this.expect(tokTypes.comma);
+					if (this.afterTrailingComma(tokTypes.braceR)) {
+						break;
+					}
+				} else {
+					first = false;
+				}
+
+				const attr =
+					/** @type {ImportAttribute} */
+					this.parseImportAttribute();
+				const keyName =
+					attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
+
+				if (Object.prototype.hasOwnProperty.call(attributeKeys, keyName)) {
+					this.raiseRecoverable(
+						attr.key.start,
+						`Duplicate attribute key '${keyName}'`
+					);
+				}
+
+				attributeKeys[keyName] = true;
+				nodes.push(attr);
+			}
+
+			if (isAssertLegacy) {
+				/** @type {EXPECTED_ANY} */
+				(nodes)[LEGACY_ASSERT_ATTRIBUTES] = true;
+			}
+
+			return nodes;
+		}
+	};
+
+// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
+let parser = AcornParser.extend(importAssertions);
+
+/** @typedef {Record<string, string> & { _isLegacyAssert?: boolean }} ImportAttributes */
+
+/**
+ * Gets import attributes.
+ * @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | ImportExpression} node node with assertions
+ * @returns {ImportAttributes | undefined} import attributes
+ */
+const getImportAttributes = (node) => {
+	if (node.type === "ImportExpression") {
+		if (
+			node.options &&
+			node.options.type === "ObjectExpression" &&
+			node.options.properties[0] &&
+			node.options.properties[0].type === "Property" &&
+			node.options.properties[0].key.type === "Identifier" &&
+			(node.options.properties[0].key.name === "with" ||
+				node.options.properties[0].key.name === "assert") &&
+			node.options.properties[0].value.type === "ObjectExpression" &&
+			node.options.properties[0].value.properties.length > 0
+		) {
+			const properties =
+				/** @type {Property[]} */
+				(node.options.properties[0].value.properties);
+			const result = /** @type {ImportAttributes} */ ({});
+			for (const property of properties) {
+				const key =
+					/** @type {string} */
+					(
+						property.key.type === "Identifier"
+							? property.key.name
+							: /** @type {Literal} */ (property.key).value
+					);
+				result[key] =
+					/** @type {string} */
+					(/** @type {Literal} */ (property.value).value);
+			}
+			const key =
+				node.options.properties[0].key.type === "Identifier"
+					? node.options.properties[0].key.name
+					: /** @type {Literal} */ (node.options.properties[0].key).value;
+
+			if (key === "assert") {
+				result._isLegacyAssert = true;
+			}
+
+			return result;
+		}
+
+		return;
+	}
+
+	if (node.attributes === undefined || node.attributes.length === 0) {
+		return;
+	}
+
+	const result = /** @type {ImportAttributes} */ ({});
+
+	for (const attribute of node.attributes) {
+		const key =
+			/** @type {string} */
+			(
+				attribute.key.type === "Identifier"
+					? attribute.key.name
+					: attribute.key.value
+			);
+
+		result[key] = /** @type {string} */ (attribute.value.value);
+	}
+
+	if (/** @type {EXPECTED_ANY} */ (node.attributes)[LEGACY_ASSERT_ATTRIBUTES]) {
+		result._isLegacyAssert = true;
+	}
+
+	return result;
+};
+
+/** @typedef {typeof VariableInfoFlags.Evaluated | typeof VariableInfoFlags.Free | typeof VariableInfoFlags.Normal | typeof VariableInfoFlags.Tagged} VariableInfoFlagsType */
+
+const VariableInfoFlags = Object.freeze({
+	Evaluated: 0b000,
+	Free: 0b001,
+	Normal: 0b010,
+	Tagged: 0b100
+});
+
+class VariableInfo {
+	/**
+	 * Creates an instance of VariableInfo.
+	 * @param {ScopeInfo} declaredScope scope in which the variable is declared
+	 * @param {string | undefined} name which name the variable use, defined name or free name or tagged name
+	 * @param {VariableInfoFlagsType} flags how the variable is created
+	 * @param {TagInfo | undefined} tagInfo info about tags
+	 */
+	constructor(declaredScope, name, flags, tagInfo) {
+		this.declaredScope = declaredScope;
+		this.name = name;
+		this.flags = flags;
+		this.tagInfo = tagInfo;
+	}
+
+	/**
+	 * Checks whether this variable info is free.
+	 * @returns {boolean} the variable is free or not
+	 */
+	isFree() {
+		return (this.flags & VariableInfoFlags.Free) > 0;
+	}
+
+	/**
+	 * Checks whether this variable info is tagged.
+	 * @returns {boolean} the variable is tagged by tagVariable or not
+	 */
+	isTagged() {
+		return (this.flags & VariableInfoFlags.Tagged) > 0;
+	}
+}
+
+/** @typedef {string | ScopeInfo | VariableInfo} ExportedVariableInfo */
+/** @typedef {Literal | string | null | undefined} ImportSource */
+
+/**
+ * Defines the internal parse options type used by this module.
+ * @typedef {Omit<ParseOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto" }} InternalParseOptions
+ */
+
+/**
+ * Defines the parse options type used by this module.
+ * @typedef {object} ParseOptions
+ * @property {"module" | "script"} sourceType
+ * @property {EcmaVersion} ecmaVersion
+ * @property {boolean=} locations
+ * @property {boolean=} comments
+ * @property {boolean=} ranges
+ * @property {boolean=} semicolons
+ * @property {boolean=} allowHashBang
+ * @property {boolean=} allowReturnOutsideFunction
+ */
+
+/**
+ * Defines the parse result type used by this module.
+ * @typedef {object} ParseResult
+ * @property {Program} ast
+ * @property {Comment[]} comments
+ * @property {Set<number>} semicolons
+ */
+
+/**
+ * Defines the parse function type used by this module.
+ * @typedef {(code: string, options: ParseOptions) => ParseResult} ParseFunction
+ */
+
+/** @typedef {symbol} Tag */
+
+/** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
+/** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySpecifierGuards} HarmonySpecifierGuards */
+/** @typedef {import("../dependencies/ImportParserPlugin").ImportSettings} ImportSettings */
+/** @typedef {import("../dependencies/CommonJsImportsParserPlugin").CommonJsImportSettings} CommonJsImportSettings */
+/** @typedef {import("../CompatibilityPlugin").CompatibilitySettings} CompatibilitySettings */
+/** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */
+
+/** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings | HarmonySpecifierGuards} KnownTagData */
+/** @typedef {KnownTagData | Record<string, EXPECTED_ANY>} TagData */
+
+/**
+ * Defines the tag info type used by this module.
+ * @typedef {object} TagInfo
+ * @property {Tag} tag
+ * @property {TagData=} data
+ * @property {TagInfo | undefined} next
+ */
+
+/** @typedef {string[]} CalleeMembers */
+/** @typedef {string[]} Members */
+/** @typedef {boolean[]} MembersOptionals */
+/** @typedef {Range[]} MemberRanges */
+
+const SCOPE_INFO_TERMINATED_RETURN = 1;
+const SCOPE_INFO_TERMINATED_THROW = 2;
+
+/**
+ * Defines the scope info type used by this module.
+ * @typedef {object} ScopeInfo
+ * @property {StackedMap<string, VariableInfo | ScopeInfo>} definitions
+ * @property {boolean | "arrow"} topLevelScope
+ * @property {boolean | string} inShorthand
+ * @property {boolean} inTaggedTemplateTag
+ * @property {boolean} inTry
+ * @property {boolean} isStrict
+ * @property {boolean} isAsmJs
+ * @property {undefined | 1 | 2} terminated
+ */
+
+/** @typedef {[number, number]} Range */
+
+/**
+ * Defines the destructuring assignment property type used by this module.
+ * @typedef {object} DestructuringAssignmentProperty
+ * @property {string} id
+ * @property {Range} range
+ * @property {SourceLocation} loc
+ * @property {Set<DestructuringAssignmentProperty> | undefined=} pattern
+ * @property {boolean | string} shorthand
+ */
+
+/**
+ * Helper function for joining two ranges into a single range. This is useful
+ * when working with AST nodes, as it allows you to combine the ranges of child nodes
+ * to create the range of the _parent node_.
+ * @param {Range} startRange start range to join
+ * @param {Range} endRange end range to join
+ * @returns {Range} joined range
+ * @example
+ * ```js
+ * 	const startRange = [0, 5];
+ * 	const endRange = [10, 15];
+ * 	const joinedRange = joinRanges(startRange, endRange);
+ * 	console.log(joinedRange); // [0, 15]
+ * ```
+ */
+const joinRanges = (startRange, endRange) => {
+	if (!endRange) return startRange;
+	if (!startRange) return endRange;
+	return [startRange[0], endRange[1]];
+};
+
+/**
+ * Helper function used to generate a string representation of a
+ * [member expression](https://github.com/estree/estree/blob/master/es5.md#memberexpression).
+ * @param {string} object object to name
+ * @param {Members} membersReversed reversed list of members
+ * @returns {string} member expression as a string
+ * @example
+ * ```js
+ * const membersReversed = ["property1", "property2", "property3"]; // Members parsed from the AST
+ * const name = objectAndMembersToName("myObject", membersReversed);
+ *
+ * console.log(name); // "myObject.property1.property2.property3"
+ * ```
+ */
+const objectAndMembersToName = (object, membersReversed) => {
+	let name = object;
+	for (let i = membersReversed.length - 1; i >= 0; i--) {
+		name = `${name}.${membersReversed[i]}`;
+	}
+	return name;
+};
+
+/**
+ * Grabs the name of a given expression and returns it as a string or undefined. Has particular
+ * handling for [Identifiers](https://github.com/estree/estree/blob/master/es5.md#identifier),
+ * [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and
+ * [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is
+ * specifically for handling the `new.target` meta property.
+ * @param {Expression | SpreadElement | Super} expression expression
+ * @returns {string | "this" | undefined} name or variable info
+ */
+const getRootName = (expression) => {
+	switch (expression.type) {
+		case "Identifier":
+			return expression.name;
+		case "ThisExpression":
+			return "this";
+		case "MetaProperty":
+			return `${expression.meta.name}.${expression.property.name}`;
+		default:
+			return undefined;
+	}
+};
+
+/** @type {ParseOptions} */
+const defaultParserOptions = {
+	sourceType: "module",
+	ecmaVersion: "latest",
+	ranges: false,
+	locations: false,
+	comments: false,
+	// https://github.com/tc39/proposal-hashbang
+	allowHashBang: true
+};
+
+const EMPTY_COMMENT_OPTIONS = {
+	options: null,
+	errors: null
+};
+
+const CLASS_NAME = "JavascriptParser";
+
+class JavascriptParser extends Parser {
+	/**
+	 * Creates an instance of JavascriptParser.
+	 * @param {"module" | "script" | "auto"=} sourceType default source type
+	 * @param {{ parse?: ParseFunction, typescript?: boolean }=} options parser options
+	 */
+	constructor(sourceType = "auto", options = {}) {
+		super();
+		this.hooks = Object.freeze({
+			/** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | null | undefined>>} */
+			evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {HookMap<SyncBailHook<[Expression | SpreadElement | PrivateIdentifier | Super], BasicEvaluatedExpression | null | undefined>>} */
+			evaluate: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | null | undefined>>} */
+			evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression], BasicEvaluatedExpression | null | undefined>>} */
+			evaluateDefinedIdentifier: new HookMap(
+				() => new SyncBailHook(["expression"])
+			),
+			/** @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | null | undefined>>} */
+			evaluateNewExpression: new HookMap(
+				() => new SyncBailHook(["expression"])
+			),
+			/** @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | null | undefined>>} */
+			evaluateCallExpression: new HookMap(
+				() => new SyncBailHook(["expression"])
+			),
+			/** @type {HookMap<SyncBailHook<[CallExpression, BasicEvaluatedExpression], BasicEvaluatedExpression | null | undefined>>} */
+			evaluateCallExpressionMember: new HookMap(
+				() => new SyncBailHook(["expression", "param"])
+			),
+			/** @type {HookMap<SyncBailHook<[Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, number], boolean | void>>} */
+			isPure: new HookMap(
+				() => new SyncBailHook(["expression", "commentsStartPosition"])
+			),
+			/** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
+			preStatement: new SyncBailHook(["statement"]),
+
+			/** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
+			blockPreStatement: new SyncBailHook(["declaration"]),
+			/** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
+			statement: new SyncBailHook(["statement"]),
+			/** @type {SyncBailHook<[IfStatement], boolean | void>} */
+			statementIf: new SyncBailHook(["statement"]),
+			/** @type {SyncBailHook<[Expression], ((walk: () => void) => void) | void>} */
+			collectGuards: new SyncBailHook(["expression"]),
+			/** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
+			classExtendsExpression: new SyncBailHook([
+				"expression",
+				"classDefinition"
+			]),
+			/** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
+			classBodyElement: new SyncBailHook(["element", "classDefinition"]),
+			/** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
+			classBodyValue: new SyncBailHook([
+				"expression",
+				"element",
+				"classDefinition"
+			]),
+			/** @type {HookMap<SyncBailHook<[LabeledStatement], boolean | void>>} */
+			label: new HookMap(() => new SyncBailHook(["statement"])),
+			/** @type {SyncBailHook<[ImportDeclaration, ImportSource], boolean | void>} */
+			import: new SyncBailHook(["statement", "source"]),
+			/** @type {SyncBailHook<[ImportDeclaration, ImportSource, string | null, string], boolean | void>} */
+			importSpecifier: new SyncBailHook([
+				"statement",
+				"source",
+				"exportName",
+				"identifierName"
+			]),
+			/** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration], boolean | void>} */
+			export: new SyncBailHook(["statement"]),
+			/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource], boolean | void>} */
+			exportImport: new SyncBailHook(["statement", "source"]),
+			/** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, Declaration], boolean | void>} */
+			exportDeclaration: new SyncBailHook(["statement", "declaration"]),
+			/** @type {SyncBailHook<[ExportDefaultDeclaration, MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression], boolean | void>} */
+			exportExpression: new SyncBailHook(["statement", "node"]),
+			/** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, string, string, number | undefined], boolean | void>} */
+			exportSpecifier: new SyncBailHook([
+				"statement",
+				"identifierName",
+				"exportName",
+				"index"
+			]),
+			/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource, string | null, string | null, number | undefined], boolean | void>} */
+			exportImportSpecifier: new SyncBailHook([
+				"statement",
+				"source",
+				"identifierName",
+				"exportName",
+				"index"
+			]),
+			/** @type {SyncBailHook<[VariableDeclarator, VariableDeclaration], boolean | void>} */
+			preDeclarator: new SyncBailHook(["declarator", "statement"]),
+			/** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
+			declarator: new SyncBailHook(["declarator", "statement"]),
+			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
+			varDeclaration: new HookMap(() => new SyncBailHook(["declaration"])),
+			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
+			varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])),
+			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
+			varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),
+			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
+			varDeclarationUsing: new HookMap(() => new SyncBailHook(["declaration"])),
+			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
+			varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])),
+			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
+			pattern: new HookMap(() => new SyncBailHook(["pattern"])),
+			/** @type {SyncBailHook<[Expression], boolean | void>} */
+			collectDestructuringAssignmentProperties: new SyncBailHook([
+				"expression"
+			]),
+			/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
+			canRename: new HookMap(() => new SyncBailHook(["initExpression"])),
+			/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
+			rename: new HookMap(() => new SyncBailHook(["initExpression"])),
+			/** @type {HookMap<SyncBailHook<[AssignmentExpression], boolean | void>>} */
+			assign: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {HookMap<SyncBailHook<[AssignmentExpression, Members], boolean | void>>} */
+			assignMemberChain: new HookMap(
+				() => new SyncBailHook(["expression", "members"])
+			),
+			/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
+			typeof: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {SyncBailHook<[ImportExpression, CallExpression?], boolean | void>} */
+			importCall: new SyncBailHook(["expression", "importThen"]),
+			/** @type {SyncBailHook<[Expression | ForOfStatement], boolean | void>} */
+			topLevelAwait: new SyncBailHook(["expression"]),
+			/** @type {HookMap<SyncBailHook<[CallExpression], boolean | void>>} */
+			call: new HookMap(() => new SyncBailHook(["expression"])),
+			/** Something like "a.b()" */
+			/** @type {HookMap<SyncBailHook<[CallExpression, Members, MembersOptionals, MemberRanges], boolean | void>>} */
+			callMemberChain: new HookMap(
+				() =>
+					new SyncBailHook([
+						"expression",
+						"members",
+						"membersOptionals",
+						"memberRanges"
+					])
+			),
+			/** Something like "a.b().c.d" */
+			/** @type {HookMap<SyncBailHook<[Expression, CalleeMembers, CallExpression, Members, MemberRanges], boolean | void>>} */
+			memberChainOfCallMemberChain: new HookMap(
+				() =>
+					new SyncBailHook([
+						"expression",
+						"calleeMembers",
+						"callExpression",
+						"members",
+						"memberRanges"
+					])
+			),
+			/** Something like "a.b().c.d()"" */
+			/** @type {HookMap<SyncBailHook<[CallExpression, CalleeMembers, CallExpression, Members, MemberRanges], boolean | void>>} */
+			callMemberChainOfCallMemberChain: new HookMap(
+				() =>
+					new SyncBailHook([
+						"expression",
+						"calleeMembers",
+						"innerCallExpression",
+						"members",
+						"memberRanges"
+					])
+			),
+			/** @type {SyncBailHook<[ChainExpression], boolean | void>} */
+			optionalChaining: new SyncBailHook(["optionalChaining"]),
+			/** @type {HookMap<SyncBailHook<[NewExpression], boolean | void>>} */
+			new: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {SyncBailHook<[BinaryExpression], boolean | void>} */
+			binaryExpression: new SyncBailHook(["binaryExpression"]),
+			/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
+			expression: new HookMap(() => new SyncBailHook(["expression"])),
+			/** @type {HookMap<SyncBailHook<[MemberExpression, Members, MembersOptionals, MemberRanges], boolean | void>>} */
+			expressionMemberChain: new HookMap(
+				() =>
+					new SyncBailHook([
+						"expression",
+						"members",
+						"membersOptionals",
+						"memberRanges"
+					])
+			),
+			/** @type {HookMap<SyncBailHook<[MemberExpression, Members], boolean | void>>} */
+			unhandledExpressionMemberChain: new HookMap(
+				() => new SyncBailHook(["expression", "members"])
+			),
+			/** @type {SyncBailHook<[ConditionalExpression], boolean | void>} */
+			expressionConditionalOperator: new SyncBailHook(["expression"]),
+			/** @type {SyncBailHook<[LogicalExpression], boolean | void>} */
+			expressionLogicalOperator: new SyncBailHook(["expression"]),
+			/** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
+			program: new SyncBailHook(["ast", "comments"]),
+			/** @type {SyncBailHook<[ThrowStatement | ReturnStatement], boolean | void>} */
+			terminate: new SyncBailHook(["statement"]),
+			/** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
+			finish: new SyncBailHook(["ast", "comments"]),
+			/** @type {SyncBailHook<[Statement], boolean | void>} */
+			unusedStatement: new SyncBailHook(["statement"])
+		});
+		this.sourceType = sourceType;
+		this.options = options;
+
+		/** @type {ScopeInfo} */
+		this.scope = /** @type {EXPECTED_ANY} */ (undefined);
+		/** @type {JavascriptParserState} */
+		this.state = /** @type {EXPECTED_ANY} */ (undefined);
+		/** @type {Comment[] | undefined} */
+		this.comments = undefined;
+		/** @type {Set<number> | undefined} */
+		this.semicolons = undefined;
+		/** @type {StatementPath | undefined} */
+		this.statementPath = undefined;
+		/** @type {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | undefined} */
+		this.prevStatement = undefined;
+		/** @type {WeakMap<Expression, DestructuringAssignmentProperties> | undefined} */
+		this.destructuringAssignmentProperties = undefined;
+		/** @type {TagData | undefined} */
+		this.currentTagData = undefined;
+		this.magicCommentContext = createMagicCommentContext();
+		this._initializeEvaluating();
+	}
+
+	_initializeEvaluating() {
+		this.hooks.evaluate.for("Literal").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {Literal} */ (_expr);
+
+			switch (typeof expr.value) {
+				case "number":
+					return new BasicEvaluatedExpression()
+						.setNumber(expr.value)
+						.setRange(/** @type {Range} */ (expr.range));
+				case "bigint":
+					return new BasicEvaluatedExpression()
+						.setBigInt(expr.value)
+						.setRange(/** @type {Range} */ (expr.range));
+				case "string":
+					return new BasicEvaluatedExpression()
+						.setString(expr.value)
+						.setRange(/** @type {Range} */ (expr.range));
+				case "boolean":
+					return new BasicEvaluatedExpression()
+						.setBoolean(expr.value)
+						.setRange(/** @type {Range} */ (expr.range));
+			}
+			if (expr.value === null) {
+				return new BasicEvaluatedExpression()
+					.setNull()
+					.setRange(/** @type {Range} */ (expr.range));
+			}
+			if (expr.value instanceof RegExp) {
+				return new BasicEvaluatedExpression()
+					.setRegExp(expr.value)
+					.setRange(/** @type {Range} */ (expr.range));
+			}
+		});
+		this.hooks.evaluate.for("NewExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {NewExpression} */ (_expr);
+			const callee = expr.callee;
+			if (callee.type !== "Identifier") return;
+			if (callee.name !== "RegExp") {
+				return this.callHooksForName(
+					this.hooks.evaluateNewExpression,
+					callee.name,
+					expr
+				);
+			} else if (
+				expr.arguments.length > 2 ||
+				this.getVariableInfo("RegExp") !== "RegExp"
+			) {
+				return;
+			}
+
+			/** @type {undefined | string} */
+			let regExp;
+			const arg1 = expr.arguments[0];
+
+			if (arg1) {
+				if (arg1.type === "SpreadElement") return;
+
+				const evaluatedRegExp = this.evaluateExpression(arg1);
+
+				if (!evaluatedRegExp) return;
+
+				regExp = evaluatedRegExp.asString();
+
+				if (!regExp) return;
+			} else {
+				return (
+					new BasicEvaluatedExpression()
+						// eslint-disable-next-line prefer-regex-literals
+						.setRegExp(new RegExp(""))
+						.setRange(/** @type {Range} */ (expr.range))
+				);
+			}
+
+			/** @type {undefined | string} */
+			let flags;
+			const arg2 = expr.arguments[1];
+
+			if (arg2) {
+				if (arg2.type === "SpreadElement") return;
+
+				const evaluatedFlags = this.evaluateExpression(arg2);
+
+				if (!evaluatedFlags) return;
+
+				if (!evaluatedFlags.isUndefined()) {
+					flags = evaluatedFlags.asString();
+
+					if (
+						flags === undefined ||
+						!BasicEvaluatedExpression.isValidRegExpFlags(flags)
+					) {
+						return;
+					}
+				}
+			}
+
+			return new BasicEvaluatedExpression()
+				.setRegExp(flags ? new RegExp(regExp, flags) : new RegExp(regExp))
+				.setRange(/** @type {Range} */ (expr.range));
+		});
+		this.hooks.evaluate.for("LogicalExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {LogicalExpression} */ (_expr);
+
+			const left = this.evaluateExpression(expr.left);
+			let returnRight = false;
+			/** @type {boolean | undefined} */
+			let allowedRight;
+			if (expr.operator === "&&") {
+				const leftAsBool = left.asBool();
+				if (leftAsBool === false) {
+					return left.setRange(/** @type {Range} */ (expr.range));
+				}
+				returnRight = leftAsBool === true;
+				allowedRight = false;
+			} else if (expr.operator === "||") {
+				const leftAsBool = left.asBool();
+				if (leftAsBool === true) {
+					return left.setRange(/** @type {Range} */ (expr.range));
+				}
+				returnRight = leftAsBool === false;
+				allowedRight = true;
+			} else if (expr.operator === "??") {
+				const leftAsNullish = left.asNullish();
+				if (leftAsNullish === false) {
+					return left.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (leftAsNullish !== true) return;
+				returnRight = true;
+			} else {
+				return;
+			}
+			const right = this.evaluateExpression(expr.right);
+			if (returnRight) {
+				if (left.couldHaveSideEffects()) right.setSideEffects();
+				return right.setRange(/** @type {Range} */ (expr.range));
+			}
+
+			const asBool = right.asBool();
+
+			if (allowedRight === true && asBool === true) {
+				return new BasicEvaluatedExpression()
+					.setRange(/** @type {Range} */ (expr.range))
+					.setTruthy();
+			} else if (allowedRight === false && asBool === false) {
+				return new BasicEvaluatedExpression()
+					.setRange(/** @type {Range} */ (expr.range))
+					.setFalsy();
+			}
+		});
+
+		/**
+		 * In simple logical cases, we can use valueAsExpression to assist us in evaluating the expression on
+		 * either side of a [BinaryExpression](https://github.com/estree/estree/blob/master/es5.md#binaryexpression).
+		 * This supports scenarios in webpack like conditionally `import()`'ing modules based on some simple evaluation:
+		 *
+		 * ```js
+		 * if (1 === 3) {
+		 *  import("./moduleA"); // webpack will auto evaluate this and not import the modules
+		 * }
+		 * ```
+		 *
+		 * Additional scenarios include evaluation of strings inside of dynamic import statements:
+		 *
+		 * ```js
+		 * const foo = "foo";
+		 * const bar = "bar";
+		 *
+		 * import("./" + foo + bar); // webpack will auto evaluate this into import("./foobar")
+		 * ```
+		 * @param {boolean | number | bigint | string} value the value to convert to an expression
+		 * @param {BinaryExpression | UnaryExpression} expr the expression being evaluated
+		 * @param {boolean} sideEffects whether the expression has side effects
+		 * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
+		 * @example
+		 *
+		 * ```js
+		 * const binaryExpr = new BinaryExpression("+",
+		 * 	{ type: "Literal", value: 2 },
+		 * 	{ type: "Literal", value: 3 }
+		 * );
+		 *
+		 * const leftValue = 2;
+		 * const rightValue = 3;
+		 *
+		 * const leftExpr = valueAsExpression(leftValue, binaryExpr.left, false);
+		 * const rightExpr = valueAsExpression(rightValue, binaryExpr.right, false);
+		 * const result = new BasicEvaluatedExpression()
+		 * 	.setNumber(leftExpr.number + rightExpr.number)
+		 * 	.setRange(binaryExpr.range);
+		 *
+		 * console.log(result.number); // Output: 5
+		 * ```
+		 */
+		const valueAsExpression = (value, expr, sideEffects) => {
+			switch (typeof value) {
+				case "boolean":
+					return new BasicEvaluatedExpression()
+						.setBoolean(value)
+						.setSideEffects(sideEffects)
+						.setRange(/** @type {Range} */ (expr.range));
+				case "number":
+					return new BasicEvaluatedExpression()
+						.setNumber(value)
+						.setSideEffects(sideEffects)
+						.setRange(/** @type {Range} */ (expr.range));
+				case "bigint":
+					return new BasicEvaluatedExpression()
+						.setBigInt(value)
+						.setSideEffects(sideEffects)
+						.setRange(/** @type {Range} */ (expr.range));
+				case "string":
+					return new BasicEvaluatedExpression()
+						.setString(value)
+						.setSideEffects(sideEffects)
+						.setRange(/** @type {Range} */ (expr.range));
+			}
+		};
+
+		this.hooks.evaluate.for("BinaryExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {BinaryExpression} */ (_expr);
+
+			/**
+			 * Evaluates a binary expression if and only if it is a const operation (e.g. 1 + 2, "a" + "b", etc.).
+			 * @template T
+			 * @param {(leftOperand: T, rightOperand: T) => boolean | number | bigint | string} operandHandler the handler for the operation (e.g. (a, b) => a + b)
+			 * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
+			 */
+			const handleConstOperation = (operandHandler) => {
+				const left = this.evaluateExpression(expr.left);
+				if (!left.isCompileTimeValue()) return;
+
+				const right = this.evaluateExpression(expr.right);
+				if (!right.isCompileTimeValue()) return;
+
+				const result = operandHandler(
+					/** @type {T} */ (left.asCompileTimeValue()),
+					/** @type {T} */ (right.asCompileTimeValue())
+				);
+				return valueAsExpression(
+					result,
+					expr,
+					left.couldHaveSideEffects() || right.couldHaveSideEffects()
+				);
+			};
+
+			/**
+			 * Helper function to determine if two booleans are always different. This is used in `handleStrictEqualityComparison`
+			 * to determine if an expressions boolean or nullish conversion is equal or not.
+			 * @param {boolean} a first boolean to compare
+			 * @param {boolean} b second boolean to compare
+			 * @returns {boolean} true if the two booleans are always different, false otherwise
+			 */
+			const isAlwaysDifferent = (a, b) =>
+				(a === true && b === false) || (a === false && b === true);
+
+			/**
+			 * Handle template string compare.
+			 * @param {BasicEvaluatedExpression} left left
+			 * @param {BasicEvaluatedExpression} right right
+			 * @param {BasicEvaluatedExpression} res res
+			 * @param {boolean} eql true for "===" and false for "!=="
+			 * @returns {BasicEvaluatedExpression | undefined} result
+			 */
+			const handleTemplateStringCompare = (left, right, res, eql) => {
+				/**
+				 * Returns value.
+				 * @param {BasicEvaluatedExpression[]} parts parts
+				 * @returns {string} value
+				 */
+				const getPrefix = (parts) => {
+					let value = "";
+					for (const p of parts) {
+						const v = p.asString();
+						if (v !== undefined) value += v;
+						else break;
+					}
+					return value;
+				};
+				/**
+				 * Returns value.
+				 * @param {BasicEvaluatedExpression[]} parts parts
+				 * @returns {string} value
+				 */
+				const getSuffix = (parts) => {
+					let value = "";
+					for (let i = parts.length - 1; i >= 0; i--) {
+						const v = parts[i].asString();
+						if (v !== undefined) value = v + value;
+						else break;
+					}
+					return value;
+				};
+				const leftPrefix = getPrefix(
+					/** @type {BasicEvaluatedExpression[]} */ (left.parts)
+				);
+				const rightPrefix = getPrefix(
+					/** @type {BasicEvaluatedExpression[]} */ (right.parts)
+				);
+				const leftSuffix = getSuffix(
+					/** @type {BasicEvaluatedExpression[]} */ (left.parts)
+				);
+				const rightSuffix = getSuffix(
+					/** @type {BasicEvaluatedExpression[]} */ (right.parts)
+				);
+				const lenPrefix = Math.min(leftPrefix.length, rightPrefix.length);
+				const lenSuffix = Math.min(leftSuffix.length, rightSuffix.length);
+				const prefixMismatch =
+					lenPrefix > 0 &&
+					leftPrefix.slice(0, lenPrefix) !== rightPrefix.slice(0, lenPrefix);
+				const suffixMismatch =
+					lenSuffix > 0 &&
+					leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix);
+				if (prefixMismatch || suffixMismatch) {
+					return res
+						.setBoolean(!eql)
+						.setSideEffects(
+							left.couldHaveSideEffects() || right.couldHaveSideEffects()
+						);
+				}
+			};
+
+			/**
+			 * Helper function to handle BinaryExpressions using strict equality comparisons (e.g. "===" and "!==").
+			 * @param {boolean} eql true for "===" and false for "!=="
+			 * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
+			 */
+			const handleStrictEqualityComparison = (eql) => {
+				const left = this.evaluateExpression(expr.left);
+				const right = this.evaluateExpression(expr.right);
+				const res = new BasicEvaluatedExpression();
+				res.setRange(/** @type {Range} */ (expr.range));
+
+				const leftConst = left.isCompileTimeValue();
+				const rightConst = right.isCompileTimeValue();
+
+				if (leftConst && rightConst) {
+					return res
+						.setBoolean(
+							eql === (left.asCompileTimeValue() === right.asCompileTimeValue())
+						)
+						.setSideEffects(
+							left.couldHaveSideEffects() || right.couldHaveSideEffects()
+						);
+				}
+
+				if (left.isArray() && right.isArray()) {
+					return res
+						.setBoolean(!eql)
+						.setSideEffects(
+							left.couldHaveSideEffects() || right.couldHaveSideEffects()
+						);
+				}
+				if (left.isTemplateString() && right.isTemplateString()) {
+					return handleTemplateStringCompare(left, right, res, eql);
+				}
+
+				const leftPrimitive = left.isPrimitiveType();
+				const rightPrimitive = right.isPrimitiveType();
+
+				if (
+					// Primitive !== Object or
+					// compile-time object types are never equal to something at runtime
+					(leftPrimitive === false && (leftConst || rightPrimitive === true)) ||
+					(rightPrimitive === false &&
+						(rightConst || leftPrimitive === true)) ||
+					// Different nullish or boolish status also means not equal
+					isAlwaysDifferent(
+						/** @type {boolean} */ (left.asBool()),
+						/** @type {boolean} */ (right.asBool())
+					) ||
+					isAlwaysDifferent(
+						/** @type {boolean} */ (left.asNullish()),
+						/** @type {boolean} */ (right.asNullish())
+					)
+				) {
+					return res
+						.setBoolean(!eql)
+						.setSideEffects(
+							left.couldHaveSideEffects() || right.couldHaveSideEffects()
+						);
+				}
+			};
+
+			/**
+			 * Helper function to handle BinaryExpressions using abstract equality comparisons (e.g. "==" and "!=").
+			 * @param {boolean} eql true for "==" and false for "!="
+			 * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
+			 */
+			const handleAbstractEqualityComparison = (eql) => {
+				const left = this.evaluateExpression(expr.left);
+				const right = this.evaluateExpression(expr.right);
+				const res = new BasicEvaluatedExpression();
+				res.setRange(/** @type {Range} */ (expr.range));
+
+				const leftConst = left.isCompileTimeValue();
+				const rightConst = right.isCompileTimeValue();
+
+				if (leftConst && rightConst) {
+					return res
+						.setBoolean(
+							eql ===
+								// eslint-disable-next-line eqeqeq
+								(left.asCompileTimeValue() == right.asCompileTimeValue())
+						)
+						.setSideEffects(
+							left.couldHaveSideEffects() || right.couldHaveSideEffects()
+						);
+				}
+
+				if (left.isArray() && right.isArray()) {
+					return res
+						.setBoolean(!eql)
+						.setSideEffects(
+							left.couldHaveSideEffects() || right.couldHaveSideEffects()
+						);
+				}
+				if (left.isTemplateString() && right.isTemplateString()) {
+					return handleTemplateStringCompare(left, right, res, eql);
+				}
+			};
+
+			if (expr.operator === "+") {
+				const left = this.evaluateExpression(expr.left);
+				const right = this.evaluateExpression(expr.right);
+				const res = new BasicEvaluatedExpression();
+				if (left.isString()) {
+					if (right.isString()) {
+						res.setString(
+							/** @type {string} */ (left.string) +
+								/** @type {string} */ (right.string)
+						);
+					} else if (right.isNumber()) {
+						res.setString(/** @type {string} */ (left.string) + right.number);
+					} else if (
+						right.isWrapped() &&
+						right.prefix &&
+						right.prefix.isString()
+					) {
+						// "left" + ("prefix" + inner + "postfix")
+						// => ("leftPrefix" + inner + "postfix")
+						res.setWrapped(
+							new BasicEvaluatedExpression()
+								.setString(
+									/** @type {string} */ (left.string) +
+										/** @type {string} */ (right.prefix.string)
+								)
+								.setRange(
+									joinRanges(
+										/** @type {Range} */ (left.range),
+										/** @type {Range} */ (right.prefix.range)
+									)
+								),
+							right.postfix,
+							right.wrappedInnerExpressions
+						);
+					} else if (right.isWrapped()) {
+						// "left" + ([null] + inner + "postfix")
+						// => ("left" + inner + "postfix")
+						res.setWrapped(left, right.postfix, right.wrappedInnerExpressions);
+					} else {
+						// "left" + expr
+						// => ("left" + expr + "")
+						res.setWrapped(left, null, [right]);
+					}
+				} else if (left.isNumber()) {
+					if (right.isString()) {
+						res.setString(left.number + /** @type {string} */ (right.string));
+					} else if (right.isNumber()) {
+						res.setNumber(
+							/** @type {number} */ (left.number) +
+								/** @type {number} */ (right.number)
+						);
+					} else {
+						return;
+					}
+				} else if (left.isBigInt()) {
+					if (right.isBigInt()) {
+						res.setBigInt(
+							/** @type {bigint} */ (left.bigint) +
+								/** @type {bigint} */ (right.bigint)
+						);
+					}
+				} else if (left.isWrapped()) {
+					if (left.postfix && left.postfix.isString() && right.isString()) {
+						// ("prefix" + inner + "postfix") + "right"
+						// => ("prefix" + inner + "postfixRight")
+						res.setWrapped(
+							left.prefix,
+							new BasicEvaluatedExpression()
+								.setString(
+									/** @type {string} */ (left.postfix.string) +
+										/** @type {string} */ (right.string)
+								)
+								.setRange(
+									joinRanges(
+										/** @type {Range} */ (left.postfix.range),
+										/** @type {Range} */ (right.range)
+									)
+								),
+							left.wrappedInnerExpressions
+						);
+					} else if (
+						left.postfix &&
+						left.postfix.isString() &&
+						right.isNumber()
+					) {
+						// ("prefix" + inner + "postfix") + 123
+						// => ("prefix" + inner + "postfix123")
+						res.setWrapped(
+							left.prefix,
+							new BasicEvaluatedExpression()
+								.setString(
+									/** @type {string} */ (left.postfix.string) +
+										/** @type {number} */ (right.number)
+								)
+								.setRange(
+									joinRanges(
+										/** @type {Range} */ (left.postfix.range),
+										/** @type {Range} */ (right.range)
+									)
+								),
+							left.wrappedInnerExpressions
+						);
+					} else if (right.isString()) {
+						// ("prefix" + inner + [null]) + "right"
+						// => ("prefix" + inner + "right")
+						res.setWrapped(left.prefix, right, left.wrappedInnerExpressions);
+					} else if (right.isNumber()) {
+						// ("prefix" + inner + [null]) + 123
+						// => ("prefix" + inner + "123")
+						res.setWrapped(
+							left.prefix,
+							new BasicEvaluatedExpression()
+								.setString(String(right.number))
+								.setRange(/** @type {Range} */ (right.range)),
+							left.wrappedInnerExpressions
+						);
+					} else if (right.isWrapped()) {
+						// ("prefix1" + inner1 + "postfix1") + ("prefix2" + inner2 + "postfix2")
+						// ("prefix1" + inner1 + "postfix1" + "prefix2" + inner2 + "postfix2")
+						res.setWrapped(
+							left.prefix,
+							right.postfix,
+							left.wrappedInnerExpressions &&
+								right.wrappedInnerExpressions && [
+									...left.wrappedInnerExpressions,
+									...(left.postfix ? [left.postfix] : []),
+									...(right.prefix ? [right.prefix] : []),
+									...right.wrappedInnerExpressions
+								]
+						);
+					} else {
+						// ("prefix" + inner + postfix) + expr
+						// => ("prefix" + inner + postfix + expr + [null])
+						res.setWrapped(
+							left.prefix,
+							null,
+							left.wrappedInnerExpressions && [
+								...left.wrappedInnerExpressions,
+								...(left.postfix ? [left.postfix, right] : [right])
+							]
+						);
+					}
+				} else if (right.isString()) {
+					// left + "right"
+					// => ([null] + left + "right")
+					res.setWrapped(null, right, [left]);
+				} else if (right.isWrapped()) {
+					// left + (prefix + inner + "postfix")
+					// => ([null] + left + prefix + inner + "postfix")
+					res.setWrapped(
+						null,
+						right.postfix,
+						right.wrappedInnerExpressions && [
+							...(right.prefix ? [left, right.prefix] : [left]),
+							...right.wrappedInnerExpressions
+						]
+					);
+				} else {
+					return;
+				}
+				if (left.couldHaveSideEffects() || right.couldHaveSideEffects()) {
+					res.setSideEffects();
+				}
+				res.setRange(/** @type {Range} */ (expr.range));
+				return res;
+			} else if (expr.operator === "-") {
+				return handleConstOperation((l, r) => l - r);
+			} else if (expr.operator === "*") {
+				return handleConstOperation((l, r) => l * r);
+			} else if (expr.operator === "/") {
+				return handleConstOperation((l, r) => l / r);
+			} else if (expr.operator === "**") {
+				return handleConstOperation((l, r) => l ** r);
+			} else if (expr.operator === "===") {
+				return handleStrictEqualityComparison(true);
+			} else if (expr.operator === "==") {
+				return handleAbstractEqualityComparison(true);
+			} else if (expr.operator === "!==") {
+				return handleStrictEqualityComparison(false);
+			} else if (expr.operator === "!=") {
+				return handleAbstractEqualityComparison(false);
+			} else if (expr.operator === "&") {
+				return handleConstOperation((l, r) => l & r);
+			} else if (expr.operator === "|") {
+				return handleConstOperation((l, r) => l | r);
+			} else if (expr.operator === "^") {
+				return handleConstOperation((l, r) => l ^ r);
+			} else if (expr.operator === ">>>") {
+				return handleConstOperation((l, r) => l >>> r);
+			} else if (expr.operator === ">>") {
+				return handleConstOperation((l, r) => l >> r);
+			} else if (expr.operator === "<<") {
+				return handleConstOperation((l, r) => l << r);
+			} else if (expr.operator === "<") {
+				return handleConstOperation((l, r) => l < r);
+			} else if (expr.operator === ">") {
+				return handleConstOperation((l, r) => l > r);
+			} else if (expr.operator === "<=") {
+				return handleConstOperation((l, r) => l <= r);
+			} else if (expr.operator === ">=") {
+				return handleConstOperation((l, r) => l >= r);
+			}
+		});
+		this.hooks.evaluate.for("UnaryExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {UnaryExpression} */ (_expr);
+
+			/**
+			 * Evaluates a UnaryExpression if and only if it is a basic const operator (e.g. +a, -a, ~a).
+			 * @template T
+			 * @param {(operand: T) => boolean | number | bigint | string} operandHandler handler for the operand
+			 * @returns {BasicEvaluatedExpression | undefined} evaluated expression
+			 */
+			const handleConstOperation = (operandHandler) => {
+				const argument = this.evaluateExpression(expr.argument);
+				if (!argument.isCompileTimeValue()) return;
+				const result = operandHandler(
+					/** @type {T} */ (argument.asCompileTimeValue())
+				);
+				return valueAsExpression(result, expr, argument.couldHaveSideEffects());
+			};
+
+			if (expr.operator === "typeof") {
+				switch (expr.argument.type) {
+					case "Identifier": {
+						const res = this.callHooksForName(
+							this.hooks.evaluateTypeof,
+							expr.argument.name,
+							expr
+						);
+						if (res !== undefined) return res;
+						break;
+					}
+					case "MetaProperty": {
+						const res = this.callHooksForName(
+							this.hooks.evaluateTypeof,
+							/** @type {string} */
+							(getRootName(expr.argument)),
+							expr
+						);
+						if (res !== undefined) return res;
+						break;
+					}
+					case "MemberExpression": {
+						const res = this.callHooksForExpression(
+							this.hooks.evaluateTypeof,
+							expr.argument,
+							expr
+						);
+						if (res !== undefined) return res;
+						break;
+					}
+					case "ChainExpression": {
+						const res = this.callHooksForExpression(
+							this.hooks.evaluateTypeof,
+							expr.argument.expression,
+							expr
+						);
+						if (res !== undefined) return res;
+						break;
+					}
+					case "FunctionExpression": {
+						return new BasicEvaluatedExpression()
+							.setString("function")
+							.setRange(/** @type {Range} */ (expr.range));
+					}
+				}
+				const arg = this.evaluateExpression(expr.argument);
+				if (arg.isUnknown()) return;
+				if (arg.isString()) {
+					return new BasicEvaluatedExpression()
+						.setString("string")
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isWrapped()) {
+					return new BasicEvaluatedExpression()
+						.setString("string")
+						.setSideEffects()
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isUndefined()) {
+					return new BasicEvaluatedExpression()
+						.setString("undefined")
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isNumber()) {
+					return new BasicEvaluatedExpression()
+						.setString("number")
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isBigInt()) {
+					return new BasicEvaluatedExpression()
+						.setString("bigint")
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isBoolean()) {
+					return new BasicEvaluatedExpression()
+						.setString("boolean")
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isConstArray() || arg.isRegExp() || arg.isNull()) {
+					return new BasicEvaluatedExpression()
+						.setString("object")
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				if (arg.isArray()) {
+					return new BasicEvaluatedExpression()
+						.setString("object")
+						.setSideEffects(arg.couldHaveSideEffects())
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+			} else if (expr.operator === "!") {
+				const argument = this.evaluateExpression(expr.argument);
+				const bool = argument.asBool();
+				if (typeof bool !== "boolean") return;
+				return new BasicEvaluatedExpression()
+					.setBoolean(!bool)
+					.setSideEffects(argument.couldHaveSideEffects())
+					.setRange(/** @type {Range} */ (expr.range));
+			} else if (expr.operator === "~") {
+				return handleConstOperation((v) => ~v);
+			} else if (expr.operator === "+") {
+				// eslint-disable-next-line no-implicit-coercion
+				return handleConstOperation((v) => +v);
+			} else if (expr.operator === "-") {
+				return handleConstOperation((v) => -v);
+			}
+		});
+		this.hooks.evaluateTypeof
+			.for("undefined")
+			.tap(CLASS_NAME, (expr) =>
+				new BasicEvaluatedExpression()
+					.setString("undefined")
+					.setRange(/** @type {Range} */ (expr.range))
+			);
+		this.hooks.evaluate.for("Identifier").tap(CLASS_NAME, (expr) => {
+			if (/** @type {Identifier} */ (expr).name === "undefined") {
+				return new BasicEvaluatedExpression()
+					.setUndefined()
+					.setRange(/** @type {Range} */ (expr.range));
+			}
+		});
+		/**
+		 * Tap evaluate with variable info.
+		 * @param {"Identifier" | "ThisExpression" | "MemberExpression"} exprType expression type name
+		 * @param {(node: Expression | SpreadElement) => GetInfoResult | undefined} getInfo get info
+		 * @returns {void}
+		 */
+		const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
+			/** @type {Expression | undefined} */
+			let cachedExpression;
+			/** @type {GetInfoResult | undefined} */
+			let cachedInfo;
+			this.hooks.evaluate.for(exprType).tap(CLASS_NAME, (expr) => {
+				const expression =
+					/** @type {Identifier | ThisExpression | MemberExpression} */ (expr);
+
+				const info = getInfo(expression);
+				if (info !== undefined) {
+					return this.callHooksForInfoWithFallback(
+						this.hooks.evaluateIdentifier,
+						info.name,
+						(_name) => {
+							cachedExpression = expression;
+							cachedInfo = info;
+							return undefined;
+						},
+						(name) => {
+							const hook = this.hooks.evaluateDefinedIdentifier.get(name);
+							if (hook !== undefined) {
+								return hook.call(expression);
+							}
+						},
+						expression
+					);
+				}
+			});
+			this.hooks.evaluate
+				.for(exprType)
+				.tap({ name: CLASS_NAME, stage: 100 }, (expr) => {
+					const expression =
+						/** @type {Identifier | ThisExpression | MemberExpression} */
+						(expr);
+					const info =
+						cachedExpression === expression ? cachedInfo : getInfo(expression);
+					if (info !== undefined) {
+						return new BasicEvaluatedExpression()
+							.setIdentifier(
+								info.name,
+								info.rootInfo,
+								info.getMembers,
+								info.getMembersOptionals,
+								info.getMemberRanges
+							)
+							.setRange(/** @type {Range} */ (expression.range));
+					}
+				});
+			this.hooks.finish.tap(CLASS_NAME, () => {
+				// Cleanup for GC
+				cachedExpression = cachedInfo = undefined;
+			});
+		};
+		tapEvaluateWithVariableInfo("Identifier", (expr) => {
+			const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name);
+			if (
+				typeof info === "string" ||
+				(info instanceof VariableInfo && (info.isFree() || info.isTagged()))
+			) {
+				return {
+					name: info,
+					rootInfo: info,
+					getMembers: () => [],
+					getMembersOptionals: () => [],
+					getMemberRanges: () => []
+				};
+			}
+		});
+		tapEvaluateWithVariableInfo("ThisExpression", (_expr) => {
+			const info = this.getVariableInfo("this");
+			if (
+				typeof info === "string" ||
+				(info instanceof VariableInfo && (info.isFree() || info.isTagged()))
+			) {
+				return {
+					name: info,
+					rootInfo: info,
+					getMembers: () => [],
+					getMembersOptionals: () => [],
+					getMemberRanges: () => []
+				};
+			}
+		});
+		this.hooks.evaluate.for("MetaProperty").tap(CLASS_NAME, (expr) => {
+			const metaProperty = /** @type {MetaProperty} */ (expr);
+
+			return this.callHooksForName(
+				this.hooks.evaluateIdentifier,
+				/** @type {string} */
+				(getRootName(metaProperty)),
+				metaProperty
+			);
+		});
+		tapEvaluateWithVariableInfo("MemberExpression", (expr) =>
+			this.getMemberExpressionInfo(
+				/** @type {MemberExpression} */ (expr),
+				ALLOWED_MEMBER_TYPES_EXPRESSION
+			)
+		);
+
+		this.hooks.evaluate.for("CallExpression").tap(CLASS_NAME, (expression) => {
+			const expr = /** @type {CallExpression} */ (expression);
+			if (
+				expr.callee.type === "MemberExpression" &&
+				expr.callee.property.type ===
+					(expr.callee.computed ? "Literal" : "Identifier")
+			) {
+				// type Super also possible here
+				const param = this.evaluateExpression(
+					/** @type {Expression} */ (expr.callee.object)
+				);
+				const property =
+					expr.callee.property.type === "Literal"
+						? `${expr.callee.property.value}`
+						: expr.callee.property.name;
+				const hook = this.hooks.evaluateCallExpressionMember.get(property);
+				if (hook !== undefined) {
+					return hook.call(expr, param);
+				}
+			} else if (expr.callee.type === "Identifier") {
+				return this.callHooksForName(
+					this.hooks.evaluateCallExpression,
+					expr.callee.name,
+					expr
+				);
+			}
+		});
+		this.hooks.evaluateCallExpressionMember
+			.for("indexOf")
+			.tap(CLASS_NAME, (expr, param) => {
+				if (!param.isString()) return;
+				if (expr.arguments.length === 0) return;
+				const [arg1, arg2] = expr.arguments;
+				if (arg1.type === "SpreadElement") return;
+				const arg1Eval = this.evaluateExpression(arg1);
+				if (!arg1Eval.isString()) return;
+				const arg1Value = /** @type {string} */ (arg1Eval.string);
+				/** @type {number} */
+				let result;
+				if (arg2) {
+					if (arg2.type === "SpreadElement") return;
+					const arg2Eval = this.evaluateExpression(arg2);
+					if (!arg2Eval.isNumber()) return;
+					result = /** @type {string} */ (param.string).indexOf(
+						arg1Value,
+						arg2Eval.number
+					);
+				} else {
+					result = /** @type {string} */ (param.string).indexOf(arg1Value);
+				}
+				return new BasicEvaluatedExpression()
+					.setNumber(result)
+					.setSideEffects(param.couldHaveSideEffects())
+					.setRange(/** @type {Range} */ (expr.range));
+			});
+		this.hooks.evaluateCallExpressionMember
+			.for("replace")
+			.tap(CLASS_NAME, (expr, param) => {
+				if (!param.isString()) return;
+				if (expr.arguments.length !== 2) return;
+				if (expr.arguments[0].type === "SpreadElement") return;
+				if (expr.arguments[1].type === "SpreadElement") return;
+				const arg1 = this.evaluateExpression(expr.arguments[0]);
+				const arg2 = this.evaluateExpression(expr.arguments[1]);
+				if (!arg1.isString() && !arg1.isRegExp()) return;
+				const arg1Value = /** @type {string | RegExp} */ (
+					arg1.regExp || arg1.string
+				);
+				if (!arg2.isString()) return;
+				const arg2Value = /** @type {string} */ (arg2.string);
+				return new BasicEvaluatedExpression()
+					.setString(
+						/** @type {string} */ (param.string).replace(arg1Value, arg2Value)
+					)
+					.setSideEffects(param.couldHaveSideEffects())
+					.setRange(/** @type {Range} */ (expr.range));
+			});
+		for (const fn of ["substr", "substring", "slice"]) {
+			this.hooks.evaluateCallExpressionMember
+				.for(fn)
+				.tap(CLASS_NAME, (expr, param) => {
+					if (!param.isString()) return;
+					/** @type {BasicEvaluatedExpression} */
+					let arg1;
+					/** @type {string} */
+					let result;
+					const str = /** @type {string} */ (param.string);
+					switch (expr.arguments.length) {
+						case 1:
+							if (expr.arguments[0].type === "SpreadElement") return;
+							arg1 = this.evaluateExpression(expr.arguments[0]);
+							if (!arg1.isNumber()) return;
+							result = str[
+								/** @type {"substr" | "substring" | "slice"} */ (fn)
+							](/** @type {number} */ (arg1.number));
+							break;
+						case 2: {
+							if (expr.arguments[0].type === "SpreadElement") return;
+							if (expr.arguments[1].type === "SpreadElement") return;
+							arg1 = this.evaluateExpression(expr.arguments[0]);
+							const arg2 = this.evaluateExpression(expr.arguments[1]);
+							if (!arg1.isNumber()) return;
+							if (!arg2.isNumber()) return;
+							result = str[
+								/** @type {"substr" | "substring" | "slice"} */ (fn)
+							](
+								/** @type {number} */ (arg1.number),
+								/** @type {number} */ (arg2.number)
+							);
+							break;
+						}
+						default:
+							return;
+					}
+					return new BasicEvaluatedExpression()
+						.setString(result)
+						.setSideEffects(param.couldHaveSideEffects())
+						.setRange(/** @type {Range} */ (expr.range));
+				});
+		}
+
+		/**
+		 * Gets simplified template result.
+		 * @param {"cooked" | "raw"} kind kind of values to get
+		 * @param {TemplateLiteral} templateLiteralExpr TemplateLiteral expr
+		 * @returns {{ quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[] }} Simplified template
+		 */
+		const getSimplifiedTemplateResult = (kind, templateLiteralExpr) => {
+			/** @type {BasicEvaluatedExpression[]} */
+			const quasis = [];
+			/** @type {BasicEvaluatedExpression[]} */
+			const parts = [];
+
+			for (let i = 0; i < templateLiteralExpr.quasis.length; i++) {
+				const quasiExpr = templateLiteralExpr.quasis[i];
+				const quasi = quasiExpr.value[kind];
+
+				if (i > 0) {
+					const prevExpr = parts[parts.length - 1];
+					const expr = this.evaluateExpression(
+						templateLiteralExpr.expressions[i - 1]
+					);
+					const exprAsString = expr.asString();
+					if (
+						typeof exprAsString === "string" &&
+						!expr.couldHaveSideEffects()
+					) {
+						// We can merge quasi + expr + quasi when expr
+						// is a const string
+
+						prevExpr.setString(prevExpr.string + exprAsString + quasi);
+						prevExpr.setRange([
+							/** @type {Range} */ (prevExpr.range)[0],
+							/** @type {Range} */ (quasiExpr.range)[1]
+						]);
+						// We unset the expression as it doesn't match to a single expression
+						prevExpr.setExpression(undefined);
+						continue;
+					}
+					parts.push(expr);
+				}
+
+				const part = new BasicEvaluatedExpression()
+					.setString(/** @type {string} */ (quasi))
+					.setRange(/** @type {Range} */ (quasiExpr.range))
+					.setExpression(quasiExpr);
+				quasis.push(part);
+				parts.push(part);
+			}
+			return {
+				quasis,
+				parts
+			};
+		};
+
+		this.hooks.evaluate.for("TemplateLiteral").tap(CLASS_NAME, (_node) => {
+			const node = /** @type {TemplateLiteral} */ (_node);
+
+			const { quasis, parts } = getSimplifiedTemplateResult("cooked", node);
+			if (parts.length === 1) {
+				return parts[0].setRange(/** @type {Range} */ (node.range));
+			}
+			return new BasicEvaluatedExpression()
+				.setTemplateString(quasis, parts, "cooked")
+				.setRange(/** @type {Range} */ (node.range));
+		});
+		this.hooks.evaluate
+			.for("TaggedTemplateExpression")
+			.tap(CLASS_NAME, (_node) => {
+				const node = /** @type {TaggedTemplateExpression} */ (_node);
+				const tag = this.evaluateExpression(node.tag);
+
+				if (tag.isIdentifier() && tag.identifier === "String.raw") {
+					const { quasis, parts } = getSimplifiedTemplateResult(
+						"raw",
+						node.quasi
+					);
+					return new BasicEvaluatedExpression()
+						.setTemplateString(quasis, parts, "raw")
+						.setRange(/** @type {Range} */ (node.range));
+				}
+			});
+
+		this.hooks.evaluateCallExpressionMember
+			.for("concat")
+			.tap(CLASS_NAME, (expr, param) => {
+				if (!param.isString() && !param.isWrapped()) return;
+				/** @type {undefined | BasicEvaluatedExpression} */
+				let stringSuffix;
+				let hasUnknownParams = false;
+				/** @type {BasicEvaluatedExpression[]} */
+				const innerExpressions = [];
+				for (let i = expr.arguments.length - 1; i >= 0; i--) {
+					const arg = expr.arguments[i];
+					if (arg.type === "SpreadElement") return;
+					const argExpr = this.evaluateExpression(arg);
+					if (
+						hasUnknownParams ||
+						(!argExpr.isString() && !argExpr.isNumber())
+					) {
+						hasUnknownParams = true;
+						innerExpressions.push(argExpr);
+						continue;
+					}
+
+					const value = argExpr.isString()
+						? /** @type {string} */ (argExpr.string)
+						: String(argExpr.number);
+
+					/** @type {string} */
+					const newString =
+						value +
+						(stringSuffix ? /** @type {string} */ (stringSuffix.string) : "");
+					const newRange = /** @type {Range} */ ([
+						/** @type {Range} */ (argExpr.range)[0],
+						/** @type {Range} */ ((stringSuffix || argExpr).range)[1]
+					]);
+					stringSuffix = new BasicEvaluatedExpression()
+						.setString(newString)
+						.setSideEffects(
+							(stringSuffix && stringSuffix.couldHaveSideEffects()) ||
+								argExpr.couldHaveSideEffects()
+						)
+						.setRange(newRange);
+				}
+
+				if (hasUnknownParams) {
+					const prefix = param.isString() ? param : param.prefix;
+					const inner =
+						param.isWrapped() && param.wrappedInnerExpressions
+							? [
+									...param.wrappedInnerExpressions,
+									...innerExpressions.reverse()
+								]
+							: innerExpressions.reverse();
+					return new BasicEvaluatedExpression()
+						.setWrapped(prefix, stringSuffix, inner)
+						.setRange(/** @type {Range} */ (expr.range));
+				} else if (param.isWrapped()) {
+					const postfix = stringSuffix || param.postfix;
+					const inner = param.wrappedInnerExpressions
+						? [...param.wrappedInnerExpressions, ...innerExpressions.reverse()]
+						: innerExpressions.reverse();
+					return new BasicEvaluatedExpression()
+						.setWrapped(param.prefix, postfix, inner)
+						.setRange(/** @type {Range} */ (expr.range));
+				}
+				const newString =
+					/** @type {string} */ (param.string) +
+					(stringSuffix ? stringSuffix.string : "");
+				return new BasicEvaluatedExpression()
+					.setString(newString)
+					.setSideEffects(
+						(stringSuffix && stringSuffix.couldHaveSideEffects()) ||
+							param.couldHaveSideEffects()
+					)
+					.setRange(/** @type {Range} */ (expr.range));
+			});
+		this.hooks.evaluateCallExpressionMember
+			.for("split")
+			.tap(CLASS_NAME, (expr, param) => {
+				if (!param.isString()) return;
+				if (expr.arguments.length !== 1) return;
+				if (expr.arguments[0].type === "SpreadElement") return;
+				/** @type {string[]} */
+				let result;
+				const arg = this.evaluateExpression(expr.arguments[0]);
+				if (arg.isString()) {
+					result =
+						/** @type {string} */
+						(param.string).split(/** @type {string} */ (arg.string));
+				} else if (arg.isRegExp()) {
+					result = /** @type {string} */ (param.string).split(
+						/** @type {RegExp} */ (arg.regExp)
+					);
+				} else {
+					return;
+				}
+				return new BasicEvaluatedExpression()
+					.setArray(result)
+					.setSideEffects(param.couldHaveSideEffects())
+					.setRange(/** @type {Range} */ (expr.range));
+			});
+		this.hooks.evaluate
+			.for("ConditionalExpression")
+			.tap(CLASS_NAME, (_expr) => {
+				const expr = /** @type {ConditionalExpression} */ (_expr);
+
+				const condition = this.evaluateExpression(expr.test);
+				const conditionValue = condition.asBool();
+				/** @type {BasicEvaluatedExpression} */
+				let res;
+				if (conditionValue === undefined) {
+					const consequent = this.evaluateExpression(expr.consequent);
+					const alternate = this.evaluateExpression(expr.alternate);
+					res = new BasicEvaluatedExpression();
+					if (consequent.isConditional()) {
+						res.setOptions(
+							/** @type {BasicEvaluatedExpression[]} */ (consequent.options)
+						);
+					} else {
+						res.setOptions([consequent]);
+					}
+					if (alternate.isConditional()) {
+						res.addOptions(
+							/** @type {BasicEvaluatedExpression[]} */ (alternate.options)
+						);
+					} else {
+						res.addOptions([alternate]);
+					}
+				} else {
+					res = this.evaluateExpression(
+						conditionValue ? expr.consequent : expr.alternate
+					);
+					if (condition.couldHaveSideEffects()) res.setSideEffects();
+				}
+				res.setRange(/** @type {Range} */ (expr.range));
+				return res;
+			});
+		this.hooks.evaluate.for("ArrayExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {ArrayExpression} */ (_expr);
+
+			const items = expr.elements.map(
+				(element) =>
+					element !== null &&
+					element.type !== "SpreadElement" &&
+					this.evaluateExpression(element)
+			);
+			if (!items.every(Boolean)) return;
+			return new BasicEvaluatedExpression()
+				.setItems(/** @type {BasicEvaluatedExpression[]} */ (items))
+				.setRange(/** @type {Range} */ (expr.range));
+		});
+		this.hooks.evaluate.for("ChainExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {ChainExpression} */ (_expr);
+			/** @type {Expression[]} */
+			const optionalExpressionsStack = [];
+			/** @type {Expression | Super} */
+			let next = expr.expression;
+
+			while (
+				next.type === "MemberExpression" ||
+				next.type === "CallExpression"
+			) {
+				if (next.type === "MemberExpression") {
+					if (next.optional) {
+						// SuperNode can not be optional
+						optionalExpressionsStack.push(
+							/** @type {Expression} */ (next.object)
+						);
+					}
+					next = next.object;
+				} else {
+					if (next.optional) {
+						// SuperNode can not be optional
+						optionalExpressionsStack.push(
+							/** @type {Expression} */ (next.callee)
+						);
+					}
+					next = next.callee;
+				}
+			}
+
+			while (optionalExpressionsStack.length > 0) {
+				const expression =
+					/** @type {Expression} */
+					(optionalExpressionsStack.pop());
+				const evaluated = this.evaluateExpression(expression);
+
+				if (evaluated.asNullish()) {
+					return evaluated.setRange(/** @type {Range} */ (_expr.range));
+				}
+			}
+			return this.evaluateExpression(expr.expression);
+		});
+		this.hooks.evaluate.for("SequenceExpression").tap(CLASS_NAME, (_expr) => {
+			const expr = /** @type {SequenceExpression} */ (_expr);
+			if (!expr.range) return;
+			let commentsStartPos = /** @type {Range} */ (expr.range)[0];
+			for (let i = 0; i < expr.expressions.length - 1; i++) {
+				const item = expr.expressions[i];
+				if (!item.range) return;
+				if (!this.isPure(item, commentsStartPos)) return;
+				commentsStartPos = /** @type {Range} */ (item.range)[1];
+			}
+			const last = expr.expressions[expr.expressions.length - 1];
+			const evaluated = this.evaluateExpression(last);
+			if (!evaluated.isCompileTimeValue()) return;
+			return evaluated.setRange(/** @type {Range} */ (expr.range));
+		});
+	}
+
+	/**
+	 * Destructuring assignment properties for.
+	 * @param {Expression} node node
+	 * @returns {DestructuringAssignmentProperties | undefined} destructured identifiers
+	 */
+	destructuringAssignmentPropertiesFor(node) {
+		if (!this.destructuringAssignmentProperties) return;
+		return this.destructuringAssignmentProperties.get(node);
+	}
+
+	/**
+	 * Gets rename identifier.
+	 * @param {Expression | SpreadElement} expr expression
+	 * @returns {string | VariableInfo | undefined} identifier
+	 */
+	getRenameIdentifier(expr) {
+		const result = this.evaluateExpression(expr);
+		if (result.isIdentifier()) {
+			return result.identifier;
+		}
+	}
+
+	/**
+	 * Processes the provided classy.
+	 * @param {ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration} classy a class node
+	 * @returns {void}
+	 */
+	walkClass(classy) {
+		if (
+			classy.superClass &&
+			!this.hooks.classExtendsExpression.call(classy.superClass, classy)
+		) {
+			this.walkExpression(classy.superClass);
+		}
+		if (classy.body && classy.body.type === "ClassBody") {
+			/** @type {Identifier[]} */
+			const scopeParams = [];
+			// Add class name in scope for recursive calls
+			if (classy.id) {
+				scopeParams.push(classy.id);
+			}
+			this.inClassScope(true, scopeParams, () => {
+				for (const classElement of classy.body.body) {
+					if (!this.hooks.classBodyElement.call(classElement, classy)) {
+						if (classElement.type === "StaticBlock") {
+							const wasTopLevel = this.scope.topLevelScope;
+							this.scope.topLevelScope = false;
+							this.walkBlockStatement(classElement);
+							this.scope.topLevelScope = wasTopLevel;
+						} else {
+							if (classElement.computed && classElement.key) {
+								this.walkExpression(classElement.key);
+							}
+
+							if (
+								classElement.value &&
+								!this.hooks.classBodyValue.call(
+									classElement.value,
+									classElement,
+									classy
+								)
+							) {
+								const wasTopLevel = this.scope.topLevelScope;
+								this.scope.topLevelScope = false;
+								this.walkExpression(classElement.value);
+								this.scope.topLevelScope = wasTopLevel;
+							}
+						}
+					}
+				}
+			});
+		}
+	}
+
+	/**
+	 * Module pre walking iterates the scope for import entries
+	 * @param {(Statement | ModuleDeclaration)[]} statements statements
+	 */
+	modulePreWalkStatements(statements) {
+		for (let index = 0, len = statements.length; index < len; index++) {
+			const statement = statements[index];
+			/** @type {StatementPath} */
+			(this.statementPath).push(statement);
+			switch (statement.type) {
+				case "ImportDeclaration":
+					this.modulePreWalkImportDeclaration(statement);
+					break;
+				case "ExportAllDeclaration":
+					this.modulePreWalkExportAllDeclaration(statement);
+					break;
+				case "ExportNamedDeclaration":
+					this.modulePreWalkExportNamedDeclaration(statement);
+					break;
+			}
+			this.prevStatement =
+				/** @type {StatementPath} */
+				(this.statementPath).pop();
+		}
+	}
+
+	/**
+	 * Pre walking iterates the scope for variable declarations
+	 * @param {(Statement | ModuleDeclaration)[]} statements statements
+	 */
+	preWalkStatements(statements) {
+		for (let index = 0, len = statements.length; index < len; index++) {
+			const statement = statements[index];
+			this.preWalkStatement(statement);
+		}
+	}
+
+	/**
+	 * Block pre walking iterates the scope for block variable declarations
+	 * @param {(Statement | ModuleDeclaration)[]} statements statements
+	 */
+	blockPreWalkStatements(statements) {
+		for (let index = 0, len = statements.length; index < len; index++) {
+			const statement = statements[index];
+			this.blockPreWalkStatement(statement);
+		}
+	}
+
+	/**
+	 * Walking iterates the statements and expressions and processes them
+	 * @param {(Statement | ModuleDeclaration)[]} statements statements
+	 */
+	walkStatements(statements) {
+		let onlyFunctionDeclaration = false;
+
+		for (let index = 0, len = statements.length; index < len; index++) {
+			const statement = statements[index];
+
+			if (
+				onlyFunctionDeclaration &&
+				statement.type !== "FunctionDeclaration" &&
+				this.hooks.unusedStatement.call(/** @type {Statement} */ (statement))
+			) {
+				continue;
+			}
+
+			this.walkStatement(statement);
+
+			if (this.scope.terminated) {
+				onlyFunctionDeclaration = true;
+			}
+		}
+	}
+
+	/**
+	 * Walking iterates the statements and expressions and processes them
+	 * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
+	 */
+	preWalkStatement(statement) {
+		/** @type {StatementPath} */
+		(this.statementPath).push(statement);
+		if (this.hooks.preStatement.call(statement)) {
+			this.prevStatement =
+				/** @type {StatementPath} */
+				(this.statementPath).pop();
+			return;
+		}
+		switch (statement.type) {
+			case "BlockStatement":
+				this.preWalkBlockStatement(statement);
+				break;
+			case "DoWhileStatement":
+				this.preWalkDoWhileStatement(statement);
+				break;
+			case "ForInStatement":
+				this.preWalkForInStatement(statement);
+				break;
+			case "ForOfStatement":
+				this.preWalkForOfStatement(statement);
+				break;
+			case "ForStatement":
+				this.preWalkForStatement(statement);
+				break;
+			case "FunctionDeclaration":
+				this.preWalkFunctionDeclaration(statement);
+				break;
+			case "IfStatement":
+				this.preWalkIfStatement(statement);
+				break;
+			case "LabeledStatement":
+				this.preWalkLabeledStatement(statement);
+				break;
+			case "SwitchStatement":
+				this.preWalkSwitchStatement(statement);
+				break;
+			case "TryStatement":
+				this.preWalkTryStatement(statement);
+				break;
+			case "VariableDeclaration":
+				this.preWalkVariableDeclaration(statement);
+				break;
+			case "WhileStatement":
+				this.preWalkWhileStatement(statement);
+				break;
+			case "WithStatement":
+				this.preWalkWithStatement(statement);
+				break;
+		}
+		this.prevStatement =
+			/** @type {StatementPath} */
+			(this.statementPath).pop();
+	}
+
+	/**
+	 * Block pre walk statement.
+	 * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
+	 */
+	blockPreWalkStatement(statement) {
+		/** @type {StatementPath} */
+		(this.statementPath).push(statement);
+		if (this.hooks.blockPreStatement.call(statement)) {
+			this.prevStatement =
+				/** @type {StatementPath} */
+				(this.statementPath).pop();
+			return;
+		}
+		switch (statement.type) {
+			case "ExportDefaultDeclaration":
+				this.blockPreWalkExportDefaultDeclaration(statement);
+				break;
+			case "ExportNamedDeclaration":
+				this.blockPreWalkExportNamedDeclaration(statement);
+				break;
+			case "VariableDeclaration":
+				this.blockPreWalkVariableDeclaration(statement);
+				break;
+			case "ClassDeclaration":
+				this.blockPreWalkClassDeclaration(statement);
+				break;
+			case "ExpressionStatement":
+				this.blockPreWalkExpressionStatement(statement);
+		}
+		this.prevStatement =
+			/** @type {StatementPath} */
+			(this.statementPath).pop();
+	}
+
+	/**
+	 * Processes the provided statement.
+	 * @param {Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} statement statement
+	 */
+	walkStatement(statement) {
+		/** @type {StatementPath} */
+		(this.statementPath).push(statement);
+		if (this.hooks.statement.call(statement) !== undefined) {
+			this.prevStatement =
+				/** @type {StatementPath} */
+				(this.statementPath).pop();
+			return;
+		}
+		switch (statement.type) {
+			case "BlockStatement":
+				this.walkBlockStatement(statement);
+				break;
+			case "ClassDeclaration":
+				this.walkClassDeclaration(statement);
+				break;
+			case "DoWhileStatement":
+				this.walkDoWhileStatement(statement);
+				break;
+			case "ExportDefaultDeclaration":
+				this.walkExportDefaultDeclaration(statement);
+				break;
+			case "ExportNamedDeclaration":
+				this.walkExportNamedDeclaration(statement);
+				break;
+			case "ExpressionStatement":
+				this.walkExpressionStatement(statement);
+				break;
+			case "ForInStatement":
+				this.walkForInStatement(statement);
+				break;
+			case "ForOfStatement":
+				this.walkForOfStatement(statement);
+				break;
+			case "ForStatement":
+				this.walkForStatement(statement);
+				break;
+			case "FunctionDeclaration":
+				this.walkFunctionDeclaration(statement);
+				break;
+			case "IfStatement":
+				this.walkIfStatement(statement);
+				break;
+			case "LabeledStatement":
+				this.walkLabeledStatement(statement);
+				break;
+			case "ReturnStatement":
+				this.walkReturnStatement(statement);
+				break;
+			case "SwitchStatement":
+				this.walkSwitchStatement(statement);
+				break;
+			case "ThrowStatement":
+				this.walkThrowStatement(statement);
+				break;
+			case "TryStatement":
+				this.walkTryStatement(statement);
+				break;
+			case "VariableDeclaration":
+				this.walkVariableDeclaration(statement);
+				break;
+			case "WhileStatement":
+				this.walkWhileStatement(statement);
+				break;
+			case "WithStatement":
+				this.walkWithStatement(statement);
+				break;
+		}
+		this.prevStatement =
+			/** @type {StatementPath} */
+			(this.statementPath).pop();
+	}
+
+	/**
+	 * Walks a statements that is nested within a parent statement
+	 * and can potentially be a non-block statement.
+	 * This enforces the nested statement to never be in ASI position.
+	 * @param {Statement} statement the nested statement
+	 */
+	walkNestedStatement(statement) {
+		this.prevStatement = undefined;
+		this.walkStatement(statement);
+	}
+
+	// Real Statements
+	/**
+	 * Pre walk block statement.
+	 * @param {BlockStatement} statement block statement
+	 */
+	preWalkBlockStatement(statement) {
+		this.preWalkStatements(statement.body);
+	}
+
+	/**
+	 * Walk block statement.
+	 * @param {BlockStatement | StaticBlock} statement block statement
+	 */
+	walkBlockStatement(statement) {
+		this.inBlockScope(() => {
+			const body = statement.body;
+			const prev = this.prevStatement;
+			this.blockPreWalkStatements(body);
+			this.prevStatement = prev;
+			this.walkStatements(body);
+		}, true);
+	}
+
+	/**
+	 * Walk expression statement.
+	 * @param {ExpressionStatement} statement expression statement
+	 */
+	walkExpressionStatement(statement) {
+		this.walkExpression(statement.expression);
+	}
+
+	/**
+	 * Pre walk if statement.
+	 * @param {IfStatement} statement if statement
+	 */
+	preWalkIfStatement(statement) {
+		this.preWalkStatement(statement.consequent);
+		if (statement.alternate) {
+			this.preWalkStatement(statement.alternate);
+		}
+	}
+
+	/**
+	 * Processes the provided statement.
+	 * @param {IfStatement} statement if statement
+	 */
+	walkIfStatement(statement) {
+		const result = this.hooks.statementIf.call(statement);
+		if (result === undefined) {
+			const inGuard = this.hooks.collectGuards.call(statement.test);
+			if (inGuard) {
+				inGuard(() => {
+					this.walkExpression(statement.test);
+					this.walkNestedStatement(statement.consequent);
+				});
+			} else {
+				this.walkExpression(statement.test);
+				this.walkNestedStatement(statement.consequent);
+			}
+
+			const consequentTerminated = this.scope.terminated;
+			this.scope.terminated = undefined;
+
+			if (statement.alternate) {
+				this.walkNestedStatement(statement.alternate);
+			}
+
+			const alternateTerminated = this.scope.terminated;
+
+			this.scope.terminated =
+				consequentTerminated && alternateTerminated
+					? alternateTerminated
+					: undefined;
+		} else if (result) {
+			this.walkNestedStatement(statement.consequent);
+		} else if (statement.alternate) {
+			this.walkNestedStatement(statement.alternate);
+		}
+	}
+
+	/**
+	 * Pre walk labeled statement.
+	 * @param {LabeledStatement} statement with statement
+	 */
+	preWalkLabeledStatement(statement) {
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk labeled statement.
+	 * @param {LabeledStatement} statement with statement
+	 */
+	walkLabeledStatement(statement) {
+		const hook = this.hooks.label.get(statement.label.name);
+		if (hook !== undefined) {
+			const result = hook.call(statement);
+			if (result === true) return;
+		}
+		this.inBlockScope(() => {
+			this.walkNestedStatement(statement.body);
+		});
+	}
+
+	/**
+	 * Pre walk with statement.
+	 * @param {WithStatement} statement with statement
+	 */
+	preWalkWithStatement(statement) {
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk with statement.
+	 * @param {WithStatement} statement with statement
+	 */
+	walkWithStatement(statement) {
+		this.inBlockScope(() => {
+			this.walkExpression(statement.object);
+			this.walkNestedStatement(statement.body);
+		});
+	}
+
+	/**
+	 * Pre walk switch statement.
+	 * @param {SwitchStatement} statement switch statement
+	 */
+	preWalkSwitchStatement(statement) {
+		this.preWalkSwitchCases(statement.cases);
+	}
+
+	/**
+	 * Walk switch statement.
+	 * @param {SwitchStatement} statement switch statement
+	 */
+	walkSwitchStatement(statement) {
+		this.walkExpression(statement.discriminant);
+		this.walkSwitchCases(statement.cases);
+	}
+
+	/**
+	 * Walk terminating statement.
+	 * @param {ReturnStatement | ThrowStatement} statement return or throw statement
+	 */
+	walkTerminatingStatement(statement) {
+		if (statement.argument) this.walkExpression(statement.argument);
+		// Skip top level scope because to handle `export` and `module.exports` after terminate
+		if (this.scope.topLevelScope === true) return;
+		if (this.hooks.terminate.call(statement)) {
+			this.scope.terminated =
+				statement.type === "ReturnStatement"
+					? SCOPE_INFO_TERMINATED_RETURN
+					: SCOPE_INFO_TERMINATED_THROW;
+		}
+	}
+
+	/**
+	 * Walk return statement.
+	 * @param {ReturnStatement} statement return statement
+	 */
+	walkReturnStatement(statement) {
+		this.walkTerminatingStatement(statement);
+	}
+
+	/**
+	 * Walk throw statement.
+	 * @param {ThrowStatement} statement return statement
+	 */
+	walkThrowStatement(statement) {
+		this.walkTerminatingStatement(statement);
+	}
+
+	/**
+	 * Pre walk try statement.
+	 * @param {TryStatement} statement try statement
+	 */
+	preWalkTryStatement(statement) {
+		this.preWalkStatement(statement.block);
+		if (statement.handler) this.preWalkCatchClause(statement.handler);
+		if (statement.finalizer) this.preWalkStatement(statement.finalizer);
+	}
+
+	/**
+	 * Walk try statement.
+	 * @param {TryStatement} statement try statement
+	 */
+	walkTryStatement(statement) {
+		if (this.scope.inTry) {
+			this.walkStatement(statement.block);
+		} else {
+			this.scope.inTry = true;
+			this.walkStatement(statement.block);
+			this.scope.inTry = false;
+		}
+
+		const tryTerminated = this.scope.terminated;
+		this.scope.terminated = undefined;
+
+		if (statement.handler) this.walkCatchClause(statement.handler);
+
+		const handlerTerminated = this.scope.terminated;
+		this.scope.terminated = undefined;
+
+		if (statement.finalizer) {
+			this.walkStatement(statement.finalizer);
+		}
+
+		const finalizerTerminated = this.scope.terminated;
+		this.scope.terminated = undefined;
+
+		if (finalizerTerminated) {
+			this.scope.terminated = finalizerTerminated;
+		} else if (
+			tryTerminated &&
+			(statement.handler ? handlerTerminated : true)
+		) {
+			this.scope.terminated = handlerTerminated || tryTerminated;
+		}
+	}
+
+	/**
+	 * Pre walk while statement.
+	 * @param {WhileStatement} statement while statement
+	 */
+	preWalkWhileStatement(statement) {
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk while statement.
+	 * @param {WhileStatement} statement while statement
+	 */
+	walkWhileStatement(statement) {
+		this.inBlockScope(() => {
+			this.walkExpression(statement.test);
+			this.walkNestedStatement(statement.body);
+		});
+	}
+
+	/**
+	 * Pre walk do while statement.
+	 * @param {DoWhileStatement} statement do while statement
+	 */
+	preWalkDoWhileStatement(statement) {
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk do while statement.
+	 * @param {DoWhileStatement} statement do while statement
+	 */
+	walkDoWhileStatement(statement) {
+		this.inBlockScope(() => {
+			this.walkNestedStatement(statement.body);
+			this.walkExpression(statement.test);
+		});
+	}
+
+	/**
+	 * Pre walk for statement.
+	 * @param {ForStatement} statement for statement
+	 */
+	preWalkForStatement(statement) {
+		if (statement.init && statement.init.type === "VariableDeclaration") {
+			this.preWalkStatement(statement.init);
+		}
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk for statement.
+	 * @param {ForStatement} statement for statement
+	 */
+	walkForStatement(statement) {
+		this.inBlockScope(() => {
+			if (statement.init) {
+				if (statement.init.type === "VariableDeclaration") {
+					this.blockPreWalkVariableDeclaration(statement.init);
+					this.prevStatement = undefined;
+					this.walkStatement(statement.init);
+				} else {
+					this.walkExpression(statement.init);
+				}
+			}
+			if (statement.test) {
+				this.walkExpression(statement.test);
+			}
+			if (statement.update) {
+				this.walkExpression(statement.update);
+			}
+
+			const body = statement.body;
+
+			if (body.type === "BlockStatement") {
+				// no need to add additional scope
+				const prev = this.prevStatement;
+				this.blockPreWalkStatements(body.body);
+				this.prevStatement = prev;
+				this.walkStatements(body.body);
+			} else {
+				this.walkNestedStatement(body);
+			}
+		});
+	}
+
+	/**
+	 * Pre walk for in statement.
+	 * @param {ForInStatement} statement for statement
+	 */
+	preWalkForInStatement(statement) {
+		if (statement.left.type === "VariableDeclaration") {
+			this.preWalkVariableDeclaration(statement.left);
+		}
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk for in statement.
+	 * @param {ForInStatement} statement for statement
+	 */
+	walkForInStatement(statement) {
+		this.inBlockScope(() => {
+			if (statement.left.type === "VariableDeclaration") {
+				this.blockPreWalkVariableDeclaration(statement.left);
+				this.walkVariableDeclaration(statement.left);
+			} else {
+				this.walkPattern(statement.left);
+			}
+
+			this.walkExpression(statement.right);
+
+			const body = statement.body;
+
+			if (body.type === "BlockStatement") {
+				// no need to add additional scope
+				const prev = this.prevStatement;
+				this.blockPreWalkStatements(body.body);
+				this.prevStatement = prev;
+				this.walkStatements(body.body);
+			} else {
+				this.walkNestedStatement(body);
+			}
+		});
+	}
+
+	/**
+	 * Pre walk for of statement.
+	 * @param {ForOfStatement} statement statement
+	 */
+	preWalkForOfStatement(statement) {
+		if (statement.await && this.scope.topLevelScope === true) {
+			this.hooks.topLevelAwait.call(statement);
+		}
+		if (statement.left.type === "VariableDeclaration") {
+			this.preWalkVariableDeclaration(statement.left);
+		}
+		this.preWalkStatement(statement.body);
+	}
+
+	/**
+	 * Walk for of statement.
+	 * @param {ForOfStatement} statement for statement
+	 */
+	walkForOfStatement(statement) {
+		this.inBlockScope(() => {
+			if (statement.left.type === "VariableDeclaration") {
+				this.blockPreWalkVariableDeclaration(statement.left);
+				this.walkVariableDeclaration(statement.left);
+			} else {
+				this.walkPattern(statement.left);
+			}
+
+			this.walkExpression(statement.right);
+
+			const body = statement.body;
+
+			if (body.type === "BlockStatement") {
+				// no need to add additional scope
+				const prev = this.prevStatement;
+				this.blockPreWalkStatements(body.body);
+				this.prevStatement = prev;
+				this.walkStatements(body.body);
+			} else {
+				this.walkNestedStatement(body);
+			}
+		});
+	}
+
+	/**
+	 * Pre walk function declaration.
+	 * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
+	 */
+	preWalkFunctionDeclaration(statement) {
+		if (statement.id) {
+			this.defineVariable(statement.id.name);
+		}
+	}
+
+	/**
+	 * Walk function declaration.
+	 * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
+	 */
+	walkFunctionDeclaration(statement) {
+		const wasTopLevel = this.scope.topLevelScope;
+		this.scope.topLevelScope = false;
+		this.inFunctionScope(true, statement.params, () => {
+			for (const param of statement.params) {
+				this.walkPattern(param);
+			}
+
+			this.detectMode(statement.body.body);
+
+			const prev = this.prevStatement;
+
+			this.preWalkStatement(statement.body);
+			this.prevStatement = prev;
+			this.walkStatement(statement.body);
+		});
+		this.scope.topLevelScope = wasTopLevel;
+	}
+
+	/**
+	 * Block pre walk expression statement.
+	 * @param {ExpressionStatement} statement expression statement
+	 */
+	blockPreWalkExpressionStatement(statement) {
+		const expression = statement.expression;
+		switch (expression.type) {
+			case "AssignmentExpression":
+				this.preWalkAssignmentExpression(expression);
+		}
+	}
+
+	/**
+	 * Pre walk assignment expression.
+	 * @param {AssignmentExpression} expression assignment expression
+	 */
+	preWalkAssignmentExpression(expression) {
+		this.enterDestructuringAssignment(expression.left, expression.right);
+	}
+
+	/**
+	 * Enter destructuring assignment.
+	 * @param {Pattern} pattern pattern
+	 * @param {Expression} expression assignment expression
+	 * @returns {Expression | undefined} destructuring expression
+	 */
+	enterDestructuringAssignment(pattern, expression) {
+		if (
+			pattern.type !== "ObjectPattern" ||
+			!this.destructuringAssignmentProperties
+		) {
+			return;
+		}
+
+		const expr =
+			expression.type === "AwaitExpression" ? expression.argument : expression;
+
+		const destructuring =
+			expr.type === "AssignmentExpression"
+				? this.enterDestructuringAssignment(expr.left, expr.right)
+				: this.hooks.collectDestructuringAssignmentProperties.call(expr)
+					? expr
+					: undefined;
+
+		if (destructuring) {
+			const keys = this._preWalkObjectPattern(pattern);
+			if (!keys) return;
+
+			// check multiple assignments
+			if (this.destructuringAssignmentProperties.has(destructuring)) {
+				const set =
+					/** @type {DestructuringAssignmentProperties} */
+					(this.destructuringAssignmentProperties.get(destructuring));
+				for (const id of keys) set.add(id);
+			} else {
+				this.destructuringAssignmentProperties.set(destructuring, keys);
+			}
+		}
+
+		return destructuring;
+	}
+
+	/**
+	 * Module pre walk import declaration.
+	 * @param {ImportDeclaration} statement statement
+	 */
+	modulePreWalkImportDeclaration(statement) {
+		const source = /** @type {ImportSource} */ (statement.source.value);
+		this.hooks.import.call(statement, source);
+		for (const specifier of statement.specifiers) {
+			const name = specifier.local.name;
+			switch (specifier.type) {
+				case "ImportDefaultSpecifier":
+					if (
+						!this.hooks.importSpecifier.call(statement, source, "default", name)
+					) {
+						this.defineVariable(name);
+					}
+					break;
+				case "ImportSpecifier":
+					if (
+						!this.hooks.importSpecifier.call(
+							statement,
+							source,
+							/** @type {Identifier} */
+							(specifier.imported).name ||
+								/** @type {string} */
+								(
+									/** @type {Literal} */
+									(specifier.imported).value
+								),
+							name
+						)
+					) {
+						this.defineVariable(name);
+					}
+					break;
+				case "ImportNamespaceSpecifier":
+					if (!this.hooks.importSpecifier.call(statement, source, null, name)) {
+						this.defineVariable(name);
+					}
+					break;
+				default:
+					this.defineVariable(name);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided declaration.
+	 * @param {Declaration} declaration declaration
+	 * @param {OnIdent} onIdent on ident callback
+	 */
+	enterDeclaration(declaration, onIdent) {
+		switch (declaration.type) {
+			case "VariableDeclaration":
+				for (const declarator of declaration.declarations) {
+					switch (declarator.type) {
+						case "VariableDeclarator": {
+							this.enterPattern(declarator.id, onIdent);
+							break;
+						}
+					}
+				}
+				break;
+			case "FunctionDeclaration":
+				this.enterPattern(declaration.id, onIdent);
+				break;
+			case "ClassDeclaration":
+				this.enterPattern(declaration.id, onIdent);
+				break;
+		}
+	}
+
+	/**
+	 * Module pre walk export named declaration.
+	 * @param {ExportNamedDeclaration} statement statement
+	 */
+	modulePreWalkExportNamedDeclaration(statement) {
+		if (!statement.source) return;
+		const source = /** @type {ImportSource} */ (statement.source.value);
+		this.hooks.exportImport.call(statement, source);
+		if (statement.specifiers) {
+			for (
+				let specifierIndex = 0;
+				specifierIndex < statement.specifiers.length;
+				specifierIndex++
+			) {
+				const specifier = statement.specifiers[specifierIndex];
+				switch (specifier.type) {
+					case "ExportSpecifier": {
+						const localName =
+							/** @type {Identifier} */ (specifier.local).name ||
+							/** @type {string} */ (
+								/** @type {Literal} */ (specifier.local).value
+							);
+						const name =
+							/** @type {Identifier} */
+							(specifier.exported).name ||
+							/** @type {string} */
+							(/** @type {Literal} */ (specifier.exported).value);
+						this.hooks.exportImportSpecifier.call(
+							statement,
+							source,
+							localName,
+							name,
+							specifierIndex
+						);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Block pre walk export named declaration.
+	 * @param {ExportNamedDeclaration} statement statement
+	 */
+	blockPreWalkExportNamedDeclaration(statement) {
+		if (statement.source) return;
+		this.hooks.export.call(statement);
+		if (
+			statement.declaration &&
+			!this.hooks.exportDeclaration.call(statement, statement.declaration)
+		) {
+			const prev = this.prevStatement;
+			this.preWalkStatement(statement.declaration);
+			this.prevStatement = prev;
+			this.blockPreWalkStatement(statement.declaration);
+			let index = 0;
+			this.enterDeclaration(statement.declaration, (def) => {
+				this.hooks.exportSpecifier.call(statement, def, def, index++);
+			});
+		}
+		if (statement.specifiers) {
+			for (
+				let specifierIndex = 0;
+				specifierIndex < statement.specifiers.length;
+				specifierIndex++
+			) {
+				const specifier = statement.specifiers[specifierIndex];
+				switch (specifier.type) {
+					case "ExportSpecifier": {
+						const localName =
+							/** @type {Identifier} */ (specifier.local).name ||
+							/** @type {string} */ (
+								/** @type {Literal} */ (specifier.local).value
+							);
+						const name =
+							/** @type {Identifier} */
+							(specifier.exported).name ||
+							/** @type {string} */
+							(/** @type {Literal} */ (specifier.exported).value);
+						this.hooks.exportSpecifier.call(
+							statement,
+							localName,
+							name,
+							specifierIndex
+						);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Walk export named declaration.
+	 * @param {ExportNamedDeclaration} statement the statement
+	 */
+	walkExportNamedDeclaration(statement) {
+		if (statement.declaration) {
+			this.walkStatement(statement.declaration);
+		}
+	}
+
+	/**
+	 * Block pre walk export default declaration.
+	 * @param {ExportDefaultDeclaration} statement statement
+	 */
+	blockPreWalkExportDefaultDeclaration(statement) {
+		if (
+			statement.declaration.type === "FunctionDeclaration" ||
+			statement.declaration.type === "ClassDeclaration"
+		) {
+			const prev = this.prevStatement;
+
+			this.preWalkStatement(statement.declaration);
+			this.prevStatement = prev;
+			this.blockPreWalkStatement(statement.declaration);
+		}
+
+		if (
+			/** @type {MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
+			(statement.declaration).id &&
+			statement.declaration.type !== "FunctionExpression" &&
+			statement.declaration.type !== "ClassExpression"
+		) {
+			const declaration =
+				/** @type {MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
+				(statement.declaration);
+
+			this.hooks.exportSpecifier.call(
+				statement,
+				/** @type {Identifier} */
+				(declaration.id).name,
+				"default",
+				undefined
+			);
+		}
+	}
+
+	/**
+	 * Walk export default declaration.
+	 * @param {ExportDefaultDeclaration} statement statement
+	 */
+	walkExportDefaultDeclaration(statement) {
+		this.hooks.export.call(statement);
+		if (
+			/** @type {FunctionDeclaration | ClassDeclaration} */
+			(statement.declaration).id &&
+			statement.declaration.type !== "FunctionExpression" &&
+			statement.declaration.type !== "ClassExpression"
+		) {
+			const declaration =
+				/** @type {FunctionDeclaration | ClassDeclaration} */
+				(statement.declaration);
+			if (!this.hooks.exportDeclaration.call(statement, declaration)) {
+				this.walkStatement(declaration);
+			}
+		} else {
+			// Acorn parses `export default function() {}` as `FunctionDeclaration` and
+			// `export default class {}` as `ClassDeclaration`, both with `id = null`.
+			// These nodes must be treated as expressions.
+			if (
+				statement.declaration.type === "FunctionDeclaration" ||
+				statement.declaration.type === "ClassDeclaration"
+			) {
+				this.walkStatement(statement.declaration);
+			} else {
+				this.walkExpression(statement.declaration);
+			}
+
+			this.hooks.exportExpression.call(statement, statement.declaration);
+		}
+	}
+
+	/**
+	 * Module pre walk export all declaration.
+	 * @param {ExportAllDeclaration} statement statement
+	 */
+	modulePreWalkExportAllDeclaration(statement) {
+		const source = /** @type {ImportSource} */ (statement.source.value);
+		const name = statement.exported
+			? /** @type {Identifier} */
+				(statement.exported).name ||
+				/** @type {string} */
+				(/** @type {Literal} */ (statement.exported).value)
+			: null;
+		this.hooks.exportImport.call(statement, source);
+		this.hooks.exportImportSpecifier.call(statement, source, null, name, 0);
+	}
+
+	/**
+	 * Pre walk variable declaration.
+	 * @param {VariableDeclaration} statement variable declaration
+	 */
+	preWalkVariableDeclaration(statement) {
+		if (statement.kind !== "var") return;
+		this._preWalkVariableDeclaration(statement, this.hooks.varDeclarationVar);
+	}
+
+	/**
+	 * Block pre walk variable declaration.
+	 * @param {VariableDeclaration} statement variable declaration
+	 */
+	blockPreWalkVariableDeclaration(statement) {
+		if (statement.kind === "var") return;
+
+		const hookMap =
+			statement.kind === "const"
+				? this.hooks.varDeclarationConst
+				: statement.kind === "using" || statement.kind === "await using"
+					? this.hooks.varDeclarationUsing
+					: this.hooks.varDeclarationLet;
+		this._preWalkVariableDeclaration(statement, hookMap);
+	}
+
+	/**
+	 * Pre walk variable declaration.
+	 * @param {VariableDeclaration} statement variable declaration
+	 * @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap map of hooks
+	 */
+	_preWalkVariableDeclaration(statement, hookMap) {
+		for (const declarator of statement.declarations) {
+			switch (declarator.type) {
+				case "VariableDeclarator": {
+					this.preWalkVariableDeclarator(declarator);
+					if (!this.hooks.preDeclarator.call(declarator, statement)) {
+						this.enterPattern(declarator.id, (name, ident) => {
+							let hook = hookMap.get(name);
+							if (hook === undefined || !hook.call(ident)) {
+								hook = this.hooks.varDeclaration.get(name);
+								if (hook === undefined || !hook.call(ident)) {
+									this.defineVariable(name);
+								}
+							}
+						});
+					}
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Pre walk object pattern.
+	 * @param {ObjectPattern} objectPattern object pattern
+	 * @returns {DestructuringAssignmentProperties | undefined} set of names or undefined if not all keys are identifiers
+	 */
+	_preWalkObjectPattern(objectPattern) {
+		/** @type {DestructuringAssignmentProperties} */
+		const props = new Set();
+		const properties = objectPattern.properties;
+		for (let i = 0; i < properties.length; i++) {
+			const property = properties[i];
+			if (property.type !== "Property") return;
+			if (property.shorthand) {
+				if (property.value.type === "Identifier") {
+					this.scope.inShorthand = property.value.name;
+				} else if (
+					property.value.type === "AssignmentPattern" &&
+					property.value.left.type === "Identifier"
+				) {
+					this.scope.inShorthand = property.value.left.name;
+				}
+			}
+			const key = property.key;
+			if (key.type === "Identifier" && !property.computed) {
+				const pattern =
+					property.value.type === "ObjectPattern"
+						? this._preWalkObjectPattern(property.value)
+						: property.value.type === "ArrayPattern"
+							? this._preWalkArrayPattern(property.value)
+							: undefined;
+				props.add({
+					id: key.name,
+					range: /** @type {Range} */ (key.range),
+					loc: /** @type {SourceLocation} */ (key.loc),
+					pattern,
+					shorthand: this.scope.inShorthand
+				});
+			} else {
+				const id = this.evaluateExpression(key);
+				const str = id.asString();
+				if (str) {
+					const pattern =
+						property.value.type === "ObjectPattern"
+							? this._preWalkObjectPattern(property.value)
+							: property.value.type === "ArrayPattern"
+								? this._preWalkArrayPattern(property.value)
+								: undefined;
+					props.add({
+						id: str,
+						range: /** @type {Range} */ (key.range),
+						loc: /** @type {SourceLocation} */ (key.loc),
+						pattern,
+						shorthand: this.scope.inShorthand
+					});
+				} else {
+					// could not evaluate key
+					return;
+				}
+			}
+			this.scope.inShorthand = false;
+		}
+
+		return props;
+	}
+
+	/**
+	 * Pre walk array pattern.
+	 * @param {ArrayPattern} arrayPattern array pattern
+	 * @returns {Set<DestructuringAssignmentProperty> | undefined} set of names or undefined if not all keys are identifiers
+	 */
+	_preWalkArrayPattern(arrayPattern) {
+		/** @type {Set<DestructuringAssignmentProperty>} */
+		const props = new Set();
+		const elements = arrayPattern.elements;
+		for (let i = 0; i < elements.length; i++) {
+			const element = elements[i];
+			if (!element) continue;
+			if (element.type === "RestElement") return;
+			const pattern =
+				element.type === "ObjectPattern"
+					? this._preWalkObjectPattern(element)
+					: element.type === "ArrayPattern"
+						? this._preWalkArrayPattern(element)
+						: undefined;
+			props.add({
+				id: `${i}`,
+				range: /** @type {Range} */ (element.range),
+				loc: /** @type {SourceLocation} */ (element.loc),
+				pattern,
+				shorthand: false
+			});
+		}
+
+		return props;
+	}
+
+	/**
+	 * Pre walk variable declarator.
+	 * @param {VariableDeclarator} declarator variable declarator
+	 */
+	preWalkVariableDeclarator(declarator) {
+		if (declarator.init) {
+			this.enterDestructuringAssignment(declarator.id, declarator.init);
+		}
+	}
+
+	/**
+	 * Walk variable declaration.
+	 * @param {VariableDeclaration} statement variable declaration
+	 */
+	walkVariableDeclaration(statement) {
+		for (const declarator of statement.declarations) {
+			switch (declarator.type) {
+				case "VariableDeclarator": {
+					const renameIdentifier =
+						declarator.init && this.getRenameIdentifier(declarator.init);
+					if (renameIdentifier && declarator.id.type === "Identifier") {
+						const hook = this.hooks.canRename.get(renameIdentifier);
+						if (
+							hook !== undefined &&
+							hook.call(/** @type {Expression} */ (declarator.init))
+						) {
+							// renaming with "var a = b;"
+							const hook = this.hooks.rename.get(renameIdentifier);
+							if (
+								hook === undefined ||
+								!hook.call(/** @type {Expression} */ (declarator.init))
+							) {
+								this.setVariable(declarator.id.name, renameIdentifier);
+							}
+							break;
+						}
+					}
+					if (!this.hooks.declarator.call(declarator, statement)) {
+						this.walkPattern(declarator.id);
+						if (declarator.init) this.walkExpression(declarator.init);
+					}
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Block pre walk class declaration.
+	 * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
+	 */
+	blockPreWalkClassDeclaration(statement) {
+		if (statement.id) {
+			this.defineVariable(statement.id.name);
+		}
+	}
+
+	/**
+	 * Walk class declaration.
+	 * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
+	 */
+	walkClassDeclaration(statement) {
+		this.walkClass(statement);
+	}
+
+	/**
+	 * Pre walk switch cases.
+	 * @param {SwitchCase[]} switchCases switch statement
+	 */
+	preWalkSwitchCases(switchCases) {
+		for (let index = 0, len = switchCases.length; index < len; index++) {
+			const switchCase = switchCases[index];
+			this.preWalkStatements(switchCase.consequent);
+		}
+	}
+
+	/**
+	 * Processes the provided switch case.
+	 * @param {SwitchCase[]} switchCases switch statement
+	 */
+	walkSwitchCases(switchCases) {
+		this.inBlockScope(() => {
+			const len = switchCases.length;
+
+			// we need to pre walk all statements first since we can have invalid code
+			// import A from "module";
+			// switch(1) {
+			//    case 1:
+			//      console.log(A); // should fail at runtime
+			//    case 2:
+			//      const A = 1;
+			// }
+			for (let index = 0; index < len; index++) {
+				const switchCase = switchCases[index];
+
+				if (switchCase.consequent.length > 0) {
+					const prev = this.prevStatement;
+					this.blockPreWalkStatements(switchCase.consequent);
+					this.prevStatement = prev;
+				}
+			}
+
+			for (let index = 0; index < len; index++) {
+				const switchCase = switchCases[index];
+
+				if (switchCase.test) {
+					this.walkExpression(switchCase.test);
+				}
+
+				if (switchCase.consequent.length > 0) {
+					this.walkStatements(switchCase.consequent);
+					this.scope.terminated = undefined;
+				}
+			}
+		});
+	}
+
+	/**
+	 * Pre walk catch clause.
+	 * @param {CatchClause} catchClause catch clause
+	 */
+	preWalkCatchClause(catchClause) {
+		this.preWalkStatement(catchClause.body);
+	}
+
+	/**
+	 * Processes the provided catch clause.
+	 * @param {CatchClause} catchClause catch clause
+	 */
+	walkCatchClause(catchClause) {
+		this.inBlockScope(() => {
+			// Error binding is optional in catch clause since ECMAScript 2019
+			if (catchClause.param !== null) {
+				this.enterPattern(catchClause.param, (ident) => {
+					this.defineVariable(ident);
+				});
+				this.walkPattern(catchClause.param);
+			}
+			const prev = this.prevStatement;
+			this.blockPreWalkStatement(catchClause.body);
+			this.prevStatement = prev;
+			this.walkStatement(catchClause.body);
+		}, true);
+	}
+
+	/**
+	 * Processes the provided pattern.
+	 * @param {Pattern} pattern pattern
+	 */
+	walkPattern(pattern) {
+		switch (pattern.type) {
+			case "ArrayPattern":
+				this.walkArrayPattern(pattern);
+				break;
+			case "AssignmentPattern":
+				this.walkAssignmentPattern(pattern);
+				break;
+			case "MemberExpression":
+				this.walkMemberExpression(pattern);
+				break;
+			case "ObjectPattern":
+				this.walkObjectPattern(pattern);
+				break;
+			case "RestElement":
+				this.walkRestElement(pattern);
+				break;
+		}
+	}
+
+	/**
+	 * Walk assignment pattern.
+	 * @param {AssignmentPattern} pattern assignment pattern
+	 */
+	walkAssignmentPattern(pattern) {
+		this.walkExpression(pattern.right);
+		this.walkPattern(pattern.left);
+	}
+
+	/**
+	 * Walk object pattern.
+	 * @param {ObjectPattern} pattern pattern
+	 */
+	walkObjectPattern(pattern) {
+		for (let i = 0, len = pattern.properties.length; i < len; i++) {
+			const prop = pattern.properties[i];
+			if (prop) {
+				if (prop.type === "RestElement") {
+					continue;
+				}
+				if (prop.computed) this.walkExpression(prop.key);
+				if (prop.value) this.walkPattern(prop.value);
+			}
+		}
+	}
+
+	/**
+	 * Walk array pattern.
+	 * @param {ArrayPattern} pattern array pattern
+	 */
+	walkArrayPattern(pattern) {
+		for (let i = 0, len = pattern.elements.length; i < len; i++) {
+			const element = pattern.elements[i];
+			if (element) this.walkPattern(element);
+		}
+	}
+
+	/**
+	 * Processes the provided pattern.
+	 * @param {RestElement} pattern rest element
+	 */
+	walkRestElement(pattern) {
+		this.walkPattern(pattern.argument);
+	}
+
+	/**
+	 * Processes the provided expression.
+	 * @param {(Expression | SpreadElement | null)[]} expressions expressions
+	 */
+	walkExpressions(expressions) {
+		for (const expression of expressions) {
+			if (expression) {
+				this.walkExpression(expression);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided expression.
+	 * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression
+	 */
+	walkExpression(expression) {
+		switch (expression.type) {
+			case "ArrayExpression":
+				this.walkArrayExpression(expression);
+				break;
+			case "ArrowFunctionExpression":
+				this.walkArrowFunctionExpression(expression);
+				break;
+			case "AssignmentExpression":
+				this.walkAssignmentExpression(expression);
+				break;
+			case "AwaitExpression":
+				this.walkAwaitExpression(expression);
+				break;
+			case "BinaryExpression":
+				this.walkBinaryExpression(expression);
+				break;
+			case "CallExpression":
+				this.walkCallExpression(expression);
+				break;
+			case "ChainExpression":
+				this.walkChainExpression(expression);
+				break;
+			case "ClassExpression":
+				this.walkClassExpression(expression);
+				break;
+			case "ConditionalExpression":
+				this.walkConditionalExpression(expression);
+				break;
+			case "FunctionExpression":
+				this.walkFunctionExpression(expression);
+				break;
+			case "Identifier":
+				this.walkIdentifier(expression);
+				break;
+			case "ImportExpression":
+				this.walkImportExpression(expression);
+				break;
+			case "LogicalExpression":
+				this.walkLogicalExpression(expression);
+				break;
+			case "MetaProperty":
+				this.walkMetaProperty(expression);
+				break;
+			case "MemberExpression":
+				this.walkMemberExpression(expression);
+				break;
+			case "NewExpression":
+				this.walkNewExpression(expression);
+				break;
+			case "ObjectExpression":
+				this.walkObjectExpression(expression);
+				break;
+			case "SequenceExpression":
+				this.walkSequenceExpression(expression);
+				break;
+			case "SpreadElement":
+				this.walkSpreadElement(expression);
+				break;
+			case "TaggedTemplateExpression":
+				this.walkTaggedTemplateExpression(expression);
+				break;
+			case "TemplateLiteral":
+				this.walkTemplateLiteral(expression);
+				break;
+			case "ThisExpression":
+				this.walkThisExpression(expression);
+				break;
+			case "UnaryExpression":
+				this.walkUnaryExpression(expression);
+				break;
+			case "UpdateExpression":
+				this.walkUpdateExpression(expression);
+				break;
+			case "YieldExpression":
+				this.walkYieldExpression(expression);
+				break;
+		}
+	}
+
+	/**
+	 * Walk await expression.
+	 * @param {AwaitExpression} expression await expression
+	 */
+	walkAwaitExpression(expression) {
+		if (this.scope.topLevelScope === true) {
+			this.hooks.topLevelAwait.call(expression);
+		}
+		this.walkExpression(expression.argument);
+	}
+
+	/**
+	 * Walk array expression.
+	 * @param {ArrayExpression} expression array expression
+	 */
+	walkArrayExpression(expression) {
+		if (expression.elements) {
+			this.walkExpressions(expression.elements);
+		}
+	}
+
+	/**
+	 * Walk spread element.
+	 * @param {SpreadElement} expression spread element
+	 */
+	walkSpreadElement(expression) {
+		if (expression.argument) {
+			this.walkExpression(expression.argument);
+		}
+	}
+
+	/**
+	 * Walk object expression.
+	 * @param {ObjectExpression} expression object expression
+	 */
+	walkObjectExpression(expression) {
+		for (
+			let propIndex = 0, len = expression.properties.length;
+			propIndex < len;
+			propIndex++
+		) {
+			const prop = expression.properties[propIndex];
+			this.walkProperty(prop);
+		}
+	}
+
+	/**
+	 * Processes the provided prop.
+	 * @param {Property | SpreadElement} prop property or spread element
+	 */
+	walkProperty(prop) {
+		if (prop.type === "SpreadElement") {
+			this.walkExpression(prop.argument);
+			return;
+		}
+		if (prop.computed) {
+			this.walkExpression(prop.key);
+		}
+		if (prop.shorthand && prop.value && prop.value.type === "Identifier") {
+			this.scope.inShorthand = prop.value.name;
+			this.walkIdentifier(prop.value);
+			this.scope.inShorthand = false;
+		} else {
+			this.walkExpression(
+				/** @type {Exclude<Property["value"], AssignmentPattern | ObjectPattern | ArrayPattern | RestElement>} */
+				(prop.value)
+			);
+		}
+	}
+
+	/**
+	 * Walk function expression.
+	 * @param {FunctionExpression} expression arrow function expression
+	 */
+	walkFunctionExpression(expression) {
+		const wasTopLevel = this.scope.topLevelScope;
+		this.scope.topLevelScope = false;
+		const scopeParams = [...expression.params];
+
+		// Add function name in scope for recursive calls
+		if (expression.id) {
+			scopeParams.push(expression.id);
+		}
+
+		this.inFunctionScope(true, scopeParams, () => {
+			for (const param of expression.params) {
+				this.walkPattern(param);
+			}
+
+			this.detectMode(expression.body.body);
+
+			const prev = this.prevStatement;
+
+			this.preWalkStatement(expression.body);
+			this.prevStatement = prev;
+			this.walkStatement(expression.body);
+		});
+		this.scope.topLevelScope = wasTopLevel;
+	}
+
+	/**
+	 * Walk arrow function expression.
+	 * @param {ArrowFunctionExpression} expression arrow function expression
+	 */
+	walkArrowFunctionExpression(expression) {
+		const wasTopLevel = this.scope.topLevelScope;
+		this.scope.topLevelScope = wasTopLevel ? "arrow" : false;
+		this.inFunctionScope(false, expression.params, () => {
+			for (const param of expression.params) {
+				this.walkPattern(param);
+			}
+			if (expression.body.type === "BlockStatement") {
+				this.detectMode(expression.body.body);
+				const prev = this.prevStatement;
+				this.preWalkStatement(expression.body);
+				this.prevStatement = prev;
+				this.walkStatement(expression.body);
+			} else {
+				this.walkExpression(expression.body);
+			}
+		});
+		this.scope.topLevelScope = wasTopLevel;
+	}
+
+	/**
+	 * Walk sequence expression.
+	 * @param {SequenceExpression} expression the sequence
+	 */
+	walkSequenceExpression(expression) {
+		if (!expression.expressions) return;
+		// We treat sequence expressions like statements when they are one statement level
+		// This has some benefits for optimizations that only work on statement level
+		const currentStatement =
+			/** @type {StatementPath} */
+			(this.statementPath)[
+				/** @type {StatementPath} */
+				(this.statementPath).length - 1
+			];
+		if (
+			currentStatement === expression ||
+			(currentStatement.type === "ExpressionStatement" &&
+				currentStatement.expression === expression)
+		) {
+			const old =
+				/** @type {StatementPathItem} */
+				(/** @type {StatementPath} */ (this.statementPath).pop());
+			const prev = this.prevStatement;
+			for (const expr of expression.expressions) {
+				/** @type {StatementPath} */
+				(this.statementPath).push(expr);
+				this.walkExpression(expr);
+				this.prevStatement =
+					/** @type {StatementPath} */
+					(this.statementPath).pop();
+			}
+			this.prevStatement = prev;
+			/** @type {StatementPath} */
+			(this.statementPath).push(old);
+		} else {
+			this.walkExpressions(expression.expressions);
+		}
+	}
+
+	/**
+	 * Walk update expression.
+	 * @param {UpdateExpression} expression the update expression
+	 */
+	walkUpdateExpression(expression) {
+		this.walkExpression(expression.argument);
+	}
+
+	/**
+	 * Walk unary expression.
+	 * @param {UnaryExpression} expression the unary expression
+	 */
+	walkUnaryExpression(expression) {
+		if (expression.operator === "typeof") {
+			const result = this.callHooksForExpression(
+				this.hooks.typeof,
+				expression.argument,
+				expression
+			);
+			if (result === true) return;
+			if (expression.argument.type === "ChainExpression") {
+				const result = this.callHooksForExpression(
+					this.hooks.typeof,
+					expression.argument.expression,
+					expression
+				);
+				if (result === true) return;
+			}
+		}
+		this.walkExpression(expression.argument);
+	}
+
+	/**
+	 * Walk left right expression.
+	 * @param {LogicalExpression | BinaryExpression} expression the expression
+	 */
+	walkLeftRightExpression(expression) {
+		this.walkExpression(expression.left);
+		this.walkExpression(expression.right);
+	}
+
+	/**
+	 * Walk binary expression.
+	 * @param {BinaryExpression} expression the binary expression
+	 */
+	walkBinaryExpression(expression) {
+		if (this.hooks.binaryExpression.call(expression) === undefined) {
+			this.walkLeftRightExpression(expression);
+		}
+	}
+
+	/**
+	 * Walk logical expression.
+	 * @param {LogicalExpression} expression the logical expression
+	 */
+	walkLogicalExpression(expression) {
+		const result = this.hooks.expressionLogicalOperator.call(expression);
+		if (result === undefined) {
+			this.walkLeftRightExpression(expression);
+		} else if (result) {
+			this.walkExpression(expression.right);
+		}
+	}
+
+	/**
+	 * Walk assignment expression.
+	 * @param {AssignmentExpression} expression assignment expression
+	 */
+	walkAssignmentExpression(expression) {
+		if (expression.left.type === "Identifier") {
+			const renameIdentifier = this.getRenameIdentifier(expression.right);
+			if (
+				renameIdentifier &&
+				this.callHooksForInfo(
+					this.hooks.canRename,
+					renameIdentifier,
+					expression.right
+				)
+			) {
+				// renaming "a = b;"
+				if (
+					!this.callHooksForInfo(
+						this.hooks.rename,
+						renameIdentifier,
+						expression.right
+					)
+				) {
+					this.setVariable(
+						expression.left.name,
+						typeof renameIdentifier === "string"
+							? this.getVariableInfo(renameIdentifier)
+							: renameIdentifier
+					);
+				}
+				return;
+			}
+			this.walkExpression(expression.right);
+			this.enterPattern(expression.left, (name, _decl) => {
+				if (!this.callHooksForName(this.hooks.assign, name, expression)) {
+					this.walkExpression(
+						/** @type {MemberExpression} */
+						(expression.left)
+					);
+				}
+			});
+		} else if (expression.left.type.endsWith("Pattern")) {
+			this.walkExpression(expression.right);
+			this.enterPattern(expression.left, (name, _decl) => {
+				if (!this.callHooksForName(this.hooks.assign, name, expression)) {
+					this.defineVariable(name);
+				}
+			});
+			this.walkPattern(expression.left);
+		} else if (expression.left.type === "MemberExpression") {
+			const exprName = this.getMemberExpressionInfo(
+				expression.left,
+				ALLOWED_MEMBER_TYPES_EXPRESSION
+			);
+			if (
+				exprName &&
+				this.callHooksForInfo(
+					this.hooks.assignMemberChain,
+					exprName.rootInfo,
+					expression,
+					exprName.getMembers()
+				)
+			) {
+				return;
+			}
+			this.walkExpression(expression.right);
+			this.walkExpression(expression.left);
+		} else {
+			this.walkExpression(expression.right);
+			this.walkExpression(
+				/** @type {Exclude<AssignmentExpression["left"], Identifier | RestElement | MemberExpression | ObjectPattern | ArrayPattern | AssignmentPattern>} */
+				(expression.left)
+			);
+		}
+	}
+
+	/**
+	 * Walk conditional expression.
+	 * @param {ConditionalExpression} expression conditional expression
+	 */
+	walkConditionalExpression(expression) {
+		const result = this.hooks.expressionConditionalOperator.call(expression);
+		if (result === undefined) {
+			const inGuard = this.hooks.collectGuards.call(expression.test);
+			if (inGuard) {
+				inGuard(() => {
+					this.walkExpression(expression.test);
+					this.walkExpression(expression.consequent);
+				});
+			} else {
+				this.walkExpression(expression.test);
+				this.walkExpression(expression.consequent);
+			}
+
+			if (expression.alternate) {
+				this.walkExpression(expression.alternate);
+			}
+		} else if (result) {
+			this.walkExpression(expression.consequent);
+		} else if (expression.alternate) {
+			this.walkExpression(expression.alternate);
+		}
+	}
+
+	/**
+	 * Walk new expression.
+	 * @param {NewExpression} expression new expression
+	 */
+	walkNewExpression(expression) {
+		// TODO: not a webpack bug — `acorn-import-phases` accepts
+		// `new import.defer(...)` / `new import.source(...)` even though
+		// `ImportCall` is a `CallExpression` per spec and is therefore not a
+		// valid `new` operand. Acorn rejects bare `new import(...)` correctly.
+		// Drop this block once the upstream plugin (or acorn itself) reports
+		// the SyntaxError. Parenthesized forms (`new (import.defer(...))`)
+		// produce the same AST shape, so we look at the source between `new`
+		// and the callee (with comments stripped) to keep them valid.
+		if (
+			expression.callee.type === "ImportExpression" &&
+			typeof this.state.source === "string"
+		) {
+			const newStart = /** @type {Range} */ (expression.range)[0];
+			const calleeStart = /** @type {Range} */ (expression.callee.range)[0];
+			const between = this.state.source
+				.slice(newStart, calleeStart)
+				.replace(/\/\*[\s\S]*?\*\//g, "")
+				.replace(/\/\/[^\n]*/g, "");
+			if (!between.includes("(")) {
+				const err =
+					/** @type {SyntaxError & { loc?: { line: number, column: number } }} */
+					(new SyntaxError("import call cannot be the target of `new`"));
+				if (expression.loc) {
+					err.loc = {
+						line: expression.loc.start.line,
+						column: expression.loc.start.column
+					};
+				}
+				throw err;
+			}
+		}
+		const result = this.callHooksForExpression(
+			this.hooks.new,
+			expression.callee,
+			expression
+		);
+		if (result === true) return;
+		this.walkExpression(expression.callee);
+		if (expression.arguments) {
+			this.walkExpressions(expression.arguments);
+		}
+	}
+
+	/**
+	 * Walk yield expression.
+	 * @param {YieldExpression} expression yield expression
+	 */
+	walkYieldExpression(expression) {
+		if (expression.argument) {
+			this.walkExpression(expression.argument);
+		}
+	}
+
+	/**
+	 * Walk template literal.
+	 * @param {TemplateLiteral} expression template literal
+	 */
+	walkTemplateLiteral(expression) {
+		if (expression.expressions) {
+			this.walkExpressions(expression.expressions);
+		}
+	}
+
+	/**
+	 * Walk tagged template expression.
+	 * @param {TaggedTemplateExpression} expression tagged template expression
+	 */
+	walkTaggedTemplateExpression(expression) {
+		if (expression.tag) {
+			this.scope.inTaggedTemplateTag = true;
+			this.walkExpression(expression.tag);
+			this.scope.inTaggedTemplateTag = false;
+		}
+		if (expression.quasi && expression.quasi.expressions) {
+			this.walkExpressions(expression.quasi.expressions);
+		}
+	}
+
+	/**
+	 * Walk class expression.
+	 * @param {ClassExpression} expression the class expression
+	 */
+	walkClassExpression(expression) {
+		this.walkClass(expression);
+	}
+
+	/**
+	 * Walk chain expression.
+	 * @param {ChainExpression} expression expression
+	 */
+	walkChainExpression(expression) {
+		const result = this.hooks.optionalChaining.call(expression);
+
+		if (result === undefined) {
+			if (expression.expression.type === "CallExpression") {
+				this.walkCallExpression(expression.expression);
+			} else {
+				this.walkMemberExpression(expression.expression);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided function expression.
+	 * @private
+	 * @param {FunctionExpression | ArrowFunctionExpression} functionExpression function expression
+	 * @param {(Expression | SpreadElement)[]} options options
+	 * @param {Expression | SpreadElement | null} currentThis current this
+	 */
+	_walkIIFE(functionExpression, options, currentThis) {
+		/**
+		 * Returns var info.
+		 * @param {Expression | SpreadElement} argOrThis arg or this
+		 * @returns {string | VariableInfo | undefined} var info
+		 */
+		const getVarInfo = (argOrThis) => {
+			const renameIdentifier = this.getRenameIdentifier(argOrThis);
+			if (
+				renameIdentifier &&
+				this.callHooksForInfo(
+					this.hooks.canRename,
+					renameIdentifier,
+					/** @type {Expression} */
+					(argOrThis)
+				) &&
+				!this.callHooksForInfo(
+					this.hooks.rename,
+					renameIdentifier,
+					/** @type {Expression} */
+					(argOrThis)
+				)
+			) {
+				return typeof renameIdentifier === "string"
+					? /** @type {string} */ (this.getVariableInfo(renameIdentifier))
+					: renameIdentifier;
+			}
+			this.walkExpression(argOrThis);
+		};
+		const { params, type } = functionExpression;
+		const arrow = type === "ArrowFunctionExpression";
+		const renameThis = currentThis ? getVarInfo(currentThis) : null;
+		const varInfoForArgs = options.map(getVarInfo);
+		const wasTopLevel = this.scope.topLevelScope;
+		this.scope.topLevelScope = wasTopLevel && arrow ? "arrow" : false;
+		const scopeParams =
+			/** @type {(Identifier | string)[]} */
+			(params.filter((identifier, idx) => !varInfoForArgs[idx]));
+
+		// Add function name in scope for recursive calls
+		if (
+			functionExpression.type === "FunctionExpression" &&
+			functionExpression.id
+		) {
+			scopeParams.push(functionExpression.id.name);
+		}
+
+		this.inFunctionScope(true, scopeParams, () => {
+			if (renameThis && !arrow) {
+				this.setVariable("this", renameThis);
+			}
+			for (let i = 0; i < varInfoForArgs.length; i++) {
+				const varInfo = varInfoForArgs[i];
+				if (!varInfo) continue;
+				if (!params[i] || params[i].type !== "Identifier") continue;
+				this.setVariable(/** @type {Identifier} */ (params[i]).name, varInfo);
+			}
+			if (functionExpression.body.type === "BlockStatement") {
+				this.detectMode(functionExpression.body.body);
+				const prev = this.prevStatement;
+				this.preWalkStatement(functionExpression.body);
+				this.prevStatement = prev;
+				this.walkStatement(functionExpression.body);
+			} else {
+				this.walkExpression(functionExpression.body);
+			}
+		});
+		this.scope.topLevelScope = wasTopLevel;
+	}
+
+	/**
+	 * Walk import expression.
+	 * @param {ImportExpression} expression import expression
+	 */
+	walkImportExpression(expression) {
+		const result = this.hooks.importCall.call(expression);
+		if (result === true) return;
+
+		this.walkExpression(expression.source);
+	}
+
+	/**
+	 * Walk call expression.
+	 * @param {CallExpression} expression expression
+	 */
+	walkCallExpression(expression) {
+		/**
+		 * Checks whether this javascript parser is simple function.
+		 * @param {FunctionExpression | ArrowFunctionExpression} fn function
+		 * @returns {boolean} true when simple function
+		 */
+		const isSimpleFunction = (fn) =>
+			fn.params.every((p) => p.type === "Identifier");
+		if (
+			expression.callee.type === "MemberExpression" &&
+			expression.callee.object.type.endsWith("FunctionExpression") &&
+			!expression.callee.computed &&
+			/** @type {boolean} */
+			(
+				/** @type {Identifier} */
+				(expression.callee.property).name === "call" ||
+					/** @type {Identifier} */
+					(expression.callee.property).name === "bind"
+			) &&
+			expression.arguments.length > 0 &&
+			isSimpleFunction(
+				/** @type {FunctionExpression | ArrowFunctionExpression} */
+				(expression.callee.object)
+			)
+		) {
+			// (function(…) { }.call/bind(?, …))
+			this._walkIIFE(
+				/** @type {FunctionExpression | ArrowFunctionExpression} */
+				(expression.callee.object),
+				expression.arguments.slice(1),
+				expression.arguments[0]
+			);
+		} else if (
+			expression.callee.type.endsWith("FunctionExpression") &&
+			isSimpleFunction(
+				/** @type {FunctionExpression | ArrowFunctionExpression} */
+				(expression.callee)
+			)
+		) {
+			// (function(…) { }(…))
+			this._walkIIFE(
+				/** @type {FunctionExpression | ArrowFunctionExpression} */
+				(expression.callee),
+				expression.arguments,
+				null
+			);
+		} else {
+			if (expression.callee.type === "MemberExpression") {
+				const exprInfo = this.getMemberExpressionInfo(
+					expression.callee,
+					ALLOWED_MEMBER_TYPES_CALL_EXPRESSION
+				);
+				if (exprInfo && exprInfo.type === "call") {
+					const result = this.callHooksForInfo(
+						this.hooks.callMemberChainOfCallMemberChain,
+						exprInfo.rootInfo,
+						expression,
+						exprInfo.getCalleeMembers(),
+						exprInfo.call,
+						exprInfo.getMembers(),
+						exprInfo.getMemberRanges()
+					);
+					if (result === true) return;
+				}
+				// import("./m").then(m => { ... })
+				if (
+					expression.callee.object.type === "ImportExpression" &&
+					expression.callee.property.type === "Identifier" &&
+					expression.callee.property.name === "then"
+				) {
+					const result = this.hooks.importCall.call(
+						expression.callee.object,
+						expression
+					);
+					if (result === true) return;
+				}
+			}
+			const callee = this.evaluateExpression(expression.callee);
+			if (callee.isIdentifier()) {
+				const result1 = this.callHooksForInfo(
+					this.hooks.callMemberChain,
+					/** @type {NonNullable<BasicEvaluatedExpression["rootInfo"]>} */
+					(callee.rootInfo),
+					expression,
+					/** @type {NonNullable<BasicEvaluatedExpression["getMembers"]>} */
+					(callee.getMembers)(),
+					callee.getMembersOptionals
+						? callee.getMembersOptionals()
+						: /** @type {NonNullable<BasicEvaluatedExpression["getMembers"]>} */
+							(callee.getMembers)().map(() => false),
+					callee.getMemberRanges ? callee.getMemberRanges() : []
+				);
+				if (result1 === true) return;
+				const result2 = this.callHooksForInfo(
+					this.hooks.call,
+					/** @type {NonNullable<BasicEvaluatedExpression["identifier"]>} */
+					(callee.identifier),
+					expression
+				);
+				if (result2 === true) return;
+			}
+
+			if (expression.callee) {
+				if (expression.callee.type === "MemberExpression") {
+					// because of call context we need to walk the call context as expression
+					this.walkExpression(expression.callee.object);
+					if (expression.callee.computed === true) {
+						this.walkExpression(expression.callee.property);
+					}
+				} else {
+					this.walkExpression(expression.callee);
+				}
+			}
+			if (expression.arguments) this.walkExpressions(expression.arguments);
+		}
+	}
+
+	/**
+	 * Walk member expression.
+	 * @param {MemberExpression} expression member expression
+	 */
+	walkMemberExpression(expression) {
+		const exprInfo = this.getMemberExpressionInfo(
+			expression,
+			ALLOWED_MEMBER_TYPES_ALL
+		);
+		if (exprInfo) {
+			switch (exprInfo.type) {
+				case "expression": {
+					const result1 = this.callHooksForInfo(
+						this.hooks.expression,
+						exprInfo.name,
+						expression
+					);
+					if (result1 === true) return;
+					const members = exprInfo.getMembers();
+					const membersOptionals = exprInfo.getMembersOptionals();
+					const memberRanges = exprInfo.getMemberRanges();
+					const result2 = this.callHooksForInfo(
+						this.hooks.expressionMemberChain,
+						exprInfo.rootInfo,
+						expression,
+						members,
+						membersOptionals,
+						memberRanges
+					);
+					if (result2 === true) return;
+					this.walkMemberExpressionWithExpressionName(
+						expression,
+						exprInfo.name,
+						exprInfo.rootInfo,
+						[...members],
+						() =>
+							this.callHooksForInfo(
+								this.hooks.unhandledExpressionMemberChain,
+								exprInfo.rootInfo,
+								expression,
+								members
+							)
+					);
+					return;
+				}
+				case "call": {
+					const result = this.callHooksForInfo(
+						this.hooks.memberChainOfCallMemberChain,
+						exprInfo.rootInfo,
+						expression,
+						exprInfo.getCalleeMembers(),
+						exprInfo.call,
+						exprInfo.getMembers(),
+						exprInfo.getMemberRanges()
+					);
+					if (result === true) return;
+					// Fast skip over the member chain as we already called memberChainOfCallMemberChain
+					// and call computed property are literals anyway
+					this.walkExpression(exprInfo.call);
+					return;
+				}
+			}
+		}
+		this.walkExpression(expression.object);
+		if (expression.computed === true) this.walkExpression(expression.property);
+	}
+
+	/**
+	 * Walk member expression with expression name.
+	 * @template R
+	 * @param {MemberExpression} expression member expression
+	 * @param {string} name name
+	 * @param {string | VariableInfo} rootInfo root info
+	 * @param {Members} members members
+	 * @param {() => R | undefined} onUnhandled on unhandled callback
+	 */
+	walkMemberExpressionWithExpressionName(
+		expression,
+		name,
+		rootInfo,
+		members,
+		onUnhandled
+	) {
+		if (expression.object.type === "MemberExpression") {
+			// optimize the case where expression.object is a MemberExpression too.
+			// we can keep info here when calling walkMemberExpression directly
+			// Read the property from `members` (already extracted by
+			// extractMemberExpressionChain) since the AST node may be a
+			// TemplateLiteral, which has neither .name nor .value.
+			const property = members[members.length - 1];
+			name = name.slice(0, -property.length - 1);
+			members.pop();
+			const result = this.callHooksForInfo(
+				this.hooks.expression,
+				name,
+				expression.object
+			);
+			if (result === true) return;
+			this.walkMemberExpressionWithExpressionName(
+				expression.object,
+				name,
+				rootInfo,
+				members,
+				onUnhandled
+			);
+		} else if (!onUnhandled || !onUnhandled()) {
+			this.walkExpression(expression.object);
+		}
+		if (expression.computed === true) this.walkExpression(expression.property);
+	}
+
+	/**
+	 * Walk this expression.
+	 * @param {ThisExpression} expression this expression
+	 */
+	walkThisExpression(expression) {
+		this.callHooksForName(this.hooks.expression, "this", expression);
+	}
+
+	/**
+	 * Processes the provided expression.
+	 * @param {Identifier} expression identifier
+	 */
+	walkIdentifier(expression) {
+		this.callHooksForName(this.hooks.expression, expression.name, expression);
+	}
+
+	/**
+	 * Walk meta property.
+	 * @param {MetaProperty} metaProperty meta property
+	 */
+	walkMetaProperty(metaProperty) {
+		this.hooks.expression.for(getRootName(metaProperty)).call(metaProperty);
+	}
+
+	/**
+	 * Call hooks for expression.
+	 * @template T
+	 * @template R
+	 * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
+	 * @param {Expression | Super} expr expression
+	 * @param {AsArray<T>} args args for the hook
+	 * @returns {R | undefined} result of hook
+	 */
+	callHooksForExpression(hookMap, expr, ...args) {
+		return this.callHooksForExpressionWithFallback(
+			hookMap,
+			expr,
+			undefined,
+			undefined,
+			...args
+		);
+	}
+
+	/**
+	 * Call hooks for expression with fallback.
+	 * @template T
+	 * @template R
+	 * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
+	 * @param {Expression | Super} expr expression info
+	 * @param {((name: string, rootInfo: string | ScopeInfo | VariableInfo, getMembers: () => Members) => R) | undefined} fallback callback when variable in not handled by hooks
+	 * @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
+	 * @param {AsArray<T>} args args for the hook
+	 * @returns {R | undefined} result of hook
+	 */
+	callHooksForExpressionWithFallback(
+		hookMap,
+		expr,
+		fallback,
+		defined,
+		...args
+	) {
+		const exprName = this.getMemberExpressionInfo(
+			expr,
+			ALLOWED_MEMBER_TYPES_EXPRESSION
+		);
+		if (exprName !== undefined) {
+			const members = exprName.getMembers();
+			return this.callHooksForInfoWithFallback(
+				hookMap,
+				members.length === 0 ? exprName.rootInfo : exprName.name,
+				fallback &&
+					((name) => fallback(name, exprName.rootInfo, exprName.getMembers)),
+				defined && (() => defined(exprName.name)),
+				...args
+			);
+		}
+	}
+
+	/**
+	 * Call hooks for name.
+	 * @template T
+	 * @template R
+	 * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
+	 * @param {string} name key in map
+	 * @param {AsArray<T>} args args for the hook
+	 * @returns {R | undefined} result of hook
+	 */
+	callHooksForName(hookMap, name, ...args) {
+		return this.callHooksForNameWithFallback(
+			hookMap,
+			name,
+			undefined,
+			undefined,
+			...args
+		);
+	}
+
+	/**
+	 * Call hooks for info.
+	 * @template T
+	 * @template R
+	 * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
+	 * @param {ExportedVariableInfo} info variable info
+	 * @param {AsArray<T>} args args for the hook
+	 * @returns {R | undefined} result of hook
+	 */
+	callHooksForInfo(hookMap, info, ...args) {
+		return this.callHooksForInfoWithFallback(
+			hookMap,
+			info,
+			undefined,
+			undefined,
+			...args
+		);
+	}
+
+	/**
+	 * Call hooks for info with fallback.
+	 * @template T
+	 * @template R
+	 * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
+	 * @param {ExportedVariableInfo} info variable info
+	 * @param {((name: string) => R | undefined) | undefined} fallback callback when variable in not handled by hooks
+	 * @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
+	 * @param {AsArray<T>} args args for the hook
+	 * @returns {R | undefined} result of hook
+	 */
+	callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
+		/** @type {string} */
+		let name;
+		if (typeof info === "string") {
+			name = info;
+		} else {
+			if (!(info instanceof VariableInfo)) {
+				if (defined !== undefined) {
+					return defined();
+				}
+				return;
+			}
+			let tagInfo = info.tagInfo;
+			while (tagInfo !== undefined) {
+				const hook = hookMap.get(tagInfo.tag);
+				if (hook !== undefined) {
+					this.currentTagData = tagInfo.data;
+					const result = hook.call(...args);
+					this.currentTagData = undefined;
+					if (result !== undefined) return result;
+				}
+				tagInfo = tagInfo.next;
+			}
+			if (!info.isFree() && !info.isTagged()) {
+				if (defined !== undefined) {
+					return defined();
+				}
+				return;
+			}
+			name = /** @type {string} */ (info.name);
+		}
+		const hook = hookMap.get(name);
+		if (hook !== undefined) {
+			const result = hook.call(...args);
+			if (result !== undefined) return result;
+		}
+		if (fallback !== undefined) {
+			return fallback(name);
+		}
+	}
+
+	/**
+	 * Call hooks for name with fallback.
+	 * @template T
+	 * @template R
+	 * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
+	 * @param {string} name key in map
+	 * @param {((value: string) => R | undefined) | undefined} fallback callback when variable in not handled by hooks
+	 * @param {(() => R) | undefined} defined callback when variable is defined
+	 * @param {AsArray<T>} args args for the hook
+	 * @returns {R | undefined} result of hook
+	 */
+	callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
+		return this.callHooksForInfoWithFallback(
+			hookMap,
+			this.getVariableInfo(name),
+			fallback,
+			defined,
+			...args
+		);
+	}
+
+	/**
+	 * Processes the provided param.
+	 * @deprecated
+	 * @param {(string | Pattern | Property)[]} params scope params
+	 * @param {() => void} fn inner function
+	 * @returns {void}
+	 */
+	inScope(params, fn) {
+		const oldScope = this.scope;
+		this.scope = {
+			topLevelScope: oldScope.topLevelScope,
+			inTry: false,
+			inShorthand: false,
+			inTaggedTemplateTag: false,
+			isStrict: oldScope.isStrict,
+			isAsmJs: oldScope.isAsmJs,
+			terminated: undefined,
+			definitions: oldScope.definitions.createChild()
+		};
+
+		this.undefineVariable("this");
+
+		this.enterPatterns(params, (ident) => {
+			this.defineVariable(ident);
+		});
+
+		fn();
+
+		this.scope = oldScope;
+	}
+
+	/**
+	 * Processes the provided has thi.
+	 * @param {boolean} hasThis true, when this is defined
+	 * @param {Identifier[]} params scope params
+	 * @param {() => void} fn inner function
+	 * @returns {void}
+	 */
+	inClassScope(hasThis, params, fn) {
+		const oldScope = this.scope;
+		this.scope = {
+			topLevelScope: oldScope.topLevelScope,
+			inTry: false,
+			inShorthand: false,
+			inTaggedTemplateTag: false,
+			isStrict: oldScope.isStrict,
+			isAsmJs: oldScope.isAsmJs,
+			terminated: undefined,
+			definitions: oldScope.definitions.createChild()
+		};
+
+		if (hasThis) {
+			this.undefineVariable("this");
+		}
+
+		this.enterPatterns(params, (ident) => {
+			this.defineVariable(ident);
+		});
+
+		fn();
+
+		this.scope = oldScope;
+	}
+
+	/**
+	 * Processes the provided has thi.
+	 * @param {boolean} hasThis true, when this is defined
+	 * @param {(Pattern | string)[]} params scope params
+	 * @param {() => void} fn inner function
+	 * @returns {void}
+	 */
+	inFunctionScope(hasThis, params, fn) {
+		const oldScope = this.scope;
+		this.scope = {
+			topLevelScope: oldScope.topLevelScope,
+			inTry: false,
+			inShorthand: false,
+			inTaggedTemplateTag: false,
+			isStrict: oldScope.isStrict,
+			isAsmJs: oldScope.isAsmJs,
+			terminated: undefined,
+			definitions: oldScope.definitions.createChild()
+		};
+
+		if (hasThis) {
+			this.undefineVariable("this");
+		}
+
+		this.enterPatterns(params, (ident) => {
+			this.defineVariable(ident);
+		});
+
+		fn();
+
+		this.scope = oldScope;
+	}
+
+	/**
+	 * Processes the provided fn.
+	 * @param {() => void} fn inner function
+	 * @param {boolean} inExecutedPath executed state
+	 * @returns {void}
+	 */
+	inBlockScope(fn, inExecutedPath = false) {
+		const oldScope = this.scope;
+		this.scope = {
+			topLevelScope: oldScope.topLevelScope,
+			inTry: oldScope.inTry,
+			inShorthand: false,
+			inTaggedTemplateTag: false,
+			isStrict: oldScope.isStrict,
+			isAsmJs: oldScope.isAsmJs,
+			terminated: oldScope.terminated,
+			definitions: oldScope.definitions.createChild()
+		};
+
+		fn();
+
+		const terminated = this.scope.terminated;
+
+		if (inExecutedPath && terminated) {
+			oldScope.terminated = terminated;
+		}
+
+		this.scope = oldScope;
+	}
+
+	/**
+	 * Processes the provided statement.
+	 * @param {(Directive | Statement | ModuleDeclaration)[]} statements statements
+	 */
+	detectMode(statements) {
+		const isLiteral =
+			statements.length >= 1 &&
+			statements[0].type === "ExpressionStatement" &&
+			statements[0].expression.type === "Literal";
+		if (
+			isLiteral &&
+			/** @type {Literal} */
+			(/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
+				"use strict"
+		) {
+			this.scope.isStrict = true;
+		}
+		if (
+			isLiteral &&
+			/** @type {Literal} */
+			(/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
+				"use asm"
+		) {
+			this.scope.isAsmJs = true;
+		}
+	}
+
+	/**
+	 * Processes the provided pattern.
+	 * @param {(string | Pattern | Property)[]} patterns patterns
+	 * @param {OnIdentString} onIdent on ident callback
+	 */
+	enterPatterns(patterns, onIdent) {
+		for (const pattern of patterns) {
+			if (typeof pattern !== "string") {
+				this.enterPattern(pattern, onIdent);
+			} else if (pattern) {
+				onIdent(pattern);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided pattern.
+	 * @param {Pattern | Property} pattern pattern
+	 * @param {OnIdent} onIdent on ident callback
+	 */
+	enterPattern(pattern, onIdent) {
+		if (!pattern) return;
+		switch (pattern.type) {
+			case "ArrayPattern":
+				this.enterArrayPattern(pattern, onIdent);
+				break;
+			case "AssignmentPattern":
+				this.enterAssignmentPattern(pattern, onIdent);
+				break;
+			case "Identifier":
+				this.enterIdentifier(pattern, onIdent);
+				break;
+			case "ObjectPattern":
+				this.enterObjectPattern(pattern, onIdent);
+				break;
+			case "RestElement":
+				this.enterRestElement(pattern, onIdent);
+				break;
+			case "Property":
+				if (pattern.shorthand && pattern.value.type === "Identifier") {
+					this.scope.inShorthand = pattern.value.name;
+					this.enterIdentifier(pattern.value, onIdent);
+					this.scope.inShorthand = false;
+				} else {
+					this.enterPattern(/** @type {Pattern} */ (pattern.value), onIdent);
+				}
+				break;
+		}
+	}
+
+	/**
+	 * Processes the provided pattern.
+	 * @param {Identifier} pattern identifier pattern
+	 * @param {OnIdent} onIdent callback
+	 */
+	enterIdentifier(pattern, onIdent) {
+		if (!this.callHooksForName(this.hooks.pattern, pattern.name, pattern)) {
+			onIdent(pattern.name, pattern);
+		}
+	}
+
+	/**
+	 * Enter object pattern.
+	 * @param {ObjectPattern} pattern object pattern
+	 * @param {OnIdent} onIdent callback
+	 */
+	enterObjectPattern(pattern, onIdent) {
+		for (
+			let propIndex = 0, len = pattern.properties.length;
+			propIndex < len;
+			propIndex++
+		) {
+			const prop = pattern.properties[propIndex];
+			this.enterPattern(prop, onIdent);
+		}
+	}
+
+	/**
+	 * Enter array pattern.
+	 * @param {ArrayPattern} pattern object pattern
+	 * @param {OnIdent} onIdent callback
+	 */
+	enterArrayPattern(pattern, onIdent) {
+		for (
+			let elementIndex = 0, len = pattern.elements.length;
+			elementIndex < len;
+			elementIndex++
+		) {
+			const element = pattern.elements[elementIndex];
+
+			if (element) {
+				this.enterPattern(element, onIdent);
+			}
+		}
+	}
+
+	/**
+	 * Enter rest element.
+	 * @param {RestElement} pattern object pattern
+	 * @param {OnIdent} onIdent callback
+	 */
+	enterRestElement(pattern, onIdent) {
+		this.enterPattern(pattern.argument, onIdent);
+	}
+
+	/**
+	 * Enter assignment pattern.
+	 * @param {AssignmentPattern} pattern object pattern
+	 * @param {OnIdent} onIdent callback
+	 */
+	enterAssignmentPattern(pattern, onIdent) {
+		this.enterPattern(pattern.left, onIdent);
+	}
+
+	/**
+	 * Evaluate expression.
+	 * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression node
+	 * @returns {BasicEvaluatedExpression} evaluation result
+	 */
+	evaluateExpression(expression) {
+		try {
+			const hook = this.hooks.evaluate.get(expression.type);
+			if (hook !== undefined) {
+				const result = hook.call(expression);
+				if (result !== undefined && result !== null) {
+					result.setExpression(expression);
+					return result;
+				}
+			}
+		} catch (err) {
+			// eslint-disable-next-line no-console
+			console.warn(err);
+			// ignore error
+		}
+		return new BasicEvaluatedExpression()
+			.setRange(/** @type {Range} */ (expression.range))
+			.setExpression(expression);
+	}
+
+	/**
+	 * Returns parsed string.
+	 * @param {Expression} expression expression
+	 * @returns {string} parsed string
+	 */
+	parseString(expression) {
+		switch (expression.type) {
+			case "BinaryExpression":
+				if (expression.operator === "+") {
+					return (
+						this.parseString(/** @type {Expression} */ (expression.left)) +
+						this.parseString(expression.right)
+					);
+				}
+				break;
+			case "Literal":
+				return String(expression.value);
+		}
+		throw new Error(
+			`${expression.type} is not supported as parameter for require`
+		);
+	}
+
+	/** @typedef {{ range?: Range, value: string, code: boolean, conditional: false | CalculatedStringResult[] }} CalculatedStringResult */
+
+	/**
+	 * Parses calculated string.
+	 * @param {Expression} expression expression
+	 * @returns {CalculatedStringResult} result
+	 */
+	parseCalculatedString(expression) {
+		switch (expression.type) {
+			case "BinaryExpression":
+				if (expression.operator === "+") {
+					const left = this.parseCalculatedString(
+						/** @type {Expression} */
+						(expression.left)
+					);
+					const right = this.parseCalculatedString(expression.right);
+					if (left.code) {
+						return {
+							range: left.range,
+							value: left.value,
+							code: true,
+							conditional: false
+						};
+					} else if (right.code) {
+						return {
+							range: [
+								/** @type {Range} */
+								(left.range)[0],
+								right.range
+									? right.range[1]
+									: /** @type {Range} */ (left.range)[1]
+							],
+							value: left.value + right.value,
+							code: true,
+							conditional: false
+						};
+					}
+					return {
+						range: [
+							/** @type {Range} */
+							(left.range)[0],
+							/** @type {Range} */
+							(right.range)[1]
+						],
+						value: left.value + right.value,
+						code: false,
+						conditional: false
+					};
+				}
+				break;
+			case "ConditionalExpression": {
+				const consequent = this.parseCalculatedString(expression.consequent);
+				const alternate = this.parseCalculatedString(expression.alternate);
+				/** @type {CalculatedStringResult[]} */
+				const items = [];
+				if (consequent.conditional) {
+					items.push(...consequent.conditional);
+				} else if (!consequent.code) {
+					items.push(consequent);
+				} else {
+					break;
+				}
+				if (alternate.conditional) {
+					items.push(...alternate.conditional);
+				} else if (!alternate.code) {
+					items.push(alternate);
+				} else {
+					break;
+				}
+				return {
+					range: undefined,
+					value: "",
+					code: true,
+					conditional: items
+				};
+			}
+			case "Literal":
+				return {
+					range: expression.range,
+					value: String(expression.value),
+					code: false,
+					conditional: false
+				};
+		}
+		return {
+			range: undefined,
+			value: "",
+			code: true,
+			conditional: false
+		};
+	}
+
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (source === null) {
+			throw new Error("source must not be null");
+		}
+
+		if (Buffer.isBuffer(source)) {
+			source = source.toString("utf8");
+			// Keep `state.source` as a string so downstream walkers can read
+			// the original text without re-decoding the Buffer on every use.
+			state.source = source;
+		}
+
+		let ast;
+		/** @type {Comment[]} */
+		let comments;
+		/** @type {Set<number>} */
+		let semicolons;
+
+		if (typeof source === "object") {
+			semicolons = new Set();
+
+			ast = /** @type {Program} */ (source);
+			comments = source.comments;
+			if (source.semicolons) {
+				// Forward semicolon information from the preparsed AST if present
+				// This ensures the output is consistent with that of a fresh AST
+				for (const pos of source.semicolons) {
+					semicolons.add(pos);
+				}
+			}
+		} else {
+			({ ast, comments, semicolons } = JavascriptParser._parse(
+				source,
+				{
+					sourceType: this.sourceType,
+					locations: true,
+					ranges: true,
+					comments: true,
+					semicolons: true
+				},
+				this.options.parse
+			));
+		}
+
+		const oldScope = this.scope;
+		const oldState = this.state;
+		const oldComments = this.comments;
+		const oldSemicolons = this.semicolons;
+		const oldStatementPath = this.statementPath;
+		const oldPrevStatement = this.prevStatement;
+		this.scope = {
+			topLevelScope: true,
+			inTry: false,
+			inShorthand: false,
+			inTaggedTemplateTag: false,
+			isStrict: false,
+			isAsmJs: false,
+			terminated: undefined,
+			definitions: new StackedMap()
+		};
+		this.state = state;
+		this.comments = comments;
+		this.semicolons = semicolons;
+		this.statementPath = [];
+		this.prevStatement = undefined;
+		if (this.hooks.program.call(ast, comments) === undefined) {
+			this.destructuringAssignmentProperties = new WeakMap();
+			this.detectMode(ast.body);
+			this.modulePreWalkStatements(ast.body);
+			this.prevStatement = undefined;
+			this.preWalkStatements(ast.body);
+			this.prevStatement = undefined;
+			this.blockPreWalkStatements(ast.body);
+			this.prevStatement = undefined;
+			this.walkStatements(ast.body);
+			this.destructuringAssignmentProperties = undefined;
+		}
+		this.hooks.finish.call(ast, comments);
+		this.scope = oldScope;
+		this.state = oldState;
+		this.comments = oldComments;
+		this.semicolons = oldSemicolons;
+		this.statementPath = oldStatementPath;
+		this.prevStatement = oldPrevStatement;
+		return state;
+	}
+
+	/**
+	 * Returns evaluation result.
+	 * @param {string} source source code
+	 * @returns {BasicEvaluatedExpression} evaluation result
+	 */
+	evaluate(source) {
+		const { ast } = JavascriptParser._parse(
+			`(${source})`,
+			{ sourceType: this.sourceType },
+			this.options.parse
+		);
+		if (ast.body.length !== 1 || ast.body[0].type !== "ExpressionStatement") {
+			throw new Error("evaluate: Source is not a expression");
+		}
+		return this.evaluateExpression(ast.body[0].expression);
+	}
+
+	/**
+	 * Checks whether this javascript parser is pure.
+	 * @param {Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | null | undefined} expr an expression
+	 * @param {number} commentsStartPos source position from which annotation comments are checked
+	 * @returns {boolean} true, when the expression is pure
+	 */
+	isPure(expr, commentsStartPos) {
+		if (!expr) return true;
+		const result = this.hooks.isPure
+			.for(expr.type)
+			.call(expr, commentsStartPos);
+		if (typeof result === "boolean") return result;
+		// TODO handle more cases
+		switch (expr.type) {
+			case "ClassDeclaration":
+			case "ClassExpression": {
+				if (expr.body.type !== "ClassBody") return false;
+				if (
+					expr.superClass &&
+					!this.isPure(expr.superClass, /** @type {Range} */ (expr.range)[0])
+				) {
+					return false;
+				}
+				const items = expr.body.body;
+				return items.every((item) => {
+					if (item.type === "StaticBlock") {
+						return false;
+					}
+
+					if (
+						item.computed &&
+						item.key &&
+						!this.isPure(
+							item.key,
+							/** @type {Range} */
+							(item.range)[0]
+						)
+					) {
+						return false;
+					}
+
+					if (
+						item.static &&
+						item.value &&
+						!this.isPure(
+							item.value,
+							item.key
+								? /** @type {Range} */ (item.key.range)[1]
+								: /** @type {Range} */ (item.range)[0]
+						)
+					) {
+						return false;
+					}
+
+					if (
+						expr.superClass &&
+						item.type === "MethodDefinition" &&
+						item.kind === "constructor"
+					) {
+						return false;
+					}
+
+					return true;
+				});
+			}
+			case "TemplateLiteral":
+				// Thread `commentsStartPos` through the interpolations so a
+				// /*#__PURE__*/ comment that sits inside `${ ... }` (or before
+				// the first interpolation) is part of the scanned range when
+				// the inner expression's purity is evaluated.
+				return expr.expressions.every((e) => {
+					const pureFlag = this.isPure(e, commentsStartPos);
+					commentsStartPos = /** @type {Range} */ (e.range)[1];
+					return pureFlag;
+				});
+			case "FunctionDeclaration":
+			case "FunctionExpression":
+			case "ArrowFunctionExpression":
+			case "ThisExpression":
+			case "Literal":
+			case "Identifier":
+			case "PrivateIdentifier":
+				return true;
+
+			case "VariableDeclaration":
+				return expr.declarations.every((decl) =>
+					this.isPure(decl.init, /** @type {Range} */ (decl.range)[0])
+				);
+
+			case "ArrayExpression":
+				return expr.elements.every((element) => {
+					if (element === null) return true;
+					if (element.type === "SpreadElement") return false;
+					const pureFlag = this.isPure(element, commentsStartPos);
+					commentsStartPos = /** @type {Range} */ (element.range)[1];
+					return pureFlag;
+				});
+
+			case "ObjectExpression": {
+				return expr.properties.every((property) => {
+					if (property.type === "SpreadElement") return false;
+
+					if (
+						property.computed &&
+						!this.isPure(property.key, commentsStartPos)
+					) {
+						return false;
+					}
+
+					const pureFlag = this.isPure(
+						/** @type {Exclude<Property["value"], AssignmentPattern | ObjectPattern | ArrayPattern | RestElement>} */
+						(property.value),
+						/** @type {Range} */ (property.key.range)[1]
+					);
+					commentsStartPos = /** @type {Range} */ (property.range)[1];
+					return pureFlag;
+				});
+			}
+
+			case "ChainExpression":
+				return this.isPure(expr.expression, commentsStartPos);
+
+			case "UnaryExpression":
+				// Safe unary operators — produce their result without invoking
+				// user code on the operand:
+				//   - `typeof` returns a type tag and never throws, even for
+				//     undeclared identifiers; no coercion.
+				//   - `void` evaluates the operand and discards it, returning
+				//     `undefined`; pure iff the operand is pure.
+				//   - `!` coerces via ToBoolean, which is defined to not call
+				//     any user code (objects → true, etc.).
+				// Other operators (`+`, `-`, `~`, `delete`) fall through to
+				// the generic evaluator which can still recognize literal
+				// cases (e.g. `-1`, `+5`).
+				if (
+					expr.operator === "typeof" ||
+					expr.operator === "void" ||
+					expr.operator === "!"
+				) {
+					return this.isPure(expr.argument, commentsStartPos);
+				}
+				break;
+
+			case "MetaProperty":
+				return true;
+
+			case "BinaryExpression":
+				// Strict (in)equality compares without coercion and never invokes
+				// user code on its operands, so the result is pure iff both sides
+				// are pure. All other binary operators may invoke `valueOf` /
+				// `toString` / `[Symbol.hasInstance]` / Proxy traps and fall through
+				// to the generic evaluator, which can still recognize the cases
+				// where both sides evaluate to known primitive literals.
+				if (expr.operator === "===" || expr.operator === "!==") {
+					return (
+						this.isPure(expr.left, commentsStartPos) &&
+						this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1])
+					);
+				}
+				break;
+
+			case "ConditionalExpression":
+				return (
+					this.isPure(expr.test, commentsStartPos) &&
+					this.isPure(
+						expr.consequent,
+						/** @type {Range} */ (expr.test.range)[1]
+					) &&
+					this.isPure(
+						expr.alternate,
+						/** @type {Range} */ (expr.consequent.range)[1]
+					)
+				);
+
+			case "LogicalExpression":
+				return (
+					this.isPure(expr.left, commentsStartPos) &&
+					this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1])
+				);
+
+			case "SequenceExpression":
+				return expr.expressions.every((expr) => {
+					const pureFlag = this.isPure(expr, commentsStartPos);
+					commentsStartPos = /** @type {Range} */ (expr.range)[1];
+					return pureFlag;
+				});
+
+			case "CallExpression": {
+				const pureFlag =
+					/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
+					this.getComments([
+						commentsStartPos,
+						/** @type {Range} */ (expr.range)[0]
+					]).some(
+						(comment) =>
+							comment.type === "Block" &&
+							CompilerHintNotationRegExp.Pure.test(comment.value)
+					);
+				if (!pureFlag) return false;
+				commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
+				return expr.arguments.every((arg) => {
+					if (arg.type === "SpreadElement") return false;
+					const pureFlag = this.isPure(arg, commentsStartPos);
+					commentsStartPos = /** @type {Range} */ (arg.range)[1];
+					return pureFlag;
+				});
+			}
+
+			case "NewExpression": {
+				const pureFlag =
+					/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
+					this.getComments([
+						commentsStartPos,
+						/** @type {Range} */ (expr.range)[0]
+					]).some(
+						(comment) =>
+							comment.type === "Block" &&
+							CompilerHintNotationRegExp.Pure.test(comment.value)
+					);
+				if (!pureFlag) return false;
+				commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
+				return expr.arguments.every((arg) => {
+					if (arg.type === "SpreadElement") return false;
+					const pureFlag = this.isPure(arg, commentsStartPos);
+					commentsStartPos = /** @type {Range} */ (arg.range)[1];
+					return pureFlag;
+				});
+			}
+
+			case "TaggedTemplateExpression": {
+				const pureFlag =
+					/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
+					this.getComments([
+						commentsStartPos,
+						/** @type {Range} */ (expr.range)[0]
+					]).some(
+						(comment) =>
+							comment.type === "Block" &&
+							CompilerHintNotationRegExp.Pure.test(comment.value)
+					);
+				if (!pureFlag) return false;
+				commentsStartPos = /** @type {Range} */ (expr.tag.range)[1];
+				return expr.quasi.expressions.every((e) => {
+					const pureFlag = this.isPure(e, commentsStartPos);
+					commentsStartPos = /** @type {Range} */ (e.range)[1];
+					return pureFlag;
+				});
+			}
+		}
+		const evaluated = this.evaluateExpression(expr);
+		return !evaluated.couldHaveSideEffects();
+	}
+
+	/**
+	 * Returns comments in the range.
+	 * @param {Range} range range
+	 * @returns {Comment[]} comments in the range
+	 */
+	getComments(range) {
+		const [rangeStart, rangeEnd] = range;
+		/**
+		 * Returns compared.
+		 * @param {Comment} comment comment
+		 * @param {number} needle needle
+		 * @returns {number} compared
+		 */
+		const compare = (comment, needle) =>
+			/** @type {Range} */ (comment.range)[0] - needle;
+		const comments = /** @type {Comment[]} */ (this.comments);
+		let idx = binarySearchBounds.ge(comments, rangeStart, compare);
+		/** @type {Comment[]} */
+		const commentsInRange = [];
+		while (
+			comments[idx] &&
+			/** @type {Range} */ (comments[idx].range)[1] <= rangeEnd
+		) {
+			commentsInRange.push(comments[idx]);
+			idx++;
+		}
+
+		return commentsInRange;
+	}
+
+	/**
+	 * Checks whether this javascript parser is asi position.
+	 * @param {number} pos source code position
+	 * @returns {boolean} true when a semicolon has been inserted before this position, false if not
+	 */
+	isAsiPosition(pos) {
+		const currentStatement =
+			/** @type {StatementPath} */
+			(this.statementPath)[
+				/** @type {StatementPath} */
+				(this.statementPath).length - 1
+			];
+		if (currentStatement === undefined) throw new Error("Not in statement");
+		const range = /** @type {Range} */ (currentStatement.range);
+
+		return (
+			// Either asking directly for the end position of the current statement
+			(range[1] === pos &&
+				/** @type {Set<number>} */ (this.semicolons).has(pos)) ||
+			// Or asking for the start position of the current statement,
+			// here we have to check multiple things
+			(range[0] === pos &&
+				// is there a previous statement which might be relevant?
+				this.prevStatement !== undefined &&
+				// is the end position of the previous statement an ASI position?
+				/** @type {Set<number>} */ (this.semicolons).has(
+					/** @type {Range} */ (this.prevStatement.range)[1]
+				))
+		);
+	}
+
+	/**
+	 * Updates asi position using the provided po.
+	 * @param {number} pos source code position
+	 * @returns {void}
+	 */
+	setAsiPosition(pos) {
+		/** @type {Set<number>} */ (this.semicolons).add(pos);
+	}
+
+	/**
+	 * Unset asi position.
+	 * @param {number} pos source code position
+	 * @returns {void}
+	 */
+	unsetAsiPosition(pos) {
+		/** @type {Set<number>} */ (this.semicolons).delete(pos);
+	}
+
+	/**
+	 * Checks whether this javascript parser is statement level expression.
+	 * @param {Expression} expr expression
+	 * @returns {boolean} true, when the expression is a statement level expression
+	 */
+	isStatementLevelExpression(expr) {
+		const currentStatement =
+			/** @type {StatementPath} */
+			(this.statementPath)[
+				/** @type {StatementPath} */
+				(this.statementPath).length - 1
+			];
+		return (
+			expr === currentStatement ||
+			(currentStatement.type === "ExpressionStatement" &&
+				currentStatement.expression === expr)
+		);
+	}
+
+	/**
+	 * Returns tag data.
+	 * @param {string} name name
+	 * @param {Tag} tag tag info
+	 * @returns {TagData | undefined} tag data
+	 */
+	getTagData(name, tag) {
+		const info = this.scope.definitions.get(name);
+		if (info instanceof VariableInfo) {
+			let tagInfo = info.tagInfo;
+			while (tagInfo !== undefined) {
+				if (tagInfo.tag === tag) return tagInfo.data;
+				tagInfo = tagInfo.next;
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided name.
+	 * @param {string} name name
+	 * @param {Tag} tag tag info
+	 * @param {TagData=} data data
+	 * @param {VariableInfoFlagsType=} flags flags
+	 */
+	tagVariable(name, tag, data, flags = VariableInfoFlags.Tagged) {
+		const oldInfo = this.scope.definitions.get(name);
+		/** @type {VariableInfo} */
+		let newInfo;
+		if (oldInfo === undefined) {
+			newInfo = new VariableInfo(this.scope, name, flags, {
+				tag,
+				data,
+				next: undefined
+			});
+		} else if (oldInfo instanceof VariableInfo) {
+			newInfo = new VariableInfo(
+				oldInfo.declaredScope,
+				oldInfo.name,
+				/** @type {VariableInfoFlagsType} */ (oldInfo.flags | flags),
+				{
+					tag,
+					data,
+					next: oldInfo.tagInfo
+				}
+			);
+		} else {
+			newInfo = new VariableInfo(oldInfo, name, flags, {
+				tag,
+				data,
+				next: undefined
+			});
+		}
+		this.scope.definitions.set(name, newInfo);
+	}
+
+	/**
+	 * Processes the provided name.
+	 * @param {string} name variable name
+	 */
+	defineVariable(name) {
+		const oldInfo = this.scope.definitions.get(name);
+		// Don't redefine variable in same scope to keep existing tags
+		if (
+			oldInfo instanceof VariableInfo &&
+			oldInfo.declaredScope === this.scope
+		) {
+			return;
+		}
+		this.scope.definitions.set(name, this.scope);
+	}
+
+	/**
+	 * Processes the provided name.
+	 * @param {string} name variable name
+	 */
+	undefineVariable(name) {
+		this.scope.definitions.delete(name);
+	}
+
+	/**
+	 * Checks whether this javascript parser is variable defined.
+	 * @param {string} name variable name
+	 * @returns {boolean} true, when variable is defined
+	 */
+	isVariableDefined(name) {
+		const info = this.scope.definitions.get(name);
+		if (info === undefined) return false;
+		if (info instanceof VariableInfo) {
+			return !info.isFree();
+		}
+		return true;
+	}
+
+	/**
+	 * Gets variable info.
+	 * @param {string} name variable name
+	 * @returns {ExportedVariableInfo} info for this variable
+	 */
+	getVariableInfo(name) {
+		const value = this.scope.definitions.get(name);
+		if (value === undefined) {
+			return name;
+		}
+		return value;
+	}
+
+	/**
+	 * Updates variable using the provided name.
+	 * @param {string} name variable name
+	 * @param {ExportedVariableInfo} variableInfo new info for this variable
+	 * @returns {void}
+	 */
+	setVariable(name, variableInfo) {
+		if (typeof variableInfo === "string") {
+			if (variableInfo === name) {
+				this.scope.definitions.delete(name);
+			} else {
+				this.scope.definitions.set(
+					name,
+					new VariableInfo(
+						this.scope,
+						variableInfo,
+						VariableInfoFlags.Free,
+						undefined
+					)
+				);
+			}
+		} else {
+			this.scope.definitions.set(name, variableInfo);
+		}
+	}
+
+	/**
+	 * Evaluated variable.
+	 * @param {TagInfo} tagInfo tag info
+	 * @returns {VariableInfo} variable info
+	 */
+	evaluatedVariable(tagInfo) {
+		return new VariableInfo(
+			this.scope,
+			undefined,
+			VariableInfoFlags.Evaluated,
+			tagInfo
+		);
+	}
+
+	/**
+	 * Parses comment options.
+	 * @param {Range} range range of the comment
+	 * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
+	 */
+	parseCommentOptions(range) {
+		const comments = this.getComments(range);
+		if (comments.length === 0) {
+			return EMPTY_COMMENT_OPTIONS;
+		}
+		/** @type {Record<string, EXPECTED_ANY>} */
+		const options = {};
+		/** @type {(Error & { comment: Comment })[]} */
+		const errors = [];
+		for (const comment of comments) {
+			const { value } = comment;
+			if (value && webpackCommentRegExp.test(value)) {
+				// try compile only if webpack options comment is present
+				try {
+					for (let [key, val] of Object.entries(
+						vm.runInContext(
+							`(function(){return {${value}};})()`,
+							this.magicCommentContext
+						)
+					)) {
+						if (typeof val === "object" && val !== null) {
+							val =
+								val.constructor.name === "RegExp"
+									? new RegExp(val)
+									: JSON.parse(JSON.stringify(val));
+						}
+						options[key] = val;
+					}
+				} catch (err) {
+					const newErr = new Error(String(/** @type {Error} */ (err).message));
+					newErr.stack = String(/** @type {Error} */ (err).stack);
+					Object.assign(newErr, { comment });
+					errors.push(/** @type {(Error & { comment: Comment })} */ (newErr));
+				}
+			}
+		}
+		return { options, errors };
+	}
+
+	/**
+	 * Extract member expression chain.
+	 * @param {Expression | Super} expression a member expression
+	 * @returns {{ members: Members, object: Expression | Super, membersOptionals: MembersOptionals, memberRanges: MemberRanges }} member names (reverse order) and remaining object
+	 */
+	extractMemberExpressionChain(expression) {
+		/** @type {Node} */
+		let expr = expression;
+		/** @type {Members} */
+		const members = [];
+		/** @type {MembersOptionals} */
+		const membersOptionals = [];
+		/** @type {MemberRanges} */
+		const memberRanges = [];
+		while (expr.type === "MemberExpression") {
+			if (expr.computed) {
+				const prop = expr.property;
+				if (prop.type === "Literal") {
+					members.push(`${prop.value}`); // the literal
+				} else if (
+					prop.type === "TemplateLiteral" &&
+					prop.expressions.length === 0 &&
+					typeof prop.quasis[0].value.cooked === "string"
+				) {
+					// `[`url`]` is statically a string just like `["url"]`
+					members.push(prop.quasis[0].value.cooked);
+				} else {
+					break;
+				}
+				memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the property
+			} else {
+				if (expr.property.type !== "Identifier") break;
+				members.push(expr.property.name); // the identifier
+				memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the identifier
+			}
+			membersOptionals.push(expr.optional);
+			expr = expr.object;
+		}
+
+		return {
+			members,
+			membersOptionals,
+			memberRanges,
+			object: expr
+		};
+	}
+
+	/**
+	 * Gets free info from variable.
+	 * @param {string} varName variable name
+	 * @returns {{ name: string, info: VariableInfo | string } | undefined} name of the free variable and variable info for that
+	 */
+	getFreeInfoFromVariable(varName) {
+		const info = this.getVariableInfo(varName);
+		/** @type {string} */
+		let name;
+		if (info instanceof VariableInfo && info.name) {
+			if (!info.isFree()) return;
+			name = info.name;
+		} else if (typeof info !== "string") {
+			return;
+		} else {
+			name = info;
+		}
+		return { info, name };
+	}
+
+	/**
+	 * Gets name info from variable.
+	 * @param {string} varName variable name
+	 * @returns {{ name: string, info: VariableInfo | string } | undefined} name of the free variable and variable info for that
+	 */
+	getNameInfoFromVariable(varName) {
+		const info = this.getVariableInfo(varName);
+		/** @type {string} */
+		let name;
+		if (info instanceof VariableInfo && info.name) {
+			if (!info.isFree() && !info.isTagged()) return;
+			name = info.name;
+		} else if (typeof info !== "string") {
+			return;
+		} else {
+			name = info;
+		}
+		return { info, name };
+	}
+
+	/** @typedef {{ type: "call", call: CallExpression, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => CalleeMembers, name: string, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} CallExpressionInfo */
+	/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} ExpressionExpressionInfo */
+
+	/**
+	 * Gets member expression info.
+	 * @param {Expression | Super} expression a member expression
+	 * @param {number} allowedTypes which types should be returned, presented in bit mask
+	 * @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
+	 */
+	getMemberExpressionInfo(expression, allowedTypes) {
+		const { object, members, membersOptionals, memberRanges } =
+			this.extractMemberExpressionChain(expression);
+		switch (object.type) {
+			case "CallExpression": {
+				if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) return;
+				let callee = object.callee;
+				let rootMembers = EMPTY_ARRAY;
+				if (callee.type === "MemberExpression") {
+					({ object: callee, members: rootMembers } =
+						this.extractMemberExpressionChain(callee));
+				}
+				const rootName = getRootName(callee);
+				if (!rootName) return;
+				const result = this.getNameInfoFromVariable(rootName);
+				if (!result) return;
+				const { info: rootInfo, name: resolvedRoot } = result;
+				const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
+				return {
+					type: "call",
+					call: object,
+					calleeName,
+					rootInfo,
+					getCalleeMembers: memoize(() => rootMembers.reverse()),
+					name: objectAndMembersToName(`${calleeName}()`, members),
+					getMembers: memoize(() => members.reverse()),
+					getMembersOptionals: memoize(() => membersOptionals.reverse()),
+					getMemberRanges: memoize(() => memberRanges.reverse())
+				};
+			}
+			case "Identifier":
+			case "MetaProperty":
+			case "ThisExpression": {
+				if ((allowedTypes & ALLOWED_MEMBER_TYPES_EXPRESSION) === 0) return;
+				const rootName = getRootName(object);
+				if (!rootName) return;
+
+				const result = this.getNameInfoFromVariable(rootName);
+				if (!result) return;
+				const { info: rootInfo, name: resolvedRoot } = result;
+				return {
+					type: "expression",
+					name: objectAndMembersToName(resolvedRoot, members),
+					rootInfo,
+					getMembers: memoize(() => members.reverse()),
+					getMembersOptionals: memoize(() => membersOptionals.reverse()),
+					getMemberRanges: memoize(() => memberRanges.reverse())
+				};
+			}
+		}
+	}
+
+	/**
+	 * Gets name for expression.
+	 * @param {Expression} expression an expression
+	 * @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => Members } | undefined} name info
+	 */
+	getNameForExpression(expression) {
+		return this.getMemberExpressionInfo(
+			expression,
+			ALLOWED_MEMBER_TYPES_EXPRESSION
+		);
+	}
+
+	/**
+	 * Get module parse function.
+	 * @param {Compilation} compilation compilation
+	 * @param {Module} module module
+	 * @returns {ParseFunction | undefined} parser
+	 */
+	static _getModuleParseFunction(compilation, module) {
+		// Get from module if available
+		if (
+			module instanceof NormalModule &&
+			module.parser instanceof JavascriptParser
+		) {
+			return module.parser.options.parse;
+		}
+
+		// Fallback to the global javascript parse function
+		if (typeof compilation.options.module.parser.javascript !== "undefined") {
+			return compilation.options.module.parser.javascript.parse;
+		}
+	}
+
+	/**
+	 * Returns parse result.
+	 * @param {string} code source code
+	 * @param {InternalParseOptions} options parsing options
+	 * @param {ParseFunction=} customParse custom function to parse
+	 * @returns {ParseResult} parse result
+	 */
+	static _parse(code, options, customParse) {
+		const type = options ? options.sourceType : "module";
+		/** @type {ParseOptions} */
+		const parserOptions = {
+			...defaultParserOptions,
+			allowReturnOutsideFunction: type === "script",
+			...options,
+			sourceType: type === "auto" ? "module" : type
+		};
+		/**
+		 * Returns parse result.
+		 * @param {string} code source code
+		 * @param {ParseOptions} options parsing options
+		 * @returns {ParseResult} parse result
+		 */
+		const internalParse = (code, options) => {
+			if (typeof customParse === "function") {
+				return customParse(code, options);
+			}
+
+			/** @type {Comment[]} */
+			const comments = [];
+
+			if (options.comments) {
+				/** @type {AcornOptions} */
+				(options).onComment = comments;
+			}
+
+			/** @type {Set<number>} */
+			const semicolons = new Set();
+
+			if (options.semicolons) {
+				/** @type {AcornOptions} */
+				(options).onInsertedSemicolon = (pos) => semicolons.add(pos);
+			}
+
+			const ast =
+				/** @type {Program} */
+				(parser.parse(code, /** @type {AcornOptions} */ (options)));
+
+			return { ast, comments, semicolons };
+		};
+
+		/** @type {Program | undefined} */
+		let ast;
+		/** @type {Comment[] | undefined} */
+		let comments;
+		/** @type {Set<number> | undefined} */
+		let semicolons;
+		let error;
+		let threw = false;
+		try {
+			({ ast, comments, semicolons } = internalParse(code, parserOptions));
+		} catch (err) {
+			error = err;
+			threw = true;
+		}
+
+		if (threw && type === "auto") {
+			parserOptions.sourceType = "script";
+			parserOptions.allowReturnOutsideFunction = true;
+
+			try {
+				({ ast, comments, semicolons } = internalParse(code, parserOptions));
+				threw = false;
+			} catch (_err) {
+				// we use the error from first parse try
+				// so nothing to do here
+			}
+		}
+
+		if (threw) {
+			throw error;
+		}
+
+		return /** @type {ParseResult} */ ({ ast, comments, semicolons });
+	}
+
+	/**
+	 * Returns parser.
+	 * @param {((BaseParser: typeof AcornParser) => typeof AcornParser)[]} plugins parser plugin
+	 * @returns {typeof JavascriptParser} parser
+	 */
+	static extend(...plugins) {
+		parser = parser.extend(...plugins);
+		return JavascriptParser;
+	}
+}
+
+module.exports = JavascriptParser;
+module.exports.ALLOWED_MEMBER_TYPES_ALL = ALLOWED_MEMBER_TYPES_ALL;
+module.exports.ALLOWED_MEMBER_TYPES_CALL_EXPRESSION =
+	ALLOWED_MEMBER_TYPES_CALL_EXPRESSION;
+module.exports.ALLOWED_MEMBER_TYPES_EXPRESSION =
+	ALLOWED_MEMBER_TYPES_EXPRESSION;
+module.exports.VariableInfo = VariableInfo;
+module.exports.VariableInfoFlags = VariableInfoFlags;
+module.exports.getImportAttributes = getImportAttributes;
Index: frontend/node_modules/webpack/lib/javascript/JavascriptParserHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/JavascriptParserHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/JavascriptParserHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,135 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ConstDependency = require("../dependencies/ConstDependency");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
+
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").SourceLocation} SourceLocation */
+/** @typedef {import("./JavascriptParser")} JavascriptParser */
+/** @typedef {import("./JavascriptParser").Range} Range */
+/** @typedef {import("./BasicEvaluatedExpression").GetMembers} GetMembers */
+
+module.exports.approve = () => true;
+
+/**
+ * Returns plugin function.
+ * @param {boolean} value the boolean value
+ * @returns {(expression: Expression) => BasicEvaluatedExpression} plugin function
+ */
+module.exports.evaluateToBoolean = (value) =>
+	function booleanExpression(expr) {
+		return new BasicEvaluatedExpression()
+			.setBoolean(value)
+			.setRange(/** @type {Range} */ (expr.range));
+	};
+
+/**
+ * Returns callback.
+ * @param {string} identifier identifier
+ * @param {string} rootInfo rootInfo
+ * @param {GetMembers} getMembers getMembers
+ * @param {boolean | null=} truthy is truthy, null if nullish
+ * @returns {(expression: Expression) => BasicEvaluatedExpression} callback
+ */
+module.exports.evaluateToIdentifier = (
+	identifier,
+	rootInfo,
+	getMembers,
+	truthy
+) =>
+	function identifierExpression(expr) {
+		const evaluatedExpression = new BasicEvaluatedExpression()
+			.setIdentifier(identifier, rootInfo, getMembers)
+			.setSideEffects(false)
+			.setRange(/** @type {Range} */ (expr.range));
+		switch (truthy) {
+			case true:
+				evaluatedExpression.setTruthy();
+				break;
+			case null:
+				evaluatedExpression.setNullish(true);
+				break;
+			case false:
+				evaluatedExpression.setFalsy();
+				break;
+		}
+
+		return evaluatedExpression;
+	};
+
+/**
+ * Returns plugin function.
+ * @param {number} value the number value
+ * @returns {(expression: Expression) => BasicEvaluatedExpression} plugin function
+ */
+module.exports.evaluateToNumber = (value) =>
+	function stringExpression(expr) {
+		return new BasicEvaluatedExpression()
+			.setNumber(value)
+			.setRange(/** @type {Range} */ (expr.range));
+	};
+
+/**
+ * Returns plugin function.
+ * @param {string} value the string value
+ * @returns {(expression: Expression) => BasicEvaluatedExpression} plugin function
+ */
+module.exports.evaluateToString = (value) =>
+	function stringExpression(expr) {
+		return new BasicEvaluatedExpression()
+			.setString(value)
+			.setRange(/** @type {Range} */ (expr.range));
+	};
+
+/**
+ * Returns callback to handle unsupported expression.
+ * @param {JavascriptParser} parser the parser
+ * @param {string} message the message
+ * @returns {(expression: Expression) => boolean | undefined} callback to handle unsupported expression
+ */
+module.exports.expressionIsUnsupported = (parser, message) =>
+	function unsupportedExpression(expr) {
+		const dep = new ConstDependency(
+			"(void 0)",
+			/** @type {Range} */ (expr.range),
+			null
+		);
+		dep.loc = /** @type {SourceLocation} */ (expr.loc);
+		parser.state.module.addPresentationalDependency(dep);
+		if (!parser.state.module) return;
+		parser.state.module.addWarning(
+			new UnsupportedFeatureWarning(
+				message,
+				/** @type {SourceLocation} */ (expr.loc)
+			)
+		);
+		return true;
+	};
+
+module.exports.skipTraversal = () => true;
+
+/**
+ * Returns plugin function.
+ * @param {JavascriptParser} parser the parser
+ * @param {string} value the const value
+ * @param {(string[] | null)=} runtimeRequirements runtime requirements
+ * @returns {(expression: Expression) => true} plugin function
+ */
+module.exports.toConstantDependency = (parser, value, runtimeRequirements) =>
+	function constDependency(expr) {
+		const dep = new ConstDependency(
+			value,
+			/** @type {Range} */
+			(expr.range),
+			runtimeRequirements
+		);
+		dep.loc = /** @type {SourceLocation} */ (expr.loc);
+		parser.state.module.addPresentationalDependency(dep);
+		return true;
+	};
Index: frontend/node_modules/webpack/lib/javascript/StartupHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/javascript/StartupHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/javascript/StartupHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,183 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const { isSubset } = require("../util/SetHelpers");
+const { getAllChunks } = require("./ChunkHelpers");
+
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+
+const EXPORT_PREFIX = `var ${RuntimeGlobals.exports} = `;
+
+/** @typedef {Set<Chunk>} Chunks */
+/** @typedef {ModuleId[]} ModuleIds */
+
+/**
+ * Returns runtime code.
+ * @param {ChunkGraph} chunkGraph chunkGraph
+ * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate
+ * @param {EntryModuleWithChunkGroup[]} entries entries
+ * @param {Chunk} chunk chunk
+ * @param {boolean} passive true: passive startup with on chunks loaded
+ * @returns {string} runtime code
+ */
+module.exports.generateEntryStartup = (
+	chunkGraph,
+	runtimeTemplate,
+	entries,
+	chunk,
+	passive
+) => {
+	/** @type {string[]} */
+	const runtime = [
+		`var __webpack_exec__ = ${runtimeTemplate.returningFunction(
+			`${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)`,
+			"moduleId"
+		)}`
+	];
+
+	/**
+	 * Returns fn to execute.
+	 * @param {ModuleId} id id
+	 * @returns {string} fn to execute
+	 */
+	const runModule = (id) => `__webpack_exec__(${JSON.stringify(id)})`;
+	/**
+	 * Output combination.
+	 * @param {Chunks} chunks chunks
+	 * @param {ModuleIds} moduleIds module ids
+	 * @param {boolean=} final true when final, otherwise false
+	 */
+	const outputCombination = (chunks, moduleIds, final) => {
+		if (chunks.size === 0) {
+			runtime.push(
+				`${final ? EXPORT_PREFIX : ""}(${moduleIds.map(runModule).join(", ")});`
+			);
+		} else {
+			const fn = runtimeTemplate.returningFunction(
+				moduleIds.map(runModule).join(", ")
+			);
+			runtime.push(
+				`${final && !passive ? EXPORT_PREFIX : ""}${
+					passive
+						? RuntimeGlobals.onChunksLoaded
+						: RuntimeGlobals.startupEntrypoint
+				}(0, ${JSON.stringify(Array.from(chunks, (c) => c.id))}, ${fn});`
+			);
+			if (final && passive) {
+				runtime.push(`${EXPORT_PREFIX}${RuntimeGlobals.onChunksLoaded}();`);
+			}
+		}
+	};
+
+	/** @type {Chunks | undefined} */
+	let currentChunks;
+	/** @type {ModuleIds | undefined} */
+	let currentModuleIds;
+
+	for (const [module, entrypoint] of entries) {
+		if (!chunkGraph.getModuleSourceTypes(module).has("javascript")) {
+			continue;
+		}
+		const runtimeChunk =
+			/** @type {Entrypoint} */
+			(entrypoint).getRuntimeChunk();
+		const moduleId = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+		const chunks = getAllChunks(
+			/** @type {Entrypoint} */
+			(entrypoint),
+			chunk,
+			runtimeChunk
+		);
+		if (
+			currentChunks &&
+			currentChunks.size === chunks.size &&
+			isSubset(currentChunks, chunks)
+		) {
+			/** @type {ModuleIds} */
+			(currentModuleIds).push(moduleId);
+		} else {
+			if (currentChunks) {
+				outputCombination(
+					currentChunks,
+					/** @type {ModuleIds} */ (currentModuleIds)
+				);
+			}
+			currentChunks = chunks;
+			currentModuleIds = [moduleId];
+		}
+	}
+
+	// output current modules with export prefix
+	if (currentChunks) {
+		outputCombination(
+			currentChunks,
+			/** @type {ModuleIds} */
+			(currentModuleIds),
+			true
+		);
+	}
+	runtime.push("");
+	return Template.asString(runtime);
+};
+
+/**
+ * Returns initially fulfilled chunk ids.
+ * @param {Chunk} chunk the chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {(chunk: Chunk, chunkGraph: ChunkGraph) => boolean} filterFn filter function
+ * @returns {Set<ChunkId>} initially fulfilled chunk ids
+ */
+module.exports.getInitialChunkIds = (chunk, chunkGraph, filterFn) => {
+	/** @type {Set<ChunkId>} */
+	const initialChunkIds = new Set(chunk.ids);
+	for (const c of chunk.getAllInitialChunks()) {
+		if (c === chunk || filterFn(c, chunkGraph)) continue;
+		for (const id of /** @type {ChunkId[]} */ (c.ids)) {
+			initialChunkIds.add(id);
+		}
+	}
+	return initialChunkIds;
+};
+
+/**
+ * Processes the provided hash.
+ * @param {Hash} hash the hash to update
+ * @param {ChunkGraph} chunkGraph chunkGraph
+ * @param {EntryModuleWithChunkGroup[]} entries entries
+ * @param {Chunk} chunk chunk
+ * @returns {void}
+ */
+module.exports.updateHashForEntryStartup = (
+	hash,
+	chunkGraph,
+	entries,
+	chunk
+) => {
+	for (const [module, entrypoint] of entries) {
+		const runtimeChunk =
+			/** @type {Entrypoint} */
+			(entrypoint).getRuntimeChunk();
+		const moduleId = chunkGraph.getModuleId(module);
+		hash.update(`${moduleId}`);
+		for (const c of getAllChunks(
+			/** @type {Entrypoint} */ (entrypoint),
+			chunk,
+			/** @type {Chunk} */ (runtimeChunk)
+		)) {
+			hash.update(`${c.id}`);
+		}
+	}
+};
Index: frontend/node_modules/webpack/lib/json/JsonData.js
===================================================================
--- frontend/node_modules/webpack/lib/json/JsonData.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/json/JsonData.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,79 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { register } = require("../util/serialization");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").JsonValue} JsonValue */
+
+class JsonData {
+	/**
+	 * Creates an instance of JsonData.
+	 * @param {Buffer | JsonValue} data JSON data
+	 */
+	constructor(data) {
+		/** @type {Buffer | undefined} */
+		this._buffer = undefined;
+		/** @type {JsonValue | undefined} */
+		this._data = undefined;
+		if (Buffer.isBuffer(data)) {
+			this._buffer = data;
+		} else {
+			this._data = data;
+		}
+	}
+
+	/**
+	 * Returns raw JSON data.
+	 * @returns {JsonValue | undefined} Raw JSON data
+	 */
+	get() {
+		if (this._data === undefined && this._buffer !== undefined) {
+			this._data = JSON.parse(this._buffer.toString());
+		}
+		return this._data;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash to be updated
+	 * @returns {void} the updated hash
+	 */
+	updateHash(hash) {
+		if (this._buffer === undefined && this._data !== undefined) {
+			this._buffer = Buffer.from(JSON.stringify(this._data));
+		}
+
+		if (this._buffer) hash.update(this._buffer);
+	}
+}
+
+register(JsonData, "webpack/lib/json/JsonData", null, {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {JsonData} obj JSONData object
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, { write }) {
+		if (obj._buffer === undefined && obj._data !== undefined) {
+			obj._buffer = Buffer.from(JSON.stringify(obj._data));
+		}
+		write(obj._buffer);
+	},
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {JsonData} deserialized JSON data
+	 */
+	deserialize({ read }) {
+		return new JsonData(read());
+	}
+});
+
+module.exports = JsonData;
Index: frontend/node_modules/webpack/lib/json/JsonGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/json/JsonGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/json/JsonGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,255 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const ConcatenationScope = require("../ConcatenationScope");
+const { UsageState } = require("../ExportsInfo");
+const Generator = require("../Generator");
+const { JAVASCRIPT_TYPES } = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").JsonGeneratorOptions} JsonGeneratorOptions */
+/** @typedef {import("../ExportsInfo")} ExportsInfo */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../util/fs").JsonArray} JsonArray */
+/** @typedef {import("../util/fs").JsonObject} JsonObject */
+/** @typedef {import("../util/fs").JsonValue} JsonValue */
+
+/**
+ * Returns stringified data.
+ * @param {JsonValue} data Raw JSON data
+ * @returns {undefined | string} stringified data
+ */
+const stringifySafe = (data) => {
+	const stringified = JSON.stringify(data);
+	if (!stringified) {
+		return; // Invalid JSON
+	}
+
+	return stringified.replace(/\u2028|\u2029/g, (str) =>
+		str === "\u2029" ? "\\u2029" : "\\u2028"
+	); // invalid in JavaScript but valid JSON
+};
+
+/**
+ * Creates an object for exports info.
+ * @param {JsonObject | JsonArray} data Raw JSON data (always an object or array)
+ * @param {ExportsInfo} exportsInfo exports info
+ * @param {RuntimeSpec} runtime the runtime
+ * @returns {JsonObject | JsonArray} reduced data
+ */
+const createObjectForExportsInfo = (data, exportsInfo, runtime) => {
+	if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
+		return data;
+	}
+	const isArray = Array.isArray(data);
+	/** @type {JsonObject | JsonArray} */
+	const reducedData = isArray ? [] : {};
+	for (const key of Object.keys(data)) {
+		const exportInfo = exportsInfo.getReadOnlyExportInfo(key);
+		const used = exportInfo.getUsed(runtime);
+		if (used === UsageState.Unused) continue;
+
+		// The real type is `JsonObject | JsonArray`, but typescript doesn't work `Object.keys(['string', 'other-string', 'etc'])` properly
+		const newData = /** @type {JsonObject} */ (data)[key];
+		const value =
+			used === UsageState.OnlyPropertiesUsed &&
+			exportInfo.exportsInfo &&
+			typeof newData === "object" &&
+			newData
+				? createObjectForExportsInfo(newData, exportInfo.exportsInfo, runtime)
+				: newData;
+
+		const name = /** @type {string} */ (exportInfo.getUsedName(key, runtime));
+		/** @type {JsonObject} */
+		(reducedData)[name] = value;
+	}
+	if (isArray) {
+		const arrayLengthWhenUsed =
+			exportsInfo.getReadOnlyExportInfo("length").getUsed(runtime) !==
+			UsageState.Unused
+				? data.length
+				: undefined;
+
+		let sizeObjectMinusArray = 0;
+		const reducedDataLength =
+			/** @type {JsonArray} */
+			(reducedData).length;
+		for (let i = 0; i < reducedDataLength; i++) {
+			if (/** @type {JsonArray} */ (reducedData)[i] === undefined) {
+				sizeObjectMinusArray -= 2;
+			} else {
+				sizeObjectMinusArray += `${i}`.length + 3;
+			}
+		}
+		if (arrayLengthWhenUsed !== undefined) {
+			sizeObjectMinusArray +=
+				`${arrayLengthWhenUsed}`.length +
+				8 -
+				(arrayLengthWhenUsed - reducedDataLength) * 2;
+		}
+		if (sizeObjectMinusArray < 0) {
+			return Object.assign(
+				arrayLengthWhenUsed === undefined
+					? {}
+					: { length: arrayLengthWhenUsed },
+				reducedData
+			);
+		}
+		/** @type {number} */
+		const generatedLength =
+			arrayLengthWhenUsed !== undefined
+				? Math.max(arrayLengthWhenUsed, reducedDataLength)
+				: reducedDataLength;
+		for (let i = 0; i < generatedLength; i++) {
+			if (/** @type {JsonArray} */ (reducedData)[i] === undefined) {
+				/** @type {JsonArray} */
+				(reducedData)[i] = 0;
+			}
+		}
+	}
+	return reducedData;
+};
+
+class JsonGenerator extends Generator {
+	/**
+	 * Creates an instance of JsonGenerator.
+	 * @param {JsonGeneratorOptions} options options
+	 */
+	constructor(options) {
+		super();
+		/** @type {JsonGeneratorOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		/** @type {JsonValue | undefined} */
+		const data =
+			module.buildInfo &&
+			module.buildInfo.jsonData &&
+			module.buildInfo.jsonData.get();
+		if (!data) return 0;
+		return /** @type {string} */ (stringifySafe(data)).length + 10;
+	}
+
+	/**
+	 * Returns the reason this module cannot be concatenated, when one exists.
+	 * @param {NormalModule} module module for which the bailout reason should be determined
+	 * @param {ConcatenationBailoutReasonContext} context context
+	 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
+	 */
+	getConcatenationBailoutReason(module, context) {
+		return undefined;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(
+		module,
+		{
+			moduleGraph,
+			runtimeTemplate,
+			runtimeRequirements,
+			runtime,
+			concatenationScope
+		}
+	) {
+		/** @type {JsonValue | undefined} */
+		const data =
+			module.buildInfo &&
+			module.buildInfo.jsonData &&
+			module.buildInfo.jsonData.get();
+		if (data === undefined) {
+			return new RawSource(
+				runtimeTemplate.missingModuleStatement({
+					request: module.rawRequest
+				})
+			);
+		}
+		const exportsInfo = moduleGraph.getExportsInfo(module);
+		/** @type {JsonValue} */
+		const finalJson =
+			typeof data === "object" &&
+			data &&
+			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused
+				? createObjectForExportsInfo(data, exportsInfo, runtime)
+				: data;
+		// Use JSON because JSON.parse() is much faster than JavaScript evaluation
+		const jsonStr = /** @type {string} */ (stringifySafe(finalJson));
+		const jsonExpr =
+			this.options.JSONParse &&
+			jsonStr.length > 20 &&
+			typeof finalJson === "object"
+				? `/*#__PURE__*/JSON.parse('${jsonStr.replace(/[\\']/g, "\\$&")}')`
+				: jsonStr.replace(/"__proto__":/g, '["__proto__"]:');
+		/** @type {string} */
+		let content;
+		if (concatenationScope) {
+			content = `${runtimeTemplate.renderConst()} ${
+				ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+			} = ${jsonExpr};`;
+			concatenationScope.registerNamespaceExport(
+				ConcatenationScope.NAMESPACE_OBJECT_EXPORT
+			);
+		} else {
+			runtimeRequirements.add(RuntimeGlobals.module);
+			content = `${module.moduleArgument}.exports = ${jsonExpr};`;
+		}
+		return new RawSource(content);
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash that will be modified
+	 * @param {UpdateHashContext} updateHashContext context for updating hash
+	 */
+	updateHash(hash, updateHashContext) {
+		if (this.options.JSONParse) {
+			hash.update("json-parse");
+		}
+	}
+}
+
+module.exports = JsonGenerator;
Index: frontend/node_modules/webpack/lib/json/JsonModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/json/JsonModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/json/JsonModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,73 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { JSON_MODULE_TYPE } = require("../ModuleTypeConstants");
+const JsonGenerator = require("./JsonGenerator");
+const JsonParser = require("./JsonParser");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "JsonModulesPlugin";
+
+/**
+ * The JsonModulesPlugin is the entrypoint plugin for the json modules feature.
+ * It adds the json module type to the compiler and registers the json parser and generator.
+ */
+class JsonModulesPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				normalModuleFactory.hooks.createParser
+					.for(JSON_MODULE_TYPE)
+					.tap(PLUGIN_NAME, (parserOptions) => {
+						compiler.validate(
+							() =>
+								require("../../schemas/plugins/json/JsonModulesPluginParser.json"),
+							parserOptions,
+							{
+								name: "Json Modules Plugin",
+								baseDataPath: "parser"
+							},
+							(options) =>
+								require("../../schemas/plugins/json/JsonModulesPluginParser.check")(
+									options
+								)
+						);
+
+						return new JsonParser(parserOptions);
+					});
+				normalModuleFactory.hooks.createGenerator
+					.for(JSON_MODULE_TYPE)
+					.tap(PLUGIN_NAME, (generatorOptions) => {
+						compiler.validate(
+							() =>
+								require("../../schemas/plugins/json/JsonModulesPluginGenerator.json"),
+							generatorOptions,
+							{
+								name: "Json Modules Plugin",
+								baseDataPath: "generator"
+							},
+							(options) =>
+								require("../../schemas/plugins/json/JsonModulesPluginGenerator.check")(
+									options
+								)
+						);
+
+						return new JsonGenerator(generatorOptions);
+					});
+			}
+		);
+	}
+}
+
+module.exports = JsonModulesPlugin;
Index: frontend/node_modules/webpack/lib/json/JsonParser.js
===================================================================
--- frontend/node_modules/webpack/lib/json/JsonParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/json/JsonParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,82 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Parser = require("../Parser");
+const JsonExportsDependency = require("../dependencies/JsonExportsDependency");
+const parseJson = require("../util/parseJson");
+const JsonData = require("./JsonData");
+
+/** @typedef {import("../../declarations/WebpackOptions").JsonParserOptions} JsonParserOptions */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+/** @typedef {import("../util/fs").JsonValue} JsonValue */
+
+/** @typedef {(input: string) => Buffer | JsonValue} ParseFn */
+
+/**
+ * Defines the function returning type used by this module.
+ * @template T
+ * @typedef {import("../util/memoize").FunctionReturning<T>} FunctionReturning
+ */
+
+class JsonParser extends Parser {
+	/**
+	 * Creates an instance of JsonParser.
+	 * @param {JsonParserOptions} options parser options
+	 */
+	constructor(options = {}) {
+		super();
+		/** @type {JsonParserOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (Buffer.isBuffer(source)) {
+			source = source.toString("utf8");
+		}
+
+		const parseFn =
+			typeof this.options.parse === "function" ? this.options.parse : parseJson;
+		/** @type {Buffer | JsonValue | undefined} */
+		const data =
+			typeof source === "object"
+				? source
+				: parseFn(source[0] === "\uFEFF" ? source.slice(1) : source);
+		const jsonData = new JsonData(/** @type {Buffer | JsonValue} */ (data));
+		const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo);
+		buildInfo.jsonData = jsonData;
+		buildInfo.strict = true;
+		const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
+		buildMeta.exportsType = "default";
+		buildMeta.defaultObject =
+			typeof data === "object"
+				? this.options.namedExports === false
+					? false
+					: this.options.namedExports === true
+						? "redirect"
+						: "redirect-warn"
+				: false;
+		state.module.addDependency(
+			new JsonExportsDependency(
+				jsonData,
+				/** @type {number} */
+				(this.options.exportsDepth)
+			)
+		);
+		return state;
+	}
+}
+
+module.exports = JsonParser;
Index: frontend/node_modules/webpack/lib/library/AbstractLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/AbstractLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/AbstractLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,354 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+const COMMON_LIBRARY_NAME_MESSAGE =
+	"Common configuration options that specific library names are 'output.library[.name]', 'entry.xyz.library[.name]', 'ModuleFederationPlugin.name' and 'ModuleFederationPlugin.library[.name]'.";
+
+/**
+ * Defines the library context type used by this module.
+ * @template T
+ * @typedef {object} LibraryContext
+ * @property {Compilation} compilation
+ * @property {ChunkGraph} chunkGraph
+ * @property {T} options
+ */
+
+/**
+ * Defines the abstract library plugin options type used by this module.
+ * @typedef {object} AbstractLibraryPluginOptions
+ * @property {string} pluginName name of the plugin
+ * @property {LibraryType} type used library type
+ */
+
+/**
+ * Represents AbstractLibraryPlugin.
+ * @template T
+ */
+class AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of AbstractLibraryPlugin.
+	 * @param {AbstractLibraryPluginOptions} options options
+	 */
+	constructor({ pluginName, type }) {
+		/** @type {AbstractLibraryPluginOptions["pluginName"]} */
+		this._pluginName = pluginName;
+		/** @type {AbstractLibraryPluginOptions["type"]} */
+		this._type = type;
+		/** @type {WeakMap<LibraryOptions, T>} */
+		this._parseCache = new WeakMap();
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _pluginName } = this;
+		compiler.hooks.thisCompilation.tap(_pluginName, (compilation) => {
+			compilation.hooks.finishModules.tap(
+				{ name: _pluginName, stage: 10 },
+				() => {
+					for (const [
+						name,
+						{
+							dependencies: deps,
+							options: { library }
+						}
+					] of compilation.entries) {
+						const options = this._parseOptionsCached(
+							library !== undefined
+								? library
+								: compilation.outputOptions.library
+						);
+						if (options !== false) {
+							const dep = deps[deps.length - 1];
+							if (dep) {
+								const module = compilation.moduleGraph.getModule(dep);
+								if (module) {
+									this.finishEntryModule(module, name, {
+										options,
+										compilation,
+										chunkGraph: compilation.chunkGraph
+									});
+								}
+							}
+						}
+					}
+				}
+			);
+
+			/**
+			 * Gets options for chunk.
+			 * @param {Chunk} chunk chunk
+			 * @returns {T | false} options for the chunk
+			 */
+			const getOptionsForChunk = (chunk) => {
+				if (compilation.chunkGraph.getNumberOfEntryModules(chunk) === 0) {
+					return false;
+				}
+				const options = chunk.getEntryOptions();
+				const library = options && options.library;
+				return this._parseOptionsCached(
+					library !== undefined ? library : compilation.outputOptions.library
+				);
+			};
+
+			if (
+				this.render !== AbstractLibraryPlugin.prototype.render ||
+				this.runtimeRequirements !==
+					AbstractLibraryPlugin.prototype.runtimeRequirements
+			) {
+				compilation.hooks.additionalChunkRuntimeRequirements.tap(
+					_pluginName,
+					(chunk, set, { chunkGraph }) => {
+						const options = getOptionsForChunk(chunk);
+						if (options !== false) {
+							this.runtimeRequirements(chunk, set, {
+								options,
+								compilation,
+								chunkGraph
+							});
+						}
+					}
+				);
+			}
+
+			const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
+
+			if (this.render !== AbstractLibraryPlugin.prototype.render) {
+				hooks.render.tap(_pluginName, (source, renderContext) => {
+					const options = getOptionsForChunk(renderContext.chunk);
+					if (options === false) return source;
+					return this.render(source, renderContext, {
+						options,
+						compilation,
+						chunkGraph: compilation.chunkGraph
+					});
+				});
+			}
+
+			if (
+				this.embedInRuntimeBailout !==
+				AbstractLibraryPlugin.prototype.embedInRuntimeBailout
+			) {
+				hooks.embedInRuntimeBailout.tap(
+					_pluginName,
+					(module, renderContext) => {
+						const options = getOptionsForChunk(renderContext.chunk);
+						if (options === false) return;
+						return this.embedInRuntimeBailout(module, renderContext, {
+							options,
+							compilation,
+							chunkGraph: compilation.chunkGraph
+						});
+					}
+				);
+			}
+
+			if (
+				this.strictRuntimeBailout !==
+				AbstractLibraryPlugin.prototype.strictRuntimeBailout
+			) {
+				hooks.strictRuntimeBailout.tap(_pluginName, (renderContext) => {
+					const options = getOptionsForChunk(renderContext.chunk);
+					if (options === false) return;
+					return this.strictRuntimeBailout(renderContext, {
+						options,
+						compilation,
+						chunkGraph: compilation.chunkGraph
+					});
+				});
+			}
+
+			if (
+				this.renderModuleContent !==
+				AbstractLibraryPlugin.prototype.renderModuleContent
+			) {
+				hooks.renderModuleContent.tap(
+					_pluginName,
+					(source, module, renderContext) =>
+						this.renderModuleContent(source, module, renderContext, {
+							compilation,
+							chunkGraph: compilation.chunkGraph
+						})
+				);
+			}
+
+			if (
+				this.renderStartup !== AbstractLibraryPlugin.prototype.renderStartup
+			) {
+				hooks.renderStartup.tap(
+					_pluginName,
+					(source, module, renderContext) => {
+						const options = getOptionsForChunk(renderContext.chunk);
+						if (options === false) return source;
+						return this.renderStartup(source, module, renderContext, {
+							options,
+							compilation,
+							chunkGraph: compilation.chunkGraph
+						});
+					}
+				);
+			}
+
+			hooks.chunkHash.tap(_pluginName, (chunk, hash, context) => {
+				const options = getOptionsForChunk(chunk);
+				if (options === false) return;
+				this.chunkHash(chunk, hash, context, {
+					options,
+					compilation,
+					chunkGraph: compilation.chunkGraph
+				});
+			});
+		});
+	}
+
+	/**
+	 * Parse options cached.
+	 * @param {LibraryOptions=} library normalized library option
+	 * @returns {T | false} preprocess as needed by overriding
+	 */
+	_parseOptionsCached(library) {
+		if (!library) return false;
+		if (library.type !== this._type) return false;
+		const cacheEntry = this._parseCache.get(library);
+		if (cacheEntry !== undefined) return cacheEntry;
+		const result = this.parseOptions(library);
+		this._parseCache.set(library, result);
+		return result;
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @abstract
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		const AbstractMethodError = require("../errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/**
+	 * Finish entry module.
+	 * @param {Module} module the exporting entry module
+	 * @param {string} entryName the name of the entrypoint
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	finishEntryModule(module, entryName, libraryContext) {}
+
+	/**
+	 * Embed in runtime bailout.
+	 * @param {Module} module the exporting entry module
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {string | undefined} bailout reason
+	 */
+	embedInRuntimeBailout(module, renderContext, libraryContext) {
+		return undefined;
+	}
+
+	/**
+	 * Strict runtime bailout.
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {string | undefined} bailout reason
+	 */
+	strictRuntimeBailout(renderContext, libraryContext) {
+		return undefined;
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {RuntimeRequirements} set runtime requirements
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	runtimeRequirements(chunk, set, libraryContext) {
+		if (this.render !== AbstractLibraryPlugin.prototype.render) {
+			set.add(RuntimeGlobals.returnExportsFromRuntime);
+		}
+	}
+
+	/**
+	 * Returns source with library export.
+	 * @param {Source} source source
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	render(source, renderContext, libraryContext) {
+		return source;
+	}
+
+	/**
+	 * Renders source with library export.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {StartupRenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	renderStartup(source, module, renderContext, libraryContext) {
+		return source;
+	}
+
+	/**
+	 * Renders module content.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {ModuleRenderContext} renderContext render context
+	 * @param {Omit<LibraryContext<T>, "options">} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	renderModuleContent(source, module, renderContext, libraryContext) {
+		return source;
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Hash} hash hash
+	 * @param {ChunkHashContext} chunkHashContext chunk hash context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	chunkHash(chunk, hash, chunkHashContext, libraryContext) {
+		const options = this._parseOptionsCached(
+			libraryContext.compilation.outputOptions.library
+		);
+		hash.update(this._pluginName);
+		hash.update(JSON.stringify(options));
+	}
+}
+
+AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE = COMMON_LIBRARY_NAME_MESSAGE;
+
+module.exports = AbstractLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/AmdLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/AmdLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/AmdLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,189 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const ExternalModule = require("../ExternalModule");
+const Template = require("../Template");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/** @typedef {import("../util/Hash")} Hash */
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+/**
+ * Defines the amd library plugin options type used by this module.
+ * @typedef {object} AmdLibraryPluginOptions
+ * @property {LibraryType} type
+ * @property {boolean=} requireAsWrapper
+ */
+
+/**
+ * Defines the amd library plugin parsed type used by this module.
+ * @typedef {object} AmdLibraryPluginParsed
+ * @property {string} name
+ * @property {string} amdContainer
+ */
+
+/**
+ * Represents the amd library plugin runtime component.
+ * @typedef {AmdLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<AmdLibraryPluginParsed>}
+ */
+class AmdLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of AmdLibraryPlugin.
+	 * @param {AmdLibraryPluginOptions} options the plugin options
+	 */
+	constructor(options) {
+		super({
+			pluginName: "AmdLibraryPlugin",
+			type: options.type
+		});
+		/** @type {AmdLibraryPluginOptions["requireAsWrapper"]} */
+		this.requireAsWrapper = options.requireAsWrapper;
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		const { name, amdContainer } = library;
+		if (this.requireAsWrapper) {
+			if (name) {
+				throw new Error(
+					`AMD library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+				);
+			}
+		} else if (name && typeof name !== "string") {
+			throw new Error(
+				`AMD library name must be a simple string or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+			);
+		}
+		const _name = /** @type {string} */ (name);
+		const _amdContainer = /** @type {string} */ (amdContainer);
+		return { name: _name, amdContainer: _amdContainer };
+	}
+
+	/**
+	 * Returns source with library export.
+	 * @param {Source} source source
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	render(
+		source,
+		{ chunkGraph, chunk, runtimeTemplate },
+		{ options, compilation }
+	) {
+		const modern = runtimeTemplate.supportsArrowFunction();
+		const modules = chunkGraph
+			.getChunkModules(chunk)
+			.filter(
+				(m) =>
+					m instanceof ExternalModule &&
+					(m.externalType === "amd" || m.externalType === "amd-require")
+			);
+		const externals = /** @type {ExternalModule[]} */ (modules);
+		const externalsDepsArray = JSON.stringify(
+			externals.map((m) =>
+				typeof m.request === "object" && !Array.isArray(m.request)
+					? m.request.amd
+					: m.request
+			)
+		);
+		const externalsArguments = externals
+			.map(
+				(m) =>
+					`__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
+						`${chunkGraph.getModuleId(m)}`
+					)}__`
+			)
+			.join(", ");
+
+		const iife = runtimeTemplate.isIIFE();
+		const fnStart =
+			(modern
+				? `(${externalsArguments}) => {`
+				: `function(${externalsArguments}) {`) +
+			(iife || !chunk.hasRuntime() ? " return " : "\n");
+		const fnEnd = iife ? ";\n}" : "\n}";
+
+		let amdContainerPrefix = "";
+		if (options.amdContainer) {
+			amdContainerPrefix = `${options.amdContainer}.`;
+		}
+
+		if (this.requireAsWrapper) {
+			return new ConcatSource(
+				`${amdContainerPrefix}require(${externalsDepsArray}, ${fnStart}`,
+				source,
+				`${fnEnd});`
+			);
+		} else if (options.name) {
+			const name = compilation.getPath(options.name, {
+				chunk
+			});
+
+			return new ConcatSource(
+				`${amdContainerPrefix}define(${JSON.stringify(
+					name
+				)}, ${externalsDepsArray}, ${fnStart}`,
+				source,
+				`${fnEnd});`
+			);
+		} else if (externalsArguments) {
+			return new ConcatSource(
+				`${amdContainerPrefix}define(${externalsDepsArray}, ${fnStart}`,
+				source,
+				`${fnEnd});`
+			);
+		}
+		return new ConcatSource(
+			`${amdContainerPrefix}define(${fnStart}`,
+			source,
+			`${fnEnd});`
+		);
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Hash} hash hash
+	 * @param {ChunkHashContext} chunkHashContext chunk hash context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	chunkHash(chunk, hash, chunkHashContext, { options, compilation }) {
+		hash.update("AmdLibraryPlugin");
+		if (this.requireAsWrapper) {
+			hash.update("requireAsWrapper");
+		} else if (options.name) {
+			hash.update("named");
+			const name = compilation.getPath(options.name, {
+				chunk
+			});
+			hash.update(name);
+		} else if (options.amdContainer) {
+			hash.update("amdContainer");
+			hash.update(options.amdContainer);
+		}
+	}
+}
+
+module.exports = AmdLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/AssignLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/AssignLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/AssignLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,461 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const { propertyAccess } = require("../util/property");
+const { getEntryRuntime } = require("../util/runtime");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryExport} LibraryExport */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+const KEYWORD_REGEX =
+	/^(?:await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|super|switch|static|this|throw|try|true|typeof|var|void|while|with|yield)$/;
+const IDENTIFIER_REGEX =
+	/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/iu;
+
+/**
+ * Validates the library name by checking for keywords and valid characters
+ * @param {string} name name to be validated
+ * @returns {boolean} true, when valid
+ */
+const isNameValid = (name) =>
+	!KEYWORD_REGEX.test(name) && IDENTIFIER_REGEX.test(name);
+
+/**
+ * Returns code to access the accessor while initializing.
+ * @param {string[]} accessor variable plus properties
+ * @param {number} existingLength items of accessor that are existing already
+ * @param {boolean=} initLast if the last property should also be initialized to an object
+ * @returns {string} code to access the accessor while initializing
+ */
+const accessWithInit = (accessor, existingLength, initLast = false) => {
+	// This generates for [a, b, c, d]:
+	// (((a = typeof a === "undefined" ? {} : a).b = a.b || {}).c = a.b.c || {}).d
+	const base = accessor[0];
+	if (accessor.length === 1 && !initLast) return base;
+	let current =
+		existingLength > 0
+			? base
+			: `(${base} = typeof ${base} === "undefined" ? {} : ${base})`;
+
+	// i is the current position in accessor that has been printed
+	let i = 1;
+
+	// all properties printed so far (excluding base)
+	/** @type {string[] | undefined} */
+	let propsSoFar;
+
+	// if there is existingLength, print all properties until this position as property access
+	if (existingLength > i) {
+		propsSoFar = accessor.slice(1, existingLength);
+		i = existingLength;
+		current += propertyAccess(propsSoFar);
+	} else {
+		propsSoFar = [];
+	}
+
+	// all remaining properties (except the last one when initLast is not set)
+	// should be printed as initializer
+	const initUntil = initLast ? accessor.length : accessor.length - 1;
+	for (; i < initUntil; i++) {
+		const prop = accessor[i];
+		propsSoFar.push(prop);
+		current = `(${current}${propertyAccess([prop])} = ${base}${propertyAccess(
+			propsSoFar
+		)} || {})`;
+	}
+
+	// print the last property as property access if not yet printed
+	if (i < accessor.length) {
+		current = `${current}${propertyAccess([accessor[accessor.length - 1]])}`;
+	}
+
+	return current;
+};
+
+/** @typedef {string[] | "global"} LibraryPrefix */
+
+/**
+ * Defines the assign library plugin options type used by this module.
+ * @typedef {object} AssignLibraryPluginOptions
+ * @property {LibraryType} type
+ * @property {LibraryPrefix} prefix name prefix
+ * @property {string | false} declare declare name as variable
+ * @property {"error" | "static" | "copy" | "assign"} unnamed behavior for unnamed library name
+ * @property {"copy" | "assign"=} named behavior for named library name
+ */
+
+/** @typedef {string | string[]} LibraryName */
+
+/**
+ * Defines the assign library plugin parsed type used by this module.
+ * @typedef {object} AssignLibraryPluginParsed
+ * @property {LibraryName} name
+ * @property {LibraryExport=} export
+ */
+
+/**
+ * Represents the assign library plugin runtime component.
+ * @typedef {AssignLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<AssignLibraryPluginParsed>}
+ */
+class AssignLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of AssignLibraryPlugin.
+	 * @param {AssignLibraryPluginOptions} options the plugin options
+	 */
+	constructor(options) {
+		super({
+			pluginName: "AssignLibraryPlugin",
+			type: options.type
+		});
+		/** @type {AssignLibraryPluginOptions["prefix"]} */
+		this.prefix = options.prefix;
+		/** @type {AssignLibraryPluginOptions["declare"]} */
+		this.declare = options.declare;
+		/** @type {AssignLibraryPluginOptions["unnamed"]} */
+		this.unnamed = options.unnamed;
+		/** @type {AssignLibraryPluginOptions["named"]} */
+		this.named = options.named || "assign";
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		const { name } = library;
+		if (this.unnamed === "error") {
+			if (typeof name !== "string" && !Array.isArray(name)) {
+				throw new Error(
+					`Library name must be a string or string array. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+				);
+			}
+		} else if (name && typeof name !== "string" && !Array.isArray(name)) {
+			throw new Error(
+				`Library name must be a string, string array or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+			);
+		}
+		const _name = /** @type {LibraryName} */ (name);
+		return {
+			name: _name,
+			export: library.export
+		};
+	}
+
+	/**
+	 * Finish entry module.
+	 * @param {Module} module the exporting entry module
+	 * @param {string} entryName the name of the entrypoint
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	finishEntryModule(
+		module,
+		entryName,
+		{ options, compilation, compilation: { moduleGraph } }
+	) {
+		const runtime = getEntryRuntime(compilation, entryName);
+		if (options.export) {
+			const exportsInfo = moduleGraph.getExportInfo(
+				module,
+				Array.isArray(options.export) ? options.export[0] : options.export
+			);
+			exportsInfo.setUsed(UsageState.Used, runtime);
+			exportsInfo.canMangleUse = false;
+		} else {
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+			exportsInfo.setUsedInUnknownWay(runtime);
+		}
+		moduleGraph.addExtraReason(module, "used as library export");
+	}
+
+	/**
+	 * Returns the prefix.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {LibraryPrefix} the prefix
+	 */
+	_getPrefix(compilation) {
+		return this.prefix === "global"
+			? [compilation.runtimeTemplate.globalObject]
+			: this.prefix;
+	}
+
+	/**
+	 * Get resolved full name.
+	 * @param {AssignLibraryPluginParsed} options the library options
+	 * @param {Chunk} chunk the chunk
+	 * @param {Compilation} compilation the compilation
+	 * @returns {string[]} the resolved full name
+	 */
+	_getResolvedFullName(options, chunk, compilation) {
+		const prefix = this._getPrefix(compilation);
+		const fullName = options.name
+			? [
+					...prefix,
+					...(Array.isArray(options.name) ? options.name : [options.name])
+				]
+			: /** @type {string[]} */ (prefix);
+		return fullName.map((n) =>
+			compilation.getPath(n, {
+				chunk
+			})
+		);
+	}
+
+	/**
+	 * Returns source with library export.
+	 * @param {Source} source source
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	render(source, { chunk }, { options, compilation }) {
+		const fullNameResolved = this._getResolvedFullName(
+			options,
+			chunk,
+			compilation
+		);
+		if (this.declare) {
+			const base = fullNameResolved[0];
+			if (!isNameValid(base)) {
+				throw new Error(
+					`Library name base (${base}) must be a valid identifier when using a var declaring library type. Either use a valid identifier (e. g. ${Template.toIdentifier(
+						base
+					)}) or use a different library type (e. g. 'type: "global"', which assign a property on the global scope instead of declaring a variable). ${
+						AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE
+					}`
+				);
+			}
+			source = new ConcatSource(`${this.declare} ${base};\n`, source);
+		}
+		return source;
+	}
+
+	/**
+	 * Embed in runtime bailout.
+	 * @param {Module} module the exporting entry module
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {string | undefined} bailout reason
+	 */
+	embedInRuntimeBailout(
+		module,
+		{ chunk, codeGenerationResults },
+		{ options, compilation }
+	) {
+		const { data } = codeGenerationResults.get(module, chunk.runtime);
+		const topLevelDeclarations =
+			(data && data.get("topLevelDeclarations")) ||
+			(module.buildInfo && module.buildInfo.topLevelDeclarations);
+		if (!topLevelDeclarations) {
+			return "it doesn't tell about top level declarations.";
+		}
+		const fullNameResolved = this._getResolvedFullName(
+			options,
+			chunk,
+			compilation
+		);
+		const base = fullNameResolved[0];
+		if (topLevelDeclarations.has(base)) {
+			return `it declares '${base}' on top-level, which conflicts with the current library output.`;
+		}
+	}
+
+	/**
+	 * Strict runtime bailout.
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {string | undefined} bailout reason
+	 */
+	strictRuntimeBailout({ chunk }, { options, compilation }) {
+		if (
+			this.declare ||
+			this.prefix === "global" ||
+			this.prefix.length > 0 ||
+			!options.name
+		) {
+			return;
+		}
+		return "a global variable is assign and maybe created";
+	}
+
+	/**
+	 * Renders source with library export.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {StartupRenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	renderStartup(
+		source,
+		module,
+		{ moduleGraph, chunk },
+		{ options, compilation }
+	) {
+		const fullNameResolved = this._getResolvedFullName(
+			options,
+			chunk,
+			compilation
+		);
+		const staticExports = this.unnamed === "static";
+		const exportAccess = options.export
+			? propertyAccess(
+					Array.isArray(options.export) ? options.export : [options.export]
+				)
+			: "";
+		const result = new ConcatSource(source);
+		if (staticExports) {
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+			const exportTarget = accessWithInit(
+				fullNameResolved,
+				this._getPrefix(compilation).length,
+				true
+			);
+
+			/** @type {ExportInfoName[]} */
+			const provided = [];
+			for (const exportInfo of exportsInfo.orderedExports) {
+				if (!exportInfo.provided) continue;
+				const nameAccess = propertyAccess([exportInfo.name]);
+				result.add(
+					`${exportTarget}${nameAccess} = ${RuntimeGlobals.exports}${exportAccess}${nameAccess};\n`
+				);
+				provided.push(exportInfo.name);
+			}
+
+			const webpackExportTarget = accessWithInit(
+				fullNameResolved,
+				this._getPrefix(compilation).length,
+				true
+			);
+			/** @type {string} */
+			let exports = RuntimeGlobals.exports;
+			if (exportAccess) {
+				result.add(
+					`var __webpack_exports_export__ = ${RuntimeGlobals.exports}${exportAccess};\n`
+				);
+
+				exports = "__webpack_exports_export__";
+			}
+			result.add(`for(var __webpack_i__ in ${exports}) {\n`);
+			const hasProvided = provided.length > 0;
+			if (hasProvided) {
+				result.add(
+					`  if (${JSON.stringify(provided)}.indexOf(__webpack_i__) === -1) {\n`
+				);
+			}
+			result.add(
+				`  ${
+					hasProvided ? "  " : ""
+				}${webpackExportTarget}[__webpack_i__] = ${exports}[__webpack_i__];\n`
+			);
+			if (hasProvided) {
+				result.add("  }\n");
+			}
+			result.add("}\n");
+			result.add(
+				`Object.defineProperty(${exportTarget}, "__esModule", { value: true });\n`
+			);
+		} else if (options.name ? this.named === "copy" : this.unnamed === "copy") {
+			result.add(
+				`var __webpack_export_target__ = ${accessWithInit(
+					fullNameResolved,
+					this._getPrefix(compilation).length,
+					true
+				)};\n`
+			);
+			/** @type {string} */
+			let exports = RuntimeGlobals.exports;
+			if (exportAccess) {
+				result.add(
+					`var __webpack_exports_export__ = ${RuntimeGlobals.exports}${exportAccess};\n`
+				);
+
+				exports = "__webpack_exports_export__";
+			}
+			result.add(
+				`for(var __webpack_i__ in ${exports}) __webpack_export_target__[__webpack_i__] = ${exports}[__webpack_i__];\n`
+			);
+			result.add(
+				`if(${exports}.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });\n`
+			);
+		} else {
+			result.add(
+				`${accessWithInit(
+					fullNameResolved,
+					this._getPrefix(compilation).length,
+					false
+				)} = ${RuntimeGlobals.exports}${exportAccess};\n`
+			);
+		}
+		return result;
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {RuntimeRequirements} set runtime requirements
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	runtimeRequirements(chunk, set, libraryContext) {
+		set.add(RuntimeGlobals.exports);
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Hash} hash hash
+	 * @param {ChunkHashContext} chunkHashContext chunk hash context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	chunkHash(chunk, hash, chunkHashContext, { options, compilation }) {
+		hash.update("AssignLibraryPlugin");
+		const fullNameResolved = this._getResolvedFullName(
+			options,
+			chunk,
+			compilation
+		);
+		if (options.name ? this.named === "copy" : this.unnamed === "copy") {
+			hash.update("copy");
+		}
+		if (this.declare) {
+			hash.update(this.declare);
+		}
+		hash.update(fullNameResolved.join("."));
+		if (options.export) {
+			hash.update(`${options.export}`);
+		}
+	}
+}
+
+module.exports = AssignLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/EnableLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/EnableLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/EnableLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,312 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../Compiler")} Compiler */
+
+/** @typedef {Set<LibraryType>} LibraryTypes */
+
+/** @type {WeakMap<Compiler, LibraryTypes>} */
+const enabledTypes = new WeakMap();
+
+/**
+ * Defines the enable library plugin options type used by this module.
+ * @typedef {object} EnableLibraryPluginOptions
+ * @property {() => void=} additionalApply function that runs when applying the current plugin.
+ */
+
+/**
+ * Returns enabled types.
+ * @param {Compiler} compiler the compiler instance
+ * @returns {LibraryTypes} enabled types
+ */
+const getEnabledTypes = (compiler) => {
+	let set = enabledTypes.get(compiler);
+	if (set === undefined) {
+		/** @type {LibraryTypes} */
+		set = new Set();
+		enabledTypes.set(compiler, set);
+	}
+	return set;
+};
+
+class EnableLibraryPlugin {
+	/**
+	 * Creates an instance of EnableLibraryPlugin.
+	 * @param {LibraryType} type library type that should be available
+	 * @param {EnableLibraryPluginOptions} options options of EnableLibraryPlugin
+	 */
+	constructor(type, options = {}) {
+		/** @type {LibraryType} */
+		this.type = type;
+		/** @type {EnableLibraryPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Updates enabled using the provided compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @param {LibraryType} type type of library
+	 * @returns {void}
+	 */
+	static setEnabled(compiler, type) {
+		getEnabledTypes(compiler).add(type);
+	}
+
+	/**
+	 * Checks enabled.
+	 * @param {Compiler} compiler the compiler instance
+	 * @param {LibraryType} type type of library
+	 * @returns {void}
+	 */
+	static checkEnabled(compiler, type) {
+		if (!getEnabledTypes(compiler).has(type)) {
+			throw new Error(
+				`Library type "${type}" is not enabled. ` +
+					"EnableLibraryPlugin need to be used to enable this type of library. " +
+					'This usually happens through the "output.enabledLibraryTypes" option. ' +
+					'If you are using a function as entry which sets "library", you need to add all potential library types to "output.enabledLibraryTypes". ' +
+					`These types are enabled: ${[...getEnabledTypes(compiler)].join(", ")}`
+			);
+		}
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { type, options } = this;
+
+		// Only enable once
+		const enabled = getEnabledTypes(compiler);
+		if (enabled.has(type)) return;
+		enabled.add(type);
+
+		if (typeof options.additionalApply === "function") {
+			options.additionalApply();
+		}
+
+		if (typeof type === "string") {
+			const enableExportProperty = () => {
+				const ExportPropertyLibraryPlugin = require("./ExportPropertyLibraryPlugin");
+
+				new ExportPropertyLibraryPlugin({
+					type
+				}).apply(compiler);
+			};
+			switch (type) {
+				case "var": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: [],
+						declare: "var",
+						unnamed: "error"
+					}).apply(compiler);
+					break;
+				}
+				case "assign-properties": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: [],
+						declare: false,
+						unnamed: "error",
+						named: "copy"
+					}).apply(compiler);
+					break;
+				}
+				case "assign": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: [],
+						declare: false,
+						unnamed: "error"
+					}).apply(compiler);
+					break;
+				}
+				case "this": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: ["this"],
+						declare: false,
+						unnamed: "copy"
+					}).apply(compiler);
+					break;
+				}
+				case "window": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: ["window"],
+						declare: false,
+						unnamed: "copy"
+					}).apply(compiler);
+					break;
+				}
+				case "self": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: ["self"],
+						declare: false,
+						unnamed: "copy"
+					}).apply(compiler);
+					break;
+				}
+				case "global": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: "global",
+						declare: false,
+						unnamed: "copy"
+					}).apply(compiler);
+					break;
+				}
+				case "commonjs": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: ["exports"],
+						declare: false,
+						unnamed: "copy"
+					}).apply(compiler);
+					break;
+				}
+				case "commonjs-static": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: ["exports"],
+						declare: false,
+						unnamed: "static"
+					}).apply(compiler);
+					break;
+				}
+				case "commonjs2":
+				case "commonjs-module": {
+					// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
+					const AssignLibraryPlugin = require("./AssignLibraryPlugin");
+
+					new AssignLibraryPlugin({
+						type,
+						prefix: ["module", "exports"],
+						declare: false,
+						unnamed: "assign"
+					}).apply(compiler);
+					break;
+				}
+				case "amd":
+				case "amd-require": {
+					enableExportProperty();
+
+					const AmdLibraryPlugin = require("./AmdLibraryPlugin");
+
+					new AmdLibraryPlugin({
+						type,
+						requireAsWrapper: type === "amd-require"
+					}).apply(compiler);
+					break;
+				}
+				case "umd":
+				case "umd2": {
+					if (compiler.options.output.iife === false) {
+						compiler.options.output.iife = true;
+
+						class WarnFalseIifeUmdPlugin {
+							/**
+							 * Applies the plugin by registering its hooks on the compiler.
+							 * @param {Compiler} compiler the compiler instance
+							 */
+							apply(compiler) {
+								compiler.hooks.thisCompilation.tap(
+									"WarnFalseIifeUmdPlugin",
+									(compilation) => {
+										const FalseIIFEUmdWarning = require("./FalseIIFEUmdWarning");
+
+										compilation.warnings.push(new FalseIIFEUmdWarning());
+									}
+								);
+							}
+						}
+
+						new WarnFalseIifeUmdPlugin().apply(compiler);
+					}
+					enableExportProperty();
+
+					const UmdLibraryPlugin = require("./UmdLibraryPlugin");
+
+					new UmdLibraryPlugin({
+						type,
+						optionalAmdExternalAsGlobal: type === "umd2"
+					}).apply(compiler);
+					break;
+				}
+				case "system": {
+					enableExportProperty();
+
+					const SystemLibraryPlugin = require("./SystemLibraryPlugin");
+
+					new SystemLibraryPlugin({
+						type
+					}).apply(compiler);
+					break;
+				}
+				case "jsonp": {
+					enableExportProperty();
+
+					const JsonpLibraryPlugin = require("./JsonpLibraryPlugin");
+
+					new JsonpLibraryPlugin({
+						type
+					}).apply(compiler);
+					break;
+				}
+				case "module":
+				case "modern-module": {
+					const ModuleLibraryPlugin = require("./ModuleLibraryPlugin");
+
+					new ModuleLibraryPlugin({
+						type
+					}).apply(compiler);
+					break;
+				}
+				default:
+					throw new Error(`Unsupported library type ${type}.
+Plugins which provide custom library types must call EnableLibraryPlugin.setEnabled(compiler, type) to disable this error.`);
+			}
+		} else {
+			// TODO support plugin instances here
+			// apply them to the compiler
+		}
+	}
+}
+
+module.exports = EnableLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/ExportPropertyLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/ExportPropertyLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/ExportPropertyLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,125 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const { propertyAccess } = require("../util/property");
+const { getEntryRuntime } = require("../util/runtime");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryExport} LibraryExport */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+/**
+ * Defines the export property library plugin parsed type used by this module.
+ * @typedef {object} ExportPropertyLibraryPluginParsed
+ * @property {LibraryExport=} export
+ */
+
+/**
+ * Defines the export property library plugin options type used by this module.
+ * @typedef {object} ExportPropertyLibraryPluginOptions
+ * @property {LibraryType} type
+ */
+/**
+ * Represents the export property library plugin runtime component.
+ * @typedef {ExportPropertyLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<ExportPropertyLibraryPluginParsed>}
+ */
+class ExportPropertyLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of ExportPropertyLibraryPlugin.
+	 * @param {ExportPropertyLibraryPluginOptions} options options
+	 */
+	constructor({ type }) {
+		super({
+			pluginName: "ExportPropertyLibraryPlugin",
+			type
+		});
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		return {
+			export: library.export
+		};
+	}
+
+	/**
+	 * Finish entry module.
+	 * @param {Module} module the exporting entry module
+	 * @param {string} entryName the name of the entrypoint
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	finishEntryModule(
+		module,
+		entryName,
+		{ options, compilation, compilation: { moduleGraph } }
+	) {
+		const runtime = getEntryRuntime(compilation, entryName);
+		if (options.export) {
+			const exportsInfo = moduleGraph.getExportInfo(
+				module,
+				Array.isArray(options.export) ? options.export[0] : options.export
+			);
+			exportsInfo.setUsed(UsageState.Used, runtime);
+			exportsInfo.canMangleUse = false;
+		} else {
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+			exportsInfo.setUsedInUnknownWay(runtime);
+		}
+		moduleGraph.addExtraReason(module, "used as library export");
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {RuntimeRequirements} set runtime requirements
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	runtimeRequirements(chunk, set, libraryContext) {
+		set.add(RuntimeGlobals.exports);
+	}
+
+	/**
+	 * Renders source with library export.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {StartupRenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	renderStartup(source, module, renderContext, { options }) {
+		if (!options.export) return source;
+		const postfix = `${RuntimeGlobals.exports} = ${
+			RuntimeGlobals.exports
+		}${propertyAccess(
+			Array.isArray(options.export) ? options.export : [options.export]
+		)};\n`;
+		return new ConcatSource(source, postfix);
+	}
+}
+
+module.exports = ExportPropertyLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/FalseIIFEUmdWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/library/FalseIIFEUmdWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/FalseIIFEUmdWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Arka Pratim Chaudhuri @arkapratimc
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+
+class FalseIIFEUmdWarning extends WebpackError {
+	constructor() {
+		super();
+		/** @type {string} */
+		this.name = "FalseIIFEUmdWarning";
+		this.message =
+			"Configuration:\nSetting 'output.iife' to 'false' is incompatible with 'output.library.type' set to 'umd'. This configuration may cause unexpected behavior, as UMD libraries are expected to use an IIFE (Immediately Invoked Function Expression) to support various module formats. Consider setting 'output.iife' to 'true' or choosing a different 'library.type' to ensure compatibility.\nLearn more: https://webpack.js.org/configuration/output/";
+	}
+}
+
+module.exports = FalseIIFEUmdWarning;
Index: frontend/node_modules/webpack/lib/library/JsonpLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/JsonpLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/JsonpLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/** @typedef {import("../util/Hash")} Hash */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+/**
+ * Defines the jsonp library plugin options type used by this module.
+ * @typedef {object} JsonpLibraryPluginOptions
+ * @property {LibraryType} type
+ */
+
+/**
+ * Defines the jsonp library plugin parsed type used by this module.
+ * @typedef {object} JsonpLibraryPluginParsed
+ * @property {string} name
+ */
+
+/**
+ * Represents the jsonp library plugin runtime component.
+ * @typedef {JsonpLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<JsonpLibraryPluginParsed>}
+ */
+class JsonpLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of JsonpLibraryPlugin.
+	 * @param {JsonpLibraryPluginOptions} options the plugin options
+	 */
+	constructor(options) {
+		super({
+			pluginName: "JsonpLibraryPlugin",
+			type: options.type
+		});
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		const { name } = library;
+		if (typeof name !== "string") {
+			throw new Error(
+				`Jsonp library name must be a simple string. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+			);
+		}
+		const _name = /** @type {string} */ (name);
+		return {
+			name: _name
+		};
+	}
+
+	/**
+	 * Returns source with library export.
+	 * @param {Source} source source
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	render(source, { chunk }, { options, compilation }) {
+		const name = compilation.getPath(options.name, {
+			chunk
+		});
+		return new ConcatSource(`${name}(`, source, ")");
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Hash} hash hash
+	 * @param {ChunkHashContext} chunkHashContext chunk hash context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	chunkHash(chunk, hash, chunkHashContext, { options, compilation }) {
+		hash.update("JsonpLibraryPlugin");
+		hash.update(compilation.getPath(options.name, { chunk }));
+	}
+}
+
+module.exports = JsonpLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/ModuleLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/ModuleLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/ModuleLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,545 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const ExternalModule = require("../ExternalModule");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
+const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
+const ConcatenatedModule = require("../optimize/ConcatenatedModule");
+const { propertyAccess } = require("../util/property");
+const { getEntryRuntime, getRuntimeKey } = require("../util/runtime");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryExport} LibraryExport */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+/**
+ * Defines the module library plugin options type used by this module.
+ * @typedef {object} ModuleLibraryPluginOptions
+ * @property {LibraryType} type
+ */
+
+/**
+ * Defines the module library plugin parsed type used by this module.
+ * @typedef {object} ModuleLibraryPluginParsed
+ * @property {string} name
+ * @property {LibraryExport=} export
+ */
+
+const PLUGIN_NAME = "ModuleLibraryPlugin";
+
+/**
+ * Represents the module library plugin runtime component.
+ * @typedef {ModuleLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<ModuleLibraryPluginParsed>}
+ */
+class ModuleLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of ModuleLibraryPlugin.
+	 * @param {ModuleLibraryPluginOptions} options the plugin options
+	 */
+	constructor(options) {
+		super({
+			pluginName: "ModuleLibraryPlugin",
+			type: options.type
+		});
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		super.apply(compiler);
+
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const { onDemandExportsGeneration } =
+				ConcatenatedModule.getCompilationHooks(compilation);
+			const javascriptHooks =
+				JavascriptModulesPlugin.getCompilationHooks(compilation);
+			onDemandExportsGeneration.tap(
+				PLUGIN_NAME,
+				(module, runtimes, source, finalName) => {
+					/** @type {BuildMeta} */
+					const buildMeta = module.buildMeta || (module.buildMeta = {});
+
+					/** @type {BuildMeta["exportsSourceByRuntime"]} */
+					const exportsSourceByRuntime =
+						buildMeta.exportsSourceByRuntime ||
+						(buildMeta.exportsSourceByRuntime = new Map());
+
+					/** @type {BuildMeta["exportsFinalNameByRuntime"]} */
+					const exportsFinalNameByRuntime =
+						buildMeta.exportsFinalNameByRuntime ||
+						(buildMeta.exportsFinalNameByRuntime = new Map());
+
+					for (const runtime of runtimes) {
+						const key = getRuntimeKey(runtime);
+						exportsSourceByRuntime.set(key, source);
+						exportsFinalNameByRuntime.set(key, finalName);
+					}
+
+					return true;
+				}
+			);
+
+			// `ModuleLibraryPlugin` stashes the on-demand exports source via
+			// `onDemandExportsGeneration` and only re-emits it when the
+			// module is wrapped in an IIFE/factory. When a single concatenated
+			// entry is inlined directly, the stashed source — and the
+			// `definePropertyGetters` / `requireScope` runtime helpers it
+			// pulled in — never make it into the output. Drop those helpers
+			// from the chunk's set in that simple shape so the bundle stays
+			// clean.
+			compilation.hooks.additionalChunkRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph, codeGenerationResults }) => {
+					if (!set.has(RuntimeGlobals.definePropertyGetters)) return;
+
+					// Only handle the simple "single concatenated entry"
+					// shape. Anything else (additional modules, multiple
+					// entries, sibling runtime chunks, or chunk-level
+					// requirements that disable inline startup) forces the
+					// module through factory/IIFE rendering, which re-emits
+					// the source.
+					if (chunkGraph.getNumberOfChunkModules(chunk) !== 1) return;
+					if (chunkGraph.getNumberOfEntryModules(chunk) !== 1) return;
+					if (chunkGraph.hasChunkEntryDependentChunks(chunk)) return;
+					if (
+						set.has(RuntimeGlobals.moduleFactories) ||
+						set.has(RuntimeGlobals.moduleCache) ||
+						set.has(RuntimeGlobals.interceptModuleExecution) ||
+						set.has(RuntimeGlobals.module) ||
+						set.has(RuntimeGlobals.thisAsExports)
+					) {
+						return;
+					}
+					// Anyone tapping `inlineInRuntimeBailout` may force factory
+					// rendering at render time, so conservatively bail out.
+					if (javascriptHooks.inlineInRuntimeBailout.isUsed()) return;
+
+					const [module] = chunkGraph.getChunkEntryModulesIterable(chunk);
+					const exportsSourceByRuntime =
+						module.buildMeta && module.buildMeta.exportsSourceByRuntime;
+					if (
+						!exportsSourceByRuntime ||
+						!exportsSourceByRuntime.has(getRuntimeKey(chunk.runtime))
+					) {
+						return;
+					}
+					// If the generated source references any
+					// `__webpack_require__.<helper>` (the on-demand `.d(...)`
+					// is stashed, but `.r(__webpack_exports__)` from the ESM
+					// compat flag, namespace objects, deferred externals, ...
+					// stay in the result) the helpers and the require scope
+					// they live in are still needed. The dot in the substring
+					// avoids matching the bare `"__webpack_require__"` string
+					// literals that some test fixtures include.
+					const codeGenResult = codeGenerationResults.get(
+						module,
+						chunk.runtime
+					);
+					const jsSource =
+						codeGenResult && codeGenResult.sources.get("javascript");
+					if (
+						jsSource &&
+						String(jsSource.source()).includes(`${RuntimeGlobals.require}.`)
+					) {
+						return;
+					}
+
+					set.delete(RuntimeGlobals.definePropertyGetters);
+					set.delete(RuntimeGlobals.exports);
+					set.delete(RuntimeGlobals.requireScope);
+				}
+			);
+		});
+	}
+
+	/**
+	 * Finish entry module.
+	 * @param {Module} module the exporting entry module
+	 * @param {string} entryName the name of the entrypoint
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	finishEntryModule(
+		module,
+		entryName,
+		{ options, compilation, compilation: { moduleGraph } }
+	) {
+		const runtime = getEntryRuntime(compilation, entryName);
+		if (options.export) {
+			const exportsInfo = moduleGraph.getExportInfo(
+				module,
+				Array.isArray(options.export) ? options.export[0] : options.export
+			);
+			exportsInfo.setUsed(UsageState.Used, runtime);
+			exportsInfo.canMangleUse = false;
+		} else {
+			const exportsInfo = moduleGraph.getExportsInfo(module);
+
+			if (
+				// If the entry module is commonjs, its exports cannot be mangled
+				(module.buildMeta && module.buildMeta.treatAsCommonJs) ||
+				// The entry module provides unknown exports
+				exportsInfo._otherExportsInfo.provided === null
+			) {
+				exportsInfo.setUsedInUnknownWay(runtime);
+			} else {
+				exportsInfo.setAllKnownExportsUsed(runtime);
+			}
+		}
+		moduleGraph.addExtraReason(module, "used as library export");
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		const { name } = library;
+		if (name) {
+			throw new Error(
+				`Library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+			);
+		}
+		const _name = /** @type {string} */ (name);
+		return {
+			name: _name,
+			export: library.export
+		};
+	}
+
+	/**
+	 * Analyze unknown provided exports.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {ModuleGraph} moduleGraph moduleGraph
+	 * @param {RuntimeSpec} runtime chunk runtime
+	 * @param {[string, string][]} exports exports
+	 * @param {Set<string>} alreadyRenderedExports already rendered exports
+	 * @returns {ConcatSource} source with null provided exports
+	 */
+	_analyzeUnknownProvidedExports(
+		source,
+		module,
+		moduleGraph,
+		runtime,
+		exports,
+		alreadyRenderedExports
+	) {
+		const result = new ConcatSource(source);
+		/** @type {Set<string>} */
+		const moduleRequests = new Set();
+		/** @type {Map<string, string>} */
+		const unknownProvidedExports = new Map();
+
+		/**
+		 * Resolves dynamic star reexport.
+		 * @param {Module} module the module
+		 * @param {boolean} isDynamicReexport if module is dynamic reexported
+		 */
+		const resolveDynamicStarReexport = (module, isDynamicReexport) => {
+			for (const connection of moduleGraph.getOutgoingConnections(module)) {
+				const dep = connection.dependency;
+
+				// Only handle star-reexport statement
+				if (
+					dep instanceof HarmonyExportImportedSpecifierDependency &&
+					dep.name === null
+				) {
+					const importedModule = connection.resolvedModule;
+					const importedModuleExportsInfo =
+						moduleGraph.getExportsInfo(importedModule);
+
+					// The imported module provides unknown exports
+					// So keep the reexports rendered in the bundle
+					if (
+						dep.getMode(moduleGraph, runtime).type === "dynamic-reexport" &&
+						importedModuleExportsInfo._otherExportsInfo.provided === null
+					) {
+						// Handle export * from 'external'
+						if (importedModule instanceof ExternalModule) {
+							moduleRequests.add(importedModule.userRequest);
+						} else {
+							resolveDynamicStarReexport(importedModule, true);
+						}
+					}
+					// If importer modules existing `dynamic-reexport` dependency
+					// We should keep export statement rendered in the bundle
+					else if (isDynamicReexport) {
+						for (const exportInfo of importedModuleExportsInfo.orderedExports) {
+							if (!exportInfo.provided || exportInfo.name === "default") {
+								continue;
+							}
+							const originalName = exportInfo.name;
+							const usedName = exportInfo.getUsedName(originalName, runtime);
+
+							if (!alreadyRenderedExports.has(originalName) && usedName) {
+								unknownProvidedExports.set(originalName, usedName);
+							}
+						}
+					}
+				}
+			}
+		};
+
+		resolveDynamicStarReexport(module, false);
+
+		for (const request of moduleRequests) {
+			result.add(`export * from "${request}";\n`);
+		}
+
+		for (const [origin, used] of unknownProvidedExports) {
+			exports.push([
+				origin,
+				`${RuntimeGlobals.exports}${propertyAccess([used])}`
+			]);
+		}
+
+		return result;
+	}
+
+	/**
+	 * Renders source with library export.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {StartupRenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	renderStartup(source, module, renderContext, { options, compilation }) {
+		const {
+			moduleGraph,
+			chunk,
+			codeGenerationResults,
+			inlined,
+			inlinedInIIFE,
+			runtimeTemplate
+		} = renderContext;
+		let result = new ConcatSource(source);
+		const exportInfos = options.export
+			? [
+					moduleGraph.getExportInfo(
+						module,
+						Array.isArray(options.export) ? options.export[0] : options.export
+					)
+				]
+			: moduleGraph.getExportsInfo(module).orderedExports;
+
+		const exportsFinalNameByRuntime =
+			(module.buildMeta &&
+				module.buildMeta.exportsFinalNameByRuntime &&
+				module.buildMeta.exportsFinalNameByRuntime.get(
+					getRuntimeKey(chunk.runtime)
+				)) ||
+			{};
+
+		const isInlinedEntryWithoutIIFE = inlined && !inlinedInIIFE;
+		// Direct export bindings from on-demand concatenation
+		const definitions = isInlinedEntryWithoutIIFE
+			? exportsFinalNameByRuntime
+			: {};
+
+		/** @type {string[]} */
+		const shortHandedExports = [];
+		/** @type {[string, string][]} */
+		const exports = [];
+		/** @type {Set<string>} */
+		const alreadyRenderedExports = new Set();
+
+		const isAsync = moduleGraph.isAsync(module);
+
+		const treatAsCommonJs =
+			module.buildMeta && module.buildMeta.treatAsCommonJs;
+		const skipRenderDefaultExport = Boolean(treatAsCommonJs);
+
+		const moduleExportsInfo = moduleGraph.getExportsInfo(module);
+
+		// Define ESM compatibility flag will rely on `__webpack_exports__`
+		const needHarmonyCompatibilityFlag =
+			moduleExportsInfo.otherExportsInfo.getUsed(chunk.runtime) !==
+				UsageState.Unused ||
+			moduleExportsInfo
+				.getReadOnlyExportInfo("__esModule")
+				.getUsed(chunk.runtime) !== UsageState.Unused;
+
+		let needExportsDeclaration =
+			!isInlinedEntryWithoutIIFE || isAsync || needHarmonyCompatibilityFlag;
+
+		if (isAsync) {
+			result.add(
+				`${RuntimeGlobals.exports} = await ${RuntimeGlobals.exports};\n`
+			);
+		}
+
+		// Try to find all known exports of the entry module
+		outer: for (const exportInfo of exportInfos) {
+			if (!exportInfo.provided) continue;
+
+			const originalName = exportInfo.name;
+			// Skip rendering the default export in some cases
+			if (skipRenderDefaultExport && originalName === "default") continue;
+
+			// Try to find all exports from the reexported modules
+			const target = exportInfo.findTarget(moduleGraph, (_m) => true);
+			if (target) {
+				const reexportsInfo = moduleGraph.getExportsInfo(target.module);
+				for (const reexportInfo of reexportsInfo.orderedExports) {
+					if (
+						reexportInfo.provided === false &&
+						reexportInfo.name !== "default" &&
+						reexportInfo.name === /** @type {string[]} */ (target.export)[0]
+					) {
+						continue outer;
+					}
+				}
+			}
+
+			const usedName =
+				/** @type {string} */
+				(exportInfo.getUsedName(originalName, chunk.runtime));
+			/** @type {string | undefined} */
+			const definition = definitions[usedName];
+			/** @type {string | undefined} */
+			let finalName;
+
+			if (definition) {
+				finalName = definition;
+			} else {
+				// Fallback to `__webpack_exports__` property access
+				// when no direct export binding was found
+				finalName = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
+				needExportsDeclaration = true;
+				result.add(
+					`${runtimeTemplate.renderConst()} ${finalName} = ${RuntimeGlobals.exports}${propertyAccess(
+						[usedName]
+					)};\n`
+				);
+			}
+
+			if (
+				// If the name includes `property access` and `call expressions`
+				finalName &&
+				(finalName.includes(".") ||
+					finalName.includes("[") ||
+					finalName.includes("("))
+			) {
+				if (exportInfo.isReexport()) {
+					const { data } = codeGenerationResults.get(module, chunk.runtime);
+					const topLevelDeclarations =
+						(data && data.get("topLevelDeclarations")) ||
+						(module.buildInfo && module.buildInfo.topLevelDeclarations);
+
+					if (topLevelDeclarations && topLevelDeclarations.has(originalName)) {
+						const name = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
+						result.add(
+							`${runtimeTemplate.renderConst()} ${name} = ${finalName};\n`
+						);
+						shortHandedExports.push(`${name} as ${originalName}`);
+					} else {
+						exports.push([originalName, finalName]);
+					}
+				} else {
+					exports.push([originalName, finalName]);
+				}
+			} else {
+				shortHandedExports.push(
+					definition && finalName === originalName
+						? finalName
+						: `${finalName} as ${originalName}`
+				);
+			}
+
+			alreadyRenderedExports.add(originalName);
+		}
+
+		// Add default export `__webpack_exports__` statement to keep better compatibility
+		if (treatAsCommonJs) {
+			needExportsDeclaration = true;
+			shortHandedExports.push(`${RuntimeGlobals.exports} as default`);
+		}
+
+		if (shortHandedExports.length > 0) {
+			result.add(`export { ${shortHandedExports.join(", ")} };\n`);
+		}
+
+		result = this._analyzeUnknownProvidedExports(
+			result,
+			module,
+			moduleGraph,
+			chunk.runtime,
+			exports,
+			alreadyRenderedExports
+		);
+
+		for (const [exportName, final] of exports) {
+			result.add(
+				`export ${runtimeTemplate.renderConst()} ${exportName} = ${final};\n`
+			);
+		}
+
+		if (!needExportsDeclaration) {
+			renderContext.needExportsDeclaration = false;
+		}
+
+		return result;
+	}
+
+	/**
+	 * Renders module content.
+	 * @param {Source} source source
+	 * @param {Module} module module
+	 * @param {ModuleRenderContext} renderContext render context
+	 * @param {Omit<LibraryContext<T>, "options">} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	renderModuleContent(
+		source,
+		module,
+		{ factory, inlinedInIIFE, chunk },
+		libraryContext
+	) {
+		const exportsSource =
+			module.buildMeta &&
+			module.buildMeta.exportsSourceByRuntime &&
+			module.buildMeta.exportsSourceByRuntime.get(getRuntimeKey(chunk.runtime));
+
+		// Re-add the module's exports source when rendered in factory
+		// or as an inlined startup module wrapped in an IIFE
+		if ((inlinedInIIFE || factory) && exportsSource) {
+			return new ConcatSource(exportsSource, source);
+		}
+		return source;
+	}
+}
+
+module.exports = ModuleLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/SystemLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/SystemLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/SystemLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,264 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Joel Denning @joeldenning
+*/
+
+"use strict";
+
+const { ConcatSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const ExternalModule = require("../ExternalModule");
+const Template = require("../Template");
+const { propertyAccess } = require("../util/property");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/** @typedef {import("../util/Hash")} Hash */
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+/**
+ * Defines the system library plugin options type used by this module.
+ * @typedef {object} SystemLibraryPluginOptions
+ * @property {LibraryType} type
+ */
+
+/**
+ * Defines the system library plugin parsed type used by this module.
+ * @typedef {object} SystemLibraryPluginParsed
+ * @property {string} name
+ */
+
+/**
+ * Represents the system library plugin runtime component.
+ * @typedef {SystemLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<SystemLibraryPluginParsed>}
+ */
+class SystemLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of SystemLibraryPlugin.
+	 * @param {SystemLibraryPluginOptions} options the plugin options
+	 */
+	constructor(options) {
+		super({
+			pluginName: "SystemLibraryPlugin",
+			type: options.type
+		});
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		const { name } = library;
+		if (name && typeof name !== "string") {
+			throw new Error(
+				`System.js library name must be a simple string or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
+			);
+		}
+		const _name = /** @type {string} */ (name);
+		return {
+			name: _name
+		};
+	}
+
+	/**
+	 * Returns source with library export.
+	 * @param {Source} source source
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	render(source, { chunkGraph, moduleGraph, chunk }, { options, compilation }) {
+		const modules = chunkGraph
+			.getChunkModules(chunk)
+			.filter(
+				(m) => m instanceof ExternalModule && m.externalType === "system"
+			);
+		const externals = /** @type {ExternalModule[]} */ (modules);
+
+		// The name this bundle should be registered as with System
+		const name = options.name
+			? `${JSON.stringify(compilation.getPath(options.name, { chunk }))}, `
+			: "";
+
+		// The array of dependencies that are external to webpack and will be provided by System
+		const systemDependencies = JSON.stringify(
+			externals.map((m) =>
+				typeof m.request === "object" && !Array.isArray(m.request)
+					? m.request.amd
+					: m.request
+			)
+		);
+
+		// The name of the variable provided by System for exporting
+		const dynamicExport = "__WEBPACK_DYNAMIC_EXPORT__";
+
+		// An array of the internal variable names for the webpack externals
+		const externalWebpackNames = externals.map(
+			(m) =>
+				`__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
+					`${chunkGraph.getModuleId(m)}`
+				)}__`
+		);
+
+		// Declaring variables for the internal variable names for the webpack externals
+		const externalVarDeclarations = externalWebpackNames
+			.map((name) => `var ${name} = {};`)
+			.join("\n");
+
+		// Define __esModule flag on all internal variables and helpers
+		/** @type {string[]} */
+		const externalVarInitialization = [];
+
+		// The system.register format requires an array of setter functions for externals.
+		const setters =
+			externalWebpackNames.length === 0
+				? ""
+				: Template.asString([
+						"setters: [",
+						Template.indent(
+							externals
+								.map((module, i) => {
+									const external = externalWebpackNames[i];
+									const exportsInfo = moduleGraph.getExportsInfo(module);
+									const otherUnused =
+										exportsInfo.otherExportsInfo.getUsed(chunk.runtime) ===
+										UsageState.Unused;
+									/** @type {string[]} */
+									const instructions = [];
+									/** @type {ExportInfoName[]} */
+									const handledNames = [];
+									for (const exportInfo of exportsInfo.orderedExports) {
+										const used = exportInfo.getUsedName(
+											undefined,
+											chunk.runtime
+										);
+										if (used) {
+											if (otherUnused || used !== exportInfo.name) {
+												if (exportInfo.name === "default") {
+													// Ideally we should use `module && module.__esModule ? module['default'] : module`
+													// But we need to keep compatibility with SystemJS format libraries (they are using `default`) and bundled SystemJS libraries from commonjs format
+													instructions.push(
+														`${external}${propertyAccess([
+															used
+														])} = module["default"] || module;`
+													);
+												} else {
+													instructions.push(
+														`${external}${propertyAccess([
+															used
+														])} = module${propertyAccess([exportInfo.name])};`
+													);
+												}
+												handledNames.push(exportInfo.name);
+											}
+										} else {
+											handledNames.push(exportInfo.name);
+										}
+									}
+									if (!otherUnused) {
+										if (
+											!Array.isArray(module.request) ||
+											module.request.length === 1
+										) {
+											externalVarInitialization.push(
+												`Object.defineProperty(${external}, "__esModule", { value: true });`
+											);
+										}
+										// See comment above
+										instructions.push(
+											`${external}["default"] = module["default"] || module;`
+										);
+										if (handledNames.length > 0) {
+											const name = `${external}handledNames`;
+											externalVarInitialization.push(
+												`var ${name} = ${JSON.stringify(handledNames)};`
+											);
+											instructions.push(
+												Template.asString([
+													"Object.keys(module).forEach(function(key) {",
+													Template.indent([
+														`if(${name}.indexOf(key) >= 0)`,
+														Template.indent(`${external}[key] = module[key];`)
+													]),
+													"});"
+												])
+											);
+										} else {
+											instructions.push(
+												Template.asString([
+													"Object.keys(module).forEach(function(key) {",
+													Template.indent([`${external}[key] = module[key];`]),
+													"});"
+												])
+											);
+										}
+									}
+									if (instructions.length === 0) return "function() {}";
+									return Template.asString([
+										"function(module) {",
+										Template.indent(instructions),
+										"}"
+									]);
+								})
+								.join(",\n")
+						),
+						"],"
+					]);
+
+		return new ConcatSource(
+			Template.asString([
+				`System.register(${name}${systemDependencies}, function(${dynamicExport}, __system_context__) {`,
+				Template.indent([
+					externalVarDeclarations,
+					Template.asString(externalVarInitialization),
+					"return {",
+					Template.indent([
+						setters,
+						"execute: function() {",
+						Template.indent(`${dynamicExport}(`)
+					])
+				]),
+				""
+			]),
+			source,
+			Template.asString([
+				"",
+				Template.indent([
+					Template.indent([Template.indent([");"]), "}"]),
+					"};"
+				]),
+				"})"
+			])
+		);
+	}
+
+	/**
+	 * Processes the provided chunk.
+	 * @param {Chunk} chunk the chunk
+	 * @param {Hash} hash hash
+	 * @param {ChunkHashContext} chunkHashContext chunk hash context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {void}
+	 */
+	chunkHash(chunk, hash, chunkHashContext, { options, compilation }) {
+		hash.update("SystemLibraryPlugin");
+		if (options.name) {
+			hash.update(compilation.getPath(options.name, { chunk }));
+		}
+	}
+}
+
+module.exports = SystemLibraryPlugin;
Index: frontend/node_modules/webpack/lib/library/UmdLibraryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/library/UmdLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/library/UmdLibraryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,371 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, OriginalSource } = require("webpack-sources");
+const ExternalModule = require("../ExternalModule");
+const Template = require("../Template");
+const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryCustomUmdCommentObject} LibraryCustomUmdCommentObject */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryCustomUmdObject} LibraryCustomUmdObject */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
+/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+/** @typedef {import("../ExternalModule").RequestRecord} RequestRecord */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T>
+ */
+
+/**
+ * Accessor to object access.
+ * @param {string[]} accessor the accessor to convert to path
+ * @returns {string} the path
+ */
+const accessorToObjectAccess = (accessor) =>
+	accessor.map((a) => `[${JSON.stringify(a)}]`).join("");
+
+/** @typedef {string | string[]} Accessor */
+
+/**
+ * Returns the path.
+ * @param {string | undefined} base the path prefix
+ * @param {Accessor} accessor the accessor
+ * @param {string=} joinWith the element separator
+ * @returns {string} the path
+ */
+const accessorAccess = (base, accessor, joinWith = ", ") => {
+	const accessors = Array.isArray(accessor) ? accessor : [accessor];
+	return accessors
+		.map((_, idx) => {
+			const a = base
+				? base + accessorToObjectAccess(accessors.slice(0, idx + 1))
+				: accessors[0] + accessorToObjectAccess(accessors.slice(1, idx + 1));
+			if (idx === accessors.length - 1) return a;
+			if (idx === 0 && base === undefined) {
+				return `${a} = typeof ${a} === "object" ? ${a} : {}`;
+			}
+			return `${a} = ${a} || {}`;
+		})
+		.join(joinWith);
+};
+
+/**
+ * Defines the umd library plugin options type used by this module.
+ * @typedef {object} UmdLibraryPluginOptions
+ * @property {LibraryType} type
+ * @property {boolean=} optionalAmdExternalAsGlobal
+ */
+
+/**
+ * Defines the umd library plugin parsed type used by this module.
+ * @typedef {object} UmdLibraryPluginParsed
+ * @property {string | string[] | undefined} name
+ * @property {LibraryCustomUmdObject} names
+ * @property {string | LibraryCustomUmdCommentObject | undefined} auxiliaryComment
+ * @property {boolean | undefined} namedDefine
+ */
+
+/**
+ * Represents the umd library plugin runtime component.
+ * @typedef {UmdLibraryPluginParsed} T
+ * @extends {AbstractLibraryPlugin<UmdLibraryPluginParsed>}
+ */
+class UmdLibraryPlugin extends AbstractLibraryPlugin {
+	/**
+	 * Creates an instance of UmdLibraryPlugin.
+	 * @param {UmdLibraryPluginOptions} options the plugin option
+	 */
+	constructor(options) {
+		super({
+			pluginName: "UmdLibraryPlugin",
+			type: options.type
+		});
+
+		/** @type {UmdLibraryPluginOptions["optionalAmdExternalAsGlobal"]} */
+		this.optionalAmdExternalAsGlobal = options.optionalAmdExternalAsGlobal;
+	}
+
+	/**
+	 * Returns preprocess as needed by overriding.
+	 * @param {LibraryOptions} library normalized library option
+	 * @returns {T} preprocess as needed by overriding
+	 */
+	parseOptions(library) {
+		/** @type {LibraryName | undefined} */
+		let name;
+		/** @type {LibraryCustomUmdObject} */
+		let names;
+		if (typeof library.name === "object" && !Array.isArray(library.name)) {
+			name = library.name.root || library.name.amd || library.name.commonjs;
+			names = library.name;
+		} else {
+			name = library.name;
+			const singleName = Array.isArray(name) ? name[0] : name;
+			names = {
+				commonjs: singleName,
+				root: library.name,
+				amd: singleName
+			};
+		}
+		return {
+			name,
+			names,
+			auxiliaryComment: library.auxiliaryComment,
+			namedDefine: library.umdNamedDefine
+		};
+	}
+
+	/**
+	 * Returns source with library export.
+	 * @param {Source} source source
+	 * @param {RenderContext} renderContext render context
+	 * @param {LibraryContext<T>} libraryContext context
+	 * @returns {Source} source with library export
+	 */
+	render(
+		source,
+		{ chunkGraph, runtimeTemplate, chunk, moduleGraph },
+		{ options, compilation }
+	) {
+		const modules = chunkGraph
+			.getChunkModules(chunk)
+			.filter(
+				(m) =>
+					m instanceof ExternalModule &&
+					(m.externalType === "umd" || m.externalType === "umd2")
+			);
+		let externals = /** @type {ExternalModule[]} */ (modules);
+		/** @type {ExternalModule[]} */
+		const optionalExternals = [];
+		/** @type {ExternalModule[]} */
+		let requiredExternals = [];
+		if (this.optionalAmdExternalAsGlobal) {
+			for (const m of externals) {
+				if (m.isOptional(moduleGraph)) {
+					optionalExternals.push(m);
+				} else {
+					requiredExternals.push(m);
+				}
+			}
+			externals = [...requiredExternals, ...optionalExternals];
+		} else {
+			requiredExternals = externals;
+		}
+
+		/**
+		 * Returns the replaced keys.
+		 * @param {string} str the string to replace
+		 * @returns {string} the replaced keys
+		 */
+		const replaceKeys = (str) =>
+			compilation.getPath(str, {
+				chunk
+			});
+
+		/**
+		 * Externals deps array.
+		 * @param {ExternalModule[]} modules external modules
+		 * @returns {string} result
+		 */
+		const externalsDepsArray = (modules) =>
+			`[${replaceKeys(
+				modules
+					.map((m) =>
+						JSON.stringify(
+							typeof m.request === "object"
+								? /** @type {RequestRecord} */
+									(m.request).amd
+								: m.request
+						)
+					)
+					.join(", ")
+			)}]`;
+
+		/**
+		 * Externals root array.
+		 * @param {ExternalModule[]} modules external modules
+		 * @returns {string} result
+		 */
+		const externalsRootArray = (modules) =>
+			replaceKeys(
+				modules
+					.map((m) => {
+						let request = m.request;
+						if (typeof request === "object") {
+							request =
+								/** @type {RequestRecord} */
+								(request).root;
+						}
+						return `root${accessorToObjectAccess([
+							...(Array.isArray(request) ? request : [request])
+						])}`;
+					})
+					.join(", ")
+			);
+
+		/**
+		 * Externals require array.
+		 * @param {string} type the type
+		 * @returns {string} external require array
+		 */
+		const externalsRequireArray = (type) =>
+			replaceKeys(
+				externals
+					.map((m) => {
+						let request = m.request;
+						if (typeof request === "object") {
+							request =
+								/** @type {RequestRecord} */
+								(request)[type];
+						}
+						if (request === undefined) {
+							throw new Error(
+								`Missing external configuration for type:${type}`
+							);
+						}
+						let expr = Array.isArray(request)
+							? `require(${JSON.stringify(
+									request[0]
+								)})${accessorToObjectAccess(request.slice(1))}`
+							: `require(${JSON.stringify(request)})`;
+						if (m.isOptional(moduleGraph)) {
+							expr = `(function webpackLoadOptionalExternalModule() { try { return ${expr}; } catch(e) {} }())`;
+						}
+						return expr;
+					})
+					.join(", ")
+			);
+
+		/**
+		 * Externals arguments.
+		 * @param {ExternalModule[]} modules external modules
+		 * @returns {string} arguments
+		 */
+		const externalsArguments = (modules) =>
+			modules
+				.map(
+					(m) =>
+						`__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
+							`${chunkGraph.getModuleId(m)}`
+						)}__`
+				)
+				.join(", ");
+
+		/**
+		 * Returns stringified library name.
+		 * @param {Accessor} library library name
+		 * @returns {string} stringified library name
+		 */
+		const libraryName = (library) =>
+			JSON.stringify(
+				replaceKeys(
+					/** @type {string} */
+					([...(Array.isArray(library) ? library : [library])].pop())
+				)
+			);
+
+		/** @type {string} */
+		let amdFactory;
+		if (optionalExternals.length > 0) {
+			const wrapperArguments = externalsArguments(requiredExternals);
+			const factoryArguments =
+				requiredExternals.length > 0
+					? `${externalsArguments(requiredExternals)}, ${externalsRootArray(
+							optionalExternals
+						)}`
+					: externalsRootArray(optionalExternals);
+			amdFactory =
+				`function webpackLoadOptionalExternalModuleAmd(${wrapperArguments}) {\n` +
+				`			return factory(${factoryArguments});\n` +
+				"		}";
+		} else {
+			amdFactory = "factory";
+		}
+
+		const { auxiliaryComment, namedDefine, names } = options;
+
+		/**
+		 * Gets auxiliary comment.
+		 * @param {keyof LibraryCustomUmdCommentObject} type type
+		 * @returns {string} comment
+		 */
+		const getAuxiliaryComment = (type) => {
+			if (auxiliaryComment) {
+				if (typeof auxiliaryComment === "string") {
+					return `\t//${auxiliaryComment}\n`;
+				}
+				if (auxiliaryComment[type]) return `\t//${auxiliaryComment[type]}\n`;
+			}
+			return "";
+		};
+
+		return new ConcatSource(
+			new OriginalSource(
+				`(function webpackUniversalModuleDefinition(root, factory) {\n${getAuxiliaryComment(
+					"commonjs2"
+				)}	if(typeof exports === 'object' && typeof module === 'object')\n` +
+					`		module.exports = factory(${externalsRequireArray(
+						"commonjs2"
+					)});\n${getAuxiliaryComment(
+						"amd"
+					)}	else if(typeof define === 'function' && define.amd)\n${
+						requiredExternals.length > 0
+							? names.amd && namedDefine === true
+								? `		define(${libraryName(names.amd)}, ${externalsDepsArray(
+										requiredExternals
+									)}, ${amdFactory});\n`
+								: `		define(${externalsDepsArray(requiredExternals)}, ${
+										amdFactory
+									});\n`
+							: names.amd && namedDefine === true
+								? `		define(${libraryName(names.amd)}, [], ${amdFactory});\n`
+								: `		define([], ${amdFactory});\n`
+					}${
+						names.root || names.commonjs
+							? `${getAuxiliaryComment(
+									"commonjs"
+								)}	else if(typeof exports === 'object')\n` +
+								`		exports[${libraryName(
+									/** @type {Accessor} */
+									(names.commonjs || names.root)
+								)}] = factory(${externalsRequireArray(
+									"commonjs"
+								)});\n${getAuxiliaryComment("root")}	else\n` +
+								`		${replaceKeys(
+									accessorAccess(
+										"root",
+										/** @type {Accessor} */
+										(names.root || names.commonjs)
+									)
+								)} = factory(${externalsRootArray(externals)});\n`
+							: `	else {\n${
+									externals.length > 0
+										? `		var a = typeof exports === 'object' ? factory(${externalsRequireArray(
+												"commonjs"
+											)}) : factory(${externalsRootArray(externals)});\n`
+										: "		var a = factory();\n"
+								}		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n` +
+								"	}\n"
+					}})(${runtimeTemplate.globalObject}, ${
+						runtimeTemplate.supportsArrowFunction()
+							? `(${externalsArguments(externals)}) =>`
+							: `function(${externalsArguments(externals)})`
+					} {\nreturn `,
+				"webpack/universalModuleDefinition"
+			),
+			source,
+			";\n})"
+		);
+	}
+}
+
+module.exports = UmdLibraryPlugin;
Index: frontend/node_modules/webpack/lib/logging/Logger.js
===================================================================
--- frontend/node_modules/webpack/lib/logging/Logger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/logging/Logger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,240 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const LogType = Object.freeze({
+	error: /** @type {"error"} */ ("error"), // message, c style arguments
+	warn: /** @type {"warn"} */ ("warn"), // message, c style arguments
+	info: /** @type {"info"} */ ("info"), // message, c style arguments
+	log: /** @type {"log"} */ ("log"), // message, c style arguments
+	debug: /** @type {"debug"} */ ("debug"), // message, c style arguments
+
+	trace: /** @type {"trace"} */ ("trace"), // no arguments
+
+	group: /** @type {"group"} */ ("group"), // [label]
+	groupCollapsed: /** @type {"groupCollapsed"} */ ("groupCollapsed"), // [label]
+	groupEnd: /** @type {"groupEnd"} */ ("groupEnd"), // [label]
+
+	profile: /** @type {"profile"} */ ("profile"), // [profileName]
+	profileEnd: /** @type {"profileEnd"} */ ("profileEnd"), // [profileName]
+
+	time: /** @type {"time"} */ ("time"), // name, time as [seconds, nanoseconds]
+
+	clear: /** @type {"clear"} */ ("clear"), // no arguments
+	status: /** @type {"status"} */ ("status") // message, arguments
+});
+
+module.exports.LogType = LogType;
+
+/** @typedef {typeof LogType[keyof typeof LogType]} LogTypeEnum */
+/** @typedef {Map<string | undefined, [number, number]>} TimersMap */
+
+const LOG_SYMBOL = Symbol("webpack logger raw log method");
+const TIMERS_SYMBOL = Symbol("webpack logger times");
+const TIMERS_AGGREGATES_SYMBOL = Symbol("webpack logger aggregated times");
+
+/** @typedef {EXPECTED_ANY[]} Args */
+/** @typedef {(type: LogTypeEnum, args?: Args) => void} LogFn */
+/** @typedef {(name: string | (() => string)) => WebpackLogger} GetChildLogger */
+
+class WebpackLogger {
+	/**
+	 * Creates an instance of WebpackLogger.
+	 * @param {LogFn} log log function
+	 * @param {GetChildLogger} getChildLogger function to create child logger
+	 */
+	constructor(log, getChildLogger) {
+		/** @type {LogFn} */
+		this[LOG_SYMBOL] = log;
+		/** @type {GetChildLogger} */
+		this.getChildLogger = getChildLogger;
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	error(...args) {
+		this[LOG_SYMBOL](LogType.error, args);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	warn(...args) {
+		this[LOG_SYMBOL](LogType.warn, args);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	info(...args) {
+		this[LOG_SYMBOL](LogType.info, args);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	log(...args) {
+		this[LOG_SYMBOL](LogType.log, args);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	debug(...args) {
+		this[LOG_SYMBOL](LogType.debug, args);
+	}
+
+	/**
+	 * Processes the provided condition.
+	 * @param {boolean=} condition condition
+	 * @param {Args} args args
+	 */
+	assert(condition, ...args) {
+		if (!condition) {
+			this[LOG_SYMBOL](LogType.error, args);
+		}
+	}
+
+	trace() {
+		this[LOG_SYMBOL](LogType.trace, ["Trace"]);
+	}
+
+	clear() {
+		this[LOG_SYMBOL](LogType.clear);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	status(...args) {
+		this[LOG_SYMBOL](LogType.status, args);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	group(...args) {
+		this[LOG_SYMBOL](LogType.group, args);
+	}
+
+	/**
+	 * Processes the provided arg.
+	 * @param {Args} args args
+	 */
+	groupCollapsed(...args) {
+		this[LOG_SYMBOL](LogType.groupCollapsed, args);
+	}
+
+	groupEnd() {
+		this[LOG_SYMBOL](LogType.groupEnd);
+	}
+
+	/**
+	 * Processes the provided label.
+	 * @param {string=} label label
+	 */
+	profile(label) {
+		this[LOG_SYMBOL](LogType.profile, [label]);
+	}
+
+	/**
+	 * Processes the provided label.
+	 * @param {string=} label label
+	 */
+	profileEnd(label) {
+		this[LOG_SYMBOL](LogType.profileEnd, [label]);
+	}
+
+	/**
+	 * Processes the provided label.
+	 * @param {string} label label
+	 */
+	time(label) {
+		/** @type {TimersMap} */
+		this[TIMERS_SYMBOL] = this[TIMERS_SYMBOL] || new Map();
+		this[TIMERS_SYMBOL].set(label, process.hrtime());
+	}
+
+	/**
+	 * Processes the provided label.
+	 * @param {string=} label label
+	 */
+	timeLog(label) {
+		const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
+		if (!prev) {
+			throw new Error(`No such label '${label}' for WebpackLogger.timeLog()`);
+		}
+		const time = process.hrtime(prev);
+		this[LOG_SYMBOL](LogType.time, [label, ...time]);
+	}
+
+	/**
+	 * Processes the provided label.
+	 * @param {string=} label label
+	 */
+	timeEnd(label) {
+		const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
+		if (!prev) {
+			throw new Error(`No such label '${label}' for WebpackLogger.timeEnd()`);
+		}
+		const time = process.hrtime(prev);
+		/** @type {TimersMap} */
+		(this[TIMERS_SYMBOL]).delete(label);
+		this[LOG_SYMBOL](LogType.time, [label, ...time]);
+	}
+
+	/**
+	 * Processes the provided label.
+	 * @param {string=} label label
+	 */
+	timeAggregate(label) {
+		const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
+		if (!prev) {
+			throw new Error(
+				`No such label '${label}' for WebpackLogger.timeAggregate()`
+			);
+		}
+		const time = process.hrtime(prev);
+		/** @type {TimersMap} */
+		(this[TIMERS_SYMBOL]).delete(label);
+		/** @type {TimersMap} */
+		this[TIMERS_AGGREGATES_SYMBOL] =
+			this[TIMERS_AGGREGATES_SYMBOL] || new Map();
+		const current = this[TIMERS_AGGREGATES_SYMBOL].get(label);
+		if (current !== undefined) {
+			if (time[1] + current[1] > 1e9) {
+				time[0] += current[0] + 1;
+				time[1] = time[1] - 1e9 + current[1];
+			} else {
+				time[0] += current[0];
+				time[1] += current[1];
+			}
+		}
+		this[TIMERS_AGGREGATES_SYMBOL].set(label, time);
+	}
+
+	/**
+	 * Time aggregate end.
+	 * @param {string=} label label
+	 */
+	timeAggregateEnd(label) {
+		if (this[TIMERS_AGGREGATES_SYMBOL] === undefined) return;
+		const time = this[TIMERS_AGGREGATES_SYMBOL].get(label);
+		if (time === undefined) return;
+		this[TIMERS_AGGREGATES_SYMBOL].delete(label);
+		this[LOG_SYMBOL](LogType.time, [label, ...time]);
+	}
+}
+
+module.exports.Logger = WebpackLogger;
Index: frontend/node_modules/webpack/lib/logging/createConsoleLogger.js
===================================================================
--- frontend/node_modules/webpack/lib/logging/createConsoleLogger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/logging/createConsoleLogger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,224 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { LogType } = require("./Logger");
+
+/** @typedef {import("../../declarations/WebpackOptions").FilterItemTypes} FilterItemTypes */
+/** @typedef {import("../../declarations/WebpackOptions").FilterTypes} FilterTypes */
+/** @typedef {import("./Logger").LogTypeEnum} LogTypeEnum */
+/** @typedef {import("./Logger").Args} Args */
+
+/** @typedef {(item: string) => boolean} FilterFunction */
+/** @typedef {(value: string, type: LogTypeEnum, args?: Args) => void} LoggingFunction */
+
+/**
+ * Defines the logger console type used by this module.
+ * @typedef {object} LoggerConsole
+ * @property {() => void} clear
+ * @property {() => void} trace
+ * @property {(...args: Args) => void} info
+ * @property {(...args: Args) => void} log
+ * @property {(...args: Args) => void} warn
+ * @property {(...args: Args) => void} error
+ * @property {(...args: Args) => void=} debug
+ * @property {(...args: Args) => void=} group
+ * @property {(...args: Args) => void=} groupCollapsed
+ * @property {(...args: Args) => void=} groupEnd
+ * @property {(...args: Args) => void=} status
+ * @property {(...args: Args) => void=} profile
+ * @property {(...args: Args) => void=} profileEnd
+ * @property {(...args: Args) => void=} logTime
+ */
+
+/**
+ * Defines the logger options type used by this module.
+ * @typedef {object} LoggerOptions
+ * @property {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} level loglevel
+ * @property {FilterTypes | boolean} debug filter for debug logging
+ * @property {LoggerConsole} console the console to log to
+ */
+
+/**
+ * Filter to function.
+ * @param {FilterItemTypes} item an input item
+ * @returns {FilterFunction | undefined} filter function
+ */
+const filterToFunction = (item) => {
+	if (typeof item === "string") {
+		const regExp = new RegExp(
+			`[\\\\/]${item.replace(/[-[\]{}()*+?.\\^$|]/g, "\\$&")}([\\\\/]|$|!|\\?)`
+		);
+		return (ident) => regExp.test(ident);
+	}
+	if (item && typeof item === "object" && typeof item.test === "function") {
+		return (ident) => item.test(ident);
+	}
+	if (typeof item === "function") {
+		return item;
+	}
+	if (typeof item === "boolean") {
+		return () => item;
+	}
+};
+
+/**
+ * Enumerates the available values.
+ * @enum {number}
+ */
+const LogLevel = {
+	none: 6,
+	false: 6,
+	error: 5,
+	warn: 4,
+	info: 3,
+	log: 2,
+	true: 2,
+	verbose: 1
+};
+
+/**
+ * Returns logging function.
+ * @param {LoggerOptions} options options object
+ * @returns {LoggingFunction} logging function
+ */
+module.exports = ({ level = "info", debug = false, console }) => {
+	const debugFilters =
+		/** @type {FilterFunction[]} */
+		(
+			typeof debug === "boolean"
+				? [() => debug]
+				: /** @type {FilterItemTypes[]} */ ([
+						...(Array.isArray(debug) ? debug : [debug])
+					]).map(filterToFunction)
+		);
+	const loglevel = LogLevel[`${level}`] || 0;
+
+	/**
+	 * Processes the provided name.
+	 * @param {string} name name of the logger
+	 * @param {LogTypeEnum} type type of the log entry
+	 * @param {Args=} args arguments of the log entry
+	 * @returns {void}
+	 */
+	const logger = (name, type, args) => {
+		/**
+		 * Returns labeled args.
+		 * @template T
+		 * @returns {[string?, ...T[]]} labeled args
+		 */
+		const labeledArgs = () => {
+			if (Array.isArray(args)) {
+				if (args.length > 0 && typeof args[0] === "string") {
+					return [`[${name}] ${args[0]}`, ...args.slice(1)];
+				}
+				return [`[${name}]`, ...args];
+			}
+			return [];
+		};
+		const debug = debugFilters.some((f) => f(name));
+		switch (type) {
+			case LogType.debug:
+				if (!debug) return;
+				if (typeof console.debug === "function") {
+					console.debug(...labeledArgs());
+				} else {
+					console.log(...labeledArgs());
+				}
+				break;
+			case LogType.log:
+				if (!debug && loglevel > LogLevel.log) return;
+				console.log(...labeledArgs());
+				break;
+			case LogType.info:
+				if (!debug && loglevel > LogLevel.info) return;
+				console.info(...labeledArgs());
+				break;
+			case LogType.warn:
+				if (!debug && loglevel > LogLevel.warn) return;
+				console.warn(...labeledArgs());
+				break;
+			case LogType.error:
+				if (!debug && loglevel > LogLevel.error) return;
+				console.error(...labeledArgs());
+				break;
+			case LogType.trace:
+				if (!debug) return;
+				console.trace();
+				break;
+			case LogType.groupCollapsed:
+				if (!debug && loglevel > LogLevel.log) return;
+				if (!debug && loglevel > LogLevel.verbose) {
+					if (typeof console.groupCollapsed === "function") {
+						console.groupCollapsed(...labeledArgs());
+					} else {
+						console.log(...labeledArgs());
+					}
+					break;
+				}
+			// falls through
+			case LogType.group:
+				if (!debug && loglevel > LogLevel.log) return;
+				if (typeof console.group === "function") {
+					console.group(...labeledArgs());
+				} else {
+					console.log(...labeledArgs());
+				}
+				break;
+			case LogType.groupEnd:
+				if (!debug && loglevel > LogLevel.log) return;
+				if (typeof console.groupEnd === "function") {
+					console.groupEnd();
+				}
+				break;
+			case LogType.time: {
+				if (!debug && loglevel > LogLevel.log) return;
+				const [label, start, end] =
+					/** @type {[string, number, number]} */
+					(args);
+				const ms = start * 1000 + end / 1000000;
+				const msg = `[${name}] ${label}: ${ms} ms`;
+				if (typeof console.logTime === "function") {
+					console.logTime(msg);
+				} else {
+					console.log(msg);
+				}
+				break;
+			}
+			case LogType.profile:
+				if (typeof console.profile === "function") {
+					console.profile(...labeledArgs());
+				}
+				break;
+			case LogType.profileEnd:
+				if (typeof console.profileEnd === "function") {
+					console.profileEnd(...labeledArgs());
+				}
+				break;
+			case LogType.clear:
+				if (!debug && loglevel > LogLevel.log) return;
+				if (typeof console.clear === "function") {
+					console.clear();
+				}
+				break;
+			case LogType.status:
+				if (!debug && loglevel > LogLevel.info) return;
+				if (typeof console.status === "function") {
+					if (!args || args.length === 0) {
+						console.status();
+					} else {
+						console.status(...labeledArgs());
+					}
+				} else if (args && args.length !== 0) {
+					console.info(...labeledArgs());
+				}
+				break;
+			default:
+				throw new Error(`Unexpected LogType ${type}`);
+		}
+	};
+	return logger;
+};
Index: frontend/node_modules/webpack/lib/logging/runtime.js
===================================================================
--- frontend/node_modules/webpack/lib/logging/runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/logging/runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncBailHook } = require("tapable");
+const { Logger } = require("./Logger");
+const createConsoleLogger = require("./createConsoleLogger");
+
+/** @type {createConsoleLogger.LoggerOptions} */
+const currentDefaultLoggerOptions = {
+	level: "info",
+	debug: false,
+	console
+};
+let currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions);
+
+/**
+ * Processes the provided create console logger.logger option.
+ * @param {createConsoleLogger.LoggerOptions} options new options, merge with old options
+ * @returns {void}
+ */
+module.exports.configureDefaultLogger = (options) => {
+	Object.assign(currentDefaultLoggerOptions, options);
+	currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions);
+};
+
+/**
+ * Returns a logger.
+ * @param {string} name name of the logger
+ * @returns {Logger} a logger
+ */
+module.exports.getLogger = (name) =>
+	new Logger(
+		(type, args) => {
+			if (module.exports.hooks.log.call(name, type, args) === undefined) {
+				currentDefaultLogger(name, type, args);
+			}
+		},
+		(childName) => module.exports.getLogger(`${name}/${childName}`)
+	);
+
+module.exports.hooks = {
+	log: new SyncBailHook(["origin", "type", "args"])
+};
Index: frontend/node_modules/webpack/lib/logging/truncateArgs.js
===================================================================
--- frontend/node_modules/webpack/lib/logging/truncateArgs.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/logging/truncateArgs.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Returns sum of all numbers in array.
+ * @param {number[]} array array of numbers
+ * @returns {number} sum of all numbers in array
+ */
+const arraySum = (array) => {
+	let sum = 0;
+	for (const item of array) sum += item;
+	return sum;
+};
+
+/**
+ * Returns truncated args.
+ * @param {string[]} args items to be truncated
+ * @param {number} maxLength maximum length of args including spaces between
+ * @returns {string[]} truncated args
+ */
+const truncateArgs = (args, maxLength) => {
+	const lengths = args.map((a) => `${a}`.length);
+	const availableLength = maxLength - lengths.length + 1;
+
+	if (availableLength > 0 && args.length === 1) {
+		if (availableLength >= args[0].length) {
+			return args;
+		} else if (availableLength > 3) {
+			return [`...${args[0].slice(-availableLength + 3)}`];
+		}
+		return [args[0].slice(-availableLength)];
+	}
+
+	// Check if there is space for at least 4 chars per arg
+	if (availableLength < arraySum(lengths.map((i) => Math.min(i, 6)))) {
+		// remove args
+		if (args.length > 1) return truncateArgs(args.slice(0, -1), maxLength);
+		return [];
+	}
+
+	let currentLength = arraySum(lengths);
+
+	// Check if all fits into maxLength
+	if (currentLength <= availableLength) return args;
+
+	// Try to remove chars from the longest items until it fits
+	while (currentLength > availableLength) {
+		const maxLength = Math.max(...lengths);
+		const shorterItems = lengths.filter((l) => l !== maxLength);
+		const nextToMaxLength =
+			shorterItems.length > 0 ? Math.max(...shorterItems) : 0;
+		const maxReduce = maxLength - nextToMaxLength;
+		let maxItems = lengths.length - shorterItems.length;
+		let overrun = currentLength - availableLength;
+		for (let i = 0; i < lengths.length; i++) {
+			if (lengths[i] === maxLength) {
+				const reduce = Math.min(Math.floor(overrun / maxItems), maxReduce);
+				lengths[i] -= reduce;
+				currentLength -= reduce;
+				overrun -= reduce;
+				maxItems--;
+			}
+		}
+	}
+
+	// Return args reduced to length in lengths
+	return args.map((a, i) => {
+		const str = `${a}`;
+		const length = lengths[i];
+		if (str.length === length) {
+			return str;
+		} else if (length > 5) {
+			return `...${str.slice(-length + 3)}`;
+		} else if (length > 0) {
+			return str.slice(-length);
+		}
+		return "";
+	});
+};
+
+module.exports = truncateArgs;
Index: frontend/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,124 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const StartupChunkDependenciesPlugin = require("../runtime/StartupChunkDependenciesPlugin");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+
+/**
+ * Defines the common js chunk loading plugin options type used by this module.
+ * @typedef {object} CommonJsChunkLoadingPluginOptions
+ * @property {boolean=} asyncChunkLoading enable async chunk loading
+ */
+
+const PLUGIN_NAME = "CommonJsChunkLoadingPlugin";
+
+class CommonJsChunkLoadingPlugin {
+	/**
+	 * Creates an instance of CommonJsChunkLoadingPlugin.
+	 * @param {CommonJsChunkLoadingPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {CommonJsChunkLoadingPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const ChunkLoadingRuntimeModule = this.options.asyncChunkLoading
+			? require("./ReadFileChunkLoadingRuntimeModule")
+			: require("./RequireChunkLoadingRuntimeModule");
+		const chunkLoadingValue = this.options.asyncChunkLoading
+			? "async-node"
+			: "require";
+		new StartupChunkDependenciesPlugin({
+			chunkLoading: chunkLoadingValue,
+			asyncChunkLoading: this.options.asyncChunkLoading
+		}).apply(compiler);
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalChunkLoading = compilation.outputOptions.chunkLoading;
+			/**
+			 * Checks whether this common js chunk loading plugin is enabled for chunk.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const chunkLoading =
+					options && options.chunkLoading !== undefined
+						? options.chunkLoading
+						: globalChunkLoading;
+				return chunkLoading === chunkLoadingValue;
+			};
+			/** @type {WeakSet<Chunk>} */
+			const onceForChunkSet = new WeakSet();
+			/**
+			 * Handles the hook callback for this code path.
+			 * @param {Chunk} chunk chunk
+			 * @param {RuntimeRequirements} set runtime requirements
+			 */
+			const handler = (chunk, set) => {
+				if (onceForChunkSet.has(chunk)) return;
+				onceForChunkSet.add(chunk);
+				if (!isEnabledForChunk(chunk)) return;
+				set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				set.add(RuntimeGlobals.hasOwnProperty);
+				compilation.addRuntimeModule(chunk, new ChunkLoadingRuntimeModule(set));
+			};
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.baseURI)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.externalInstallChunk)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.onChunksLoaded)
+				.tap(PLUGIN_NAME, handler);
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.getChunkScriptFilename);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
+					set.add(RuntimeGlobals.moduleCache);
+					set.add(RuntimeGlobals.hmrModuleData);
+					set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.getUpdateManifestFilename);
+				});
+		});
+	}
+}
+
+module.exports = CommonJsChunkLoadingPlugin;
Index: frontend/node_modules/webpack/lib/node/NodeEnvironmentPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/NodeEnvironmentPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/NodeEnvironmentPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,77 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { CachedInputFileSystem } = require("enhanced-resolve");
+const fs = require("graceful-fs");
+const createConsoleLogger = require("../logging/createConsoleLogger");
+const NodeWatchFileSystem = require("./NodeWatchFileSystem");
+const nodeConsole = require("./nodeConsole");
+
+/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+/**
+ * Defines the node environment plugin options type used by this module.
+ * @typedef {object} NodeEnvironmentPluginOptions
+ * @property {InfrastructureLogging} infrastructureLogging infrastructure logging options
+ */
+
+const PLUGIN_NAME = "NodeEnvironmentPlugin";
+
+class NodeEnvironmentPlugin {
+	/**
+	 * Creates an instance of NodeEnvironmentPlugin.
+	 * @param {NodeEnvironmentPluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {NodeEnvironmentPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { infrastructureLogging } = this.options;
+		compiler.infrastructureLogger = createConsoleLogger({
+			level: infrastructureLogging.level || "info",
+			debug: infrastructureLogging.debug || false,
+			console:
+				infrastructureLogging.console ||
+				nodeConsole({
+					colors: infrastructureLogging.colors,
+					appendOnly: infrastructureLogging.appendOnly,
+					stream:
+						/** @type {NodeJS.WritableStream} */
+						(infrastructureLogging.stream),
+					compiler
+				})
+		});
+		// @ts-expect-error need to fix on enhanced-resolve side
+		compiler.inputFileSystem = new CachedInputFileSystem(fs, 60000);
+		const inputFileSystem =
+			/** @type {InputFileSystem} */
+			(compiler.inputFileSystem);
+		compiler.outputFileSystem = fs;
+		compiler.intermediateFileSystem = fs;
+		compiler.watchFileSystem = new NodeWatchFileSystem(inputFileSystem);
+		compiler.hooks.beforeRun.tap(PLUGIN_NAME, (compiler) => {
+			if (
+				compiler.inputFileSystem === inputFileSystem &&
+				inputFileSystem.purge
+			) {
+				compiler.fsStartTime = Date.now();
+				inputFileSystem.purge();
+			}
+		});
+	}
+}
+
+module.exports = NodeEnvironmentPlugin;
Index: frontend/node_modules/webpack/lib/node/NodeSourcePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/NodeSourcePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/NodeSourcePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Compiler")} Compiler */
+
+class NodeSourcePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {}
+}
+
+module.exports = NodeSourcePlugin;
Index: frontend/node_modules/webpack/lib/node/NodeTargetPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/NodeTargetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/NodeTargetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,103 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ExternalsPlugin = require("../ExternalsPlugin");
+
+/** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
+/** @typedef {import("../Compiler")} Compiler */
+
+const builtins = [
+	"assert",
+	"assert/strict",
+	"async_hooks",
+	"buffer",
+	"child_process",
+	"cluster",
+	"console",
+	"constants",
+	"crypto",
+	"dgram",
+	"diagnostics_channel",
+	"dns",
+	"dns/promises",
+	"domain",
+	"events",
+	"fs",
+	"fs/promises",
+	"http",
+	"http2",
+	"https",
+	"inspector",
+	"inspector/promises",
+	"module",
+	"net",
+	"os",
+	"path",
+	"path/posix",
+	"path/win32",
+	"perf_hooks",
+	"process",
+	"punycode",
+	"querystring",
+	"readline",
+	"readline/promises",
+	"repl",
+	"stream",
+	"stream/consumers",
+	"stream/promises",
+	"stream/web",
+	"string_decoder",
+	"sys",
+	"timers",
+	"timers/promises",
+	"tls",
+	"trace_events",
+	"tty",
+	"url",
+	"util",
+	"util/types",
+	"v8",
+	"vm",
+	"wasi",
+	"worker_threads",
+	"zlib",
+	/^node:/,
+
+	// cspell:word pnpapi
+	// Yarn PnP adds pnpapi as "builtin"
+	"pnpapi"
+];
+
+class NodeTargetPlugin {
+	/**
+	 * Creates an instance of NodeTargetPlugin.
+	 * @param {ExternalsType} type default external type
+	 */
+	constructor(type = "node-commonjs") {
+		/** @type {ExternalsType} */
+		this.type = type;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		new ExternalsPlugin((dependency) => {
+			// When `require` node.js built-in modules with module output
+			// we should still emit `createRequire` for compatibility
+			if (dependency.category === "commonjs") {
+				return "node-commonjs";
+			}
+
+			return this.type;
+		}, builtins).apply(compiler);
+	}
+}
+
+module.exports = NodeTargetPlugin;
Index: frontend/node_modules/webpack/lib/node/NodeTemplatePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/NodeTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/NodeTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const CommonJsChunkFormatPlugin = require("../javascript/CommonJsChunkFormatPlugin");
+const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Represents the node template plugin runtime component.
+ * @typedef {object} NodeTemplatePluginOptions
+ * @property {boolean=} asyncChunkLoading enable async chunk loading
+ */
+
+class NodeTemplatePlugin {
+	/**
+	 * Creates an instance of NodeTemplatePlugin.
+	 * @param {NodeTemplatePluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {NodeTemplatePluginOptions} */
+		this._options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const chunkLoading = this._options.asyncChunkLoading
+			? "async-node"
+			: "require";
+		compiler.options.output.chunkLoading = chunkLoading;
+		new CommonJsChunkFormatPlugin().apply(compiler);
+		new EnableChunkLoadingPlugin(chunkLoading).apply(compiler);
+	}
+}
+
+module.exports = NodeTemplatePlugin;
Index: frontend/node_modules/webpack/lib/node/NodeWatchFileSystem.js
===================================================================
--- frontend/node_modules/webpack/lib/node/NodeWatchFileSystem.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/NodeWatchFileSystem.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,200 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const Watchpack = require("watchpack");
+
+/** @typedef {import("watchpack").TimeInfoEntries} TimeInfoEntries */
+/** @typedef {import("watchpack").WatchOptions} WatchOptions */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../util/fs").WatchMethod} WatchMethod */
+/** @typedef {import("../util/fs").Changes} Changes */
+/** @typedef {import("../util/fs").Removals} Removals */
+
+class NodeWatchFileSystem {
+	/**
+	 * Creates an instance of NodeWatchFileSystem.
+	 * @param {InputFileSystem} inputFileSystem input filesystem
+	 */
+	constructor(inputFileSystem) {
+		/** @type {InputFileSystem} */
+		this.inputFileSystem = inputFileSystem;
+		/** @type {WatchOptions} */
+		this.watcherOptions = {
+			aggregateTimeout: 0
+		};
+		/** @type {Watchpack | null} */
+		this.watcher = new Watchpack(this.watcherOptions);
+	}
+
+	/** @type {WatchMethod} */
+	watch(
+		files,
+		directories,
+		missing,
+		startTime,
+		options,
+		callback,
+		callbackUndelayed
+	) {
+		if (!files || typeof files[Symbol.iterator] !== "function") {
+			throw new Error("Invalid arguments: 'files'");
+		}
+		if (!directories || typeof directories[Symbol.iterator] !== "function") {
+			throw new Error("Invalid arguments: 'directories'");
+		}
+		if (!missing || typeof missing[Symbol.iterator] !== "function") {
+			throw new Error("Invalid arguments: 'missing'");
+		}
+		if (typeof callback !== "function") {
+			throw new Error("Invalid arguments: 'callback'");
+		}
+		if (typeof startTime !== "number" && startTime) {
+			throw new Error("Invalid arguments: 'startTime'");
+		}
+		if (typeof options !== "object") {
+			throw new Error("Invalid arguments: 'options'");
+		}
+		if (typeof callbackUndelayed !== "function" && callbackUndelayed) {
+			throw new Error("Invalid arguments: 'callbackUndelayed'");
+		}
+		const oldWatcher = this.watcher;
+		this.watcher = new Watchpack(options);
+
+		if (callbackUndelayed) {
+			this.watcher.once("change", callbackUndelayed);
+		}
+
+		const fetchTimeInfo = () => {
+			/** @type {TimeInfoEntries} */
+			const fileTimeInfoEntries = new Map();
+			/** @type {TimeInfoEntries} */
+			const contextTimeInfoEntries = new Map();
+			if (this.watcher) {
+				this.watcher.collectTimeInfoEntries(
+					fileTimeInfoEntries,
+					contextTimeInfoEntries
+				);
+			}
+			return { fileTimeInfoEntries, contextTimeInfoEntries };
+		};
+		this.watcher.once(
+			"aggregated",
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {Changes} changes changes
+			 * @param {Removals} removals removals
+			 */
+			(changes, removals) => {
+				// pause emitting events (avoids clearing aggregated changes and removals on timeout)
+				/** @type {Watchpack} */
+				(this.watcher).pause();
+
+				const fs = this.inputFileSystem;
+				if (fs && fs.purge) {
+					for (const item of changes) {
+						fs.purge(item);
+					}
+					for (const item of removals) {
+						fs.purge(item);
+					}
+				}
+				const { fileTimeInfoEntries, contextTimeInfoEntries } = fetchTimeInfo();
+				callback(
+					null,
+					fileTimeInfoEntries,
+					contextTimeInfoEntries,
+					changes,
+					removals
+				);
+			}
+		);
+
+		this.watcher.watch({ files, directories, missing, startTime });
+
+		if (oldWatcher) {
+			oldWatcher.close();
+		}
+		return {
+			close: () => {
+				if (this.watcher) {
+					this.watcher.close();
+					this.watcher = null;
+				}
+			},
+			pause: () => {
+				if (this.watcher) {
+					this.watcher.pause();
+				}
+			},
+			getAggregatedRemovals: util.deprecate(
+				() => {
+					const items = this.watcher && this.watcher.aggregatedRemovals;
+					const fs = this.inputFileSystem;
+					if (items && fs && fs.purge) {
+						for (const item of items) {
+							fs.purge(item);
+						}
+					}
+					return items;
+				},
+				"Watcher.getAggregatedRemovals is deprecated in favor of Watcher.getInfo since that's more performant.",
+				"DEP_WEBPACK_WATCHER_GET_AGGREGATED_REMOVALS"
+			),
+			getAggregatedChanges: util.deprecate(
+				() => {
+					const items = this.watcher && this.watcher.aggregatedChanges;
+					const fs = this.inputFileSystem;
+					if (items && fs && fs.purge) {
+						for (const item of items) {
+							fs.purge(item);
+						}
+					}
+					return items;
+				},
+				"Watcher.getAggregatedChanges is deprecated in favor of Watcher.getInfo since that's more performant.",
+				"DEP_WEBPACK_WATCHER_GET_AGGREGATED_CHANGES"
+			),
+			getFileTimeInfoEntries: util.deprecate(
+				() => fetchTimeInfo().fileTimeInfoEntries,
+				"Watcher.getFileTimeInfoEntries is deprecated in favor of Watcher.getInfo since that's more performant.",
+				"DEP_WEBPACK_WATCHER_FILE_TIME_INFO_ENTRIES"
+			),
+			getContextTimeInfoEntries: util.deprecate(
+				() => fetchTimeInfo().contextTimeInfoEntries,
+				"Watcher.getContextTimeInfoEntries is deprecated in favor of Watcher.getInfo since that's more performant.",
+				"DEP_WEBPACK_WATCHER_CONTEXT_TIME_INFO_ENTRIES"
+			),
+			getInfo: () => {
+				const removals = this.watcher && this.watcher.aggregatedRemovals;
+				const changes = this.watcher && this.watcher.aggregatedChanges;
+				const fs = this.inputFileSystem;
+				if (fs && fs.purge) {
+					if (removals) {
+						for (const item of removals) {
+							fs.purge(item);
+						}
+					}
+					if (changes) {
+						for (const item of changes) {
+							fs.purge(item);
+						}
+					}
+				}
+				const { fileTimeInfoEntries, contextTimeInfoEntries } = fetchTimeInfo();
+				return {
+					changes,
+					removals,
+					fileTimeInfoEntries,
+					contextTimeInfoEntries
+				};
+			}
+		};
+	}
+}
+
+module.exports = NodeWatchFileSystem;
Index: frontend/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,289 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+	generateJavascriptHMR
+} = require("../hmr/JavascriptHotModuleReplacementHelper");
+const {
+	chunkHasJs,
+	getChunkFilenameTemplate
+} = require("../javascript/JavascriptModulesPlugin");
+const { getInitialChunkIds } = require("../javascript/StartupHelpers");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * Creates an instance of ReadFileChunkLoadingRuntimeModule.
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("readFile chunk loading", RuntimeModule.STAGE_ATTACH);
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this.runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Returns generated code.
+	 * @private
+	 * @param {Chunk} chunk chunk
+	 * @param {string} rootOutputDir root output directory
+	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
+	 * @returns {string} generated code
+	 */
+	_generateBaseUri(chunk, rootOutputDir, runtimeTemplate) {
+		const options = chunk.getEntryOptions();
+		if (options && options.baseUri) {
+			return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
+		}
+
+		return `${RuntimeGlobals.baseURI} = require(${runtimeTemplate.renderNodePrefixForCoreModule("url")}).pathToFileURL(${
+			rootOutputDir
+				? `__dirname + ${JSON.stringify(`/${rootOutputDir}`)}`
+				: "__filename"
+		});`;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI);
+		const withExternalInstallChunk = this.runtimeRequirements.has(
+			RuntimeGlobals.externalInstallChunk
+		);
+		const withOnChunkLoad = this.runtimeRequirements.has(
+			RuntimeGlobals.onChunksLoaded
+		);
+		const withLoading = this.runtimeRequirements.has(
+			RuntimeGlobals.ensureChunkHandlers
+		);
+		const withHmr = this.runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		const withHmrManifest = this.runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadManifest
+		);
+		const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
+		const hasJsMatcher = compileBooleanMatcher(conditionMap);
+		const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
+
+		const outputName = compilation.getPath(
+			getChunkFilenameTemplate(chunk, compilation.outputOptions),
+			{
+				chunk,
+				contentHashType: "javascript"
+			}
+		);
+		const rootOutputDir = getUndoPath(
+			outputName,
+			compilation.outputOptions.path,
+			false
+		);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_readFileVm`
+			: undefined;
+
+		return Template.asString([
+			withBaseURI
+				? this._generateBaseUri(chunk, rootOutputDir, runtimeTemplate)
+				: "// no baseURI",
+			"",
+			"// object to store loaded chunks",
+			'// "0" means "already loaded", Promise means loading',
+			`var installedChunks = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{`,
+			Template.indent(
+				Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(
+					",\n"
+				)
+			),
+			"};",
+			"",
+			withOnChunkLoad
+				? `${
+						RuntimeGlobals.onChunksLoaded
+					}.readFileVm = ${runtimeTemplate.returningFunction(
+						"installedChunks[chunkId] === 0",
+						"chunkId"
+					)};`
+				: "// no on chunks loaded",
+			"",
+			withLoading || withExternalInstallChunk
+				? `var installChunk = ${runtimeTemplate.basicFunction("chunk", [
+						"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
+						"for(var moduleId in moreModules) {",
+						Template.indent([
+							`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
+							Template.indent([
+								`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
+							]),
+							"}"
+						]),
+						"}",
+						`if(runtime) runtime(${RuntimeGlobals.require});`,
+						"for(var i = 0; i < chunkIds.length; i++) {",
+						Template.indent([
+							"if(installedChunks[chunkIds[i]]) {",
+							Template.indent(["installedChunks[chunkIds[i]][0]();"]),
+							"}",
+							"installedChunks[chunkIds[i]] = 0;"
+						]),
+						"}",
+						withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
+					])};`
+				: "// no chunk install function needed",
+			"",
+			withLoading
+				? Template.asString([
+						"// ReadFile + VM.run chunk loading for javascript",
+						`${fn}.readFileVm = function(chunkId, promises) {`,
+						hasJsMatcher !== false
+							? Template.indent([
+									"",
+									"var installedChunkData = installedChunks[chunkId];",
+									'if(installedChunkData !== 0) { // 0 means "already installed".',
+									Template.indent([
+										'// array of [resolve, reject, promise] means "currently loading"',
+										"if(installedChunkData) {",
+										Template.indent(["promises.push(installedChunkData[2]);"]),
+										"} else {",
+										Template.indent([
+											hasJsMatcher === true
+												? "if(true) { // all chunks have JS"
+												: `if(${hasJsMatcher("chunkId")}) {`,
+											Template.indent([
+												"// load the chunk and return promise to it",
+												"var promise = new Promise(function(resolve, reject) {",
+												Template.indent([
+													"installedChunkData = installedChunks[chunkId] = [resolve, reject];",
+													`var filename = require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).join(__dirname, ${JSON.stringify(
+														rootOutputDir
+													)} + ${
+														RuntimeGlobals.getChunkScriptFilename
+													}(chunkId));`,
+													`require(${runtimeTemplate.renderNodePrefixForCoreModule("fs")}).readFile(filename, 'utf-8', function(err, content) {`,
+													Template.indent([
+														"if(err) return reject(err);",
+														"var chunk = {};",
+														`require(${runtimeTemplate.renderNodePrefixForCoreModule("vm")}).runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)` +
+															`(chunk, require, require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).dirname(filename), filename);`,
+														"installChunk(chunk);"
+													]),
+													"});"
+												]),
+												"});",
+												"promises.push(installedChunkData[2] = promise);"
+											]),
+											hasJsMatcher === true
+												? "}"
+												: "} else installedChunks[chunkId] = 0;"
+										]),
+										"}"
+									]),
+									"}"
+								])
+							: Template.indent(["installedChunks[chunkId] = 0;"]),
+						"};"
+					])
+				: "// no chunk loading",
+			"",
+			withExternalInstallChunk
+				? Template.asString([
+						`module.exports = ${RuntimeGlobals.require};`,
+						`${RuntimeGlobals.externalInstallChunk} = installChunk;`
+					])
+				: "// no external install chunk",
+			"",
+			withHmr
+				? Template.asString([
+						"function loadUpdateChunk(chunkId, updatedModulesList) {",
+						Template.indent([
+							"return new Promise(function(resolve, reject) {",
+							Template.indent([
+								`var filename = require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).join(__dirname, ${JSON.stringify(
+									rootOutputDir
+								)} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`,
+								`require(${runtimeTemplate.renderNodePrefixForCoreModule("fs")}).readFile(filename, 'utf-8', function(err, content) {`,
+								Template.indent([
+									"if(err) return reject(err);",
+									"var update = {};",
+									`require(${runtimeTemplate.renderNodePrefixForCoreModule("vm")}).runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)` +
+										`(update, require, require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).dirname(filename), filename);`,
+									"var updatedModules = update.modules;",
+									"var runtime = update.runtime;",
+									"for(var moduleId in updatedModules) {",
+									Template.indent([
+										`if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
+										Template.indent([
+											"currentUpdate[moduleId] = updatedModules[moduleId];",
+											"if(updatedModulesList) updatedModulesList.push(moduleId);"
+										]),
+										"}"
+									]),
+									"}",
+									"if(runtime) currentUpdateRuntime.push(runtime);",
+									"resolve();"
+								]),
+								"});"
+							]),
+							"});"
+						]),
+						"}",
+						"",
+						generateJavascriptHMR("readFileVm")
+					])
+				: "// no HMR",
+			"",
+			withHmrManifest
+				? Template.asString([
+						`${RuntimeGlobals.hmrDownloadManifest} = function() {`,
+						Template.indent([
+							"return new Promise(function(resolve, reject) {",
+							Template.indent([
+								`var filename = require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).join(__dirname, ${JSON.stringify(
+									rootOutputDir
+								)} + ${RuntimeGlobals.getUpdateManifestFilename}());`,
+								`require(${runtimeTemplate.renderNodePrefixForCoreModule("fs")}).readFile(filename, 'utf-8', function(err, content) {`,
+								Template.indent([
+									"if(err) {",
+									Template.indent([
+										'if(["MODULE_NOT_FOUND", "ENOENT"].includes(err.code)) return resolve();',
+										"return reject(err);"
+									]),
+									"}",
+									"try { resolve(JSON.parse(content)); }",
+									"catch(e) { reject(e); }"
+								]),
+								"});"
+							]),
+							"});"
+						]),
+						"}"
+					])
+				: "// no HMR manifest"
+		]);
+	}
+}
+
+module.exports = ReadFileChunkLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/node/ReadFileCompileAsyncWasmPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/ReadFileCompileAsyncWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/ReadFileCompileAsyncWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,148 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const AsyncWasmCompileRuntimeModule = require("../wasm-async/AsyncWasmCompileRuntimeModule");
+const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the read file compile async wasm plugin options type used by this module.
+ * @typedef {object} ReadFileCompileAsyncWasmPluginOptions
+ * @property {boolean=} import use import?
+ */
+
+const PLUGIN_NAME = "ReadFileCompileAsyncWasmPlugin";
+
+class ReadFileCompileAsyncWasmPlugin {
+	/**
+	 * Creates an instance of ReadFileCompileAsyncWasmPlugin.
+	 * @param {ReadFileCompileAsyncWasmPluginOptions=} options options object
+	 */
+	constructor({ import: useImport = false } = {}) {
+		/** @type {boolean} */
+		this._import = useImport;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalWasmLoading = compilation.outputOptions.wasmLoading;
+			/**
+			 * Checks whether this read file compile async wasm plugin is enabled for chunk.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const wasmLoading =
+					options && options.wasmLoading !== undefined
+						? options.wasmLoading
+						: globalWasmLoading;
+				return wasmLoading === "async-node";
+			};
+
+			/**
+			 * @type {(path: string) => string} callback to generate code to load the wasm file
+			 */
+			const generateLoadBinaryCode = this._import
+				? (path) =>
+						Template.asString([
+							"Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
+							Template.indent([
+								`readFile(new URL(${path}, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
+								Template.indent([
+									"if (err) return reject(err);",
+									"",
+									"// Fake fetch response",
+									"resolve({",
+									Template.indent(["arrayBuffer() { return buffer; }"]),
+									"});"
+								]),
+								"});"
+							]),
+							"}))"
+						])
+				: (path) =>
+						Template.asString([
+							"new Promise(function (resolve, reject) {",
+							Template.indent([
+								"try {",
+								Template.indent([
+									`var { readFile } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("fs")});`,
+									`var { join } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("path")});`,
+									"",
+									`readFile(join(__dirname, ${path}), function(err, buffer){`,
+									Template.indent([
+										"if (err) return reject(err);",
+										"",
+										"// Fake fetch response",
+										"resolve({",
+										Template.indent(["arrayBuffer() { return buffer; }"]),
+										"});"
+									]),
+									"});"
+								]),
+								"} catch (err) { reject(err); }"
+							]),
+							"})"
+						]);
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.instantiateWasm)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
+						)
+					) {
+						return;
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncWasmLoadingRuntimeModule({
+							generateLoadBinaryCode,
+							supportsStreaming: false
+						})
+					);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.compileWasm)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
+						)
+					) {
+						return;
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncWasmCompileRuntimeModule({
+							generateLoadBinaryCode,
+							supportsStreaming: false
+						})
+					);
+				});
+		});
+	}
+}
+
+module.exports = ReadFileCompileAsyncWasmPlugin;
Index: frontend/node_modules/webpack/lib/node/ReadFileCompileWasmPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/node/ReadFileCompileWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/ReadFileCompileWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,130 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the read file compile wasm plugin options type used by this module.
+ * @typedef {object} ReadFileCompileWasmPluginOptions
+ * @property {boolean=} mangleImports mangle imports
+ * @property {boolean=} import use import?
+ */
+
+const PLUGIN_NAME = "ReadFileCompileWasmPlugin";
+
+class ReadFileCompileWasmPlugin {
+	/**
+	 * Creates an instance of ReadFileCompileWasmPlugin.
+	 * @param {ReadFileCompileWasmPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {ReadFileCompileWasmPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalWasmLoading = compilation.outputOptions.wasmLoading;
+			/**
+			 * Checks whether this read file compile wasm plugin is enabled for chunk.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, when wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const wasmLoading =
+					options && options.wasmLoading !== undefined
+						? options.wasmLoading
+						: globalWasmLoading;
+				return wasmLoading === "async-node";
+			};
+
+			/**
+			 * @type {(path: string) => string} callback to generate code to load the wasm file
+			 */
+			const generateLoadBinaryCode = this.options.import
+				? (path) =>
+						Template.asString([
+							"Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
+							Template.indent([
+								`readFile(new URL(${path}, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
+								Template.indent([
+									"if (err) return reject(err);",
+									"",
+									"// Fake fetch response",
+									"resolve({",
+									Template.indent(["arrayBuffer() { return buffer; }"]),
+									"});"
+								]),
+								"});"
+							]),
+							"}))"
+						])
+				: (path) =>
+						Template.asString([
+							"new Promise(function (resolve, reject) {",
+							Template.indent([
+								`var { readFile } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("fs")});`,
+								`var { join } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("path")});`,
+								"",
+								"try {",
+								Template.indent([
+									`readFile(join(__dirname, ${path}), function(err, buffer){`,
+									Template.indent([
+										"if (err) return reject(err);",
+										"",
+										"// Fake fetch response",
+										"resolve({",
+										Template.indent(["arrayBuffer() { return buffer; }"]),
+										"});"
+									]),
+									"});"
+								]),
+								"} catch (err) { reject(err); }"
+							]),
+							"})"
+						]);
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC
+						)
+					) {
+						return;
+					}
+					set.add(RuntimeGlobals.moduleCache);
+					compilation.addRuntimeModule(
+						chunk,
+						new WasmChunkLoadingRuntimeModule({
+							generateLoadBinaryCode,
+							supportsStreaming: false,
+							mangleImports: this.options.mangleImports,
+							runtimeRequirements: set
+						})
+					);
+				});
+		});
+	}
+}
+
+module.exports = ReadFileCompileWasmPlugin;
Index: frontend/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,242 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+	generateJavascriptHMR
+} = require("../hmr/JavascriptHotModuleReplacementHelper");
+const {
+	chunkHasJs,
+	getChunkFilenameTemplate
+} = require("../javascript/JavascriptModulesPlugin");
+const { getInitialChunkIds } = require("../javascript/StartupHelpers");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+class RequireChunkLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * Creates an instance of RequireChunkLoadingRuntimeModule.
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("require chunk loading", RuntimeModule.STAGE_ATTACH);
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this.runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Returns generated code.
+	 * @private
+	 * @param {Chunk} chunk chunk
+	 * @param {string} rootOutputDir root output directory
+	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
+	 * @returns {string} generated code
+	 */
+	_generateBaseUri(chunk, rootOutputDir, runtimeTemplate) {
+		const options = chunk.getEntryOptions();
+		if (options && options.baseUri) {
+			return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
+		}
+
+		return `${RuntimeGlobals.baseURI} = require(${runtimeTemplate.renderNodePrefixForCoreModule("url")}).pathToFileURL(${
+			rootOutputDir !== "./"
+				? `__dirname + ${JSON.stringify(`/${rootOutputDir}`)}`
+				: "__filename"
+		});`;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI);
+		const withExternalInstallChunk = this.runtimeRequirements.has(
+			RuntimeGlobals.externalInstallChunk
+		);
+		const withOnChunkLoad = this.runtimeRequirements.has(
+			RuntimeGlobals.onChunksLoaded
+		);
+		const withLoading = this.runtimeRequirements.has(
+			RuntimeGlobals.ensureChunkHandlers
+		);
+		const withHmr = this.runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		const withHmrManifest = this.runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadManifest
+		);
+		const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
+		const hasJsMatcher = compileBooleanMatcher(conditionMap);
+		const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
+
+		const outputName = compilation.getPath(
+			getChunkFilenameTemplate(chunk, compilation.outputOptions),
+			{
+				chunk,
+				contentHashType: "javascript"
+			}
+		);
+		const rootOutputDir = getUndoPath(
+			outputName,
+			compilation.outputOptions.path,
+			true
+		);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_require`
+			: undefined;
+
+		return Template.asString([
+			withBaseURI
+				? this._generateBaseUri(chunk, rootOutputDir, runtimeTemplate)
+				: "// no baseURI",
+			"",
+			"// object to store loaded chunks",
+			'// "1" means "loaded", otherwise not loaded yet',
+			`var installedChunks = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{`,
+			Template.indent(
+				Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 1`).join(
+					",\n"
+				)
+			),
+			"};",
+			"",
+			withOnChunkLoad
+				? `${
+						RuntimeGlobals.onChunksLoaded
+					}.require = ${runtimeTemplate.returningFunction(
+						"installedChunks[chunkId]",
+						"chunkId"
+					)};`
+				: "// no on chunks loaded",
+			"",
+			withLoading || withExternalInstallChunk
+				? `var installChunk = ${runtimeTemplate.basicFunction("chunk", [
+						"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
+						"for(var moduleId in moreModules) {",
+						Template.indent([
+							`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
+							Template.indent([
+								`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
+							]),
+							"}"
+						]),
+						"}",
+						`if(runtime) runtime(${RuntimeGlobals.require});`,
+						"for(var i = 0; i < chunkIds.length; i++)",
+						Template.indent("installedChunks[chunkIds[i]] = 1;"),
+						withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
+					])};`
+				: "// no chunk install function needed",
+			"",
+			withLoading
+				? Template.asString([
+						"// require() chunk loading for javascript",
+						`${fn}.require = ${runtimeTemplate.basicFunction(
+							"chunkId, promises",
+							hasJsMatcher !== false
+								? [
+										'// "1" is the signal for "already loaded"',
+										"if(!installedChunks[chunkId]) {",
+										Template.indent([
+											hasJsMatcher === true
+												? "if(true) { // all chunks have JS"
+												: `if(${hasJsMatcher("chunkId")}) {`,
+											Template.indent([
+												// The require function loads and runs a chunk. When the chunk is being run,
+												// it can call __webpack_require__.C to directly complete installed.
+												`var installedChunk = require(${JSON.stringify(
+													rootOutputDir
+												)} + ${
+													RuntimeGlobals.getChunkScriptFilename
+												}(chunkId));`,
+												"if (!installedChunks[chunkId]) {",
+												Template.indent(["installChunk(installedChunk);"]),
+												"}"
+											]),
+											"} else installedChunks[chunkId] = 1;",
+											""
+										]),
+										"}"
+									]
+								: "installedChunks[chunkId] = 1;"
+						)};`
+					])
+				: "// no chunk loading",
+			"",
+			withExternalInstallChunk
+				? Template.asString([
+						`module.exports = ${RuntimeGlobals.require};`,
+						`${RuntimeGlobals.externalInstallChunk} = installChunk;`
+					])
+				: "// no external install chunk",
+			"",
+			withHmr
+				? Template.asString([
+						"function loadUpdateChunk(chunkId, updatedModulesList) {",
+						Template.indent([
+							`var update = require(${JSON.stringify(rootOutputDir)} + ${
+								RuntimeGlobals.getChunkUpdateScriptFilename
+							}(chunkId));`,
+							"var updatedModules = update.modules;",
+							"var runtime = update.runtime;",
+							"for(var moduleId in updatedModules) {",
+							Template.indent([
+								`if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
+								Template.indent([
+									"currentUpdate[moduleId] = updatedModules[moduleId];",
+									"if(updatedModulesList) updatedModulesList.push(moduleId);"
+								]),
+								"}"
+							]),
+							"}",
+							"if(runtime) currentUpdateRuntime.push(runtime);"
+						]),
+						"}",
+						"",
+						generateJavascriptHMR("require")
+					])
+				: "// no HMR",
+			"",
+			withHmrManifest
+				? Template.asString([
+						`${RuntimeGlobals.hmrDownloadManifest} = function() {`,
+						Template.indent([
+							"return Promise.resolve().then(function() {",
+							Template.indent([
+								`return require(${JSON.stringify(rootOutputDir)} + ${
+									RuntimeGlobals.getUpdateManifestFilename
+								}());`
+							]),
+							`}).catch(${runtimeTemplate.basicFunction("err", [
+								"if(['MODULE_NOT_FOUND', 'ENOENT'].includes(err.code)) return;",
+								"throw err;"
+							])});`
+						]),
+						"}"
+					])
+				: "// no HMR manifest"
+		]);
+	}
+}
+
+module.exports = RequireChunkLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/node/nodeConsole.js
===================================================================
--- frontend/node_modules/webpack/lib/node/nodeConsole.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/node/nodeConsole.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,237 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const truncateArgs = require("../logging/truncateArgs");
+const memoize = require("../util/memoize");
+
+const getCli = memoize(() => require("../cli"));
+
+const ESC = "\u001B[";
+const CURSOR_UP = `${ESC}1A`;
+const CLEAR_LINE = `${ESC}2K\r`;
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../config/defaults").InfrastructureLoggingNormalizedWithDefaults} InfrastructureLoggingNormalizedWithDefaults */
+/** @typedef {import("../logging/createConsoleLogger").LoggerConsole} LoggerConsole */
+/**
+ * @typedef {object} StatusMessageState
+ * @property {string[] | undefined} currentMessage current status message
+ * @property {number} currentLines current status message rows
+ */
+
+/** @type {WeakMap<Compiler, StatusMessageState>} */
+const logStatusStateByCompiler = new WeakMap();
+/** @type {Set<StatusMessageState>} */
+const logStatusStates = new Set();
+
+/**
+ * Returns status state
+ * @param {Compiler} compiler compiler
+ * @returns {StatusMessageState} status state
+ */
+const getLogStatusState = (compiler) => {
+	let state = logStatusStateByCompiler.get(compiler);
+	if (state === undefined) {
+		state = {
+			currentMessage: undefined,
+			currentLines: 0
+		};
+		logStatusStateByCompiler.set(compiler, state);
+		logStatusStates.add(state);
+	}
+	return state;
+};
+
+/* eslint-disable no-console */
+
+/**
+ * Returns logger function.
+ * @param {object} options options
+ * @param {boolean=} options.colors colors
+ * @param {boolean=} options.appendOnly append only
+ * @param {InfrastructureLoggingNormalizedWithDefaults["stream"]} options.stream stream
+ * @param {Compiler} options.compiler compiler
+ * @returns {LoggerConsole} logger function
+ */
+module.exports = ({ colors, appendOnly, stream, compiler }) => {
+	const c = getCli().createColors({ useColor: Boolean(colors) });
+	const logStatusState = getLogStatusState(compiler);
+
+	let currentIndent = "";
+	let currentCollapsed = 0;
+
+	/**
+	 * Returns indented string.
+	 * @param {string} str string
+	 * @param {string} prefix prefix
+	 * @param {(line: string) => string} colorFn color function
+	 * @returns {string} indented string
+	 */
+	const indent = (str, prefix, colorFn) => {
+		if (str === "") return str;
+		prefix = currentIndent + prefix;
+		return (
+			prefix +
+			str
+				.split("\n")
+				.map((line) => colorFn(line))
+				.join(`\n${prefix}`)
+		);
+	};
+
+	const clearStatusMessage = () => {
+		let lines = 0;
+		for (const state of logStatusStates) {
+			if (state.currentLines) {
+				lines += state.currentLines;
+				state.currentLines = 0;
+			}
+		}
+		for (let i = 0; i < lines; i++) {
+			if (i > 0) stream.write(CURSOR_UP);
+			stream.write(CLEAR_LINE);
+		}
+	};
+
+	const writeStatusMessage = () => {
+		const column = stream.columns || 40;
+		/** @type {string[]} */
+		const all = [];
+
+		for (const state of logStatusStates) {
+			if (!state.currentMessage) continue;
+			/** @type {string[][]} */
+			const lines = [[]];
+			for (const item of state.currentMessage) {
+				const parts = item.split("\n");
+				lines[lines.length - 1].push(parts[0]);
+				for (let i = 1; i < parts.length; i++) {
+					lines.push([parts[i]]);
+				}
+			}
+			const truncateLines = lines.map((args) =>
+				truncateArgs(args, column - 1).join(" ")
+			);
+			state.currentLines = truncateLines.length;
+			for (const line of truncateLines) all.push(line);
+		}
+		if (all.length === 0) return;
+
+		const coloredLines = all.map((str) => c.bold(str));
+		stream.write(`${CLEAR_LINE}${coloredLines.join(`\n${CLEAR_LINE}`)}`);
+	};
+
+	/**
+	 * @param {EXPECTED_ANY[]} statusMessage status message
+	 * @returns {void}
+	 */
+	const setStatusMessage = (statusMessage) => {
+		clearStatusMessage();
+		logStatusState.currentMessage = statusMessage.map((item) => `${item}`);
+		writeStatusMessage();
+	};
+
+	/**
+	 * Returns function to write with colors.
+	 * @template T
+	 * @param {string} prefix prefix
+	 * @param {(line: string) => string} colorFn color function
+	 * @returns {(...args: T[]) => void} function to write with colors
+	 */
+	const writeColored =
+		(prefix, colorFn) =>
+		(...args) => {
+			if (currentCollapsed > 0) return;
+			clearStatusMessage();
+			const str = indent(util.format(...args), prefix, colorFn);
+			stream.write(`${str}\n`);
+			writeStatusMessage();
+		};
+
+	/** @type {<T extends unknown[]>(...args: T) => void} */
+	const writeGroupMessage = writeColored("<-> ", (str) => c.bold(c.cyan(str)));
+
+	/** @type {<T extends unknown[]>(...args: T) => void} */
+	const writeGroupCollapsedMessage = writeColored("<+> ", (str) =>
+		c.bold(c.cyan(str))
+	);
+
+	return {
+		/** @type {LoggerConsole["log"]} */
+		log: writeColored("    ", c.bold),
+		/** @type {LoggerConsole["debug"]} */
+		debug: writeColored("    ", String),
+		/** @type {LoggerConsole["trace"]} */
+		trace: writeColored("    ", String),
+		/** @type {LoggerConsole["info"]} */
+		info: writeColored("<i> ", (str) => c.bold(c.green(str))),
+		/** @type {LoggerConsole["warn"]} */
+		warn: writeColored("<w> ", (str) => c.bold(c.yellow(str))),
+		/** @type {LoggerConsole["error"]} */
+		error: writeColored("<e> ", (str) => c.bold(c.red(str))),
+		/** @type {LoggerConsole["logTime"]} */
+		logTime: writeColored("<t> ", (str) => c.bold(c.magenta(str))),
+		/** @type {LoggerConsole["group"]} */
+		group: (...args) => {
+			writeGroupMessage(...args);
+			if (currentCollapsed > 0) {
+				currentCollapsed++;
+			} else {
+				currentIndent += "  ";
+			}
+		},
+		/** @type {LoggerConsole["groupCollapsed"]} */
+		groupCollapsed: (...args) => {
+			writeGroupCollapsedMessage(...args);
+			currentCollapsed++;
+		},
+		/** @type {LoggerConsole["groupEnd"]} */
+		groupEnd: () => {
+			if (currentCollapsed > 0) {
+				currentCollapsed--;
+			} else if (currentIndent.length >= 2) {
+				currentIndent = currentIndent.slice(0, -2);
+			}
+		},
+		/** @type {LoggerConsole["profile"]} */
+		profile: console.profile && ((name) => console.profile(name)),
+		/** @type {LoggerConsole["profileEnd"]} */
+		profileEnd: console.profileEnd && ((name) => console.profileEnd(name)),
+		/** @type {LoggerConsole["clear"]} */
+		clear:
+			/** @type {() => void} */
+			(
+				!appendOnly &&
+					console.clear &&
+					(() => {
+						clearStatusMessage();
+						console.clear();
+						writeStatusMessage();
+					})
+			),
+		/** @type {LoggerConsole["status"]} */
+		status: appendOnly
+			? writeColored("<s> ", String)
+			: (name, ...args) => {
+					args = args.filter(Boolean);
+					if (name === undefined && args.length === 0) {
+						clearStatusMessage();
+						logStatusState.currentMessage = undefined;
+					} else if (
+						typeof name === "string" &&
+						name.startsWith("[webpack.Progress] ")
+					) {
+						setStatusMessage([name.slice(19), ...args]);
+					} else if (name === "[webpack.Progress]") {
+						setStatusMessage([...args]);
+					} else {
+						setStatusMessage([name, ...args]);
+					}
+				}
+	};
+};
Index: frontend/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the aggressive merging plugin options type used by this module.
+ * @typedef {object} AggressiveMergingPluginOptions
+ * @property {number=} minSizeReduce minimal size reduction to trigger merging
+ */
+
+const PLUGIN_NAME = "AggressiveMergingPlugin";
+
+class AggressiveMergingPlugin {
+	/**
+	 * Creates an instance of AggressiveMergingPlugin.
+	 * @param {AggressiveMergingPluginOptions=} options options object
+	 */
+	constructor(options) {
+		if (
+			(options !== undefined && typeof options !== "object") ||
+			Array.isArray(options)
+		) {
+			throw new Error(
+				"Argument should be an options object. To use defaults, pass in nothing.\nFor more info on options, see https://webpack.js.org/plugins/"
+			);
+		}
+		/** @type {AggressiveMergingPluginOptions} */
+		this.options = options || {};
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const options = this.options;
+		const minSizeReduce = options.minSizeReduce || 1.5;
+
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_ADVANCED
+				},
+				(chunks) => {
+					const chunkGraph = compilation.chunkGraph;
+					/** @type {{ a: Chunk, b: Chunk, improvement: number }[]} */
+					const combinations = [];
+					for (const a of chunks) {
+						if (a.canBeInitial()) continue;
+						for (const b of chunks) {
+							if (b.canBeInitial()) continue;
+							if (b === a) break;
+							if (!chunkGraph.canChunksBeIntegrated(a, b)) {
+								continue;
+							}
+							const aSize = chunkGraph.getChunkSize(b, {
+								chunkOverhead: 0
+							});
+							const bSize = chunkGraph.getChunkSize(a, {
+								chunkOverhead: 0
+							});
+							const abSize = chunkGraph.getIntegratedChunksSize(b, a, {
+								chunkOverhead: 0
+							});
+							const improvement = (aSize + bSize) / abSize;
+							combinations.push({
+								a,
+								b,
+								improvement
+							});
+						}
+					}
+
+					combinations.sort((a, b) => b.improvement - a.improvement);
+
+					const pair = combinations[0];
+
+					if (!pair) return;
+					if (pair.improvement < minSizeReduce) return;
+
+					chunkGraph.integrateChunks(pair.b, pair.a);
+					compilation.chunks.delete(pair.a);
+					return true;
+				}
+			);
+		});
+	}
+}
+
+module.exports = AggressiveMergingPlugin;
Index: frontend/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,344 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+const { intersect } = require("../util/SetHelpers");
+const {
+	compareChunks,
+	compareModulesByIdentifier
+} = require("../util/comparators");
+const identifierUtils = require("../util/identifier");
+
+/** @typedef {import("../../declarations/plugins/optimize/AggressiveSplittingPlugin").AggressiveSplittingPluginOptions} AggressiveSplittingPluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+/**
+ * Move module between.
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Chunk} oldChunk the old chunk
+ * @param {Chunk} newChunk the new chunk
+ * @returns {(module: Module) => void} function to move module between chunks
+ */
+const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => (module) => {
+	chunkGraph.disconnectChunkAndModule(oldChunk, module);
+	chunkGraph.connectChunkAndModule(newChunk, module);
+};
+
+/**
+ * Checks whether this object is not a entry module.
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Chunk} chunk the chunk
+ * @returns {(module: Module) => boolean} filter for entry module
+ */
+const isNotAEntryModule = (chunkGraph, chunk) => (module) =>
+	!chunkGraph.isEntryModuleInChunk(module, chunk);
+
+/** @typedef {{ id?: NonNullable<Chunk["id"]>, hash?: NonNullable<Chunk["hash"]>, modules: string[], size: number }} SplitData */
+
+/** @type {WeakSet<Chunk>} */
+const recordedChunks = new WeakSet();
+
+const PLUGIN_NAME = "AggressiveSplittingPlugin";
+
+class AggressiveSplittingPlugin {
+	/**
+	 * Creates an instance of AggressiveSplittingPlugin.
+	 * @param {AggressiveSplittingPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		/** @type {AggressiveSplittingPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Was chunk recorded.
+	 * @param {Chunk} chunk the chunk to test
+	 * @returns {boolean} true if the chunk was recorded
+	 */
+	static wasChunkRecorded(chunk) {
+		return recordedChunks.has(chunk);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.json"),
+				this.options,
+				{
+					name: "Aggressive Splitting Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.check")(
+						options
+					)
+			);
+		});
+
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			let needAdditionalSeal = false;
+			/** @type {SplitData[]} */
+			let newSplits;
+			/** @type {Set<Chunk>} */
+			let fromAggressiveSplittingSet;
+			/** @type {Map<Chunk, SplitData>} */
+			let chunkSplitDataMap;
+			compilation.hooks.optimize.tap(PLUGIN_NAME, () => {
+				newSplits = [];
+				fromAggressiveSplittingSet = new Set();
+				chunkSplitDataMap = new Map();
+			});
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_ADVANCED
+				},
+				(chunks) => {
+					const chunkGraph = compilation.chunkGraph;
+					// Precompute stuff
+					/** @type {Map<string, Module>} */
+					const nameToModuleMap = new Map();
+					/** @type {Map<Module, string>} */
+					const moduleToNameMap = new Map();
+					const makePathsRelative =
+						identifierUtils.makePathsRelative.bindContextCache(
+							compiler.context,
+							compiler.root
+						);
+					for (const m of compilation.modules) {
+						const name = makePathsRelative(m.identifier());
+						nameToModuleMap.set(name, m);
+						moduleToNameMap.set(m, name);
+					}
+
+					// Check used chunk ids
+					/** @type {Set<ChunkId>} */
+					const usedIds = new Set();
+					for (const chunk of chunks) {
+						usedIds.add(/** @type {ChunkId} */ (chunk.id));
+					}
+
+					const recordedSplits =
+						(compilation.records && compilation.records.aggressiveSplits) || [];
+					const usedSplits = newSplits
+						? [...recordedSplits, ...newSplits]
+						: recordedSplits;
+
+					const minSize = this.options.minSize || 30 * 1024;
+					const maxSize = this.options.maxSize || 50 * 1024;
+
+					/**
+					 * Returns true when applied, otherwise false.
+					 * @param {SplitData} splitData split data
+					 * @returns {boolean} true when applied, otherwise false
+					 */
+					const applySplit = (splitData) => {
+						// Cannot split if id is already taken
+						if (splitData.id !== undefined && usedIds.has(splitData.id)) {
+							return false;
+						}
+
+						// Get module objects from names
+						const selectedModules = splitData.modules.map(
+							(name) => /** @type {Module} */ (nameToModuleMap.get(name))
+						);
+
+						// Does the modules exist at all?
+						if (!selectedModules.every(Boolean)) return false;
+
+						// Check if size matches (faster than waiting for hash)
+						let size = 0;
+						for (const m of selectedModules) size += m.size();
+						if (size !== splitData.size) return false;
+
+						// get chunks with all modules
+						const selectedChunks = intersect(
+							selectedModules.map(
+								(m) => new Set(chunkGraph.getModuleChunksIterable(m))
+							)
+						);
+
+						// No relevant chunks found
+						if (selectedChunks.size === 0) return false;
+
+						// The found chunk is already the split or similar
+						if (
+							selectedChunks.size === 1 &&
+							chunkGraph.getNumberOfChunkModules([...selectedChunks][0]) ===
+								selectedModules.length
+						) {
+							const chunk = [...selectedChunks][0];
+							if (fromAggressiveSplittingSet.has(chunk)) return false;
+							fromAggressiveSplittingSet.add(chunk);
+							chunkSplitDataMap.set(chunk, splitData);
+							return true;
+						}
+
+						// split the chunk into two parts
+						const newChunk = compilation.addChunk();
+						newChunk.chunkReason = "aggressive splitted";
+						for (const chunk of selectedChunks) {
+							for (const module of selectedModules) {
+								moveModuleBetween(chunkGraph, chunk, newChunk)(module);
+							}
+							chunk.split(newChunk);
+							chunk.name = null;
+						}
+						fromAggressiveSplittingSet.add(newChunk);
+						chunkSplitDataMap.set(newChunk, splitData);
+
+						if (splitData.id !== null && splitData.id !== undefined) {
+							newChunk.id = splitData.id;
+							newChunk.ids = [splitData.id];
+						}
+						return true;
+					};
+
+					// try to restore to recorded splitting
+					let changed = false;
+					for (let j = 0; j < usedSplits.length; j++) {
+						const splitData = usedSplits[j];
+						if (applySplit(splitData)) changed = true;
+					}
+
+					// for any chunk which isn't splitted yet, split it and create a new entry
+					// start with the biggest chunk
+					const cmpFn = compareChunks(chunkGraph);
+					const sortedChunks = [...chunks].sort((a, b) => {
+						const diff1 =
+							chunkGraph.getChunkModulesSize(b) -
+							chunkGraph.getChunkModulesSize(a);
+						if (diff1) return diff1;
+						const diff2 =
+							chunkGraph.getNumberOfChunkModules(a) -
+							chunkGraph.getNumberOfChunkModules(b);
+						if (diff2) return diff2;
+						return cmpFn(a, b);
+					});
+					for (const chunk of sortedChunks) {
+						if (fromAggressiveSplittingSet.has(chunk)) continue;
+						const size = chunkGraph.getChunkModulesSize(chunk);
+						if (
+							size > maxSize &&
+							chunkGraph.getNumberOfChunkModules(chunk) > 1
+						) {
+							const modules = chunkGraph
+								.getOrderedChunkModules(chunk, compareModulesByIdentifier)
+								.filter(isNotAEntryModule(chunkGraph, chunk));
+							/** @type {Module[]} */
+							const selectedModules = [];
+							let selectedModulesSize = 0;
+							for (let k = 0; k < modules.length; k++) {
+								const module = modules[k];
+								const newSize = selectedModulesSize + module.size();
+								if (newSize > maxSize && selectedModulesSize >= minSize) {
+									break;
+								}
+								selectedModulesSize = newSize;
+								selectedModules.push(module);
+							}
+							if (selectedModules.length === 0) continue;
+							/** @type {SplitData} */
+							const splitData = {
+								modules: selectedModules
+									.map((m) => /** @type {string} */ (moduleToNameMap.get(m)))
+									.sort(),
+								size: selectedModulesSize
+							};
+
+							if (applySplit(splitData)) {
+								newSplits = [...(newSplits || []), splitData];
+								changed = true;
+							}
+						}
+					}
+					if (changed) return true;
+				}
+			);
+			compilation.hooks.recordHash.tap(PLUGIN_NAME, (records) => {
+				// 4. save made splittings to records
+				/** @type {Set<SplitData>} */
+				const allSplits = new Set();
+				/** @type {Set<SplitData>} */
+				const invalidSplits = new Set();
+
+				// Check if some splittings are invalid
+				// We remove invalid splittings and try again
+				for (const chunk of compilation.chunks) {
+					const splitData = chunkSplitDataMap.get(chunk);
+					if (
+						splitData !== undefined &&
+						splitData.hash &&
+						chunk.hash !== splitData.hash
+					) {
+						// Split was successful, but hash doesn't equal
+						// We can throw away the split since it's useless now
+						invalidSplits.add(splitData);
+					}
+				}
+
+				if (invalidSplits.size > 0) {
+					records.aggressiveSplits =
+						/** @type {SplitData[]} */
+						(records.aggressiveSplits).filter(
+							(splitData) => !invalidSplits.has(splitData)
+						);
+					needAdditionalSeal = true;
+				} else {
+					// set hash and id values on all (new) splittings
+					for (const chunk of compilation.chunks) {
+						const splitData = chunkSplitDataMap.get(chunk);
+						if (splitData !== undefined) {
+							splitData.hash =
+								/** @type {NonNullable<Chunk["hash"]>} */
+								(chunk.hash);
+							splitData.id =
+								/** @type {NonNullable<Chunk["id"]>} */
+								(chunk.id);
+							allSplits.add(splitData);
+							// set flag for stats
+							recordedChunks.add(chunk);
+						}
+					}
+
+					// Also add all unused historical splits (after the used ones)
+					// They can still be used in some future compilation
+					const recordedSplits =
+						compilation.records && compilation.records.aggressiveSplits;
+					if (recordedSplits) {
+						for (const splitData of recordedSplits) {
+							if (!invalidSplits.has(splitData)) allSplits.add(splitData);
+						}
+					}
+
+					// record all splits
+					records.aggressiveSplits = [...allSplits];
+
+					needAdditionalSeal = false;
+				}
+			});
+			compilation.hooks.needAdditionalSeal.tap(PLUGIN_NAME, () => {
+				if (needAdditionalSeal) {
+					needAdditionalSeal = false;
+					return true;
+				}
+			});
+		});
+	}
+}
+
+module.exports = AggressiveSplittingPlugin;
Index: frontend/node_modules/webpack/lib/optimize/ConcatenatedModule.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/ConcatenatedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/ConcatenatedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2347 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const eslintScope = require("eslint-scope");
+const Referencer = require("eslint-scope/lib/referencer");
+const { SyncBailHook } = require("tapable");
+const {
+	CachedSource,
+	ConcatSource,
+	ReplaceSource
+} = require("webpack-sources");
+const ConcatenationScope = require("../ConcatenationScope");
+const Dependency = require("../Dependency");
+const { UsageState } = require("../ExportsInfo");
+const Module = require("../Module");
+const {
+	JAVASCRIPT_TYPE,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const { DEFAULTS } = require("../config/defaults");
+const { ImportPhaseUtils } = require("../dependencies/ImportPhase");
+const JavascriptParser = require("../javascript/JavascriptParser");
+const {
+	getMakeDeferredNamespaceModeFromExportsType,
+	getOptimizedDeferredModule
+} = require("../runtime/MakeDeferredNamespaceObjectRuntime");
+const { equals } = require("../util/ArrayHelpers");
+const LazySet = require("../util/LazySet");
+const { concatComparators } = require("../util/comparators");
+const {
+	RESERVED_NAMES,
+	addScopeSymbols,
+	findNewName,
+	getAllReferences,
+	getPathInAst,
+	getUsedNamesInScopeInfo
+} = require("../util/concatenate");
+const createHash = require("../util/createHash");
+const { makePathsRelative } = require("../util/identifier");
+const makeSerializable = require("../util/makeSerializable");
+const { propertyAccess, propertyName } = require("../util/property");
+const {
+	filterRuntime,
+	intersectRuntime,
+	mergeRuntimeCondition,
+	mergeRuntimeConditionNonFalse,
+	runtimeConditionToString,
+	subtractRuntimeCondition
+} = require("../util/runtime");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../dependencies/ModuleDependency")} ModuleDependency */
+/** @typedef {import("../dependencies/HarmonyImportDependency")} HarmonyImportDependency */
+/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NameForCondition} NameForCondition */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").Scope} Scope */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").Reference} Reference */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").Variable} Variable */
+/** @typedef {import("../javascript/JavascriptParser").Program} Program */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+/** @typedef {import("../util/concatenate").UsedNames} UsedNames */
+/** @typedef {import("../util/concatenate").ScopeInfo} ScopeInfo */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/**
+ * @template T
+ * @typedef {import("../InitFragment")<T>} InitFragment
+ */
+
+/**
+ * @template T
+ * @typedef {import("../util/comparators").Comparator<T>} Comparator
+ */
+
+// fix eslint-scope to support class properties correctly
+// cspell:word Referencer
+const ReferencerClass = Referencer;
+if (!ReferencerClass.prototype.PropertyDefinition) {
+	ReferencerClass.prototype.PropertyDefinition =
+		ReferencerClass.prototype.Property;
+}
+
+/** @typedef {RawBinding | SymbolBinding} Binding */
+
+/** @typedef {string[]} ExportName */
+
+/**
+ * @typedef {object} RawBinding
+ * @property {ModuleInfo} info
+ * @property {string} rawName
+ * @property {string=} comment
+ * @property {ExportName} ids
+ * @property {ExportName} exportName
+ */
+
+/**
+ * @typedef {object} SymbolBinding
+ * @property {ConcatenatedModuleInfo} info
+ * @property {string} name
+ * @property {string=} comment
+ * @property {ExportName} ids
+ * @property {ExportName} exportName
+ */
+
+/** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo} ModuleInfo */
+/** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo | ReferenceToModuleInfo} ModuleInfoOrReference */
+
+/** @typedef {Map<string, string>} ExportMap */
+
+/**
+ * @typedef {object} ConcatenatedModuleInfo
+ * @property {"concatenated"} type
+ * @property {Module} module
+ * @property {number} index
+ * @property {Program | undefined} ast
+ * @property {Source | undefined} internalSource
+ * @property {ReplaceSource | undefined} source
+ * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
+ * @property {ReadOnlyRuntimeRequirements | undefined} runtimeRequirements
+ * @property {Scope | undefined} globalScope
+ * @property {Scope | undefined} moduleScope
+ * @property {Map<string, string>} internalNames
+ * @property {ExportMap | undefined} exportMap
+ * @property {ExportMap | undefined} rawExportMap
+ * @property {string=} namespaceExportSymbol
+ * @property {string | undefined} namespaceObjectName
+ * @property {ConcatenationScope | undefined} concatenationScope
+ * @property {boolean} interopNamespaceObjectUsed "default-with-named" namespace
+ * @property {string | undefined} interopNamespaceObjectName "default-with-named" namespace
+ * @property {boolean} interopNamespaceObject2Used "default-only" namespace
+ * @property {string | undefined} interopNamespaceObject2Name "default-only" namespace
+ * @property {boolean} interopDefaultAccessUsed runtime namespace object that detects "__esModule"
+ * @property {string | undefined} interopDefaultAccessName runtime namespace object that detects "__esModule"
+ */
+
+/**
+ * @typedef {object} ExternalModuleInfo
+ * @property {"external"} type
+ * @property {Module} module
+ * @property {RuntimeSpec | boolean} runtimeCondition
+ * @property {NonDeferAccess} nonDeferAccess
+ * @property {number} index
+ * @property {string | undefined} name module.exports / harmony namespace object
+ * @property {string | undefined} deferredName deferred module.exports / harmony namespace object
+ * @property {boolean} deferred the module is deferred at least once
+ * @property {boolean} deferredNamespaceObjectUsed deferred namespace object that being used in a not-analyzable way so it must be materialized
+ * @property {string | undefined} deferredNamespaceObjectName deferred namespace object that being used in a not-analyzable way so it must be materialized
+ * @property {boolean} interopNamespaceObjectUsed "default-with-named" namespace
+ * @property {string | undefined} interopNamespaceObjectName "default-with-named" namespace
+ * @property {boolean} interopNamespaceObject2Used "default-only" namespace
+ * @property {string | undefined} interopNamespaceObject2Name "default-only" namespace
+ * @property {boolean} interopDefaultAccessUsed runtime namespace object that detects "__esModule"
+ * @property {string | undefined} interopDefaultAccessName runtime namespace object that detects "__esModule"
+ */
+
+/**
+ * @typedef {object} ReferenceToModuleInfo
+ * @property {"reference"} type
+ * @property {RuntimeSpec | boolean} runtimeCondition
+ * @property {NonDeferAccess} nonDeferAccess
+ * @property {ModuleInfo} target
+ */
+
+/**
+ * @template T
+ * @param {string} property property
+ * @param {(a: T[keyof T], b: T[keyof T]) => 0 | 1 | -1} comparator comparator
+ * @returns {Comparator<T>} comparator
+ */
+
+const createComparator = (property, comparator) => (a, b) =>
+	comparator(
+		a[/** @type {keyof T} */ (property)],
+		b[/** @type {keyof T} */ (property)]
+	);
+
+/**
+ * @param {number} a a
+ * @param {number} b b
+ * @returns {0 | 1 | -1} result
+ */
+const compareNumbers = (a, b) => {
+	if (Number.isNaN(a)) {
+		if (!Number.isNaN(b)) {
+			return 1;
+		}
+	} else {
+		if (Number.isNaN(b)) {
+			return -1;
+		}
+		if (a !== b) {
+			return a < b ? -1 : 1;
+		}
+	}
+	return 0;
+};
+
+const bySourceOrder = createComparator("sourceOrder", compareNumbers);
+const byRangeStart = createComparator("rangeStart", compareNumbers);
+
+/**
+ * @param {Iterable<string>} iterable iterable object
+ * @returns {string} joined iterable object
+ */
+const joinIterableWithComma = (iterable) => {
+	// This is more performant than Array.from().join(", ")
+	// as it doesn't create an array
+	let str = "";
+	let first = true;
+	for (const item of iterable) {
+		if (first) {
+			first = false;
+		} else {
+			str += ", ";
+		}
+		str += item;
+	}
+	return str;
+};
+
+/** @typedef {boolean} NonDeferAccess */
+
+/**
+ * @param {NonDeferAccess} a a
+ * @param {NonDeferAccess} b b
+ * @returns {NonDeferAccess} merged
+ */
+const mergeNonDeferAccess = (a, b) => a || b;
+
+/**
+ * @param {NonDeferAccess} a first
+ * @param {NonDeferAccess} b second
+ * @returns {NonDeferAccess} first - second
+ */
+const subtractNonDeferAccess = (a, b) => a && !b;
+
+/**
+ * @typedef {object} ConcatenationEntry
+ * @property {"concatenated" | "external"} type
+ * @property {Module} module
+ * @property {RuntimeSpec | boolean} runtimeCondition
+ * @property {NonDeferAccess} nonDeferAccess
+ */
+
+/** @typedef {Set<ConcatenatedModuleInfo>} NeededNamespaceObjects */
+
+/** @typedef {Map<Module, ModuleInfo>} ModuleToInfoMap */
+
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ModuleInfo} info module info
+ * @param {ExportName} exportName exportName
+ * @param {ModuleToInfoMap} moduleToInfoMap moduleToInfoMap
+ * @param {RuntimeSpec} runtime for which runtime
+ * @param {RequestShortener} requestShortener the request shortener
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {NeededNamespaceObjects} neededNamespaceObjects modules for which a namespace object should be generated
+ * @param {boolean} asCall asCall
+ * @param {boolean} depDeferred the dependency is deferred
+ * @param {boolean | undefined} strictHarmonyModule strictHarmonyModule
+ * @param {boolean | undefined} asiSafe asiSafe
+ * @param {Set<ExportInfo>} alreadyVisited alreadyVisited
+ * @returns {Binding} the final variable
+ */
+const getFinalBinding = (
+	moduleGraph,
+	info,
+	exportName,
+	moduleToInfoMap,
+	runtime,
+	requestShortener,
+	runtimeTemplate,
+	neededNamespaceObjects,
+	asCall,
+	depDeferred,
+	strictHarmonyModule,
+	asiSafe,
+	alreadyVisited = new Set()
+) => {
+	const exportsType = info.module.getExportsType(
+		moduleGraph,
+		strictHarmonyModule
+	);
+	const moduleDeferred =
+		info.type === "external" &&
+		info.deferred &&
+		!(/** @type {BuildMeta} */ (info.module.buildMeta).async);
+	const deferred = depDeferred && moduleDeferred;
+	if (exportName.length === 0) {
+		switch (exportsType) {
+			case "default-only":
+				if (deferred) info.deferredNamespaceObjectUsed = true;
+				else info.interopNamespaceObject2Used = true;
+				return {
+					info,
+					rawName: /** @type {string} */ (
+						deferred
+							? info.deferredNamespaceObjectName
+							: info.interopNamespaceObject2Name
+					),
+					ids: exportName,
+					exportName
+				};
+			case "default-with-named":
+				if (deferred) info.deferredNamespaceObjectUsed = true;
+				else info.interopNamespaceObjectUsed = true;
+				return {
+					info,
+					rawName: /** @type {string} */ (
+						deferred
+							? info.deferredNamespaceObjectName
+							: info.interopNamespaceObjectName
+					),
+					ids: exportName,
+					exportName
+				};
+			case "namespace":
+			case "dynamic":
+				break;
+			default:
+				throw new Error(`Unexpected exportsType ${exportsType}`);
+		}
+	} else {
+		switch (exportsType) {
+			case "namespace":
+				break;
+			case "default-with-named":
+				switch (exportName[0]) {
+					case "default":
+						exportName = exportName.slice(1);
+						if (deferred) {
+							// `ns.default` for a deferred default-with-named external
+							// module must read through the optimized `.a` getter
+							// (which lazily evaluates the module and returns its
+							// exports), not the proxy namespace itself — otherwise
+							// `typeof ns.default` / `ns.default instanceof X`
+							// observe the proxy instead of the actual default.
+							return {
+								info,
+								rawName: `${info.deferredName}.a`,
+								ids: exportName,
+								exportName
+							};
+						}
+						break;
+					case "__esModule":
+						return {
+							info,
+							rawName: "/* __esModule */true",
+							ids: exportName.slice(1),
+							exportName
+						};
+				}
+				break;
+			case "default-only": {
+				const exportId = exportName[0];
+				if (exportId === "__esModule") {
+					return {
+						info,
+						rawName: "/* __esModule */true",
+						ids: exportName.slice(1),
+						exportName
+					};
+				}
+				exportName = exportName.slice(1);
+				if (exportId !== "default") {
+					return {
+						info,
+						rawName:
+							"/* non-default import from default-exporting module */undefined",
+						ids: exportName,
+						exportName
+					};
+				}
+				if (deferred) {
+					// As with default-with-named above, `ns.default` for a
+					// deferred default-only external must read through the
+					// optimized `.a` getter so that `typeof` / `instanceof`
+					// observe the actual default value rather than the proxy.
+					return {
+						info,
+						rawName: `${info.deferredName}.a`,
+						ids: exportName,
+						exportName
+					};
+				}
+				break;
+			}
+			case "dynamic":
+				switch (exportName[0]) {
+					case "default": {
+						exportName = exportName.slice(1);
+						if (deferred) {
+							return {
+								info,
+								rawName: `${info.deferredName}.a`,
+								ids: exportName,
+								exportName
+							};
+						}
+						if (moduleDeferred) {
+							return {
+								info,
+								rawName: /** @type {string} */ (info.name),
+								ids: exportName,
+								exportName
+							};
+						}
+						info.interopDefaultAccessUsed = true;
+						const defaultExport = asCall
+							? `${info.interopDefaultAccessName}()`
+							: asiSafe
+								? `(${info.interopDefaultAccessName}())`
+								: asiSafe === false
+									? `;(${info.interopDefaultAccessName}())`
+									: `${info.interopDefaultAccessName}.a`;
+						return {
+							info,
+							rawName: defaultExport,
+							ids: exportName,
+							exportName
+						};
+					}
+					case "__esModule":
+						return {
+							info,
+							rawName: "/* __esModule */true",
+							ids: exportName.slice(1),
+							exportName
+						};
+				}
+				break;
+			default:
+				throw new Error(`Unexpected exportsType ${exportsType}`);
+		}
+	}
+	if (exportName.length === 0) {
+		switch (info.type) {
+			case "concatenated":
+				neededNamespaceObjects.add(info);
+				return {
+					info,
+					rawName:
+						/** @type {NonNullable<ConcatenatedModuleInfo["namespaceObjectName"]>} */
+						(info.namespaceObjectName),
+					ids: exportName,
+					exportName
+				};
+			case "external":
+				if (deferred) {
+					info.deferredNamespaceObjectUsed = true;
+					return {
+						info,
+						rawName: /** @type {string} */ (info.deferredNamespaceObjectName),
+						ids: exportName,
+						exportName
+					};
+				}
+				return {
+					info,
+					rawName:
+						/** @type {NonNullable<ExternalModuleInfo["name"]>} */
+						(info.name),
+					ids: exportName,
+					exportName
+				};
+		}
+	}
+	const exportsInfo = moduleGraph.getExportsInfo(info.module);
+	const exportInfo = exportsInfo.getExportInfo(exportName[0]);
+	if (alreadyVisited.has(exportInfo)) {
+		return {
+			info,
+			rawName: "/* circular reexport */ Object(function x() { x() }())",
+			ids: [],
+			exportName
+		};
+	}
+	alreadyVisited.add(exportInfo);
+	switch (info.type) {
+		case "concatenated": {
+			const exportId = exportName[0];
+			if (exportInfo.provided === false) {
+				// It's not provided, but it could be on the prototype
+				neededNamespaceObjects.add(info);
+				return {
+					info,
+					rawName: /** @type {string} */ (info.namespaceObjectName),
+					ids: exportName,
+					exportName
+				};
+			}
+			const directExport = info.exportMap && info.exportMap.get(exportId);
+			if (directExport) {
+				const usedName = /** @type {ExportName} */ (
+					exportsInfo.getUsedName(exportName, runtime)
+				);
+				if (!usedName) {
+					return {
+						info,
+						rawName: "/* unused export */ undefined",
+						ids: exportName.slice(1),
+						exportName
+					};
+				}
+				return {
+					info,
+					name: directExport,
+					ids: usedName.slice(1),
+					exportName
+				};
+			}
+			const rawExport = info.rawExportMap && info.rawExportMap.get(exportId);
+			if (rawExport) {
+				return {
+					info,
+					rawName: rawExport,
+					ids: exportName.slice(1),
+					exportName
+				};
+			}
+			const reexport = exportInfo.findTarget(moduleGraph, (module) =>
+				moduleToInfoMap.has(module)
+			);
+			if (reexport === false) {
+				throw new Error(
+					`Target module of reexport from '${info.module.readableIdentifier(
+						requestShortener
+					)}' is not part of the concatenation (export '${exportId}')\nModules in the concatenation:\n${Array.from(
+						moduleToInfoMap,
+						([m, info]) =>
+							` * ${info.type} ${m.readableIdentifier(requestShortener)}`
+					).join("\n")}`
+				);
+			}
+			if (reexport) {
+				const refInfo = moduleToInfoMap.get(reexport.module);
+				return getFinalBinding(
+					moduleGraph,
+					/** @type {ModuleInfo} */ (refInfo),
+					reexport.export
+						? [...reexport.export, ...exportName.slice(1)]
+						: exportName.slice(1),
+					moduleToInfoMap,
+					runtime,
+					requestShortener,
+					runtimeTemplate,
+					neededNamespaceObjects,
+					asCall,
+					reexport.deferred,
+					/** @type {BuildMeta} */
+					(info.module.buildMeta).strictHarmonyModule,
+					asiSafe,
+					alreadyVisited
+				);
+			}
+			if (info.namespaceExportSymbol) {
+				const usedName = /** @type {ExportName} */ (
+					exportsInfo.getUsedName(exportName, runtime)
+				);
+				return {
+					info,
+					rawName: /** @type {string} */ (info.namespaceObjectName),
+					ids: usedName,
+					exportName
+				};
+			}
+			throw new Error(
+				`Cannot get final name for export '${exportName.join(
+					"."
+				)}' of ${info.module.readableIdentifier(requestShortener)}`
+			);
+		}
+
+		case "external": {
+			const used = /** @type {ExportName} */ (
+				exportsInfo.getUsedName(exportName, runtime)
+			);
+			if (!used) {
+				return {
+					info,
+					rawName: "/* unused export */ undefined",
+					ids: exportName.slice(1),
+					exportName
+				};
+			}
+			const comment = equals(used, exportName)
+				? ""
+				: Template.toNormalComment(`${exportName.join(".")}`);
+			return {
+				info,
+				rawName:
+					(deferred ? info.deferredName : info.name) +
+					(deferred ? ".a" : "") +
+					comment,
+				ids: used,
+				exportName
+			};
+		}
+	}
+};
+
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ModuleInfo} info module info
+ * @param {ExportName} exportName exportName
+ * @param {ModuleToInfoMap} moduleToInfoMap moduleToInfoMap
+ * @param {RuntimeSpec} runtime for which runtime
+ * @param {RequestShortener} requestShortener the request shortener
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {NeededNamespaceObjects} neededNamespaceObjects modules for which a namespace object should be generated
+ * @param {boolean} asCall asCall
+ * @param {boolean} depDeferred the dependency is deferred
+ * @param {boolean | undefined} callContext callContext
+ * @param {boolean | undefined} strictHarmonyModule strictHarmonyModule
+ * @param {boolean | undefined} asiSafe asiSafe
+ * @returns {string} the final name
+ */
+const getFinalName = (
+	moduleGraph,
+	info,
+	exportName,
+	moduleToInfoMap,
+	runtime,
+	requestShortener,
+	runtimeTemplate,
+	neededNamespaceObjects,
+	asCall,
+	depDeferred,
+	callContext,
+	strictHarmonyModule,
+	asiSafe
+) => {
+	const binding = getFinalBinding(
+		moduleGraph,
+		info,
+		exportName,
+		moduleToInfoMap,
+		runtime,
+		requestShortener,
+		runtimeTemplate,
+		neededNamespaceObjects,
+		asCall,
+		depDeferred,
+		strictHarmonyModule,
+		asiSafe
+	);
+	{
+		const { ids, comment } = binding;
+		/** @type {string} */
+		let reference;
+		/** @type {boolean} */
+		let isPropertyAccess;
+		if ("rawName" in binding) {
+			reference = `${binding.rawName}${comment || ""}${propertyAccess(ids)}`;
+			isPropertyAccess = ids.length > 0;
+		} else {
+			const { info, name: exportId } = binding;
+			const name = info.internalNames.get(exportId);
+			if (!name) {
+				throw new Error(
+					`The export "${exportId}" in "${info.module.readableIdentifier(
+						requestShortener
+					)}" has no internal name (existing names: ${
+						Array.from(
+							info.internalNames,
+							([name, symbol]) => `${name}: ${symbol}`
+						).join(", ") || "none"
+					})`
+				);
+			}
+			reference = `${name}${comment || ""}${propertyAccess(ids)}`;
+			isPropertyAccess = ids.length > 1;
+		}
+		if (isPropertyAccess && asCall && callContext === false) {
+			return asiSafe
+				? `(0,${reference})`
+				: asiSafe === false
+					? `;(0,${reference})`
+					: `/*#__PURE__*/Object(${reference})`;
+		}
+		return reference;
+	}
+};
+
+/**
+ * @typedef {object} ConcatenateModuleHooks
+ * @property {SyncBailHook<[ConcatenatedModule, RuntimeSpec[], string, Record<string, string>], boolean>} onDemandExportsGeneration
+ * @property {SyncBailHook<[Partial<ConcatenatedModuleInfo>, ConcatenatedModuleInfo], boolean | void>} concatenatedModuleInfo
+ */
+
+/** @typedef {BuildInfo["topLevelDeclarations"]} TopLevelDeclarations */
+
+/** @type {WeakMap<Compilation, ConcatenateModuleHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class ConcatenatedModule extends Module {
+	/**
+	 * @param {Module} rootModule the root module of the concatenation
+	 * @param {Set<Module>} modules all modules in the concatenation (including the root module)
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @param {Compilation} compilation the compilation
+	 * @param {AssociatedObjectForCache=} associatedObjectForCache object for caching
+	 * @param {HashFunction=} hashFunction hash function to use
+	 * @returns {ConcatenatedModule} the module
+	 */
+	static create(
+		rootModule,
+		modules,
+		runtime,
+		compilation,
+		associatedObjectForCache,
+		hashFunction = DEFAULTS.HASH_FUNCTION
+	) {
+		const identifier = ConcatenatedModule._createIdentifier(
+			rootModule,
+			modules,
+			associatedObjectForCache,
+			hashFunction
+		);
+		return new ConcatenatedModule({
+			identifier,
+			rootModule,
+			modules,
+			runtime,
+			compilation
+		});
+	}
+
+	/**
+	 * @param {Compilation} compilation the compilation
+	 * @returns {ConcatenateModuleHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				onDemandExportsGeneration: new SyncBailHook([
+					"module",
+					"runtimes",
+					"exportsFinalName",
+					"exportsSource"
+				]),
+				concatenatedModuleInfo: new SyncBailHook([
+					"updatedInfo",
+					"concatenatedModuleInfo"
+				])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * @param {object} options options
+	 * @param {string} options.identifier the identifier of the module
+	 * @param {Module} options.rootModule the root module of the concatenation
+	 * @param {RuntimeSpec} options.runtime the selected runtime
+	 * @param {Set<Module>} options.modules all concatenated modules
+	 * @param {Compilation} options.compilation the compilation
+	 */
+	constructor({ identifier, rootModule, modules, runtime, compilation }) {
+		super(JAVASCRIPT_MODULE_TYPE_ESM, null, rootModule && rootModule.layer);
+
+		// Info from Factory
+		/** @type {string} */
+		this._identifier = identifier;
+		/** @type {Module} */
+		this.rootModule = rootModule;
+		/** @type {Set<Module>} */
+		this._modules = modules;
+		this._runtime = runtime;
+		this.factoryMeta = rootModule && rootModule.factoryMeta;
+		/** @type {Compilation} */
+		this.compilation = compilation;
+	}
+
+	/**
+	 * 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) {
+		throw new Error("Must not be called");
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	get modules() {
+		return [...this._modules];
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this._identifier;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `${this.rootModule.readableIdentifier(
+			requestShortener
+		)} + ${this._modules.size - 1} modules`;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return this.rootModule.libIdent(options);
+	}
+
+	/**
+	 * Returns the path used when matching this module against rule conditions.
+	 * @returns {NameForCondition | null} absolute path which should be used for condition matching (usually the resource path)
+	 */
+	nameForCondition() {
+		return this.rootModule.nameForCondition();
+	}
+
+	/**
+	 * Gets side effects connection state.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only
+	 */
+	getSideEffectsConnectionState(moduleGraph) {
+		return this.rootModule.getSideEffectsConnectionState(moduleGraph);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		const { rootModule } = this;
+		const { moduleArgument, exportsArgument } =
+			/** @type {BuildInfo} */
+			(rootModule.buildInfo);
+		/** @type {BuildInfo} */
+		this.buildInfo = {
+			strict: true,
+			cacheable: true,
+			moduleArgument,
+			exportsArgument,
+			fileDependencies: new LazySet(),
+			contextDependencies: new LazySet(),
+			missingDependencies: new LazySet(),
+			topLevelDeclarations: new Set(),
+			assets: undefined
+		};
+		this.buildMeta = rootModule.buildMeta;
+		this.clearDependenciesAndBlocks();
+		this.clearWarningsAndErrors();
+
+		for (const m of this._modules) {
+			// populate cacheable
+			if (!(/** @type {BuildInfo} */ (m.buildInfo).cacheable)) {
+				this.buildInfo.cacheable = false;
+			}
+
+			// populate dependencies
+			for (const d of m.dependencies.filter(
+				(dep) =>
+					!Dependency.canConcatenate(dep) ||
+					!this._modules.has(
+						/** @type {Module} */
+						(compilation.moduleGraph.getModule(dep))
+					)
+			)) {
+				this.dependencies.push(d);
+			}
+			// populate codeGenerationDependencies — the inner modules'
+			// templates are applied during ConcatenatedModule.codeGeneration,
+			// so the referenced modules must have been code-generated by then.
+			// Skip references that point back into the concat set itself.
+			if (m.codeGenerationDependencies !== undefined) {
+				for (const d of m.codeGenerationDependencies) {
+					const referenced =
+						/** @type {Module} */
+						(compilation.moduleGraph.getModule(d));
+					if (!this._modules.has(referenced)) {
+						this.addCodeGenerationDependency(d);
+					}
+				}
+			}
+			// populate blocks
+			for (const d of m.blocks) {
+				this.blocks.push(d);
+			}
+
+			// populate warnings
+			const warnings = m.getWarnings();
+			if (warnings !== undefined) {
+				for (const warning of warnings) {
+					this.addWarning(warning);
+				}
+			}
+
+			// populate errors
+			const errors = m.getErrors();
+			if (errors !== undefined) {
+				for (const error of errors) {
+					this.addError(error);
+				}
+			}
+
+			const { assets, assetsInfo, topLevelDeclarations, needCreateRequire } =
+				/** @type {BuildInfo} */ (m.buildInfo);
+
+			const buildInfo = this.buildInfo;
+
+			// populate topLevelDeclarations
+			if (topLevelDeclarations) {
+				const topLevelDeclarations = buildInfo.topLevelDeclarations;
+				if (topLevelDeclarations !== undefined) {
+					for (const decl of topLevelDeclarations) {
+						topLevelDeclarations.add(decl);
+					}
+				}
+			} else {
+				buildInfo.topLevelDeclarations = undefined;
+			}
+
+			// populate needCreateRequire
+			if (needCreateRequire) {
+				this.buildInfo.needCreateRequire = true;
+			}
+
+			// populate assets
+			if (assets) {
+				if (buildInfo.assets === undefined) {
+					buildInfo.assets = Object.create(null);
+				}
+				Object.assign(
+					/** @type {NonNullable<BuildInfo["assets"]>} */
+					(buildInfo.assets),
+					assets
+				);
+			}
+			if (assetsInfo) {
+				if (buildInfo.assetsInfo === undefined) {
+					buildInfo.assetsInfo = new Map();
+				}
+				for (const [key, value] of assetsInfo) {
+					buildInfo.assetsInfo.set(key, value);
+				}
+			}
+		}
+		callback();
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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) {
+		// Guess size from embedded modules
+		let size = 0;
+		for (const module of this._modules) {
+			size += module.size(type);
+		}
+		return size;
+	}
+
+	/**
+	 * @private
+	 * @param {Module} rootModule the root of the concatenation
+	 * @param {Set<Module>} modulesSet a set of modules which should be concatenated
+	 * @param {RuntimeSpec} runtime for this runtime
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {ConcatenationEntry[]} concatenation list
+	 */
+	_createConcatenationList(rootModule, modulesSet, runtime, moduleGraph) {
+		/** @type {ConcatenationEntry[]} */
+		const list = [];
+		/** @type {Map<Module, { runtimeCondition: RuntimeSpec | true, nonDeferAccess: NonDeferAccess }>} */
+		const existingEntries = new Map();
+
+		/**
+		 * @param {Module} module a module
+		 * @returns {Iterable<{ connection: ModuleGraphConnection, runtimeCondition: RuntimeSpec | true, nonDeferAccess: NonDeferAccess }>} imported modules in order
+		 */
+		const getConcatenatedImports = (module) => {
+			const connections = [...moduleGraph.getOutgoingConnections(module)];
+			if (module === rootModule) {
+				for (const c of moduleGraph.getOutgoingConnections(this)) {
+					connections.push(c);
+				}
+			}
+			/**
+			 * @type {{ connection: ModuleGraphConnection, sourceOrder: number, rangeStart: number | undefined, defer?: boolean }[]}
+			 */
+			const references = connections
+				.filter((connection) => {
+					if (
+						!connection.dependency ||
+						!Dependency.canConcatenate(connection.dependency)
+					) {
+						return false;
+					}
+					if (
+						!Module.getSourceBasicTypes(connection.module).has(JAVASCRIPT_TYPE)
+					) {
+						return false;
+					}
+					return (
+						connection &&
+						connection.resolvedOriginModule === module &&
+						connection.module &&
+						connection.isTargetActive(runtime)
+					);
+				})
+				.map((connection) => {
+					const dep =
+						/** @type {HarmonyImportDependency} */
+						(connection.dependency);
+					return {
+						connection,
+						sourceOrder: /** @type {number} */ (dep.sourceOrder),
+						rangeStart: dep.range && dep.range[0],
+						defer: ImportPhaseUtils.isDefer(dep.phase)
+					};
+				});
+			/**
+			 * bySourceOrder
+			 * @example
+			 * import a from "a"; // sourceOrder=1
+			 * import b from "b"; // sourceOrder=2
+			 *
+			 * byRangeStart
+			 * @example
+			 * import {a, b} from "a"; // sourceOrder=1
+			 * a.a(); // first range
+			 * b.b(); // second range
+			 *
+			 * If there is no reexport, we have the same source.
+			 * If there is reexport, but module has side effects, this will lead to reexport module only.
+			 * If there is side-effects-free reexport, we can get simple deterministic result with range start comparison.
+			 */
+			references.sort(concatComparators(bySourceOrder, byRangeStart));
+			/** @type {Map<Module, { connection: ModuleGraphConnection, runtimeCondition: RuntimeSpec | true, nonDeferAccess: NonDeferAccess }>} */
+			const referencesMap = new Map();
+			for (const { connection, defer } of references) {
+				const runtimeCondition = filterRuntime(runtime, (r) =>
+					connection.isTargetActive(r)
+				);
+				if (runtimeCondition === false) continue;
+				const nonDeferAccess = !defer;
+				const module = connection.module;
+				const entry = referencesMap.get(module);
+				if (entry === undefined) {
+					referencesMap.set(module, {
+						connection,
+						runtimeCondition,
+						nonDeferAccess
+					});
+					continue;
+				}
+				entry.runtimeCondition = mergeRuntimeConditionNonFalse(
+					entry.runtimeCondition,
+					runtimeCondition,
+					runtime
+				);
+				entry.nonDeferAccess = mergeNonDeferAccess(
+					entry.nonDeferAccess,
+					nonDeferAccess
+				);
+			}
+			return referencesMap.values();
+		};
+
+		/**
+		 * @param {ModuleGraphConnection} connection graph connection
+		 * @param {RuntimeSpec | true} runtimeCondition runtime condition
+		 * @param {NonDeferAccess} nonDeferAccess non-defer access
+		 * @returns {void}
+		 */
+		const enterModule = (connection, runtimeCondition, nonDeferAccess) => {
+			const module = connection.module;
+			if (!module) return;
+			const existingEntry = existingEntries.get(module);
+			if (
+				existingEntry &&
+				existingEntry.runtimeCondition === true &&
+				existingEntry.nonDeferAccess === true
+			) {
+				return;
+			}
+			if (modulesSet.has(module)) {
+				existingEntries.set(module, {
+					runtimeCondition: true,
+					nonDeferAccess: true
+				});
+				if (runtimeCondition !== true) {
+					throw new Error(
+						`Cannot runtime-conditional concatenate a module (${module.identifier()} in ${this.rootModule.identifier()}, ${runtimeConditionToString(
+							runtimeCondition
+						)}). This should not happen.`
+					);
+				}
+				if (nonDeferAccess !== true) {
+					throw new Error(
+						`Cannot deferred concatenate a module (${module.identifier()} in ${this.rootModule.identifier()}. This should not happen.`
+					);
+				}
+				const imports = getConcatenatedImports(module);
+				for (const {
+					connection,
+					runtimeCondition,
+					nonDeferAccess
+				} of imports) {
+					enterModule(connection, runtimeCondition, nonDeferAccess);
+				}
+				list.push({
+					type: "concatenated",
+					module: connection.module,
+					runtimeCondition,
+					nonDeferAccess
+				});
+			} else {
+				/** @type {RuntimeSpec | boolean} */
+				let reducedRuntimeCondition;
+				/** @type {NonDeferAccess} */
+				let reducedNonDeferAccess;
+				if (existingEntry !== undefined) {
+					reducedRuntimeCondition = subtractRuntimeCondition(
+						runtimeCondition,
+						existingEntry.runtimeCondition,
+						runtime
+					);
+					reducedNonDeferAccess = subtractNonDeferAccess(
+						nonDeferAccess,
+						existingEntry.nonDeferAccess
+					);
+					if (
+						reducedRuntimeCondition === false &&
+						reducedNonDeferAccess === false
+					) {
+						return;
+					}
+					if (reducedRuntimeCondition !== false) {
+						existingEntry.runtimeCondition = mergeRuntimeConditionNonFalse(
+							existingEntry.runtimeCondition,
+							reducedRuntimeCondition,
+							runtime
+						);
+					}
+					if (reducedNonDeferAccess !== false) {
+						existingEntry.nonDeferAccess = mergeNonDeferAccess(
+							existingEntry.nonDeferAccess,
+							reducedNonDeferAccess
+						);
+					}
+				} else {
+					reducedRuntimeCondition = runtimeCondition;
+					reducedNonDeferAccess = nonDeferAccess;
+					existingEntries.set(connection.module, {
+						runtimeCondition,
+						nonDeferAccess
+					});
+				}
+				if (list.length > 0) {
+					const lastItem = list[list.length - 1];
+					if (
+						lastItem.type === "external" &&
+						lastItem.module === connection.module
+					) {
+						lastItem.runtimeCondition = mergeRuntimeCondition(
+							lastItem.runtimeCondition,
+							reducedRuntimeCondition,
+							runtime
+						);
+						lastItem.nonDeferAccess = mergeNonDeferAccess(
+							lastItem.nonDeferAccess,
+							reducedNonDeferAccess
+						);
+						return;
+					}
+				}
+				list.push({
+					type: "external",
+					get module() {
+						// We need to use a getter here, because the module in the dependency
+						// could be replaced by some other process (i. e. also replaced with a
+						// concatenated module)
+						return connection.module;
+					},
+					runtimeCondition: reducedRuntimeCondition,
+					nonDeferAccess: reducedNonDeferAccess
+				});
+			}
+		};
+
+		existingEntries.set(rootModule, {
+			runtimeCondition: true,
+			nonDeferAccess: true
+		});
+		const imports = getConcatenatedImports(rootModule);
+		for (const { connection, runtimeCondition, nonDeferAccess } of imports) {
+			enterModule(connection, runtimeCondition, nonDeferAccess);
+		}
+		list.push({
+			type: "concatenated",
+			module: rootModule,
+			runtimeCondition: true,
+			nonDeferAccess: true
+		});
+
+		return list;
+	}
+
+	/**
+	 * @param {Module} rootModule the root module of the concatenation
+	 * @param {Set<Module>} modules all modules in the concatenation (including the root module)
+	 * @param {AssociatedObjectForCache=} associatedObjectForCache object for caching
+	 * @param {HashFunction=} hashFunction hash function to use
+	 * @returns {string} the identifier
+	 */
+	static _createIdentifier(
+		rootModule,
+		modules,
+		associatedObjectForCache,
+		hashFunction = DEFAULTS.HASH_FUNCTION
+	) {
+		const cachedMakePathsRelative = makePathsRelative.bindContextCache(
+			/** @type {string} */ (rootModule.context),
+			associatedObjectForCache
+		);
+		/** @type {string[]} */
+		const identifiers = [];
+		for (const module of modules) {
+			identifiers.push(cachedMakePathsRelative(module.identifier()));
+		}
+		identifiers.sort();
+		const hash = createHash(hashFunction);
+		hash.update(identifiers.join(" "));
+		return `${rootModule.identifier()}|${hash.digest("hex")}`;
+	}
+
+	/**
+	 * Adds the provided file dependencies to the module.
+	 * @param {FileSystemDependencies} fileDependencies set where file dependencies are added to
+	 * @param {FileSystemDependencies} contextDependencies set where context dependencies are added to
+	 * @param {FileSystemDependencies} missingDependencies set where missing dependencies are added to
+	 * @param {FileSystemDependencies} buildDependencies set where build dependencies are added to
+	 */
+	addCacheDependencies(
+		fileDependencies,
+		contextDependencies,
+		missingDependencies,
+		buildDependencies
+	) {
+		for (const module of this._modules) {
+			module.addCacheDependencies(
+				fileDependencies,
+				contextDependencies,
+				missingDependencies,
+				buildDependencies
+			);
+		}
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({
+		dependencyTemplates,
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime: generationRuntime,
+		runtimes,
+		codeGenerationResults
+	}) {
+		const { concatenatedModuleInfo } = ConcatenatedModule.getCompilationHooks(
+			this.compilation
+		);
+
+		/** @type {RuntimeRequirements} */
+		const runtimeRequirements = new Set();
+		const runtime = intersectRuntime(generationRuntime, this._runtime);
+
+		const requestShortener = runtimeTemplate.requestShortener;
+		// Meta info for each module
+		const [modulesWithInfo, moduleToInfoMap] = this._getModulesWithInfo(
+			moduleGraph,
+			runtime
+		);
+
+		// Set with modules that need a generated namespace object
+		/** @type {NeededNamespaceObjects} */
+		const neededNamespaceObjects = new Set();
+
+		// List of all used names to avoid conflicts
+		const allUsedNames = new Set(RESERVED_NAMES);
+
+		// Generate source code and analyse scopes
+		// Prepare a ReplaceSource for the final source
+		for (const info of moduleToInfoMap.values()) {
+			this._analyseModule(
+				moduleToInfoMap,
+				info,
+				dependencyTemplates,
+				runtimeTemplate,
+				moduleGraph,
+				chunkGraph,
+				runtime,
+				runtimes,
+				/** @type {CodeGenerationResults} */
+				(codeGenerationResults),
+				allUsedNames
+			);
+		}
+
+		// Updated Top level declarations are created by renaming
+		/** @type {TopLevelDeclarations} */
+		const topLevelDeclarations = new Set();
+
+		// List of additional names in scope for module references
+		/** @type {Map<string, ScopeInfo>} */
+		const usedNamesInScopeInfo = new Map();
+
+		// Set of already checked scopes
+		/** @type {Set<Scope>} */
+		const ignoredScopes = new Set();
+
+		// get all global names
+		for (const info of modulesWithInfo) {
+			if (info.type === "concatenated") {
+				// ignore symbols from moduleScope
+				if (info.moduleScope) {
+					ignoredScopes.add(info.moduleScope);
+				}
+
+				// The super class expression in class scopes behaves weird
+				// We get ranges of all super class expressions to make
+				// renaming to work correctly
+				/** @typedef {{ range: Range, variables: Variable[] }} ClassInfo */
+				/** @type {WeakMap<Scope, ClassInfo[]>} */
+				const superClassCache = new WeakMap();
+				/**
+				 * @param {Scope} scope scope
+				 * @returns {ClassInfo[]} result
+				 */
+				const getSuperClassExpressions = (scope) => {
+					const cacheEntry = superClassCache.get(scope);
+					if (cacheEntry !== undefined) return cacheEntry;
+					/** @type {ClassInfo[]} */
+					const superClassExpressions = [];
+					for (const childScope of scope.childScopes) {
+						if (childScope.type !== "class") continue;
+						const block = childScope.block;
+						if (
+							(block.type === "ClassDeclaration" ||
+								block.type === "ClassExpression") &&
+							block.superClass
+						) {
+							superClassExpressions.push({
+								range: /** @type {Range} */ (block.superClass.range),
+								variables: childScope.variables
+							});
+						}
+					}
+					superClassCache.set(scope, superClassExpressions);
+					return superClassExpressions;
+				};
+
+				// add global symbols
+				if (info.globalScope) {
+					for (const reference of info.globalScope.through) {
+						const name = reference.identifier.name;
+						if (ConcatenationScope.isModuleReference(name)) {
+							const match = ConcatenationScope.matchModuleReference(name);
+							if (!match) continue;
+							const referencedInfo = modulesWithInfo[match.index];
+							if (referencedInfo.type === "reference") {
+								throw new Error("Module reference can't point to a reference");
+							}
+							const binding = getFinalBinding(
+								moduleGraph,
+								referencedInfo,
+								match.ids,
+								moduleToInfoMap,
+								runtime,
+								requestShortener,
+								runtimeTemplate,
+								neededNamespaceObjects,
+								false,
+								match.deferredImport,
+								/** @type {BuildMeta} */
+								(info.module.buildMeta).strictHarmonyModule,
+								true
+							);
+							if (!binding.ids) continue;
+							const { usedNames, alreadyCheckedScopes } =
+								getUsedNamesInScopeInfo(
+									usedNamesInScopeInfo,
+									binding.info.module.identifier(),
+									"name" in binding ? binding.name : ""
+								);
+							for (const expr of getSuperClassExpressions(reference.from)) {
+								if (
+									expr.range[0] <=
+										/** @type {Range} */ (reference.identifier.range)[0] &&
+									expr.range[1] >=
+										/** @type {Range} */ (reference.identifier.range)[1]
+								) {
+									for (const variable of expr.variables) {
+										usedNames.add(variable.name);
+									}
+								}
+							}
+							addScopeSymbols(
+								reference.from,
+								usedNames,
+								alreadyCheckedScopes,
+								ignoredScopes
+							);
+						} else {
+							allUsedNames.add(name);
+						}
+					}
+				}
+			}
+		}
+
+		/**
+		 * @param {string} name the name to find a new name for
+		 * @param {ConcatenatedModuleInfo} info the info of the module
+		 * @param {Reference[]} references the references to the name
+		 * @returns {string | undefined} the new name or undefined if the name is not found
+		 */
+		const _findNewName = (name, info, references) => {
+			const { usedNames, alreadyCheckedScopes } = getUsedNamesInScopeInfo(
+				usedNamesInScopeInfo,
+				info.module.identifier(),
+				name
+			);
+			if (allUsedNames.has(name) || usedNames.has(name)) {
+				for (const ref of references) {
+					addScopeSymbols(
+						ref.from,
+						usedNames,
+						alreadyCheckedScopes,
+						ignoredScopes
+					);
+				}
+				const newName = findNewName(
+					name,
+					allUsedNames,
+					usedNames,
+					info.module.readableIdentifier(requestShortener)
+				);
+				allUsedNames.add(newName);
+				info.internalNames.set(name, newName);
+				topLevelDeclarations.add(newName);
+				return newName;
+			}
+		};
+
+		/**
+		 * @param {string} name the name to find a new name for
+		 * @param {ConcatenatedModuleInfo} info the info of the module
+		 * @param {Reference[]} references the references to the name
+		 * @returns {string | undefined} the new name or undefined if the name is not found
+		 */
+		const _findNewNameForSpecifier = (name, info, references) => {
+			const { usedNames: moduleUsedNames, alreadyCheckedScopes } =
+				getUsedNamesInScopeInfo(
+					usedNamesInScopeInfo,
+					info.module.identifier(),
+					name
+				);
+			/** @type {UsedNames} */
+			const referencesUsedNames = new Set();
+			for (const ref of references) {
+				addScopeSymbols(
+					ref.from,
+					referencesUsedNames,
+					alreadyCheckedScopes,
+					ignoredScopes
+				);
+			}
+			if (moduleUsedNames.has(name) || referencesUsedNames.has(name)) {
+				const newName = findNewName(
+					name,
+					allUsedNames,
+					new Set([...moduleUsedNames, ...referencesUsedNames]),
+					info.module.readableIdentifier(requestShortener)
+				);
+				allUsedNames.add(newName);
+				topLevelDeclarations.add(newName);
+				return newName;
+			}
+		};
+
+		// generate names for symbols
+		for (const info of moduleToInfoMap.values()) {
+			const { usedNames: namespaceObjectUsedNames } = getUsedNamesInScopeInfo(
+				usedNamesInScopeInfo,
+				info.module.identifier(),
+				""
+			);
+			switch (info.type) {
+				case "concatenated": {
+					const variables = /** @type {Scope} */ (info.moduleScope).variables;
+					for (const variable of variables) {
+						const name = variable.name;
+						const references = getAllReferences(variable);
+						const newName = _findNewName(name, info, references);
+						if (newName) {
+							const source = /** @type {ReplaceSource} */ (info.source);
+							const allIdentifiers = new Set([
+								...references.map((r) => r.identifier),
+								...variable.identifiers
+							]);
+							for (const identifier of allIdentifiers) {
+								const r = /** @type {Range} */ (identifier.range);
+								const path = getPathInAst(
+									/** @type {NonNullable<ConcatenatedModuleInfo["ast"]>} */
+									(info.ast),
+									identifier
+								);
+								if (path && path.length > 1) {
+									const maybeProperty =
+										path[1].type === "AssignmentPattern" &&
+										path[1].left === path[0]
+											? path[2]
+											: path[1];
+									if (
+										maybeProperty.type === "Property" &&
+										maybeProperty.shorthand
+									) {
+										source.insert(r[1], `: ${newName}`);
+										continue;
+									}
+								}
+								source.replace(r[0], r[1] - 1, newName);
+							}
+						} else {
+							allUsedNames.add(name);
+							info.internalNames.set(name, name);
+							topLevelDeclarations.add(name);
+						}
+					}
+					/** @type {string} */
+					let namespaceObjectName;
+					if (info.namespaceExportSymbol) {
+						namespaceObjectName =
+							/** @type {string} */
+							(info.internalNames.get(info.namespaceExportSymbol));
+					} else {
+						namespaceObjectName = findNewName(
+							"namespaceObject",
+							allUsedNames,
+							namespaceObjectUsedNames,
+							info.module.readableIdentifier(requestShortener)
+						);
+						allUsedNames.add(namespaceObjectName);
+					}
+					info.namespaceObjectName = namespaceObjectName;
+					topLevelDeclarations.add(namespaceObjectName);
+					break;
+				}
+				case "external": {
+					const externalName = findNewName(
+						"",
+						allUsedNames,
+						namespaceObjectUsedNames,
+						info.module.readableIdentifier(requestShortener)
+					);
+					allUsedNames.add(externalName);
+					info.name = externalName;
+					topLevelDeclarations.add(externalName);
+
+					if (info.deferred) {
+						const externalName = findNewName(
+							"deferred",
+							allUsedNames,
+							namespaceObjectUsedNames,
+							info.module.readableIdentifier(requestShortener)
+						);
+						allUsedNames.add(externalName);
+						info.deferredName = externalName;
+						topLevelDeclarations.add(externalName);
+
+						const externalNameInterop = findNewName(
+							"deferredNamespaceObject",
+							allUsedNames,
+							namespaceObjectUsedNames,
+							info.module.readableIdentifier(requestShortener)
+						);
+						allUsedNames.add(externalNameInterop);
+						info.deferredNamespaceObjectName = externalNameInterop;
+						topLevelDeclarations.add(externalNameInterop);
+					}
+					break;
+				}
+			}
+			const buildMeta = /** @type {BuildMeta} */ (info.module.buildMeta);
+			if (buildMeta.exportsType !== "namespace") {
+				const externalNameInterop = findNewName(
+					"namespaceObject",
+					allUsedNames,
+					namespaceObjectUsedNames,
+					info.module.readableIdentifier(requestShortener)
+				);
+				allUsedNames.add(externalNameInterop);
+				info.interopNamespaceObjectName = externalNameInterop;
+				topLevelDeclarations.add(externalNameInterop);
+			}
+			if (
+				buildMeta.exportsType === "default" &&
+				buildMeta.defaultObject !== "redirect" &&
+				info.interopNamespaceObject2Used
+			) {
+				const externalNameInterop = findNewName(
+					"namespaceObject2",
+					allUsedNames,
+					namespaceObjectUsedNames,
+					info.module.readableIdentifier(requestShortener)
+				);
+				allUsedNames.add(externalNameInterop);
+				info.interopNamespaceObject2Name = externalNameInterop;
+				topLevelDeclarations.add(externalNameInterop);
+			}
+			if (buildMeta.exportsType === "dynamic" || !buildMeta.exportsType) {
+				const externalNameInterop = findNewName(
+					"default",
+					allUsedNames,
+					namespaceObjectUsedNames,
+					info.module.readableIdentifier(requestShortener)
+				);
+				allUsedNames.add(externalNameInterop);
+				info.interopDefaultAccessName = externalNameInterop;
+				topLevelDeclarations.add(externalNameInterop);
+			}
+		}
+
+		// Find and replace references to modules
+		for (const info of moduleToInfoMap.values()) {
+			if (info.type === "concatenated") {
+				const globalScope = /** @type {Scope} */ (info.globalScope);
+				// group references by name
+				/** @type {Map<string, Reference[]>} */
+				const referencesByName = new Map();
+				for (const reference of globalScope.through) {
+					const name = reference.identifier.name;
+					if (!referencesByName.has(name)) {
+						referencesByName.set(name, []);
+					}
+					/** @type {Reference[]} */
+					(referencesByName.get(name)).push(reference);
+				}
+				for (const [name, references] of referencesByName) {
+					const match = ConcatenationScope.matchModuleReference(name);
+					if (match) {
+						const referencedInfo = modulesWithInfo[match.index];
+						if (referencedInfo.type === "reference") {
+							throw new Error("Module reference can't point to a reference");
+						}
+						const concatenationScope = /** @type {ConcatenatedModuleInfo} */ (
+							referencedInfo
+						).concatenationScope;
+						const exportId = match.ids[0];
+						const specifier =
+							concatenationScope && concatenationScope.getRawExport(exportId);
+						if (specifier) {
+							const newName = _findNewNameForSpecifier(
+								specifier,
+								info,
+								references
+							);
+							const initFragmentChanged =
+								newName &&
+								concatenatedModuleInfo.call(
+									{
+										rawExportMap: new Map([
+											[exportId, /** @type {string} */ (newName)]
+										])
+									},
+									/** @type {ConcatenatedModuleInfo} */ (referencedInfo)
+								);
+							if (initFragmentChanged) {
+								concatenationScope.setRawExportMap(exportId, newName);
+							}
+						}
+						const finalName = getFinalName(
+							moduleGraph,
+							referencedInfo,
+							match.ids,
+							moduleToInfoMap,
+							runtime,
+							requestShortener,
+							runtimeTemplate,
+							neededNamespaceObjects,
+							match.call,
+							match.deferredImport,
+							!match.directImport,
+							/** @type {BuildMeta} */
+							(info.module.buildMeta).strictHarmonyModule,
+							match.asiSafe
+						);
+
+						for (const reference of references) {
+							const r = /** @type {Range} */ (reference.identifier.range);
+							const source = /** @type {ReplaceSource} */ (info.source);
+							// range is extended by 2 chars to cover the appended "._"
+							source.replace(r[0], r[1] + 1, finalName);
+						}
+					}
+				}
+			}
+		}
+
+		// Map with all root exposed used exports
+		/** @type {Map<string, (requestShortener: RequestShortener) => string>} */
+		const exportsMap = new Map();
+
+		// Set with all root exposed unused exports
+		/** @type {Set<string>} */
+		const unusedExports = new Set();
+
+		const rootInfo =
+			/** @type {ConcatenatedModuleInfo} */
+			(moduleToInfoMap.get(this.rootModule));
+		const strictHarmonyModule =
+			/** @type {BuildMeta} */
+			(rootInfo.module.buildMeta).strictHarmonyModule;
+		const exportsInfo = moduleGraph.getExportsInfo(rootInfo.module);
+		/** @type {Record<string, string>} */
+		const exportsFinalName = {};
+		for (const exportInfo of exportsInfo.orderedExports) {
+			const name = exportInfo.name;
+			if (exportInfo.provided === false) continue;
+			const used = exportInfo.getUsedName(undefined, runtime);
+			if (!used) {
+				unusedExports.add(name);
+				continue;
+			}
+			exportsMap.set(used, (requestShortener) => {
+				try {
+					const finalName = getFinalName(
+						moduleGraph,
+						rootInfo,
+						[name],
+						moduleToInfoMap,
+						runtime,
+						requestShortener,
+						runtimeTemplate,
+						neededNamespaceObjects,
+						false,
+						false,
+						false,
+						strictHarmonyModule,
+						true
+					);
+					exportsFinalName[used] = finalName;
+					return `/* ${
+						exportInfo.isReexport() ? "reexport" : "binding"
+					} */ ${finalName}`;
+				} catch (err) {
+					/** @type {Error} */
+					(err).message +=
+						`\nwhile generating the root export '${name}' (used name: '${used}')`;
+					throw err;
+				}
+			});
+		}
+
+		const result = new ConcatSource();
+
+		// add harmony compatibility flag (must be first because of possible circular dependencies)
+		let shouldAddHarmonyFlag = false;
+		const rootExportsInfo = moduleGraph.getExportsInfo(this);
+		if (
+			rootExportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused ||
+			rootExportsInfo.getReadOnlyExportInfo("__esModule").getUsed(runtime) !==
+				UsageState.Unused
+		) {
+			shouldAddHarmonyFlag = true;
+		}
+
+		// define exports
+		if (exportsMap.size > 0) {
+			/** @type {string[]} */
+			const definitions = [];
+			for (const [key, value] of exportsMap) {
+				definitions.push(
+					`\n  ${propertyName(key)}: ${runtimeTemplate.returningFunction(
+						value(requestShortener)
+					)}`
+				);
+			}
+
+			runtimeRequirements.add(RuntimeGlobals.exports);
+			runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+
+			if (shouldAddHarmonyFlag) {
+				result.add("// ESM COMPAT FLAG\n");
+				result.add(
+					runtimeTemplate.defineEsModuleFlagStatement({
+						exportsArgument: this.exportsArgument,
+						runtimeRequirements
+					})
+				);
+			}
+
+			const exportsSource =
+				"\n// EXPORTS\n" +
+				`${RuntimeGlobals.definePropertyGetters}(${this.exportsArgument}, {${definitions.join(
+					","
+				)}\n});\n`;
+
+			const { onDemandExportsGeneration } =
+				ConcatenatedModule.getCompilationHooks(this.compilation);
+
+			if (
+				!onDemandExportsGeneration.call(
+					this,
+					runtimes,
+					exportsSource,
+					exportsFinalName
+				)
+			) {
+				result.add(exportsSource);
+			}
+		}
+
+		// list unused exports
+		if (unusedExports.size > 0) {
+			result.add(
+				`\n// UNUSED EXPORTS: ${joinIterableWithComma(unusedExports)}\n`
+			);
+		}
+
+		// generate namespace objects
+		/** @type {Map<ConcatenatedModuleInfo, string>} */
+		const namespaceObjectSources = new Map();
+		for (const info of neededNamespaceObjects) {
+			if (info.namespaceExportSymbol) continue;
+			/** @type {string[]} */
+			const nsObj = [];
+			const exportsInfo = moduleGraph.getExportsInfo(info.module);
+			for (const exportInfo of exportsInfo.orderedExports) {
+				if (exportInfo.provided === false) continue;
+				const usedName = exportInfo.getUsedName(undefined, runtime);
+				if (usedName) {
+					const finalName = getFinalName(
+						moduleGraph,
+						info,
+						[exportInfo.name],
+						moduleToInfoMap,
+						runtime,
+						requestShortener,
+						runtimeTemplate,
+						neededNamespaceObjects,
+						false,
+						false,
+						undefined,
+						/** @type {BuildMeta} */
+						(info.module.buildMeta).strictHarmonyModule,
+						true
+					);
+					nsObj.push(
+						`\n  ${propertyName(usedName)}: ${runtimeTemplate.returningFunction(
+							finalName
+						)}`
+					);
+				}
+			}
+			const name = info.namespaceObjectName;
+			const defineGetters =
+				nsObj.length > 0
+					? `${RuntimeGlobals.definePropertyGetters}(${name}, {${nsObj.join(
+							","
+						)}\n});\n`
+					: "";
+			if (nsObj.length > 0) {
+				runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+			}
+			namespaceObjectSources.set(
+				info,
+				`
+// NAMESPACE OBJECT: ${info.module.readableIdentifier(requestShortener)}
+var ${name} = {};
+${RuntimeGlobals.makeNamespaceObject}(${name});
+${defineGetters}`
+			);
+			runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
+		}
+
+		// define required namespace objects (must be before evaluation modules)
+		for (const info of modulesWithInfo) {
+			if (info.type === "concatenated") {
+				const source = namespaceObjectSources.get(info);
+				if (!source) continue;
+				result.add(source);
+			}
+
+			if (info.type === "external" && info.deferred) {
+				const moduleId = JSON.stringify(chunkGraph.getModuleId(info.module));
+				const loader = getOptimizedDeferredModule(
+					moduleId,
+					info.module.getExportsType(
+						moduleGraph,
+						/** @type {BuildMeta} */
+						(this.rootModule.buildMeta).strictHarmonyModule
+					),
+					// an async module will opt-out of the concat module optimization.
+					[],
+					runtimeRequirements
+				);
+				runtimeRequirements.add(RuntimeGlobals.require);
+				result.add(
+					`\n// DEFERRED EXTERNAL MODULE: ${info.module.readableIdentifier(requestShortener)}\nvar ${info.deferredName} = ${loader};`
+				);
+				if (info.deferredNamespaceObjectUsed) {
+					runtimeRequirements.add(RuntimeGlobals.makeDeferredNamespaceObject);
+					result.add(
+						`\nvar ${info.deferredNamespaceObjectName} = /*#__PURE__*/${
+							RuntimeGlobals.makeDeferredNamespaceObject
+						}(${JSON.stringify(
+							chunkGraph.getModuleId(info.module)
+						)}, ${getMakeDeferredNamespaceModeFromExportsType(
+							info.module.getExportsType(moduleGraph, strictHarmonyModule)
+						)});`
+					);
+				}
+			}
+		}
+
+		/** @type {InitFragment<ChunkRenderContext>[]} */
+		const chunkInitFragments = [];
+
+		// evaluate modules in order
+		for (const rawInfo of modulesWithInfo) {
+			/** @type {undefined | string} */
+			let name;
+			let isConditional = false;
+			const info = rawInfo.type === "reference" ? rawInfo.target : rawInfo;
+			switch (info.type) {
+				case "concatenated": {
+					result.add(
+						`\n;// ${info.module.readableIdentifier(requestShortener)}\n`
+					);
+					result.add(/** @type {ReplaceSource} */ (info.source));
+					if (info.chunkInitFragments) {
+						for (const f of info.chunkInitFragments) chunkInitFragments.push(f);
+					}
+					if (info.runtimeRequirements) {
+						for (const r of info.runtimeRequirements) {
+							runtimeRequirements.add(r);
+						}
+					}
+					name = info.namespaceObjectName;
+					break;
+				}
+				case "external": {
+					// deferred case is handled in the "const info of modulesWithInfo" loop above
+					if (!info.deferred) {
+						result.add(
+							`\n// EXTERNAL MODULE: ${info.module.readableIdentifier(
+								requestShortener
+							)}\n`
+						);
+						runtimeRequirements.add(RuntimeGlobals.require);
+						const { runtimeCondition } =
+							/** @type {ExternalModuleInfo | ReferenceToModuleInfo} */
+							(rawInfo);
+						const condition = runtimeTemplate.runtimeConditionExpression({
+							chunkGraph,
+							runtimeCondition,
+							runtime,
+							runtimeRequirements
+						});
+						if (condition !== "true") {
+							isConditional = true;
+							result.add(`if (${condition}) {\n`);
+						}
+						const moduleId = JSON.stringify(
+							chunkGraph.getModuleId(info.module)
+						);
+						result.add(`var ${info.name} = __webpack_require__(${moduleId});`);
+						name = info.name;
+					}
+					// If a module is deferred in other places, but used as non-deferred here,
+					// the module itself will be emitted as mod_deferred (in the case "external"),
+					// we need to emit an extra import declaration to evaluate it in order.
+					const { nonDeferAccess } =
+						/** @type {ExternalModuleInfo | ReferenceToModuleInfo} */
+						(rawInfo);
+					if (info.deferred && nonDeferAccess) {
+						result.add(
+							`\n// non-deferred import to a deferred module (${info.module.readableIdentifier(requestShortener)})\nvar ${info.name} = ${info.deferredName}.a;`
+						);
+					}
+					break;
+				}
+				default:
+					// @ts-expect-error never is expected here
+					throw new Error(`Unsupported concatenation entry type ${info.type}`);
+			}
+			if (info.interopNamespaceObjectUsed) {
+				runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+				result.add(
+					`\nvar ${info.interopNamespaceObjectName} = /*#__PURE__*/${RuntimeGlobals.createFakeNamespaceObject}(${name}, 2);`
+				);
+			}
+			if (info.interopNamespaceObject2Used) {
+				runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
+				result.add(
+					`\nvar ${info.interopNamespaceObject2Name} = /*#__PURE__*/${RuntimeGlobals.createFakeNamespaceObject}(${name});`
+				);
+			}
+			if (info.interopDefaultAccessUsed) {
+				runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport);
+				result.add(
+					`\nvar ${info.interopDefaultAccessName} = /*#__PURE__*/${RuntimeGlobals.compatGetDefaultExport}(${name});`
+				);
+			}
+			if (isConditional) {
+				result.add("\n}");
+			}
+		}
+
+		/** @type {CodeGenerationResultData} */
+		const data = new Map();
+		if (chunkInitFragments.length > 0) {
+			data.set("chunkInitFragments", chunkInitFragments);
+		}
+		data.set("topLevelDeclarations", topLevelDeclarations);
+
+		/** @type {CodeGenerationResult} */
+		const resultEntry = {
+			sources: new Map([[JAVASCRIPT_TYPE, new CachedSource(result)]]),
+			data,
+			runtimeRequirements
+		};
+
+		return resultEntry;
+	}
+
+	/**
+	 * @param {ModuleToInfoMap} modulesMap modulesMap
+	 * @param {ModuleInfo} info info
+	 * @param {DependencyTemplates} dependencyTemplates dependencyTemplates
+	 * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate
+	 * @param {ModuleGraph} moduleGraph moduleGraph
+	 * @param {ChunkGraph} chunkGraph chunkGraph
+	 * @param {RuntimeSpec} runtime runtime
+	 * @param {RuntimeSpec[]} runtimes runtimes
+	 * @param {CodeGenerationResults} codeGenerationResults codeGenerationResults
+	 * @param {UsedNames} usedNames used names
+	 */
+	_analyseModule(
+		modulesMap,
+		info,
+		dependencyTemplates,
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime,
+		runtimes,
+		codeGenerationResults,
+		usedNames
+	) {
+		if (info.type === "concatenated") {
+			const m = info.module;
+			try {
+				// Create a concatenation scope to track and capture information
+				const concatenationScope = new ConcatenationScope(
+					modulesMap,
+					info,
+					usedNames
+				);
+
+				// TODO cache codeGeneration results
+				const codeGenResult = m.codeGeneration({
+					dependencyTemplates,
+					runtimeTemplate,
+					moduleGraph,
+					chunkGraph,
+					runtime,
+					runtimes,
+					concatenationScope,
+					codeGenerationResults,
+					sourceTypes: JAVASCRIPT_TYPES
+				});
+				const source =
+					/** @type {Source} */
+					(codeGenResult.sources.get(JAVASCRIPT_TYPE));
+				const data = codeGenResult.data;
+				const chunkInitFragments = data && data.get("chunkInitFragments");
+				const code = source.source().toString();
+
+				/** @type {Program} */
+				let ast;
+
+				try {
+					({ ast } = JavascriptParser._parse(
+						code,
+						{
+							sourceType: "module",
+							ranges: true
+						},
+						JavascriptParser._getModuleParseFunction(this.compilation, m)
+					));
+				} catch (_err) {
+					const err =
+						/** @type {Error & { loc?: { line: number, column: number } }} */
+						(_err);
+					if (
+						err.loc &&
+						typeof err.loc === "object" &&
+						typeof err.loc.line === "number"
+					) {
+						const lineNumber = err.loc.line;
+						const lines = code.split("\n");
+						err.message += `\n| ${lines
+							.slice(Math.max(0, lineNumber - 3), lineNumber + 2)
+							.join("\n| ")}`;
+					}
+					throw err;
+				}
+				const scopeManager = eslintScope.analyze(ast, {
+					ecmaVersion: 6,
+					sourceType: "module",
+					optimistic: true,
+					ignoreEval: true,
+					impliedStrict: true
+				});
+				const globalScope = /** @type {Scope} */ (scopeManager.acquire(ast));
+				const moduleScope = globalScope.childScopes[0];
+				const resultSource = new ReplaceSource(source);
+				info.runtimeRequirements =
+					/** @type {ReadOnlyRuntimeRequirements} */
+					(codeGenResult.runtimeRequirements);
+				info.ast = ast;
+				info.internalSource = source;
+				info.source = resultSource;
+				info.chunkInitFragments = chunkInitFragments;
+				info.globalScope = globalScope;
+				info.moduleScope = moduleScope;
+				info.concatenationScope = concatenationScope;
+			} catch (err) {
+				/** @type {Error} */
+				(err).message +=
+					`\nwhile analyzing module ${m.identifier()} for concatenation`;
+				throw err;
+			}
+		}
+	}
+
+	/**
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {RuntimeSpec} runtime the runtime
+	 * @returns {[ModuleInfoOrReference[], ModuleToInfoMap]} module info items
+	 */
+	_getModulesWithInfo(moduleGraph, runtime) {
+		const orderedConcatenationList = this._createConcatenationList(
+			this.rootModule,
+			this._modules,
+			runtime,
+			moduleGraph
+		);
+		/** @type {ModuleToInfoMap} */
+		const map = new Map();
+		const list = orderedConcatenationList.map((info, index) => {
+			let item = map.get(info.module);
+			if (item === undefined) {
+				switch (info.type) {
+					case "concatenated":
+						item = {
+							type: "concatenated",
+							module: info.module,
+							index,
+							ast: undefined,
+							internalSource: undefined,
+							runtimeRequirements: undefined,
+							source: undefined,
+							globalScope: undefined,
+							moduleScope: undefined,
+							internalNames: new Map(),
+							exportMap: undefined,
+							rawExportMap: undefined,
+							namespaceExportSymbol: undefined,
+							namespaceObjectName: undefined,
+							interopNamespaceObjectUsed: false,
+							interopNamespaceObjectName: undefined,
+							interopNamespaceObject2Used: false,
+							interopNamespaceObject2Name: undefined,
+							interopDefaultAccessUsed: false,
+							interopDefaultAccessName: undefined,
+							concatenationScope: undefined
+						};
+						break;
+					case "external":
+						item = {
+							type: "external",
+							module: info.module,
+							runtimeCondition: info.runtimeCondition,
+							nonDeferAccess: info.nonDeferAccess,
+							index,
+							name: undefined,
+							deferredName: undefined,
+							interopNamespaceObjectUsed: false,
+							interopNamespaceObjectName: undefined,
+							interopNamespaceObject2Used: false,
+							interopNamespaceObject2Name: undefined,
+							interopDefaultAccessUsed: false,
+							interopDefaultAccessName: undefined,
+							deferred: moduleGraph.isDeferred(info.module),
+							deferredNamespaceObjectName: undefined,
+							deferredNamespaceObjectUsed: false
+						};
+						break;
+					default:
+						throw new Error(
+							`Unsupported concatenation entry type ${info.type}`
+						);
+				}
+				map.set(
+					/** @type {ModuleInfo} */ (item).module,
+					/** @type {ModuleInfo} */ (item)
+				);
+				return /** @type {ModuleInfo} */ (item);
+			}
+			/** @type {ReferenceToModuleInfo} */
+			const ref = {
+				type: "reference",
+				runtimeCondition: info.runtimeCondition,
+				nonDeferAccess: info.nonDeferAccess,
+				target: item
+			};
+			return ref;
+		});
+		return [list, map];
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		const { chunkGraph, runtime } = context;
+		for (const info of this._createConcatenationList(
+			this.rootModule,
+			this._modules,
+			intersectRuntime(runtime, this._runtime),
+			chunkGraph.moduleGraph
+		)) {
+			switch (info.type) {
+				case "concatenated":
+					info.module.updateHash(hash, context);
+					break;
+				case "external":
+					hash.update(`${chunkGraph.getModuleId(info.module)}`);
+					// TODO runtimeCondition
+					break;
+			}
+		}
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {ConcatenatedModule} ConcatenatedModule
+	 */
+	static deserialize(context) {
+		const obj = new ConcatenatedModule({
+			identifier: /** @type {EXPECTED_ANY} */ (undefined),
+			rootModule: /** @type {EXPECTED_ANY} */ (undefined),
+			modules: /** @type {EXPECTED_ANY} */ (undefined),
+			runtime: undefined,
+			compilation: /** @type {EXPECTED_ANY} */ (undefined)
+		});
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(ConcatenatedModule, "webpack/lib/optimize/ConcatenatedModule");
+
+module.exports = ConcatenatedModule;
Index: frontend/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,89 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_BASIC } = require("../OptimizationStages");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "EnsureChunkConditionsPlugin";
+
+class EnsureChunkConditionsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			/**
+			 * Handles the hook callback for this code path.
+			 * @param {Iterable<Chunk>} chunks the chunks
+			 */
+			const handler = (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+				// These sets are hoisted here to save memory
+				// They are cleared at the end of every loop
+				/** @type {Set<Chunk>} */
+				const sourceChunks = new Set();
+				/** @type {Set<ChunkGroup>} */
+				const chunkGroups = new Set();
+				for (const module of compilation.modules) {
+					if (!module.hasChunkCondition()) continue;
+					for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
+						if (!module.chunkCondition(chunk, compilation)) {
+							sourceChunks.add(chunk);
+							for (const group of chunk.groupsIterable) {
+								chunkGroups.add(group);
+							}
+						}
+					}
+					if (sourceChunks.size === 0) continue;
+					/** @type {Set<Chunk>} */
+					const targetChunks = new Set();
+					chunkGroupLoop: for (const chunkGroup of chunkGroups) {
+						// Can module be placed in a chunk of this group?
+						for (const chunk of chunkGroup.chunks) {
+							if (module.chunkCondition(chunk, compilation)) {
+								targetChunks.add(chunk);
+								continue chunkGroupLoop;
+							}
+						}
+						// We reached the entrypoint: fail
+						if (chunkGroup.isInitial()) {
+							throw new Error(
+								`Cannot fulfil chunk condition of ${module.identifier()}`
+							);
+						}
+						// Try placing in all parents
+						for (const group of chunkGroup.parentsIterable) {
+							chunkGroups.add(group);
+						}
+					}
+					for (const sourceChunk of sourceChunks) {
+						chunkGraph.disconnectChunkAndModule(sourceChunk, module);
+					}
+					for (const targetChunk of targetChunks) {
+						chunkGraph.connectChunkAndModule(targetChunk, module);
+					}
+					sourceChunks.clear();
+					chunkGroups.clear();
+				}
+			};
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_BASIC
+				},
+				handler
+			);
+		});
+	}
+}
+
+module.exports = EnsureChunkConditionsPlugin;
Index: frontend/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,138 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { compareIds } = require("../util/comparators");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+const PLUGIN_NAME = "FlagIncludedChunksPlugin";
+
+class FlagIncludedChunksPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.optimizeChunkIds.tap(PLUGIN_NAME, (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+
+				// prepare two bit integers for each module
+				// 2^31 is the max number represented as SMI in v8
+				// we want the bits distributed this way:
+				// the bit 2^31 is pretty rar and only one module should get it
+				// so it has a probability of 1 / modulesCount
+				// the first bit (2^0) is the easiest and every module could get it
+				// if it doesn't get a better bit
+				// from bit 2^n to 2^(n+1) there is a probability of p
+				// so 1 / modulesCount == p^31
+				// <=> p = sqrt31(1 / modulesCount)
+				// so we use a modulo of 1 / sqrt31(1 / modulesCount)
+				/** @type {WeakMap<Module, number>} */
+				const moduleBits = new WeakMap();
+				const modulesCount = compilation.modules.size;
+
+				// precalculate the modulo values for each bit
+				const modulo = 1 / (1 / modulesCount) ** (1 / 31);
+				/** @type {number[]} */
+				const modulos = Array.from(
+					{ length: 31 },
+					/**
+					 * Handles the callback logic for this hook.
+					 * @param {number} x x
+					 * @param {number} i i
+					 * @returns {number} result
+					 */
+					(x, i) => (modulo ** i) | 0
+				);
+
+				// iterate all modules to generate bit values
+				let i = 0;
+				for (const module of compilation.modules) {
+					let bit = 30;
+					while (i % modulos[bit] !== 0) {
+						bit--;
+					}
+					moduleBits.set(module, 1 << bit);
+					i++;
+				}
+
+				// iterate all chunks to generate bitmaps
+				/** @type {WeakMap<Chunk, number>} */
+				const chunkModulesHash = new WeakMap();
+				for (const chunk of chunks) {
+					let hash = 0;
+					for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+						hash |= /** @type {number} */ (moduleBits.get(module));
+					}
+					chunkModulesHash.set(chunk, hash);
+				}
+
+				for (const chunkA of chunks) {
+					const chunkAHash =
+						/** @type {number} */
+						(chunkModulesHash.get(chunkA));
+					const chunkAModulesCount = chunkGraph.getNumberOfChunkModules(chunkA);
+					if (chunkAModulesCount === 0) continue;
+					/** @type {undefined | Module} */
+					let bestModule;
+					for (const module of chunkGraph.getChunkModulesIterable(chunkA)) {
+						if (
+							bestModule === undefined ||
+							chunkGraph.getNumberOfModuleChunks(bestModule) >
+								chunkGraph.getNumberOfModuleChunks(module)
+						) {
+							bestModule = module;
+						}
+					}
+					loopB: for (const chunkB of chunkGraph.getModuleChunksIterable(
+						/** @type {Module} */ (bestModule)
+					)) {
+						// as we iterate the same iterables twice
+						// skip if we find ourselves
+						if (chunkA === chunkB) continue;
+
+						const chunkBModulesCount =
+							chunkGraph.getNumberOfChunkModules(chunkB);
+
+						// ids for empty chunks are not included
+						if (chunkBModulesCount === 0) continue;
+
+						// instead of swapping A and B just bail
+						// as we loop twice the current A will be B and B then A
+						if (chunkAModulesCount > chunkBModulesCount) continue;
+
+						// is chunkA in chunkB?
+
+						// we do a cheap check for the hash value
+						const chunkBHash =
+							/** @type {number} */
+							(chunkModulesHash.get(chunkB));
+						if ((chunkBHash & chunkAHash) !== chunkAHash) continue;
+
+						// compare all modules
+						for (const m of chunkGraph.getChunkModulesIterable(chunkA)) {
+							if (!chunkGraph.isModuleInChunk(m, chunkB)) continue loopB;
+						}
+
+						/** @type {ChunkId[]} */
+						(chunkB.ids).push(/** @type {ChunkId} */ (chunkA.id));
+						// https://github.com/webpack/webpack/issues/18837
+						/** @type {ChunkId[]} */
+						(chunkB.ids).sort(compareIds);
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = FlagIncludedChunksPlugin;
Index: frontend/node_modules/webpack/lib/optimize/InnerGraph.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/InnerGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/InnerGraph.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,383 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+const JavascriptParser = require("../javascript/JavascriptParser");
+
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {Set<string | TopLevelSymbol>} InnerGraphValueSet */
+/** @typedef {InnerGraphValueSet | true} InnerGraphValue */
+/** @typedef {TopLevelSymbol | null} InnerGraphKey */
+/** @typedef {Map<InnerGraphKey, InnerGraphValue | undefined>} InnerGraph */
+/** @typedef {(value: boolean | Set<string> | undefined) => void} UsageCallback */
+
+/**
+ * Defines the state object type used by this module.
+ * @typedef {object} StateObject
+ * @property {InnerGraph} innerGraph
+ * @property {TopLevelSymbol=} currentTopLevelSymbol
+ * @property {Map<TopLevelSymbol, Set<UsageCallback>>} usageCallbackMap
+ */
+
+/** @typedef {false | StateObject} State */
+
+class TopLevelSymbol {
+	/**
+	 * Creates an instance of TopLevelSymbol.
+	 * @param {string} name name of the variable
+	 */
+	constructor(name) {
+		/** @type {string} */
+		this.name = name;
+	}
+}
+
+module.exports.TopLevelSymbol = TopLevelSymbol;
+
+/** @type {WeakMap<ParserState, State>} */
+const parserStateMap = new WeakMap();
+const topLevelSymbolTag = Symbol("top level symbol");
+
+/**
+ * Returns state.
+ * @param {ParserState} parserState parser state
+ * @returns {State | undefined} state
+ */
+function getState(parserState) {
+	return parserStateMap.get(parserState);
+}
+
+/**
+ * Processes the provided state.
+ * @param {ParserState} state parser state
+ * @param {TopLevelSymbol | null} symbol the symbol, or null for all symbols
+ * @param {Usage} usage usage data
+ * @returns {void}
+ */
+module.exports.addUsage = (state, symbol, usage) => {
+	const innerGraphState = getState(state);
+
+	if (innerGraphState) {
+		const { innerGraph } = innerGraphState;
+		const info = innerGraph.get(symbol);
+		if (usage === true) {
+			innerGraph.set(symbol, true);
+		} else if (info === undefined) {
+			innerGraph.set(symbol, new Set([usage]));
+		} else if (info !== true) {
+			info.add(usage);
+		}
+	}
+};
+
+/** @typedef {string | TopLevelSymbol | true} Usage */
+
+/**
+ * Processes the provided parser.
+ * @param {JavascriptParser} parser the parser
+ * @param {string} name name of variable
+ * @param {Usage} usage usage data
+ * @returns {void}
+ */
+module.exports.addVariableUsage = (parser, name, usage) => {
+	const symbol =
+		/** @type {TopLevelSymbol} */ (
+			parser.getTagData(name, topLevelSymbolTag)
+		) || module.exports.tagTopLevelSymbol(parser, name);
+	if (symbol) {
+		module.exports.addUsage(parser.state, symbol, usage);
+	}
+};
+
+/**
+ * Processes the provided parser state.
+ * @param {ParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.bailout = (parserState) => {
+	parserStateMap.set(parserState, false);
+};
+
+/**
+ * Processes the provided parser state.
+ * @param {ParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.enable = (parserState) => {
+	const state = parserStateMap.get(parserState);
+	if (state === false) {
+		return;
+	}
+	parserStateMap.set(parserState, {
+		innerGraph: new Map(),
+		currentTopLevelSymbol: undefined,
+		usageCallbackMap: new Map()
+	});
+};
+
+/** @typedef {Set<string> | boolean} UsedByExports */
+
+/**
+ * Usage callback map.
+ * @param {Dependency} dependency the dependency
+ * @param {UsedByExports | undefined} usedByExports usedByExports info
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @returns {null | false | GetConditionFn} function to determine if the connection is active
+ */
+module.exports.getDependencyUsedByExportsCondition = (
+	dependency,
+	usedByExports,
+	moduleGraph
+) => {
+	if (usedByExports === false) return false;
+	if (usedByExports !== true && usedByExports !== undefined) {
+		const selfModule =
+			/** @type {Module} */
+			(moduleGraph.getParentModule(dependency));
+		const exportsInfo = moduleGraph.getExportsInfo(selfModule);
+		return (_connections, runtime) => {
+			for (const exportName of usedByExports) {
+				if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) {
+					return true;
+				}
+			}
+			return false;
+		};
+	}
+	return null;
+};
+
+/**
+ * Returns usage data.
+ * @param {ParserState} state parser state
+ * @returns {TopLevelSymbol | void} usage data
+ */
+module.exports.getTopLevelSymbol = (state) => {
+	const innerGraphState = getState(state);
+
+	if (innerGraphState) {
+		return innerGraphState.currentTopLevelSymbol;
+	}
+};
+
+/**
+ * Processes the provided state.
+ * @param {ParserState} state parser state
+ * @returns {void}
+ */
+module.exports.inferDependencyUsage = (state) => {
+	const innerGraphState = getState(state);
+
+	if (!innerGraphState) {
+		return;
+	}
+
+	const { innerGraph, usageCallbackMap } = innerGraphState;
+	/** @type {Map<InnerGraphKey, InnerGraphValueSet | undefined>} */
+	const processed = new Map();
+	// flatten graph to terminal nodes (string, undefined or true)
+	const nonTerminal = new Set(innerGraph.keys());
+	while (nonTerminal.size > 0) {
+		for (const key of nonTerminal) {
+			/** @type {InnerGraphValue} */
+			let newSet = new Set();
+			let isTerminal = true;
+			const value = innerGraph.get(key);
+			let alreadyProcessed = processed.get(key);
+			if (alreadyProcessed === undefined) {
+				/** @type {InnerGraphValueSet} */
+				alreadyProcessed = new Set();
+				processed.set(key, alreadyProcessed);
+			}
+			if (value !== true && value !== undefined) {
+				for (const item of value) {
+					alreadyProcessed.add(item);
+				}
+				for (const item of value) {
+					if (typeof item === "string") {
+						newSet.add(item);
+					} else {
+						const itemValue = innerGraph.get(item);
+						if (itemValue === true) {
+							newSet = true;
+							break;
+						}
+						if (itemValue !== undefined) {
+							for (const i of itemValue) {
+								if (i === key) continue;
+								if (alreadyProcessed.has(i)) continue;
+								newSet.add(i);
+								if (typeof i !== "string") {
+									isTerminal = false;
+								}
+							}
+						}
+					}
+				}
+				if (newSet === true) {
+					innerGraph.set(key, true);
+				} else if (newSet.size === 0) {
+					innerGraph.set(key, undefined);
+				} else {
+					innerGraph.set(key, newSet);
+				}
+			}
+			if (isTerminal) {
+				nonTerminal.delete(key);
+
+				// For the global key, merge with all other keys
+				if (key === null) {
+					const globalValue = innerGraph.get(null);
+					if (globalValue) {
+						for (const [key, value] of innerGraph) {
+							if (key !== null && value !== true) {
+								if (globalValue === true) {
+									innerGraph.set(key, true);
+								} else {
+									const newSet = new Set(value);
+									for (const item of globalValue) {
+										newSet.add(item);
+									}
+									innerGraph.set(key, newSet);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/** @type {Map<Dependency, true | Set<string>>} */
+	for (const [symbol, callbacks] of usageCallbackMap) {
+		const usage = /** @type {true | Set<string> | undefined} */ (
+			innerGraph.get(symbol)
+		);
+		for (const callback of callbacks) {
+			callback(usage === undefined ? false : usage);
+		}
+	}
+};
+
+/**
+ * Returns false, when unused. Otherwise true.
+ * @param {Dependency} dependency the dependency
+ * @param {UsedByExports | undefined} usedByExports usedByExports info
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @param {RuntimeSpec} runtime runtime
+ * @returns {boolean} false, when unused. Otherwise true
+ */
+module.exports.isDependencyUsedByExports = (
+	dependency,
+	usedByExports,
+	moduleGraph,
+	runtime
+) => {
+	if (usedByExports === false) return false;
+	if (usedByExports !== true && usedByExports !== undefined) {
+		const selfModule =
+			/** @type {Module} */
+			(moduleGraph.getParentModule(dependency));
+		const exportsInfo = moduleGraph.getExportsInfo(selfModule);
+		let used = false;
+		for (const exportName of usedByExports) {
+			if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) {
+				used = true;
+			}
+		}
+		if (!used) return false;
+	}
+	return true;
+};
+
+/**
+ * Returns true, when enabled.
+ * @param {ParserState} parserState parser state
+ * @returns {boolean} true, when enabled
+ */
+module.exports.isEnabled = (parserState) => {
+	const state = parserStateMap.get(parserState);
+	return Boolean(state);
+};
+
+/**
+ * Processes the provided state.
+ * @param {ParserState} state parser state
+ * @param {UsageCallback} onUsageCallback on usage callback
+ */
+module.exports.onUsage = (state, onUsageCallback) => {
+	const innerGraphState = getState(state);
+
+	if (innerGraphState) {
+		const { usageCallbackMap, currentTopLevelSymbol } = innerGraphState;
+		if (currentTopLevelSymbol) {
+			let callbacks = usageCallbackMap.get(currentTopLevelSymbol);
+
+			if (callbacks === undefined) {
+				/** @type {Set<UsageCallback>} */
+				callbacks = new Set();
+				usageCallbackMap.set(currentTopLevelSymbol, callbacks);
+			}
+
+			callbacks.add(onUsageCallback);
+		} else {
+			onUsageCallback(true);
+		}
+	} else {
+		onUsageCallback(undefined);
+	}
+};
+
+/**
+ * Processes the provided state.
+ * @param {ParserState} state parser state
+ * @param {TopLevelSymbol | undefined} symbol the symbol
+ */
+module.exports.setTopLevelSymbol = (state, symbol) => {
+	const innerGraphState = getState(state);
+
+	if (innerGraphState) {
+		innerGraphState.currentTopLevelSymbol = symbol;
+	}
+};
+
+/**
+ * Returns symbol.
+ * @param {JavascriptParser} parser parser
+ * @param {string} name name of variable
+ * @returns {TopLevelSymbol | undefined} symbol
+ */
+module.exports.tagTopLevelSymbol = (parser, name) => {
+	const innerGraphState = getState(parser.state);
+	if (!innerGraphState) return;
+
+	parser.defineVariable(name);
+
+	const existingTag = /** @type {TopLevelSymbol} */ (
+		parser.getTagData(name, topLevelSymbolTag)
+	);
+	if (existingTag) {
+		return existingTag;
+	}
+
+	const symbol = new TopLevelSymbol(name);
+	parser.tagVariable(
+		name,
+		topLevelSymbolTag,
+		symbol,
+		JavascriptParser.VariableInfoFlags.Normal
+	);
+	return symbol;
+};
+
+module.exports.topLevelSymbolTag = topLevelSymbolTag;
Index: frontend/node_modules/webpack/lib/optimize/InnerGraphPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/InnerGraphPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/InnerGraphPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,473 @@
+/*
+	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
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const PureExpressionDependency = require("../dependencies/PureExpressionDependency");
+const InnerGraph = require("./InnerGraph");
+
+/** @typedef {import("estree").ClassDeclaration} ClassDeclaration */
+/** @typedef {import("estree").ClassExpression} ClassExpression */
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
+/** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
+/** @typedef {import("estree").Node} Node */
+/** @typedef {import("estree").VariableDeclarator} VariableDeclarator */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./InnerGraph").TopLevelSymbol} TopLevelSymbol */
+
+const { topLevelSymbolTag } = InnerGraph;
+
+const PLUGIN_NAME = "InnerGraphPlugin";
+const impureVariableDeclarationKinds = new Set(["using", "await using"]);
+
+class InnerGraphPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const logger = compilation.getLogger("webpack.InnerGraphPlugin");
+
+				compilation.dependencyTemplates.set(
+					PureExpressionDependency,
+					new PureExpressionDependency.Template()
+				);
+
+				/**
+				 * Handles the hook callback for this code path.
+				 * @param {JavascriptParser} parser the parser
+				 * @param {JavascriptParserOptions} parserOptions options
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					/**
+					 * Processes the provided sup.
+					 * @param {Expression} sup sup
+					 */
+					const onUsageSuper = (sup) => {
+						InnerGraph.onUsage(parser.state, (usedByExports) => {
+							switch (usedByExports) {
+								case undefined:
+								case true:
+									return;
+								default: {
+									const dep = new PureExpressionDependency(
+										/** @type {Range} */
+										(sup.range)
+									);
+									dep.loc = /** @type {DependencyLocation} */ (sup.loc);
+									dep.usedByExports = usedByExports;
+									parser.state.module.addDependency(dep);
+									break;
+								}
+							}
+						});
+					};
+
+					parser.hooks.program.tap(PLUGIN_NAME, () => {
+						InnerGraph.enable(parser.state);
+
+						statementWithTopLevelSymbol = new WeakMap();
+						statementPurePart = new WeakMap();
+						classWithTopLevelSymbol = new WeakMap();
+						declWithTopLevelSymbol = new WeakMap();
+						pureDeclarators = new WeakSet();
+					});
+
+					parser.hooks.finish.tap(PLUGIN_NAME, () => {
+						if (!InnerGraph.isEnabled(parser.state)) return;
+
+						logger.time("infer dependency usage");
+						InnerGraph.inferDependencyUsage(parser.state);
+						logger.timeAggregate("infer dependency usage");
+					});
+
+					// During prewalking the following datastructures are filled with
+					// nodes that have a TopLevelSymbol assigned and
+					// variables are tagged with the assigned TopLevelSymbol
+
+					// We differ 3 types of nodes:
+					// 1. full statements (export default, function declaration)
+					// 2. classes (class declaration, class expression)
+					// 3. variable declarators (const x = ...)
+
+					/** @type {WeakMap<Node | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, TopLevelSymbol>} */
+					let statementWithTopLevelSymbol = new WeakMap();
+					/** @type {WeakMap<Node | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, Node>} */
+					let statementPurePart = new WeakMap();
+
+					/** @type {WeakMap<ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration, TopLevelSymbol>} */
+					let classWithTopLevelSymbol = new WeakMap();
+
+					/** @type {WeakMap<VariableDeclarator, TopLevelSymbol>} */
+					let declWithTopLevelSymbol = new WeakMap();
+					/** @type {WeakSet<VariableDeclarator>} */
+					let pureDeclarators = new WeakSet();
+
+					// The following hooks are used during prewalking:
+
+					parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
+						if (!InnerGraph.isEnabled(parser.state)) return;
+
+						if (
+							parser.scope.topLevelScope === true &&
+							statement.type === "FunctionDeclaration"
+						) {
+							const name = statement.id ? statement.id.name : "*default*";
+							const symbol =
+								/** @type {TopLevelSymbol} */
+								(InnerGraph.tagTopLevelSymbol(parser, name));
+							statementWithTopLevelSymbol.set(statement, symbol);
+							return true;
+						}
+					});
+
+					parser.hooks.blockPreStatement.tap(PLUGIN_NAME, (statement) => {
+						if (!InnerGraph.isEnabled(parser.state)) return;
+
+						if (parser.scope.topLevelScope === true) {
+							if (
+								statement.type === "ClassDeclaration" &&
+								parser.isPure(
+									statement,
+									/** @type {Range} */ (statement.range)[0]
+								)
+							) {
+								const name = statement.id ? statement.id.name : "*default*";
+								const symbol = /** @type {TopLevelSymbol} */ (
+									InnerGraph.tagTopLevelSymbol(parser, name)
+								);
+								classWithTopLevelSymbol.set(statement, symbol);
+								return true;
+							}
+							if (statement.type === "ExportDefaultDeclaration") {
+								const name = "*default*";
+								const symbol =
+									/** @type {TopLevelSymbol} */
+									(InnerGraph.tagTopLevelSymbol(parser, name));
+								const decl = statement.declaration;
+								if (
+									(decl.type === "ClassExpression" ||
+										decl.type === "ClassDeclaration") &&
+									parser.isPure(
+										/** @type {ClassExpression | ClassDeclaration} */
+										(decl),
+										/** @type {Range} */
+										(decl.range)[0]
+									)
+								) {
+									classWithTopLevelSymbol.set(
+										/** @type {ClassExpression | ClassDeclaration} */
+										(decl),
+										symbol
+									);
+								} else if (
+									parser.isPure(
+										/** @type {Expression} */
+										(decl),
+										/** @type {Range} */
+										(statement.range)[0]
+									)
+								) {
+									statementWithTopLevelSymbol.set(statement, symbol);
+									if (
+										!decl.type.endsWith("FunctionExpression") &&
+										!decl.type.endsWith("Declaration") &&
+										decl.type !== "Literal"
+									) {
+										statementPurePart.set(
+											statement,
+											/** @type {Expression} */
+											(decl)
+										);
+									}
+								}
+							}
+						}
+					});
+
+					parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => {
+						if (!InnerGraph.isEnabled(parser.state)) return;
+						if (impureVariableDeclarationKinds.has(statement.kind)) return;
+						if (
+							parser.scope.topLevelScope === true &&
+							decl.init &&
+							decl.id.type === "Identifier"
+						) {
+							const name = decl.id.name;
+							// Skip webpack runtime variables handled by CompatibilityPlugin
+							if (
+								name === RuntimeGlobals.require ||
+								name === RuntimeGlobals.exports
+							) {
+								return;
+							}
+							if (
+								decl.init.type === "ClassExpression" &&
+								parser.isPure(
+									decl.init,
+									/** @type {Range} */ (decl.id.range)[1]
+								)
+							) {
+								const symbol =
+									/** @type {TopLevelSymbol} */
+									(InnerGraph.tagTopLevelSymbol(parser, name));
+								classWithTopLevelSymbol.set(decl.init, symbol);
+							} else if (
+								parser.isPure(
+									decl.init,
+									/** @type {Range} */ (decl.id.range)[1]
+								)
+							) {
+								const symbol =
+									/** @type {TopLevelSymbol} */
+									(InnerGraph.tagTopLevelSymbol(parser, name));
+								declWithTopLevelSymbol.set(decl, symbol);
+								if (
+									!decl.init.type.endsWith("FunctionExpression") &&
+									decl.init.type !== "Literal"
+								) {
+									pureDeclarators.add(decl);
+								}
+							}
+						}
+					});
+
+					// During real walking we set the TopLevelSymbol state to the assigned
+					// TopLevelSymbol by using the fill datastructures.
+
+					// In addition to tracking TopLevelSymbols, we sometimes need to
+					// add a PureExpressionDependency. This is needed to skip execution
+					// of pure expressions, even when they are not dropped due to
+					// minimizing. Otherwise symbols used there might not exist anymore
+					// as they are removed as unused by this optimization
+
+					// When we find a reference to a TopLevelSymbol, we register a
+					// TopLevelSymbol dependency from TopLevelSymbol in state to the
+					// referenced TopLevelSymbol. This way we get a graph of all
+					// TopLevelSymbols.
+
+					// The following hooks are called during walking:
+
+					parser.hooks.statement.tap(PLUGIN_NAME, (statement) => {
+						if (!InnerGraph.isEnabled(parser.state)) return;
+						if (parser.scope.topLevelScope === true) {
+							InnerGraph.setTopLevelSymbol(parser.state, undefined);
+
+							const symbol = statementWithTopLevelSymbol.get(statement);
+							if (symbol) {
+								InnerGraph.setTopLevelSymbol(parser.state, symbol);
+								const purePart = statementPurePart.get(statement);
+								if (purePart) {
+									InnerGraph.onUsage(parser.state, (usedByExports) => {
+										switch (usedByExports) {
+											case undefined:
+											case true:
+												return;
+											default: {
+												const dep = new PureExpressionDependency(
+													/** @type {Range} */ (purePart.range)
+												);
+												dep.loc =
+													/** @type {DependencyLocation} */
+													(statement.loc);
+												dep.usedByExports = usedByExports;
+												parser.state.module.addDependency(dep);
+												break;
+											}
+										}
+									});
+								}
+							}
+						}
+					});
+
+					parser.hooks.classExtendsExpression.tap(
+						PLUGIN_NAME,
+						(expr, statement) => {
+							if (!InnerGraph.isEnabled(parser.state)) return;
+							if (parser.scope.topLevelScope === true) {
+								const symbol = classWithTopLevelSymbol.get(statement);
+								if (
+									symbol &&
+									parser.isPure(
+										expr,
+										statement.id
+											? /** @type {Range} */ (statement.id.range)[1]
+											: /** @type {Range} */ (statement.range)[0]
+									)
+								) {
+									InnerGraph.setTopLevelSymbol(parser.state, symbol);
+									onUsageSuper(expr);
+								}
+							}
+						}
+					);
+
+					parser.hooks.classBodyElement.tap(
+						PLUGIN_NAME,
+						(element, classDefinition) => {
+							if (!InnerGraph.isEnabled(parser.state)) return;
+							if (parser.scope.topLevelScope === true) {
+								const symbol = classWithTopLevelSymbol.get(classDefinition);
+								if (symbol) {
+									InnerGraph.setTopLevelSymbol(parser.state, undefined);
+								}
+							}
+						}
+					);
+
+					parser.hooks.classBodyValue.tap(
+						PLUGIN_NAME,
+						(expression, element, classDefinition) => {
+							if (!InnerGraph.isEnabled(parser.state)) return;
+							if (parser.scope.topLevelScope === true) {
+								const symbol = classWithTopLevelSymbol.get(classDefinition);
+								if (symbol) {
+									if (
+										!element.static ||
+										parser.isPure(
+											expression,
+											element.key
+												? /** @type {Range} */ (element.key.range)[1]
+												: /** @type {Range} */ (element.range)[0]
+										)
+									) {
+										InnerGraph.setTopLevelSymbol(parser.state, symbol);
+										if (element.type !== "MethodDefinition" && element.static) {
+											InnerGraph.onUsage(parser.state, (usedByExports) => {
+												switch (usedByExports) {
+													case undefined:
+													case true:
+														return;
+													default: {
+														const dep = new PureExpressionDependency(
+															/** @type {Range} */ (expression.range)
+														);
+														dep.loc =
+															/** @type {DependencyLocation} */
+															(expression.loc);
+														dep.usedByExports = usedByExports;
+														parser.state.module.addDependency(dep);
+														break;
+													}
+												}
+											});
+										}
+									} else {
+										InnerGraph.setTopLevelSymbol(parser.state, undefined);
+									}
+								}
+							}
+						}
+					);
+
+					parser.hooks.declarator.tap(PLUGIN_NAME, (decl, _statement) => {
+						if (!InnerGraph.isEnabled(parser.state)) return;
+						const symbol = declWithTopLevelSymbol.get(decl);
+
+						if (symbol) {
+							InnerGraph.setTopLevelSymbol(parser.state, symbol);
+							if (pureDeclarators.has(decl)) {
+								if (
+									/** @type {ClassExpression} */
+									(decl.init).type === "ClassExpression"
+								) {
+									if (decl.init.superClass) {
+										onUsageSuper(decl.init.superClass);
+									}
+								} else {
+									InnerGraph.onUsage(parser.state, (usedByExports) => {
+										switch (usedByExports) {
+											case undefined:
+											case true:
+												return;
+											default: {
+												const dep = new PureExpressionDependency(
+													/** @type {Range} */ (
+														/** @type {ClassExpression} */
+														(decl.init).range
+													)
+												);
+												dep.loc = /** @type {DependencyLocation} */ (decl.loc);
+												dep.usedByExports = usedByExports;
+												parser.state.module.addDependency(dep);
+												break;
+											}
+										}
+									});
+								}
+							}
+							parser.walkExpression(
+								/** @type {NonNullable<VariableDeclarator["init"]>} */ (
+									decl.init
+								)
+							);
+							InnerGraph.setTopLevelSymbol(parser.state, undefined);
+							return true;
+						} else if (
+							decl.id.type === "Identifier" &&
+							decl.init &&
+							decl.init.type === "ClassExpression" &&
+							classWithTopLevelSymbol.has(decl.init)
+						) {
+							parser.walkExpression(decl.init);
+							InnerGraph.setTopLevelSymbol(parser.state, undefined);
+							return true;
+						}
+					});
+
+					parser.hooks.expression
+						.for(topLevelSymbolTag)
+						.tap(PLUGIN_NAME, () => {
+							const topLevelSymbol = /** @type {TopLevelSymbol} */ (
+								parser.currentTagData
+							);
+							const currentTopLevelSymbol = InnerGraph.getTopLevelSymbol(
+								parser.state
+							);
+							InnerGraph.addUsage(
+								parser.state,
+								topLevelSymbol,
+								currentTopLevelSymbol || true
+							);
+						});
+					parser.hooks.assign
+						.for(topLevelSymbolTag)
+						.tap(PLUGIN_NAME, (expr) => {
+							if (!InnerGraph.isEnabled(parser.state)) return;
+							if (expr.operator === "=") return true;
+						});
+				};
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
+					.tap(PLUGIN_NAME, handler);
+				normalModuleFactory.hooks.parser
+					.for(JAVASCRIPT_MODULE_TYPE_ESM)
+					.tap(PLUGIN_NAME, handler);
+
+				compilation.hooks.finishModules.tap(PLUGIN_NAME, () => {
+					logger.timeAggregateEnd("infer dependency usage");
+				});
+			}
+		);
+	}
+}
+
+module.exports = InnerGraphPlugin;
Index: frontend/node_modules/webpack/lib/optimize/LimitChunkCountPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/LimitChunkCountPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/LimitChunkCountPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,315 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+const LazyBucketSortedSet = require("../util/LazyBucketSortedSet");
+const { compareChunks } = require("../util/comparators");
+
+/** @typedef {import("../../declarations/plugins/optimize/LimitChunkCountPlugin").LimitChunkCountPluginOptions} LimitChunkCountPluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Defines the chunk combination type used by this module.
+ * @typedef {object} ChunkCombination
+ * @property {boolean} deleted this is set to true when combination was removed
+ * @property {number} sizeDiff
+ * @property {number} integratedSize
+ * @property {Chunk} a
+ * @property {Chunk} b
+ * @property {number} aIdx
+ * @property {number} bIdx
+ * @property {number} aSize
+ * @property {number} bSize
+ */
+
+/**
+ * Adds the provided map to this object.
+ * @template K, V
+ * @param {Map<K, Set<V>>} map map
+ * @param {K} key key
+ * @param {V} value value
+ */
+const addToSetMap = (map, key, value) => {
+	const set = map.get(key);
+	if (set === undefined) {
+		map.set(key, new Set([value]));
+	} else {
+		set.add(value);
+	}
+};
+
+const PLUGIN_NAME = "LimitChunkCountPlugin";
+
+class LimitChunkCountPlugin {
+	/**
+	 * Creates an instance of LimitChunkCountPlugin.
+	 * @param {LimitChunkCountPluginOptions=} options options object
+	 */
+	constructor(options = { maxChunks: 1 }) {
+		/** @type {LimitChunkCountPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the webpack compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/optimize/LimitChunkCountPlugin.json"),
+				this.options,
+				{
+					name: "Limit Chunk Count Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/optimize/LimitChunkCountPlugin.check")(
+						options
+					)
+			);
+		});
+
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_ADVANCED
+				},
+				(chunks) => {
+					const chunkGraph = compilation.chunkGraph;
+					const maxChunks = this.options.maxChunks;
+					if (!maxChunks) return;
+					if (maxChunks < 1) return;
+					if (compilation.chunks.size <= maxChunks) return;
+
+					let remainingChunksToMerge = compilation.chunks.size - maxChunks;
+
+					// order chunks in a deterministic way
+					const compareChunksWithGraph = compareChunks(chunkGraph);
+					/** @type {Chunk[]} */
+					const orderedChunks = [...chunks].sort(compareChunksWithGraph);
+
+					// create a lazy sorted data structure to keep all combinations
+					// this is large. Size = chunks * (chunks - 1) / 2
+					// It uses a multi layer bucket sort plus normal sort in the last layer
+					// It's also lazy so only accessed buckets are sorted
+					/** @type {LazyBucketSortedSet<ChunkCombination, number>} */
+					const combinations = new LazyBucketSortedSet(
+						// Layer 1: ordered by largest size benefit
+						(c) => c.sizeDiff,
+						(a, b) => b - a,
+
+						// Layer 2: ordered by smallest combined size
+						/**
+						 * Handles the stage callback for this hook.
+						 * @param {ChunkCombination} c combination
+						 * @returns {number} integrated size
+						 */
+						(c) => c.integratedSize,
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {number} a a
+						 * @param {number} b b
+						 * @returns {number} result
+						 */
+						(a, b) => a - b,
+
+						// Layer 3: ordered by position difference in orderedChunk (-> to be deterministic)
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {ChunkCombination} c combination
+						 * @returns {number} position difference
+						 */
+						(c) => c.bIdx - c.aIdx,
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {number} a a
+						 * @param {number} b b
+						 * @returns {number} result
+						 */
+						(a, b) => a - b,
+
+						// Layer 4: ordered by position in orderedChunk (-> to be deterministic)
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {ChunkCombination} a a
+						 * @param {ChunkCombination} b b
+						 * @returns {number} result
+						 */
+						(a, b) => a.bIdx - b.bIdx
+					);
+
+					// we keep a mapping from chunk to all combinations
+					// but this mapping is not kept up-to-date with deletions
+					// so `deleted` flag need to be considered when iterating this
+					/** @type {Map<Chunk, Set<ChunkCombination>>} */
+					const combinationsByChunk = new Map();
+
+					for (const [bIdx, b] of orderedChunks.entries()) {
+						// create combination pairs with size and integrated size
+						for (let aIdx = 0; aIdx < bIdx; aIdx++) {
+							const a = orderedChunks[aIdx];
+							// filter pairs that can not be integrated!
+							if (!chunkGraph.canChunksBeIntegrated(a, b)) continue;
+
+							const integratedSize = chunkGraph.getIntegratedChunksSize(
+								a,
+								b,
+								this.options
+							);
+
+							const aSize = chunkGraph.getChunkSize(a, this.options);
+							const bSize = chunkGraph.getChunkSize(b, this.options);
+							/** @type {ChunkCombination} */
+							const c = {
+								deleted: false,
+								sizeDiff: aSize + bSize - integratedSize,
+								integratedSize,
+								a,
+								b,
+								aIdx,
+								bIdx,
+								aSize,
+								bSize
+							};
+							combinations.add(c);
+							addToSetMap(combinationsByChunk, a, c);
+							addToSetMap(combinationsByChunk, b, c);
+						}
+					}
+
+					// list of modified chunks during this run
+					// combinations affected by this change are skipped to allow
+					// further optimizations
+					/** @type {Set<Chunk>} */
+					const modifiedChunks = new Set();
+
+					let changed = false;
+					loop: while (true) {
+						const combination = combinations.popFirst();
+						if (combination === undefined) break;
+
+						combination.deleted = true;
+						const { a, b, integratedSize } = combination;
+
+						// skip over pair when
+						// one of the already merged chunks is a parent of one of the chunks
+						if (modifiedChunks.size > 0) {
+							const queue = new Set(a.groupsIterable);
+							for (const group of b.groupsIterable) {
+								queue.add(group);
+							}
+							for (const group of queue) {
+								for (const mChunk of modifiedChunks) {
+									if (mChunk !== a && mChunk !== b && mChunk.isInGroup(group)) {
+										// This is a potential pair which needs recalculation
+										// We can't do that now, but it merge before following pairs
+										// so we leave space for it, and consider chunks as modified
+										// just for the worse case
+										remainingChunksToMerge--;
+										if (remainingChunksToMerge <= 0) break loop;
+										modifiedChunks.add(a);
+										modifiedChunks.add(b);
+										continue loop;
+									}
+								}
+								for (const parent of group.parentsIterable) {
+									queue.add(parent);
+								}
+							}
+						}
+
+						// merge the chunks
+						if (chunkGraph.canChunksBeIntegrated(a, b)) {
+							chunkGraph.integrateChunks(a, b);
+							compilation.chunks.delete(b);
+
+							// flag chunk a as modified as further optimization are possible for all children here
+							modifiedChunks.add(a);
+
+							changed = true;
+							remainingChunksToMerge--;
+							if (remainingChunksToMerge <= 0) break;
+
+							// Update all affected combinations
+							// delete all combination with the removed chunk
+							// we will use combinations with the kept chunk instead
+							for (const combination of /** @type {Set<ChunkCombination>} */ (
+								combinationsByChunk.get(a)
+							)) {
+								if (combination.deleted) continue;
+								combination.deleted = true;
+								combinations.delete(combination);
+							}
+
+							// Update combinations with the kept chunk with new sizes
+							for (const combination of /** @type {Set<ChunkCombination>} */ (
+								combinationsByChunk.get(b)
+							)) {
+								if (combination.deleted) continue;
+								if (combination.a === b) {
+									if (!chunkGraph.canChunksBeIntegrated(a, combination.b)) {
+										combination.deleted = true;
+										combinations.delete(combination);
+										continue;
+									}
+									// Update size
+									const newIntegratedSize = chunkGraph.getIntegratedChunksSize(
+										a,
+										combination.b,
+										this.options
+									);
+									const finishUpdate = combinations.startUpdate(combination);
+									combination.a = a;
+									combination.integratedSize = newIntegratedSize;
+									combination.aSize = integratedSize;
+									combination.sizeDiff =
+										combination.bSize + integratedSize - newIntegratedSize;
+									finishUpdate();
+								} else if (combination.b === b) {
+									if (!chunkGraph.canChunksBeIntegrated(combination.a, a)) {
+										combination.deleted = true;
+										combinations.delete(combination);
+										continue;
+									}
+									// Update size
+									const newIntegratedSize = chunkGraph.getIntegratedChunksSize(
+										combination.a,
+										a,
+										this.options
+									);
+
+									const finishUpdate = combinations.startUpdate(combination);
+									combination.b = a;
+									combination.integratedSize = newIntegratedSize;
+									combination.bSize = integratedSize;
+									combination.sizeDiff =
+										integratedSize + combination.aSize - newIntegratedSize;
+									finishUpdate();
+								}
+							}
+							combinationsByChunk.set(
+								a,
+								/** @type {Set<ChunkCombination>} */ (
+									combinationsByChunk.get(b)
+								)
+							);
+							combinationsByChunk.delete(b);
+						}
+					}
+					if (changed) return true;
+				}
+			);
+		});
+	}
+}
+
+module.exports = LimitChunkCountPlugin;
Index: frontend/node_modules/webpack/lib/optimize/MangleExportsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/MangleExportsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/MangleExportsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,198 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+const {
+	NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS,
+	NUMBER_OF_IDENTIFIER_START_CHARS,
+	numberToIdentifier
+} = require("../Template");
+const { assignDeterministicIds } = require("../ids/IdHelpers");
+const { compareSelect, compareStringsNumeric } = require("../util/comparators");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../ExportsInfo")} ExportsInfo */
+/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("../util/concatenate").UsedNames} UsedNames */
+
+/**
+ * Defines the comparator type used by this module.
+ * @template T
+ * @typedef {import("../util/comparators").Comparator<T>} Comparator
+ */
+
+/**
+ * Checks whether it can mangle.
+ * @param {ExportsInfo} exportsInfo exports info
+ * @returns {boolean} mangle is possible
+ */
+const canMangle = (exportsInfo) => {
+	if (exportsInfo.otherExportsInfo.getUsed(undefined) !== UsageState.Unused) {
+		return false;
+	}
+	let hasSomethingToMangle = false;
+	for (const exportInfo of exportsInfo.exports) {
+		if (exportInfo.canMangle === true) {
+			hasSomethingToMangle = true;
+		}
+	}
+	return hasSomethingToMangle;
+};
+
+// Sort by name
+/** @type {Comparator<ExportInfo>} */
+const comparator = compareSelect((e) => e.name, compareStringsNumeric);
+/**
+ * Mangle exports info.
+ * @param {boolean} deterministic use deterministic names
+ * @param {ExportsInfo} exportsInfo exports info
+ * @param {boolean | undefined} isNamespace is namespace object
+ * @returns {void}
+ */
+const mangleExportsInfo = (deterministic, exportsInfo, isNamespace) => {
+	if (!canMangle(exportsInfo)) return;
+	/** @type {UsedNames} */
+	const usedNames = new Set();
+	/** @type {ExportInfo[]} */
+	const mangleableExports = [];
+
+	// Avoid to renamed exports that are not provided when
+	// 1. it's not a namespace export: non-provided exports can be found in prototype chain
+	// 2. there are other provided exports and deterministic mode is chosen:
+	//    non-provided exports would break the determinism
+	let avoidMangleNonProvided = !isNamespace;
+	if (!avoidMangleNonProvided && deterministic) {
+		for (const exportInfo of exportsInfo.ownedExports) {
+			if (exportInfo.provided !== false) {
+				avoidMangleNonProvided = true;
+				break;
+			}
+		}
+	}
+	for (const exportInfo of exportsInfo.ownedExports) {
+		const name = exportInfo.name;
+		if (!exportInfo.hasUsedName()) {
+			if (
+				// Can the export be mangled?
+				exportInfo.canMangle !== true ||
+				// Never rename 1 char exports
+				(name.length === 1 && /^[a-z0-9_$]/i.test(name)) ||
+				// Don't rename 2 char exports in deterministic mode
+				(deterministic &&
+					name.length === 2 &&
+					/^[a-z_$][a-z0-9_$]|^[1-9][0-9]/i.test(name)) ||
+				// Don't rename exports that are not provided
+				(avoidMangleNonProvided && exportInfo.provided !== true)
+			) {
+				exportInfo.setUsedName(name);
+				usedNames.add(name);
+			} else {
+				mangleableExports.push(exportInfo);
+			}
+		}
+		if (exportInfo.exportsInfoOwned) {
+			const used = exportInfo.getUsed(undefined);
+			if (
+				used === UsageState.OnlyPropertiesUsed ||
+				used === UsageState.Unused
+			) {
+				mangleExportsInfo(
+					deterministic,
+					/** @type {ExportsInfo} */ (exportInfo.exportsInfo),
+					false
+				);
+			}
+		}
+	}
+	if (deterministic) {
+		assignDeterministicIds(
+			mangleableExports,
+			(e) => e.name,
+			comparator,
+			(e, id) => {
+				const name = numberToIdentifier(id);
+				const size = usedNames.size;
+				usedNames.add(name);
+				if (size === usedNames.size) return false;
+				e.setUsedName(name);
+				return true;
+			},
+			[
+				NUMBER_OF_IDENTIFIER_START_CHARS,
+				NUMBER_OF_IDENTIFIER_START_CHARS *
+					NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS
+			],
+			NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS,
+			usedNames.size
+		);
+	} else {
+		/** @type {ExportInfo[]} */
+		const usedExports = [];
+		/** @type {ExportInfo[]} */
+		const unusedExports = [];
+		for (const exportInfo of mangleableExports) {
+			if (exportInfo.getUsed(undefined) === UsageState.Unused) {
+				unusedExports.push(exportInfo);
+			} else {
+				usedExports.push(exportInfo);
+			}
+		}
+		usedExports.sort(comparator);
+		unusedExports.sort(comparator);
+		let i = 0;
+		for (const list of [usedExports, unusedExports]) {
+			for (const exportInfo of list) {
+				/** @type {string} */
+				let name;
+				do {
+					name = numberToIdentifier(i++);
+				} while (usedNames.has(name));
+				exportInfo.setUsedName(name);
+			}
+		}
+	}
+};
+
+const PLUGIN_NAME = "MangleExportsPlugin";
+
+class MangleExportsPlugin {
+	/**
+	 * Creates an instance of MangleExportsPlugin.
+	 * @param {boolean} deterministic use deterministic names
+	 */
+	constructor(deterministic) {
+		/** @type {boolean} */
+		this._deterministic = deterministic;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _deterministic: deterministic } = this;
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const moduleGraph = compilation.moduleGraph;
+			compilation.hooks.optimizeCodeGeneration.tap(PLUGIN_NAME, (modules) => {
+				if (compilation.moduleMemCaches) {
+					throw new Error(
+						"optimization.mangleExports can't be used with cacheUnaffected as export mangling is a global effect"
+					);
+				}
+				for (const module of modules) {
+					const isNamespace =
+						module.buildMeta && module.buildMeta.exportsType === "namespace";
+					const exportsInfo = moduleGraph.getExportsInfo(module);
+					mangleExportsInfo(deterministic, exportsInfo, isNamespace);
+				}
+			});
+		});
+	}
+}
+
+module.exports = MangleExportsPlugin;
Index: frontend/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,143 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_BASIC } = require("../OptimizationStages");
+const { runtimeEqual } = require("../util/runtime");
+
+/** @typedef {import("../../declarations/plugins/optimize/MergeDuplicateChunksPlugin").MergeDuplicateChunksPluginOptions} MergeDuplicateChunksPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Chunk")} Chunk */
+
+const PLUGIN_NAME = "MergeDuplicateChunksPlugin";
+
+class MergeDuplicateChunksPlugin {
+	/**
+	 * Creates an instance of MergeDuplicateChunksPlugin.
+	 * @param {MergeDuplicateChunksPluginOptions=} options options object
+	 */
+	constructor(options = { stage: STAGE_BASIC }) {
+		/** @type {MergeDuplicateChunksPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() =>
+					require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.json"),
+				this.options,
+				{
+					name: "Merge Duplicate Chunks Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.check")(
+						options
+					)
+			);
+		});
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: this.options.stage
+				},
+				(chunks) => {
+					const { chunkGraph, moduleGraph } = compilation;
+
+					// remember already tested chunks for performance
+					/** @type {Set<Chunk>} */
+					const notDuplicates = new Set();
+
+					// for each chunk
+					for (const chunk of chunks) {
+						// track a Set of all chunk that could be duplicates
+						/** @type {Set<Chunk> | undefined} */
+						let possibleDuplicates;
+						for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+							if (possibleDuplicates === undefined) {
+								// when possibleDuplicates is not yet set,
+								// create a new Set from chunks of the current module
+								// including only chunks with the same number of modules
+								for (const dup of chunkGraph.getModuleChunksIterable(module)) {
+									if (
+										dup !== chunk &&
+										chunkGraph.getNumberOfChunkModules(chunk) ===
+											chunkGraph.getNumberOfChunkModules(dup) &&
+										!notDuplicates.has(dup)
+									) {
+										// delay allocating the new Set until here, reduce memory pressure
+										if (possibleDuplicates === undefined) {
+											possibleDuplicates = new Set();
+										}
+										possibleDuplicates.add(dup);
+									}
+								}
+								// when no chunk is possible we can break here
+								if (possibleDuplicates === undefined) break;
+							} else {
+								// validate existing possible duplicates
+								for (const dup of possibleDuplicates) {
+									// remove possible duplicate when module is not contained
+									if (!chunkGraph.isModuleInChunk(module, dup)) {
+										possibleDuplicates.delete(dup);
+									}
+								}
+								// when all chunks has been removed we can break here
+								if (possibleDuplicates.size === 0) break;
+							}
+						}
+
+						// when we found duplicates
+						if (
+							possibleDuplicates !== undefined &&
+							possibleDuplicates.size > 0
+						) {
+							outer: for (const otherChunk of possibleDuplicates) {
+								if (otherChunk.hasRuntime() !== chunk.hasRuntime()) continue;
+								if (chunkGraph.getNumberOfEntryModules(chunk) > 0) continue;
+								if (chunkGraph.getNumberOfEntryModules(otherChunk) > 0) {
+									continue;
+								}
+								if (!runtimeEqual(chunk.runtime, otherChunk.runtime)) {
+									for (const module of chunkGraph.getChunkModulesIterable(
+										chunk
+									)) {
+										const exportsInfo = moduleGraph.getExportsInfo(module);
+										if (
+											!exportsInfo.isEquallyUsed(
+												chunk.runtime,
+												otherChunk.runtime
+											)
+										) {
+											continue outer;
+										}
+									}
+								}
+								// merge them
+								if (chunkGraph.canChunksBeIntegrated(chunk, otherChunk)) {
+									chunkGraph.integrateChunks(chunk, otherChunk);
+									compilation.chunks.delete(otherChunk);
+								}
+							}
+						}
+
+						// don't check already processed chunks twice
+						notDuplicates.add(chunk);
+					}
+				}
+			);
+		});
+	}
+}
+
+module.exports = MergeDuplicateChunksPlugin;
Index: frontend/node_modules/webpack/lib/optimize/MinChunkSizePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/MinChunkSizePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/MinChunkSizePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,126 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+
+/** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "MinChunkSizePlugin";
+
+class MinChunkSizePlugin {
+	/**
+	 * Creates an instance of MinChunkSizePlugin.
+	 * @param {MinChunkSizePluginOptions} options options object
+	 */
+	constructor(options) {
+		/** @type {MinChunkSizePluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"),
+				this.options,
+				{
+					name: "Min Chunk Size Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/optimize/MinChunkSizePlugin.check")(
+						options
+					)
+			);
+		});
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_ADVANCED
+				},
+				(chunks) => {
+					const chunkGraph = compilation.chunkGraph;
+					const equalOptions = {
+						chunkOverhead: 1,
+						entryChunkMultiplicator: 1
+					};
+
+					/** @type {Map<Chunk, number>} */
+					const chunkSizesMap = new Map();
+					/** @type {[Chunk, Chunk][]} */
+					const combinations = [];
+					/** @type {Chunk[]} */
+					const smallChunks = [];
+					/** @type {Chunk[]} */
+					const visitedChunks = [];
+					for (const a of chunks) {
+						// check if one of the chunks sizes is smaller than the minChunkSize
+						// and filter pairs that can NOT be integrated!
+						if (
+							chunkGraph.getChunkSize(a, equalOptions) <
+							this.options.minChunkSize
+						) {
+							smallChunks.push(a);
+							for (const b of visitedChunks) {
+								if (chunkGraph.canChunksBeIntegrated(b, a)) {
+									combinations.push([b, a]);
+								}
+							}
+						} else {
+							for (const b of smallChunks) {
+								if (chunkGraph.canChunksBeIntegrated(b, a)) {
+									combinations.push([b, a]);
+								}
+							}
+						}
+						chunkSizesMap.set(a, chunkGraph.getChunkSize(a, this.options));
+						visitedChunks.push(a);
+					}
+
+					const sortedSizeFilteredExtendedPairCombinations = combinations
+						.map((pair) => {
+							// extend combination pairs with size and integrated size
+							const a = /** @type {number} */ (chunkSizesMap.get(pair[0]));
+							const b = /** @type {number} */ (chunkSizesMap.get(pair[1]));
+							const ab = chunkGraph.getIntegratedChunksSize(
+								pair[0],
+								pair[1],
+								this.options
+							);
+							/** @type {[number, number, Chunk, Chunk]} */
+							const extendedPair = [a + b - ab, ab, pair[0], pair[1]];
+							return extendedPair;
+						})
+						.sort((a, b) => {
+							// sadly javascript does an in place sort here
+							// sort by size
+							const diff = b[0] - a[0];
+							if (diff !== 0) return diff;
+							return a[1] - b[1];
+						});
+
+					if (sortedSizeFilteredExtendedPairCombinations.length === 0) return;
+
+					const pair = sortedSizeFilteredExtendedPairCombinations[0];
+
+					chunkGraph.integrateChunks(pair[2], pair[3]);
+					compilation.chunks.delete(pair[3]);
+					return true;
+				}
+			);
+		});
+	}
+}
+
+module.exports = MinChunkSizePlugin;
Index: frontend/node_modules/webpack/lib/optimize/MinMaxSizeWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/MinMaxSizeWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/MinMaxSizeWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const formatSize = require("../util/formatSize");
+
+class MinMaxSizeWarning extends WebpackError {
+	/**
+	 * Creates an instance of MinMaxSizeWarning.
+	 * @param {string[] | undefined} keys keys
+	 * @param {number} minSize minimum size
+	 * @param {number} maxSize maximum size
+	 */
+	constructor(keys, minSize, maxSize) {
+		let keysMessage = "Fallback cache group";
+		if (keys) {
+			keysMessage =
+				keys.length > 1
+					? `Cache groups ${keys.sort().join(", ")}`
+					: `Cache group ${keys[0]}`;
+		}
+		super(
+			"SplitChunksPlugin\n" +
+				`${keysMessage}\n` +
+				`Configured minSize (${formatSize(minSize)}) is ` +
+				`bigger than maxSize (${formatSize(maxSize)}).\n` +
+				"This seem to be a invalid optimization.splitChunks configuration."
+		);
+	}
+}
+
+module.exports = MinMaxSizeWarning;
Index: frontend/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,999 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const asyncLib = require("neo-async");
+const ChunkGraph = require("../ChunkGraph");
+const Dependency = require("../Dependency");
+const Module = require("../Module");
+const ModuleGraph = require("../ModuleGraph");
+const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
+const { STAGE_DEFAULT } = require("../OptimizationStages");
+const { compareModulesByIdentifier } = require("../util/comparators");
+const {
+	filterRuntime,
+	intersectRuntime,
+	mergeRuntime,
+	mergeRuntimeOwned,
+	runtimeToString
+} = require("../util/runtime");
+const ConcatenatedModule = require("./ConcatenatedModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {Module | ((requestShortener: RequestShortener) => string)} Problem */
+
+/**
+ * Defines the statistics type used by this module.
+ * @typedef {object} Statistics
+ * @property {number} cached
+ * @property {number} alreadyInConfig
+ * @property {number} invalidModule
+ * @property {number} incorrectChunks
+ * @property {number} incorrectDependency
+ * @property {number} incorrectModuleDependency
+ * @property {number} incorrectChunksOfImporter
+ * @property {number} incorrectRuntimeCondition
+ * @property {number} importerFailed
+ * @property {number} added
+ */
+
+/**
+ * Format bailout reason.
+ * @param {string} msg message
+ * @returns {string} formatted message
+ */
+const formatBailoutReason = (msg) => `ModuleConcatenation bailout: ${msg}`;
+
+const PLUGIN_NAME = "ModuleConcatenationPlugin";
+
+class ModuleConcatenationPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _backCompat: backCompat } = compiler;
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			if (compilation.moduleMemCaches) {
+				throw new Error(
+					"optimization.concatenateModules can't be used with cacheUnaffected as module concatenation is a global effect"
+				);
+			}
+			const moduleGraph = compilation.moduleGraph;
+			/** @type {Map<Module, string | ((requestShortener: RequestShortener) => string)>} */
+			const bailoutReasonMap = new Map();
+
+			/**
+			 * Sets bailout reason.
+			 * @param {Module} module the module
+			 * @param {string | ((requestShortener: RequestShortener) => string)} reason the reason
+			 */
+			const setBailoutReason = (module, reason) => {
+				setInnerBailoutReason(module, reason);
+				moduleGraph
+					.getOptimizationBailout(module)
+					.push(
+						typeof reason === "function"
+							? (rs) => formatBailoutReason(reason(rs))
+							: formatBailoutReason(reason)
+					);
+			};
+
+			/**
+			 * Sets inner bailout reason.
+			 * @param {Module} module the module
+			 * @param {string | ((requestShortener: RequestShortener) => string)} reason the reason
+			 */
+			const setInnerBailoutReason = (module, reason) => {
+				bailoutReasonMap.set(module, reason);
+			};
+
+			/**
+			 * Gets inner bailout reason.
+			 * @param {Module} module the module
+			 * @param {RequestShortener} requestShortener the request shortener
+			 * @returns {string | ((requestShortener: RequestShortener) => string) | undefined} the reason
+			 */
+			const getInnerBailoutReason = (module, requestShortener) => {
+				const reason = bailoutReasonMap.get(module);
+				if (typeof reason === "function") return reason(requestShortener);
+				return reason;
+			};
+
+			/**
+			 * Format bailout warning.
+			 * @param {Module} module the module
+			 * @param {Problem} problem the problem
+			 * @returns {(requestShortener: RequestShortener) => string} the reason
+			 */
+			const formatBailoutWarning = (module, problem) => (requestShortener) => {
+				if (typeof problem === "function") {
+					return formatBailoutReason(
+						`Cannot concat with ${module.readableIdentifier(
+							requestShortener
+						)}: ${problem(requestShortener)}`
+					);
+				}
+				const reason = getInnerBailoutReason(module, requestShortener);
+				const reasonWithPrefix = reason ? `: ${reason}` : "";
+				if (module === problem) {
+					return formatBailoutReason(
+						`Cannot concat with ${module.readableIdentifier(
+							requestShortener
+						)}${reasonWithPrefix}`
+					);
+				}
+				return formatBailoutReason(
+					`Cannot concat with ${module.readableIdentifier(
+						requestShortener
+					)} because of ${problem.readableIdentifier(
+						requestShortener
+					)}${reasonWithPrefix}`
+				);
+			};
+
+			compilation.hooks.optimizeChunkModules.tapAsync(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_DEFAULT
+				},
+				(allChunks, modules, callback) => {
+					const logger = compilation.getLogger(
+						"webpack.ModuleConcatenationPlugin"
+					);
+					const { chunkGraph, moduleGraph } = compilation;
+					/** @type {Module[]} */
+					const relevantModules = [];
+					/** @type {Set<Module>} */
+					const possibleInners = new Set();
+					const context = {
+						chunkGraph,
+						moduleGraph
+					};
+					const deferEnabled = compilation.options.experiments.deferImport;
+					logger.time("select relevant modules");
+					for (const module of modules) {
+						let canBeRoot = true;
+						let canBeInner = true;
+
+						const bailoutReason = module.getConcatenationBailoutReason(context);
+						if (bailoutReason) {
+							setBailoutReason(module, bailoutReason);
+							continue;
+						}
+
+						// Must not be an async module
+						if (moduleGraph.isAsync(module)) {
+							setBailoutReason(module, "Module is async");
+							continue;
+						}
+
+						// Must be in strict mode
+						if (!(/** @type {BuildInfo} */ (module.buildInfo).strict)) {
+							setBailoutReason(module, "Module is not in strict mode");
+							continue;
+						}
+
+						// Module must be in any chunk (we don't want to do useless work)
+						if (chunkGraph.getNumberOfModuleChunks(module) === 0) {
+							setBailoutReason(module, "Module is not in any chunk");
+							continue;
+						}
+
+						// Exports must be known (and not dynamic)
+						const exportsInfo = moduleGraph.getExportsInfo(module);
+						const relevantExports = exportsInfo.getRelevantExports(undefined);
+						const unknownReexports = relevantExports.filter(
+							(exportInfo) =>
+								exportInfo.isReexport() && !exportInfo.getTarget(moduleGraph)
+						);
+						if (unknownReexports.length > 0) {
+							setBailoutReason(
+								module,
+								`Reexports in this module do not have a static target (${Array.from(
+									unknownReexports,
+									(exportInfo) =>
+										`${
+											exportInfo.name || "other exports"
+										}: ${exportInfo.getUsedInfo()}`
+								).join(", ")})`
+							);
+							continue;
+						}
+
+						// Root modules must have a static list of exports
+						const unknownProvidedExports = relevantExports.filter(
+							(exportInfo) => exportInfo.provided !== true
+						);
+						if (unknownProvidedExports.length > 0) {
+							setBailoutReason(
+								module,
+								`List of module exports is dynamic (${Array.from(
+									unknownProvidedExports,
+									(exportInfo) =>
+										`${
+											exportInfo.name || "other exports"
+										}: ${exportInfo.getProvidedInfo()} and ${exportInfo.getUsedInfo()}`
+								).join(", ")})`
+							);
+							canBeRoot = false;
+						}
+
+						// TODO: ConcatenatedModule.getSourceTypes only javascript now
+						const basicTypes = Module.getSourceBasicTypes(module);
+						if (basicTypes.size !== 1 || !basicTypes.has(JAVASCRIPT_TYPE)) {
+							canBeRoot = false;
+						}
+
+						// Module must not be an entry point
+						if (chunkGraph.isEntryModule(module)) {
+							setInnerBailoutReason(module, "Module is an entry point");
+							canBeInner = false;
+						}
+
+						if (deferEnabled && moduleGraph.isDeferred(module)) {
+							setInnerBailoutReason(module, "Module is deferred");
+							canBeInner = false;
+						}
+
+						if (canBeRoot) relevantModules.push(module);
+						if (canBeInner) possibleInners.add(module);
+					}
+					logger.timeEnd("select relevant modules");
+					logger.debug(
+						`${relevantModules.length} potential root modules, ${possibleInners.size} potential inner modules`
+					);
+					// sort by depth
+					// modules with lower depth are more likely suited as roots
+					// this improves performance, because modules already selected as inner are skipped
+					logger.time("sort relevant modules");
+					relevantModules.sort(
+						(a, b) =>
+							/** @type {number} */ (moduleGraph.getDepth(a)) -
+							/** @type {number} */ (moduleGraph.getDepth(b))
+					);
+					logger.timeEnd("sort relevant modules");
+
+					/** @type {Statistics} */
+					const stats = {
+						cached: 0,
+						alreadyInConfig: 0,
+						invalidModule: 0,
+						incorrectChunks: 0,
+						incorrectDependency: 0,
+						incorrectModuleDependency: 0,
+						incorrectChunksOfImporter: 0,
+						incorrectRuntimeCondition: 0,
+						importerFailed: 0,
+						added: 0
+					};
+					let statsCandidates = 0;
+					let statsSizeSum = 0;
+					let statsEmptyConfigurations = 0;
+
+					logger.time("find modules to concatenate");
+					/** @type {ConcatConfiguration[]} */
+					const concatConfigurations = [];
+					/** @type {Set<Module>} */
+					const usedAsInner = new Set();
+					for (const currentRoot of relevantModules) {
+						// when used by another configuration as inner:
+						// the other configuration is better and we can skip this one
+						// TODO reconsider that when it's only used in a different runtime
+						if (usedAsInner.has(currentRoot)) continue;
+
+						/** @type {RuntimeSpec} */
+						let chunkRuntime;
+						for (const r of chunkGraph.getModuleRuntimes(currentRoot)) {
+							chunkRuntime = mergeRuntimeOwned(chunkRuntime, r);
+						}
+						const exportsInfo = moduleGraph.getExportsInfo(currentRoot);
+						const filteredRuntime = filterRuntime(chunkRuntime, (r) =>
+							exportsInfo.isModuleUsed(r)
+						);
+						const activeRuntime =
+							filteredRuntime === true
+								? chunkRuntime
+								: filteredRuntime === false
+									? undefined
+									: filteredRuntime;
+
+						// create a configuration with the root
+						const currentConfiguration = new ConcatConfiguration(
+							currentRoot,
+							activeRuntime
+						);
+
+						// cache failures to add modules
+						/** @type {Map<Module, Problem>} */
+						const failureCache = new Map();
+
+						// potential optional import candidates
+						/** @type {Set<Module>} */
+						const candidates = new Set();
+
+						// try to add all imports
+						for (const imp of this._getImports(
+							compilation,
+							currentRoot,
+							activeRuntime
+						)) {
+							candidates.add(imp);
+						}
+
+						for (const imp of candidates) {
+							/** @type {Set<Module>} */
+							const impCandidates = new Set();
+							const problem = this._tryToAdd(
+								compilation,
+								currentConfiguration,
+								imp,
+								chunkRuntime,
+								activeRuntime,
+								possibleInners,
+								impCandidates,
+								failureCache,
+								chunkGraph,
+								true,
+								stats
+							);
+							if (problem) {
+								failureCache.set(imp, problem);
+								currentConfiguration.addWarning(imp, problem);
+							} else {
+								for (const c of impCandidates) {
+									candidates.add(c);
+								}
+							}
+						}
+						statsCandidates += candidates.size;
+						if (!currentConfiguration.isEmpty()) {
+							const modules = currentConfiguration.getModules();
+							statsSizeSum += modules.size;
+							concatConfigurations.push(currentConfiguration);
+							for (const module of modules) {
+								if (module !== currentConfiguration.rootModule) {
+									usedAsInner.add(module);
+								}
+							}
+						} else {
+							statsEmptyConfigurations++;
+							const optimizationBailouts =
+								moduleGraph.getOptimizationBailout(currentRoot);
+							for (const warning of currentConfiguration.getWarningsSorted()) {
+								optimizationBailouts.push(
+									formatBailoutWarning(warning[0], warning[1])
+								);
+							}
+						}
+					}
+					logger.timeEnd("find modules to concatenate");
+					logger.debug(
+						`${
+							concatConfigurations.length
+						} successful concat configurations (avg size: ${
+							statsSizeSum / concatConfigurations.length
+						}), ${statsEmptyConfigurations} bailed out completely`
+					);
+					logger.debug(
+						`${statsCandidates} candidates were considered for adding (${stats.cached} cached failure, ${stats.alreadyInConfig} already in config, ${stats.invalidModule} invalid module, ${stats.incorrectChunks} incorrect chunks, ${stats.incorrectDependency} incorrect dependency, ${stats.incorrectChunksOfImporter} incorrect chunks of importer, ${stats.incorrectModuleDependency} incorrect module dependency, ${stats.incorrectRuntimeCondition} incorrect runtime condition, ${stats.importerFailed} importer failed, ${stats.added} added)`
+					);
+					// HACK: Sort configurations by length and start with the longest one
+					// to get the biggest groups possible. Used modules are marked with usedModules
+					// TODO: Allow to reuse existing configuration while trying to add dependencies.
+					// This would improve performance. O(n^2) -> O(n)
+					logger.time("sort concat configurations");
+					concatConfigurations.sort((a, b) => b.modules.size - a.modules.size);
+					logger.timeEnd("sort concat configurations");
+					/** @type {Set<Module>} */
+					const usedModules = new Set();
+
+					logger.time("create concatenated modules");
+					asyncLib.each(
+						concatConfigurations,
+						(concatConfiguration, callback) => {
+							const rootModule = concatConfiguration.rootModule;
+
+							// Avoid overlapping configurations
+							// TODO: remove this when todo above is fixed
+							if (usedModules.has(rootModule)) return callback();
+							const modules = concatConfiguration.getModules();
+							for (const m of modules) {
+								usedModules.add(m);
+							}
+
+							// Create a new ConcatenatedModule
+							const newModule = ConcatenatedModule.create(
+								rootModule,
+								modules,
+								concatConfiguration.runtime,
+								compilation,
+								compiler.root,
+								compilation.outputOptions.hashFunction
+							);
+
+							const build = () => {
+								newModule.build(
+									compilation.options,
+									compilation,
+									/** @type {EXPECTED_ANY} */
+									(null),
+									/** @type {EXPECTED_ANY} */
+									(null),
+									(err) => {
+										if (err) {
+											if (!err.module) {
+												err.module = newModule;
+											}
+											return callback(err);
+										}
+										integrate();
+									}
+								);
+							};
+
+							const integrate = () => {
+								if (backCompat) {
+									ChunkGraph.setChunkGraphForModule(newModule, chunkGraph);
+									ModuleGraph.setModuleGraphForModule(newModule, moduleGraph);
+								}
+
+								for (const warning of concatConfiguration.getWarningsSorted()) {
+									moduleGraph
+										.getOptimizationBailout(newModule)
+										.push(formatBailoutWarning(warning[0], warning[1]));
+								}
+								moduleGraph.cloneModuleAttributes(rootModule, newModule);
+								for (const m of modules) {
+									// add to builtModules when one of the included modules was built
+									if (compilation.builtModules.has(m)) {
+										compilation.builtModules.add(newModule);
+									}
+									if (m !== rootModule) {
+										// attach external references to the concatenated module too
+										moduleGraph.copyOutgoingModuleConnections(
+											m,
+											newModule,
+											(c) =>
+												c.originModule === m &&
+												!(
+													c.dependency &&
+													Dependency.canConcatenate(c.dependency) &&
+													modules.has(c.module)
+												)
+										);
+										// remove module from chunk
+										for (const chunk of chunkGraph.getModuleChunksIterable(
+											rootModule
+										)) {
+											const sourceTypes = chunkGraph.getChunkModuleSourceTypes(
+												chunk,
+												m
+											);
+											if (
+												sourceTypes.size === 1 &&
+												sourceTypes.has(JAVASCRIPT_TYPE)
+											) {
+												chunkGraph.disconnectChunkAndModule(chunk, m);
+											} else {
+												const newSourceTypes = new Set(sourceTypes);
+												newSourceTypes.delete(JAVASCRIPT_TYPE);
+												chunkGraph.setChunkModuleSourceTypes(
+													chunk,
+													m,
+													newSourceTypes
+												);
+											}
+										}
+									}
+								}
+								compilation.modules.delete(rootModule);
+								ChunkGraph.clearChunkGraphForModule(rootModule);
+								ModuleGraph.clearModuleGraphForModule(rootModule);
+
+								// remove module from chunk
+								chunkGraph.replaceModule(rootModule, newModule);
+								// replace module references with the concatenated module
+								moduleGraph.moveModuleConnections(
+									rootModule,
+									newModule,
+									(c) => {
+										const otherModule =
+											c.module === rootModule ? c.originModule : c.module;
+										const innerConnection =
+											c.dependency &&
+											Dependency.canConcatenate(c.dependency) &&
+											modules.has(/** @type {Module} */ (otherModule));
+										return !innerConnection;
+									}
+								);
+								// add concatenated module to the compilation
+								compilation.modules.add(newModule);
+
+								callback();
+							};
+
+							build();
+						},
+						(err) => {
+							logger.timeEnd("create concatenated modules");
+							process.nextTick(callback.bind(null, err));
+						}
+					);
+				}
+			);
+		});
+	}
+
+	/**
+	 * Returns the imported modules.
+	 * @param {Compilation} compilation the compilation
+	 * @param {Module} module the module to be added
+	 * @param {RuntimeSpec} runtime the runtime scope
+	 * @returns {Set<Module>} the imported modules
+	 */
+	_getImports(compilation, module, runtime) {
+		const moduleGraph = compilation.moduleGraph;
+		/** @type {Set<Module>} */
+		const set = new Set();
+		for (const dep of module.dependencies) {
+			// Get reference info only for dependencies that support concatenation
+			if (!Dependency.canConcatenate(dep)) continue;
+
+			const connection = moduleGraph.getConnection(dep);
+			// Reference is valid and has a module
+			if (
+				!connection ||
+				!connection.module ||
+				!connection.isTargetActive(runtime)
+			) {
+				continue;
+			}
+
+			const importedNames = compilation.getDependencyReferencedExports(
+				dep,
+				undefined
+			);
+
+			if (
+				importedNames.every((i) =>
+					Array.isArray(i) ? i.length > 0 : i.name.length > 0
+				) ||
+				Array.isArray(moduleGraph.getProvidedExports(module))
+			) {
+				set.add(connection.module);
+			}
+		}
+		return set;
+	}
+
+	/**
+	 * Returns the problematic module.
+	 * @param {Compilation} compilation webpack compilation
+	 * @param {ConcatConfiguration} config concat configuration (will be modified when added)
+	 * @param {Module} module the module to be added
+	 * @param {RuntimeSpec} runtime the runtime scope of the generated code
+	 * @param {RuntimeSpec} activeRuntime the runtime scope of the root module
+	 * @param {Set<Module>} possibleModules modules that are candidates
+	 * @param {Set<Module>} candidates list of potential candidates (will be added to)
+	 * @param {Map<Module, Problem>} failureCache cache for problematic modules to be more performant
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {boolean} avoidMutateOnFailure avoid mutating the config when adding fails
+	 * @param {Statistics} statistics gathering metrics
+	 * @returns {null | Problem} the problematic module
+	 */
+	_tryToAdd(
+		compilation,
+		config,
+		module,
+		runtime,
+		activeRuntime,
+		possibleModules,
+		candidates,
+		failureCache,
+		chunkGraph,
+		avoidMutateOnFailure,
+		statistics
+	) {
+		const cacheEntry = failureCache.get(module);
+		if (cacheEntry) {
+			statistics.cached++;
+			return cacheEntry;
+		}
+
+		// Already added?
+		if (config.has(module)) {
+			statistics.alreadyInConfig++;
+			return null;
+		}
+
+		// Not possible to add?
+		if (!possibleModules.has(module)) {
+			statistics.invalidModule++;
+			failureCache.set(module, module); // cache failures for performance
+			return module;
+		}
+
+		// Module must be in the correct chunks
+		const missingChunks = [
+			...chunkGraph.getModuleChunksIterable(config.rootModule)
+		].filter((chunk) => !chunkGraph.isModuleInChunk(module, chunk));
+		if (missingChunks.length > 0) {
+			/**
+			 * Returns problem description.
+			 * @param {RequestShortener} requestShortener request shortener
+			 * @returns {string} problem description
+			 */
+			const problem = (requestShortener) => {
+				const missingChunksList = [
+					...new Set(
+						missingChunks.map((chunk) => chunk.name || "unnamed chunk(s)")
+					)
+				].sort();
+				const chunks = [
+					...new Set(
+						[...chunkGraph.getModuleChunksIterable(module)].map(
+							(chunk) => chunk.name || "unnamed chunk(s)"
+						)
+					)
+				].sort();
+				return `Module ${module.readableIdentifier(
+					requestShortener
+				)} is not in the same chunk(s) (expected in chunk(s) ${missingChunksList.join(
+					", "
+				)}, module is in chunk(s) ${chunks.join(", ")})`;
+			};
+			statistics.incorrectChunks++;
+			failureCache.set(module, problem); // cache failures for performance
+			return problem;
+		}
+
+		const moduleGraph = compilation.moduleGraph;
+
+		const incomingConnections =
+			moduleGraph.getIncomingConnectionsByOriginModule(module);
+
+		const incomingConnectionsFromNonModules =
+			incomingConnections.get(null) || incomingConnections.get(undefined);
+		if (incomingConnectionsFromNonModules) {
+			const activeNonModulesConnections =
+				incomingConnectionsFromNonModules.filter((connection) =>
+					// We are not interested in inactive connections
+					// or connections without dependency
+					connection.isActive(runtime)
+				);
+			if (activeNonModulesConnections.length > 0) {
+				/**
+				 * Returns problem description.
+				 * @param {RequestShortener} requestShortener request shortener
+				 * @returns {string} problem description
+				 */
+				const problem = (requestShortener) => {
+					/** @type {Set<string>} */
+					const importingExplanations = new Set(
+						activeNonModulesConnections
+							.map((c) => c.explanation)
+							.filter(Boolean)
+					);
+					const explanations = [...importingExplanations].sort();
+					return `Module ${module.readableIdentifier(
+						requestShortener
+					)} is referenced ${
+						explanations.length > 0
+							? `by: ${explanations.join(", ")}`
+							: "in an unsupported way"
+					}`;
+				};
+				statistics.incorrectDependency++;
+				failureCache.set(module, problem); // cache failures for performance
+				return problem;
+			}
+		}
+
+		/** @type {Map<Module, ReadonlyArray<ModuleGraph.ModuleGraphConnection>>} */
+		const incomingConnectionsFromModules = new Map();
+		for (const [originModule, connections] of incomingConnections) {
+			if (originModule) {
+				// Ignore connection from orphan modules
+				if (chunkGraph.getNumberOfModuleChunks(originModule) === 0) continue;
+
+				// We don't care for connections from other runtimes
+				/** @type {RuntimeSpec} */
+				let originRuntime;
+				for (const r of chunkGraph.getModuleRuntimes(originModule)) {
+					originRuntime = mergeRuntimeOwned(originRuntime, r);
+				}
+
+				if (!intersectRuntime(runtime, originRuntime)) continue;
+
+				// We are not interested in inactive connections
+				const activeConnections = connections.filter((connection) =>
+					connection.isActive(runtime)
+				);
+				if (activeConnections.length > 0) {
+					incomingConnectionsFromModules.set(originModule, activeConnections);
+				}
+			}
+		}
+
+		const incomingModules = [...incomingConnectionsFromModules.keys()];
+
+		// Module must be in the same chunks like the referencing module
+		const otherChunkModules = incomingModules.filter((originModule) => {
+			for (const chunk of chunkGraph.getModuleChunksIterable(
+				config.rootModule
+			)) {
+				if (!chunkGraph.isModuleInChunk(originModule, chunk)) {
+					return true;
+				}
+			}
+			return false;
+		});
+		if (otherChunkModules.length > 0) {
+			/**
+			 * Returns problem description.
+			 * @param {RequestShortener} requestShortener request shortener
+			 * @returns {string} problem description
+			 */
+			const problem = (requestShortener) => {
+				const names = otherChunkModules
+					.map((m) => m.readableIdentifier(requestShortener))
+					.sort();
+				return `Module ${module.readableIdentifier(
+					requestShortener
+				)} is referenced from different chunks by these modules: ${names.join(
+					", "
+				)}`;
+			};
+			statistics.incorrectChunksOfImporter++;
+			failureCache.set(module, problem); // cache failures for performance
+			return problem;
+		}
+
+		/** @type {Map<Module, ReadonlyArray<ModuleGraph.ModuleGraphConnection>>} */
+		const nonHarmonyConnections = new Map();
+		for (const [originModule, connections] of incomingConnectionsFromModules) {
+			const selected = connections.filter(
+				(connection) =>
+					!connection.dependency ||
+					!Dependency.canConcatenate(connection.dependency)
+			);
+			if (selected.length > 0) {
+				nonHarmonyConnections.set(originModule, connections);
+			}
+		}
+		if (nonHarmonyConnections.size > 0) {
+			/**
+			 * Returns problem description.
+			 * @param {RequestShortener} requestShortener request shortener
+			 * @returns {string} problem description
+			 */
+			const problem = (requestShortener) => {
+				const names = [...nonHarmonyConnections]
+					.map(
+						([originModule, connections]) =>
+							`${originModule.readableIdentifier(
+								requestShortener
+							)} (referenced with ${[
+								...new Set(
+									connections
+										.map((c) => c.dependency && c.dependency.type)
+										.filter(Boolean)
+								)
+							]
+								.sort()
+								.join(", ")})`
+					)
+					.sort();
+				return `Module ${module.readableIdentifier(
+					requestShortener
+				)} is referenced from these modules with unsupported syntax: ${names.join(
+					", "
+				)}`;
+			};
+			statistics.incorrectModuleDependency++;
+			failureCache.set(module, problem); // cache failures for performance
+			return problem;
+		}
+
+		if (runtime !== undefined && typeof runtime !== "string") {
+			// Module must be consistently referenced in the same runtimes
+			/** @type {{ originModule: Module, runtimeCondition: RuntimeSpec }[]} */
+			const otherRuntimeConnections = [];
+			outer: for (const [
+				originModule,
+				connections
+			] of incomingConnectionsFromModules) {
+				/** @type {false | RuntimeSpec} */
+				let currentRuntimeCondition = false;
+				for (const connection of connections) {
+					const runtimeCondition = filterRuntime(runtime, (runtime) =>
+						connection.isTargetActive(runtime)
+					);
+					if (runtimeCondition === false) continue;
+					if (runtimeCondition === true) continue outer;
+					currentRuntimeCondition =
+						currentRuntimeCondition !== false
+							? mergeRuntime(currentRuntimeCondition, runtimeCondition)
+							: runtimeCondition;
+				}
+				if (currentRuntimeCondition !== false) {
+					otherRuntimeConnections.push({
+						originModule,
+						runtimeCondition: currentRuntimeCondition
+					});
+				}
+			}
+			if (otherRuntimeConnections.length > 0) {
+				/**
+				 * Returns problem description.
+				 * @param {RequestShortener} requestShortener request shortener
+				 * @returns {string} problem description
+				 */
+				const problem = (requestShortener) =>
+					`Module ${module.readableIdentifier(
+						requestShortener
+					)} is runtime-dependent referenced by these modules: ${Array.from(
+						otherRuntimeConnections,
+						({ originModule, runtimeCondition }) =>
+							`${originModule.readableIdentifier(
+								requestShortener
+							)} (expected runtime ${runtimeToString(
+								runtime
+							)}, module is only referenced in ${runtimeToString(
+								/** @type {RuntimeSpec} */ (runtimeCondition)
+							)})`
+					).join(", ")}`;
+				statistics.incorrectRuntimeCondition++;
+				failureCache.set(module, problem); // cache failures for performance
+				return problem;
+			}
+		}
+
+		/** @type {undefined | number} */
+		let backup;
+		if (avoidMutateOnFailure) {
+			backup = config.snapshot();
+		}
+
+		// Add the module
+		config.add(module);
+
+		incomingModules.sort(compareModulesByIdentifier);
+
+		// Every module which depends on the added module must be in the configuration too.
+		for (const originModule of incomingModules) {
+			const problem = this._tryToAdd(
+				compilation,
+				config,
+				originModule,
+				runtime,
+				activeRuntime,
+				possibleModules,
+				candidates,
+				failureCache,
+				chunkGraph,
+				false,
+				statistics
+			);
+			if (problem) {
+				if (backup !== undefined) config.rollback(backup);
+				statistics.importerFailed++;
+				failureCache.set(module, problem); // cache failures for performance
+				return problem;
+			}
+		}
+
+		// Add imports to possible candidates list
+		for (const imp of this._getImports(compilation, module, runtime)) {
+			candidates.add(imp);
+		}
+		statistics.added++;
+		return null;
+	}
+}
+
+/** @typedef {Map<Module, Problem>} Warnings */
+
+class ConcatConfiguration {
+	/**
+	 * Creates an instance of ConcatConfiguration.
+	 * @param {Module} rootModule the root module
+	 * @param {RuntimeSpec} runtime the runtime
+	 */
+	constructor(rootModule, runtime) {
+		/** @type {Module} */
+		this.rootModule = rootModule;
+		/** @type {RuntimeSpec} */
+		this.runtime = runtime;
+		/** @type {Set<Module>} */
+		this.modules = new Set();
+		this.modules.add(rootModule);
+		/** @type {Warnings} */
+		this.warnings = new Map();
+	}
+
+	/**
+	 * Processes the provided module.
+	 * @param {Module} module the module
+	 */
+	add(module) {
+		this.modules.add(module);
+	}
+
+	/**
+	 * Returns true, when the module is in the module set.
+	 * @param {Module} module the module
+	 * @returns {boolean} true, when the module is in the module set
+	 */
+	has(module) {
+		return this.modules.has(module);
+	}
+
+	isEmpty() {
+		return this.modules.size === 1;
+	}
+
+	/**
+	 * Adds the provided module to the concat configuration.
+	 * @param {Module} module the module
+	 * @param {Problem} problem the problem
+	 */
+	addWarning(module, problem) {
+		this.warnings.set(module, problem);
+	}
+
+	/**
+	 * Gets warnings sorted.
+	 * @returns {Warnings} warnings
+	 */
+	getWarningsSorted() {
+		return new Map(
+			[...this.warnings].sort((a, b) => {
+				const ai = a[0].identifier();
+				const bi = b[0].identifier();
+				if (ai < bi) return -1;
+				if (ai > bi) return 1;
+				return 0;
+			})
+		);
+	}
+
+	/**
+	 * Returns modules as set.
+	 * @returns {Set<Module>} modules as set
+	 */
+	getModules() {
+		return this.modules;
+	}
+
+	snapshot() {
+		return this.modules.size;
+	}
+
+	/**
+	 * Processes the provided snapshot.
+	 * @param {number} snapshot snapshot
+	 */
+	rollback(snapshot) {
+		const modules = this.modules;
+		for (const m of modules) {
+			if (snapshot === 0) {
+				modules.delete(m);
+			} else {
+				snapshot--;
+			}
+		}
+	}
+}
+
+module.exports = ModuleConcatenationPlugin;
Index: frontend/node_modules/webpack/lib/optimize/RealContentHashPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/RealContentHashPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/RealContentHashPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,566 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncBailHook } = require("tapable");
+const { CachedSource, CompatSource, RawSource } = require("webpack-sources");
+const Compilation = require("../Compilation");
+const WebpackError = require("../errors/WebpackError");
+const { compareSelect, compareStrings } = require("../util/comparators");
+const createHash = require("../util/createHash");
+
+/** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
+/** @typedef {import("../../declarations/WebpackOptions").HashDigest} HashDigest */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Cache").Etag} Etag */
+/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {typeof import("../util/Hash")} Hash */
+
+/**
+ * Defines the comparator type used by this module.
+ * @template T
+ * @typedef {import("../util/comparators").Comparator<T>} Comparator
+ */
+
+/** @type {Hashes} */
+const EMPTY_SET = new Set();
+
+/**
+ * Adds the provided item or item to this object.
+ * @template T
+ * @param {T | T[]} itemOrItems item or items
+ * @param {Set<T>} list list
+ */
+const addToList = (itemOrItems, list) => {
+	if (Array.isArray(itemOrItems)) {
+		for (const item of itemOrItems) {
+			list.add(item);
+		}
+	} else if (itemOrItems) {
+		list.add(itemOrItems);
+	}
+};
+
+/**
+ * Compares two non-empty buffer chunk arrays for byte-equality without
+ * allocating a concatenated buffer.
+ * @param {Buffer[]} a first chunk array
+ * @param {Buffer[]} b second chunk array
+ * @returns {boolean} true if the concatenations are byte-equal
+ */
+const bufferArraysEqual = (a, b) => {
+	let aIdx = 0;
+	let aOff = 0;
+	let bIdx = 0;
+	let bOff = 0;
+	while (aIdx < a.length && bIdx < b.length) {
+		const aBuf = a[aIdx];
+		const bBuf = b[bIdx];
+		const len = Math.min(aBuf.length - aOff, bBuf.length - bOff);
+		if (aBuf.compare(bBuf, bOff, bOff + len, aOff, aOff + len) !== 0) {
+			return false;
+		}
+		aOff += len;
+		bOff += len;
+		if (aOff === aBuf.length) {
+			aIdx++;
+			aOff = 0;
+		}
+		if (bOff === bBuf.length) {
+			bIdx++;
+			bOff = 0;
+		}
+	}
+	return aIdx === a.length && bIdx === b.length;
+};
+
+/**
+ * Map sources to their buffer chunks and deduplicate by total byte content,
+ * grouping by total length first to avoid full comparisons.
+ * @template T
+ * @param {T[]} input list
+ * @param {(item: T) => Source} fn map function returning a Source
+ * @returns {Buffer[][]} unique chunk arrays
+ */
+const mapAndDeduplicateSourceBuffers = (input, fn) => {
+	/** @type {Map<number, Buffer[][]>} */
+	const bySize = new Map();
+	/** @type {Buffer[][]} */
+	const result = [];
+	for (const value of input) {
+		const source = fn(value);
+		// TODO webpack 6: drop the `buffers` check, require webpack-sources >= 3.4
+		// and call `source.buffers()` unconditionally.
+		const chunks =
+			// TODO remove in webpack 6, this is protection against authors who directly use `webpack-sources` outdated version
+			typeof source.buffers === "function"
+				? source.buffers()
+				: [source.buffer()];
+		let total = 0;
+		for (const c of chunks) total += c.length;
+		const sameSize = bySize.get(total);
+		if (sameSize) {
+			let duplicate = false;
+			for (const other of sameSize) {
+				if (bufferArraysEqual(chunks, other)) {
+					duplicate = true;
+					break;
+				}
+			}
+			if (duplicate) continue;
+			sameSize.push(chunks);
+		} else {
+			bySize.set(total, [chunks]);
+		}
+		result.push(chunks);
+	}
+	return result;
+};
+
+/**
+ * Escapes regular expression metacharacters
+ * @param {string} str String to quote
+ * @returns {string} Escaped string
+ */
+const quoteMeta = (str) => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
+
+/** @type {WeakMap<Source, CachedSource>} */
+const cachedSourceMap = new WeakMap();
+
+/**
+ * Returns cached source.
+ * @param {Source} source source
+ * @returns {CachedSource} cached source
+ */
+const toCachedSource = (source) => {
+	if (source instanceof CachedSource) {
+		return source;
+	}
+	const entry = cachedSourceMap.get(source);
+	if (entry !== undefined) return entry;
+	const newSource = new CachedSource(CompatSource.from(source));
+	cachedSourceMap.set(source, newSource);
+	return newSource;
+};
+
+/** @typedef {Set<string>} Hashes */
+
+/**
+ * Defines the asset info for real content hash type used by this module.
+ * @typedef {object} AssetInfoForRealContentHash
+ * @property {string} name
+ * @property {AssetInfo} info
+ * @property {Source} source
+ * @property {RawSource | undefined} newSource
+ * @property {RawSource | undefined} newSourceWithoutOwn
+ * @property {string} content
+ * @property {Hashes | undefined} ownHashes
+ * @property {Promise<void> | undefined} contentComputePromise
+ * @property {Promise<void> | undefined} contentComputeWithoutOwnPromise
+ * @property {Hashes | undefined} referencedHashes
+ * @property {Hashes} hashes
+ */
+
+/**
+ * Defines the compilation hooks type used by this module.
+ * @typedef {object} CompilationHooks
+ * @property {SyncBailHook<[Buffer[], string], string | void>} updateHash
+ */
+
+/** @type {WeakMap<Compilation, CompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+/**
+ * Defines the real content hash plugin options type used by this module.
+ * @typedef {object} RealContentHashPluginOptions
+ * @property {HashFunction} hashFunction the hash function to use
+ * @property {HashDigest} hashDigest the hash digest to use
+ */
+
+const PLUGIN_NAME = "RealContentHashPlugin";
+
+class RealContentHashPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CompilationHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				updateHash: new SyncBailHook(["content", "oldHash"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Creates an instance of RealContentHashPlugin.
+	 * @param {RealContentHashPluginOptions} options options
+	 */
+	constructor({ hashFunction, hashDigest }) {
+		/** @type {HashFunction} */
+		this._hashFunction = hashFunction;
+		/** @type {HashDigest} */
+		this._hashDigest = hashDigest;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			const cacheAnalyse = compilation.getCache(
+				"RealContentHashPlugin|analyse"
+			);
+			const cacheGenerate = compilation.getCache(
+				"RealContentHashPlugin|generate"
+			);
+			const hooks = RealContentHashPlugin.getCompilationHooks(compilation);
+			compilation.hooks.processAssets.tapPromise(
+				{
+					name: PLUGIN_NAME,
+					stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH
+				},
+				async () => {
+					const assets = compilation.getAssets();
+					/** @type {AssetInfoForRealContentHash[]} */
+					const assetsWithInfo = [];
+					/** @type {Map<string, [AssetInfoForRealContentHash]>} */
+					const hashToAssets = new Map();
+					for (const { source, info, name } of assets) {
+						const cachedSource = toCachedSource(source);
+						const content = /** @type {string} */ (cachedSource.source());
+						/** @type {Hashes} */
+						const hashes = new Set();
+						addToList(info.contenthash, hashes);
+						/** @type {AssetInfoForRealContentHash} */
+						const data = {
+							name,
+							info,
+							source: cachedSource,
+							newSource: undefined,
+							newSourceWithoutOwn: undefined,
+							content,
+							ownHashes: undefined,
+							contentComputePromise: undefined,
+							contentComputeWithoutOwnPromise: undefined,
+							referencedHashes: undefined,
+							hashes
+						};
+						assetsWithInfo.push(data);
+						for (const hash of hashes) {
+							const list = hashToAssets.get(hash);
+							if (list === undefined) {
+								hashToAssets.set(hash, [data]);
+							} else {
+								list.push(data);
+							}
+						}
+					}
+					if (hashToAssets.size === 0) return;
+					const hashRegExp = new RegExp(
+						Array.from(hashToAssets.keys(), quoteMeta).join("|"),
+						"g"
+					);
+					await Promise.all(
+						assetsWithInfo.map(async (asset) => {
+							const { name, source, content, hashes } = asset;
+							if (Buffer.isBuffer(content)) {
+								asset.referencedHashes = EMPTY_SET;
+								asset.ownHashes = EMPTY_SET;
+								return;
+							}
+							const etag = cacheAnalyse.mergeEtags(
+								cacheAnalyse.getLazyHashedEtag(source),
+								[...hashes].join("|")
+							);
+							[asset.referencedHashes, asset.ownHashes] =
+								await cacheAnalyse.providePromise(name, etag, () => {
+									/** @type {Hashes} */
+									const referencedHashes = new Set();
+									/** @type {Hashes} */
+									const ownHashes = new Set();
+									const inContent = content.match(hashRegExp);
+									if (inContent) {
+										for (const hash of inContent) {
+											if (hashes.has(hash)) {
+												ownHashes.add(hash);
+												continue;
+											}
+											referencedHashes.add(hash);
+										}
+									}
+									return [referencedHashes, ownHashes];
+								});
+						})
+					);
+					/**
+					 * Returns the referenced hashes.
+					 * @param {string} hash the hash
+					 * @returns {undefined | Hashes} the referenced hashes
+					 */
+					const getDependencies = (hash) => {
+						const assets = hashToAssets.get(hash);
+						if (!assets) {
+							const referencingAssets = assetsWithInfo.filter((asset) =>
+								/** @type {Hashes} */ (asset.referencedHashes).has(hash)
+							);
+							const err = new WebpackError(`RealContentHashPlugin
+Some kind of unexpected caching problem occurred.
+An asset was cached with a reference to another asset (${hash}) that's not in the compilation anymore.
+Either the asset was incorrectly cached, or the referenced asset should also be restored from cache.
+Referenced by:
+${referencingAssets
+	.map((a) => {
+		const match = new RegExp(`.{0,20}${quoteMeta(hash)}.{0,20}`).exec(
+			a.content
+		);
+		return ` - ${a.name}: ...${match ? match[0] : "???"}...`;
+	})
+	.join("\n")}`);
+							compilation.errors.push(err);
+							return;
+						}
+						/** @type {Hashes} */
+						const hashes = new Set();
+						for (const { referencedHashes, ownHashes } of assets) {
+							if (!(/** @type {Hashes} */ (ownHashes).has(hash))) {
+								for (const hash of /** @type {Hashes} */ (ownHashes)) {
+									hashes.add(hash);
+								}
+							}
+							for (const hash of /** @type {Hashes} */ (referencedHashes)) {
+								hashes.add(hash);
+							}
+						}
+						return hashes;
+					};
+					/**
+					 * Returns the hash info.
+					 * @param {string} hash the hash
+					 * @returns {string} the hash info
+					 */
+					const hashInfo = (hash) => {
+						const assets = hashToAssets.get(hash);
+						return `${hash} (${Array.from(
+							/** @type {AssetInfoForRealContentHash[]} */ (assets),
+							(a) => a.name
+						)})`;
+					};
+					/** @type {Hashes} */
+					const hashesInOrder = new Set();
+					for (const hash of hashToAssets.keys()) {
+						/**
+						 * Processes the provided hash.
+						 * @param {string} hash the hash
+						 * @param {Set<string>} stack stack of hashes
+						 */
+						const add = (hash, stack) => {
+							const deps = getDependencies(hash);
+							if (!deps) return;
+							stack.add(hash);
+							for (const dep of deps) {
+								if (hashesInOrder.has(dep)) continue;
+								if (stack.has(dep)) {
+									throw new Error(
+										`Circular hash dependency ${Array.from(
+											stack,
+											hashInfo
+										).join(" -> ")} -> ${hashInfo(dep)}`
+									);
+								}
+								add(dep, stack);
+							}
+							hashesInOrder.add(hash);
+							stack.delete(hash);
+						};
+						if (hashesInOrder.has(hash)) continue;
+						add(hash, new Set());
+					}
+					/** @type {Map<string, string>} */
+					const hashToNewHash = new Map();
+					/**
+					 * Returns etag.
+					 * @param {AssetInfoForRealContentHash} asset asset info
+					 * @returns {Etag} etag
+					 */
+					const getEtag = (asset) =>
+						cacheGenerate.mergeEtags(
+							cacheGenerate.getLazyHashedEtag(asset.source),
+							Array.from(
+								/** @type {Hashes} */ (asset.referencedHashes),
+								(hash) => hashToNewHash.get(hash)
+							).join("|")
+						);
+					/**
+					 * Compute new content.
+					 * @param {AssetInfoForRealContentHash} asset asset info
+					 * @returns {Promise<void>}
+					 */
+					const computeNewContent = (asset) => {
+						if (asset.contentComputePromise) return asset.contentComputePromise;
+						return (asset.contentComputePromise = (async () => {
+							if (
+								/** @type {Hashes} */ (asset.ownHashes).size > 0 ||
+								[.../** @type {Hashes} */ (asset.referencedHashes)].some(
+									(hash) => hashToNewHash.get(hash) !== hash
+								)
+							) {
+								const identifier = asset.name;
+								const etag = getEtag(asset);
+								asset.newSource = await cacheGenerate.providePromise(
+									identifier,
+									etag,
+									() => {
+										const newContent = asset.content.replace(
+											hashRegExp,
+											(hash) => /** @type {string} */ (hashToNewHash.get(hash))
+										);
+										return new RawSource(newContent);
+									}
+								);
+							}
+						})());
+					};
+					/**
+					 * Compute new content without own.
+					 * @param {AssetInfoForRealContentHash} asset asset info
+					 * @returns {Promise<void>}
+					 */
+					const computeNewContentWithoutOwn = (asset) => {
+						if (asset.contentComputeWithoutOwnPromise) {
+							return asset.contentComputeWithoutOwnPromise;
+						}
+						return (asset.contentComputeWithoutOwnPromise = (async () => {
+							if (
+								/** @type {Hashes} */ (asset.ownHashes).size > 0 ||
+								[.../** @type {Hashes} */ (asset.referencedHashes)].some(
+									(hash) => hashToNewHash.get(hash) !== hash
+								)
+							) {
+								const identifier = `${asset.name}|without-own`;
+								const etag = getEtag(asset);
+								asset.newSourceWithoutOwn = await cacheGenerate.providePromise(
+									identifier,
+									etag,
+									() => {
+										const newContent = asset.content.replace(
+											hashRegExp,
+											(hash) => {
+												if (
+													/** @type {Hashes} */
+													(asset.ownHashes).has(hash)
+												) {
+													return "";
+												}
+												return /** @type {string} */ (hashToNewHash.get(hash));
+											}
+										);
+										return new RawSource(newContent);
+									}
+								);
+							}
+						})());
+					};
+					/** @type {Comparator<AssetInfoForRealContentHash>} */
+					const comparator = compareSelect((a) => a.name, compareStrings);
+					for (const oldHash of hashesInOrder) {
+						const assets =
+							/** @type {AssetInfoForRealContentHash[]} */
+							(hashToAssets.get(oldHash));
+						assets.sort(comparator);
+						await Promise.all(
+							assets.map((asset) =>
+								/** @type {Hashes} */ (asset.ownHashes).has(oldHash)
+									? computeNewContentWithoutOwn(asset)
+									: computeNewContent(asset)
+							)
+						);
+						const uniqueChunkArrays = mapAndDeduplicateSourceBuffers(
+							assets,
+							(asset) => {
+								if (/** @type {Hashes} */ (asset.ownHashes).has(oldHash)) {
+									return asset.newSourceWithoutOwn || asset.source;
+								}
+								return asset.newSource || asset.source;
+							}
+						);
+						/** @type {string | undefined} */
+						let newHash;
+						// Only materialize the public `Buffer[]` (one entry per unique
+						// asset) when something is tapped; otherwise the hot path feeds
+						// chunks into the hash directly, avoiding per-asset Buffer.concat.
+						if (hooks.updateHash.isUsed()) {
+							const assetsContent = uniqueChunkArrays.map((chunks) =>
+								chunks.length === 1 ? chunks[0] : Buffer.concat(chunks)
+							);
+							newHash =
+								hooks.updateHash.call(assetsContent, oldHash) || undefined;
+						}
+						if (!newHash) {
+							const hash = createHash(this._hashFunction);
+							if (compilation.outputOptions.hashSalt) {
+								hash.update(compilation.outputOptions.hashSalt);
+							}
+							for (const chunks of uniqueChunkArrays) {
+								for (const c of chunks) hash.update(c);
+							}
+							const digest = hash.digest(this._hashDigest);
+							newHash = digest.slice(0, oldHash.length);
+						}
+						hashToNewHash.set(oldHash, newHash);
+					}
+					await Promise.all(
+						assetsWithInfo.map(async (asset) => {
+							await computeNewContent(asset);
+							const newName = asset.name.replace(
+								hashRegExp,
+								(hash) => /** @type {string} */ (hashToNewHash.get(hash))
+							);
+
+							const infoUpdate = {};
+							const hash =
+								/** @type {Exclude<AssetInfo["contenthash"], undefined>} */
+								(asset.info.contenthash);
+							infoUpdate.contenthash = Array.isArray(hash)
+								? hash.map(
+										(hash) => /** @type {string} */ (hashToNewHash.get(hash))
+									)
+								: /** @type {string} */ (hashToNewHash.get(hash));
+
+							if (asset.newSource !== undefined) {
+								compilation.updateAsset(
+									asset.name,
+									asset.newSource,
+									infoUpdate
+								);
+							} else {
+								compilation.updateAsset(asset.name, asset.source, infoUpdate);
+							}
+
+							if (asset.name !== newName) {
+								compilation.renameAsset(asset.name, newName);
+							}
+						})
+					);
+				}
+			);
+		});
+	}
+}
+
+module.exports = RealContentHashPlugin;
Index: frontend/node_modules/webpack/lib/optimize/RemoveEmptyChunksPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/RemoveEmptyChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/RemoveEmptyChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,60 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_ADVANCED, STAGE_BASIC } = require("../OptimizationStages");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "RemoveEmptyChunksPlugin";
+
+class RemoveEmptyChunksPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			/**
+			 * Handles the hook callback for this code path.
+			 * @param {Iterable<Chunk>} chunks the chunks array
+			 * @returns {void}
+			 */
+			const handler = (chunks) => {
+				const chunkGraph = compilation.chunkGraph;
+				for (const chunk of chunks) {
+					if (
+						chunkGraph.getNumberOfChunkModules(chunk) === 0 &&
+						!chunk.hasRuntime() &&
+						chunkGraph.getNumberOfEntryModules(chunk) === 0
+					) {
+						compilation.chunkGraph.disconnectChunk(chunk);
+						compilation.chunks.delete(chunk);
+					}
+				}
+			};
+
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_BASIC
+				},
+				handler
+			);
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_ADVANCED
+				},
+				handler
+			);
+		});
+	}
+}
+
+module.exports = RemoveEmptyChunksPlugin;
Index: frontend/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,218 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_BASIC } = require("../OptimizationStages");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+/**
+ * Intersects multiple masks represented as bigints
+ * @param {bigint[]} masks The module masks to intersect
+ * @returns {bigint} The intersection of all masks
+ */
+function intersectMasks(masks) {
+	let result = masks[0];
+	for (let i = masks.length - 1; i >= 1; i--) {
+		result &= masks[i];
+	}
+	return result;
+}
+
+const ZERO_BIGINT = BigInt(0);
+const ONE_BIGINT = BigInt(1);
+const THIRTY_TWO_BIGINT = BigInt(32);
+
+/**
+ * Parses the module mask and returns the modules represented by it
+ * @param {bigint} mask the module mask
+ * @param {Module[]} ordinalModules the modules in the order they were added to the mask (LSB is index 0)
+ * @returns {Generator<Module, undefined, undefined>} the modules represented by the mask
+ */
+function* getModulesFromMask(mask, ordinalModules) {
+	let offset = 31;
+	while (mask !== ZERO_BIGINT) {
+		// Consider the last 32 bits, since that's what Math.clz32 can handle
+		let last32 = Number(BigInt.asUintN(32, mask));
+		while (last32 > 0) {
+			const last = Math.clz32(last32);
+			// The number of trailing zeros is the number trimmed off the input mask + 31 - the number of leading zeros
+			// The 32 is baked into the initial value of offset
+			const moduleIndex = offset - last;
+			// The number of trailing zeros is the index into the array generated by getOrCreateModuleMask
+			const module = ordinalModules[moduleIndex];
+			yield module;
+			// Remove the matched module from the mask
+			// Since we can only count leading zeros, not trailing, we can't just downshift the mask
+			last32 &= ~(1 << (31 - last));
+		}
+
+		// Remove the processed chunk from the mask
+		mask >>= THIRTY_TWO_BIGINT;
+		offset += 32;
+	}
+}
+
+const PLUGIN_NAME = "RemoveParentModulesPlugin";
+
+class RemoveParentModulesPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			/**
+			 * Handles the hook callback for this code path.
+			 * @param {Iterable<Chunk>} chunks the chunks
+			 * @param {ChunkGroup[]} chunkGroups the chunk groups
+			 */
+			const handler = (chunks, chunkGroups) => {
+				const chunkGraph = compilation.chunkGraph;
+				/** @type {Set<ChunkGroup>} */
+				const queue = new Set();
+				/** @type {WeakMap<ChunkGroup, bigint | undefined>} */
+				const availableModulesMap = new WeakMap();
+
+				let nextModuleMask = ONE_BIGINT;
+				/** @type {WeakMap<Module, bigint>} */
+				const maskByModule = new WeakMap();
+				/** @type {Module[]} */
+				const ordinalModules = [];
+
+				/**
+				 * Gets or create module mask.
+				 * @param {Module} mod the module to get the mask for
+				 * @returns {bigint} the module mask to uniquely identify the module
+				 */
+				const getOrCreateModuleMask = (mod) => {
+					let id = maskByModule.get(mod);
+					if (id === undefined) {
+						id = nextModuleMask;
+						ordinalModules.push(mod);
+						maskByModule.set(mod, id);
+						nextModuleMask <<= ONE_BIGINT;
+					}
+					return id;
+				};
+
+				// Initialize masks by chunk and by chunk group for quicker comparisons
+				/** @type {WeakMap<Chunk, bigint>} */
+				const chunkMasks = new WeakMap();
+				for (const chunk of chunks) {
+					let mask = ZERO_BIGINT;
+					for (const m of chunkGraph.getChunkModulesIterable(chunk)) {
+						const id = getOrCreateModuleMask(m);
+						mask |= id;
+					}
+					chunkMasks.set(chunk, mask);
+				}
+
+				/** @type {WeakMap<ChunkGroup, bigint>} */
+				const chunkGroupMasks = new WeakMap();
+				for (const chunkGroup of chunkGroups) {
+					let mask = ZERO_BIGINT;
+					for (const chunk of chunkGroup.chunks) {
+						const chunkMask = chunkMasks.get(chunk);
+						if (chunkMask !== undefined) {
+							mask |= chunkMask;
+						}
+					}
+					chunkGroupMasks.set(chunkGroup, mask);
+				}
+
+				for (const chunkGroup of compilation.entrypoints.values()) {
+					// initialize available modules for chunks without parents
+					availableModulesMap.set(chunkGroup, ZERO_BIGINT);
+					for (const child of chunkGroup.childrenIterable) {
+						queue.add(child);
+					}
+				}
+				for (const chunkGroup of compilation.asyncEntrypoints) {
+					// initialize available modules for chunks without parents
+					availableModulesMap.set(chunkGroup, ZERO_BIGINT);
+					for (const child of chunkGroup.childrenIterable) {
+						queue.add(child);
+					}
+				}
+
+				for (const chunkGroup of queue) {
+					let availableModulesMask = availableModulesMap.get(chunkGroup);
+					let changed = false;
+					for (const parent of chunkGroup.parentsIterable) {
+						const availableModulesInParent = availableModulesMap.get(parent);
+						if (availableModulesInParent !== undefined) {
+							const parentMask =
+								availableModulesInParent |
+								/** @type {bigint} */ (chunkGroupMasks.get(parent));
+							// If we know the available modules in parent: process these
+							if (availableModulesMask === undefined) {
+								// if we have not own info yet: create new entry
+								availableModulesMask = parentMask;
+								changed = true;
+							} else {
+								const newMask = availableModulesMask & parentMask;
+								if (newMask !== availableModulesMask) {
+									changed = true;
+									availableModulesMask = newMask;
+								}
+							}
+						}
+					}
+
+					if (changed) {
+						availableModulesMap.set(chunkGroup, availableModulesMask);
+						// if something changed: enqueue our children
+						for (const child of chunkGroup.childrenIterable) {
+							// Push the child to the end of the queue
+							queue.delete(child);
+							queue.add(child);
+						}
+					}
+				}
+
+				// now we have available modules for every chunk
+				for (const chunk of chunks) {
+					const chunkMask = chunkMasks.get(chunk);
+					if (chunkMask === undefined) continue; // No info about this chunk
+
+					const availableModulesSets = Array.from(
+						chunk.groupsIterable,
+						(chunkGroup) => availableModulesMap.get(chunkGroup)
+					);
+					if (availableModulesSets.includes(undefined)) continue; // No info about this chunk group
+
+					const availableModulesMask = intersectMasks(
+						/** @type {bigint[]} */
+						(availableModulesSets)
+					);
+					const toRemoveMask = chunkMask & availableModulesMask;
+					if (toRemoveMask !== ZERO_BIGINT) {
+						for (const module of getModulesFromMask(
+							toRemoveMask,
+							ordinalModules
+						)) {
+							chunkGraph.disconnectChunkAndModule(chunk, module);
+						}
+					}
+				}
+			};
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_BASIC
+				},
+				handler
+			);
+		});
+	}
+}
+
+module.exports = RemoveParentModulesPlugin;
Index: frontend/node_modules/webpack/lib/optimize/RuntimeChunkPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/RuntimeChunkPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/RuntimeChunkPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,53 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Compilation").EntryData} EntryData */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "RuntimeChunkPlugin";
+
+/** @typedef {(entrypoint: { name: string }) => string} RuntimeChunkFunction */
+
+class RuntimeChunkPlugin {
+	/**
+	 * Creates an instance of RuntimeChunkPlugin.
+	 * @param {{ name?: RuntimeChunkFunction }=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {{ name: string | RuntimeChunkFunction }} */
+		this.options = {
+			name: (entrypoint) => `runtime~${entrypoint.name}`,
+			...options
+		};
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.addEntry.tap(PLUGIN_NAME, (_, { name: entryName }) => {
+				if (entryName === undefined) return;
+				const data =
+					/** @type {EntryData} */
+					(compilation.entries.get(entryName));
+				if (data.options.runtime === undefined && !data.options.dependOn) {
+					// Determine runtime chunk name
+					let name = this.options.name;
+					if (typeof name === "function") {
+						name = name({ name: entryName });
+					}
+					data.options.runtime = name;
+				}
+			});
+		});
+	}
+}
+
+module.exports = RuntimeChunkPlugin;
Index: frontend/node_modules/webpack/lib/optimize/SideEffectsFlagPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/SideEffectsFlagPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/SideEffectsFlagPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,530 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const glob2regexp = require("glob-to-regexp");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+const { STAGE_DEFAULT } = require("../OptimizationStages");
+const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
+const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
+const formatLocation = require("../util/formatLocation");
+const { CompilerHintNotationRegExp } = require("../util/magicComment");
+
+/** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
+/** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
+/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */
+/** @typedef {import("estree").Statement} Statement */
+/** @typedef {import("estree").CallExpression} CallExpression */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+/**
+ * Defines the export in module type used by this module.
+ * @typedef {object} ExportInModule
+ * @property {Module} module the module
+ * @property {string} exportName the name of the export
+ * @property {boolean} checked if the export is conditional
+ */
+
+/** @typedef {string | boolean | string[] | undefined} SideEffectsFlagValue */
+
+/** @typedef {Map<string, RegExp>} CacheItem */
+
+/** @type {WeakMap<Compiler, CacheItem>} */
+const globToRegexpCache = new WeakMap();
+
+/**
+ * Returns a regular expression.
+ * @param {string} glob the pattern
+ * @param {CacheItem} cache the glob to RegExp cache
+ * @returns {RegExp} a regular expression
+ */
+const globToRegexp = (glob, cache) => {
+	const cacheEntry = cache.get(glob);
+	if (cacheEntry !== undefined) return cacheEntry;
+	if (!glob.includes("/")) {
+		glob = `**/${glob}`;
+	}
+	const baseRegexp = glob2regexp(glob, { globstar: true, extended: true });
+	const regexpSource = baseRegexp.source;
+	const regexp = new RegExp(`^(\\./)?${regexpSource.slice(1)}`);
+	cache.set(glob, regexp);
+	return regexp;
+};
+
+/**
+ * @param {JavascriptParser} parser parser
+ * @param {number} start start position
+ * @param {number} end end position
+ * @returns {boolean} if annotation is found in the range
+ */
+const hasNoSideEffectsNotation = (parser, start, end) => {
+	// Fast path
+	if (end - start < 18) return false;
+
+	const comments = parser.getComments([start, end]);
+	return comments.some(
+		(c) =>
+			c.type === "Block" &&
+			CompilerHintNotationRegExp.NoSideEffects.test(c.value)
+	);
+};
+
+const PLUGIN_NAME = "SideEffectsFlagPlugin";
+
+class SideEffectsFlagPlugin {
+	/**
+	 * Creates an instance of SideEffectsFlagPlugin.
+	 * @param {boolean} analyseSource analyse source code for side effects
+	 */
+	constructor(analyseSource = true) {
+		/** @type {boolean} */
+		this._analyseSource = analyseSource;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		let cache = globToRegexpCache.get(compiler.root);
+		if (cache === undefined) {
+			cache = new Map();
+			globToRegexpCache.set(compiler.root, cache);
+		}
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const moduleGraph = compilation.moduleGraph;
+				normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module, data) => {
+					const resolveData = data.resourceResolveData;
+					if (
+						resolveData &&
+						resolveData.descriptionFileData &&
+						resolveData.relativePath
+					) {
+						const sideEffects = resolveData.descriptionFileData.sideEffects;
+						if (sideEffects !== undefined) {
+							if (module.factoryMeta === undefined) {
+								module.factoryMeta = {};
+							}
+							const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(
+								resolveData.relativePath,
+								/** @type {SideEffectsFlagValue} */ (sideEffects),
+								/** @type {CacheItem} */ (cache)
+							);
+							module.factoryMeta.sideEffectFree = !hasSideEffects;
+						}
+					}
+
+					return module;
+				});
+				normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module, data) => {
+					const settings = data.settings;
+					if (typeof settings.sideEffects === "boolean") {
+						if (module.factoryMeta === undefined) {
+							module.factoryMeta = {};
+						}
+						module.factoryMeta.sideEffectFree = !settings.sideEffects;
+					}
+					return module;
+				});
+				if (this._analyseSource) {
+					/**
+					 * Processes the provided parser.
+					 * @param {JavascriptParser} parser the parser
+					 * @returns {void}
+					 */
+					const applySideEffectsStmtHandler = (parser) => {
+						/** @type {undefined | Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
+						let sideEffectsStatement;
+						parser.hooks.program.tap(PLUGIN_NAME, () => {
+							sideEffectsStatement = undefined;
+						});
+						parser.hooks.statement.tap(
+							{ name: PLUGIN_NAME, stage: -100 },
+							(statement) => {
+								if (sideEffectsStatement) return;
+								if (parser.scope.topLevelScope !== true) return;
+								switch (statement.type) {
+									case "ExpressionStatement":
+										if (
+											!parser.isPure(
+												statement.expression,
+												/** @type {Range} */
+												(statement.range)[0]
+											)
+										) {
+											sideEffectsStatement = statement;
+										}
+										break;
+									case "IfStatement":
+									case "WhileStatement":
+									case "DoWhileStatement":
+										if (
+											!parser.isPure(
+												statement.test,
+												/** @type {Range} */
+												(statement.range)[0]
+											)
+										) {
+											sideEffectsStatement = statement;
+										}
+										// statement hook will be called for child statements too
+										break;
+									case "ForStatement":
+										if (
+											!parser.isPure(
+												statement.init,
+												/** @type {Range} */ (statement.range)[0]
+											) ||
+											!parser.isPure(
+												statement.test,
+												statement.init
+													? /** @type {Range} */ (statement.init.range)[1]
+													: /** @type {Range} */ (statement.range)[0]
+											) ||
+											!parser.isPure(
+												statement.update,
+												statement.test
+													? /** @type {Range} */ (statement.test.range)[1]
+													: statement.init
+														? /** @type {Range} */ (statement.init.range)[1]
+														: /** @type {Range} */ (statement.range)[0]
+											)
+										) {
+											sideEffectsStatement = statement;
+										}
+										// statement hook will be called for child statements too
+										break;
+									case "SwitchStatement":
+										if (
+											!parser.isPure(
+												statement.discriminant,
+												/** @type {Range} */
+												(statement.range)[0]
+											)
+										) {
+											sideEffectsStatement = statement;
+										}
+										// statement hook will be called for child statements too
+										break;
+									case "VariableDeclaration":
+									case "ClassDeclaration":
+									case "FunctionDeclaration":
+										if (
+											!parser.isPure(
+												statement,
+												/** @type {Range} */ (statement.range)[0]
+											)
+										) {
+											sideEffectsStatement = statement;
+										}
+										break;
+									case "ExportNamedDeclaration":
+									case "ExportDefaultDeclaration":
+										if (
+											!parser.isPure(
+												statement.declaration,
+												/** @type {Range} */
+												(statement.range)[0]
+											)
+										) {
+											sideEffectsStatement = statement;
+										}
+										break;
+									case "LabeledStatement":
+									case "BlockStatement":
+										// statement hook will be called for child statements too
+										break;
+									case "EmptyStatement":
+										break;
+									case "ExportAllDeclaration":
+									case "ImportDeclaration":
+										// imports will be handled by the dependencies
+										break;
+									default:
+										sideEffectsStatement = statement;
+										break;
+								}
+							}
+						);
+						parser.hooks.finish.tap(PLUGIN_NAME, () => {
+							if (sideEffectsStatement === undefined) {
+								/** @type {BuildMeta} */
+								(parser.state.module.buildMeta).sideEffectFree = true;
+							} else {
+								const { loc, type } = sideEffectsStatement;
+								moduleGraph
+									.getOptimizationBailout(parser.state.module)
+									.push(
+										() =>
+											`Statement (${type}) with side effects in source code at ${formatLocation(
+												/** @type {DependencyLocation} */ (loc)
+											)}`
+									);
+							}
+						});
+					};
+
+					/**
+					 * @param {JavascriptParser} parser the parser
+					 * @returns {void}
+					 */
+					const applyNoSideEffectsNotationHandler = (parser) => {
+						/** @type {Set<string>} */
+						let noSideEffectsFnNames;
+
+						parser.hooks.program.tap(PLUGIN_NAME, () => {
+							noSideEffectsFnNames = new Set();
+						});
+
+						// Detect on function declarations
+						// Covers:
+						// 	1. function foo
+						//  2. export function foo
+						//  3. export default function foo
+						parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
+							if (parser.scope.topLevelScope !== true) return;
+							if (statement.type !== "FunctionDeclaration" || !statement.id) {
+								return;
+							}
+							const commentsStart = parser.prevStatement
+								? /** @type {Range} */ (parser.prevStatement.range)[1]
+								: 0;
+							if (
+								hasNoSideEffectsNotation(
+									parser,
+									commentsStart,
+									/** @type {Range} */ (statement.range)[0]
+								)
+							) {
+								noSideEffectsFnNames.add(statement.id.name);
+							}
+						});
+
+						// Detect on variable declarations with function init
+						parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => {
+							if (parser.scope.topLevelScope !== true) return;
+							if (!decl.init || decl.id.type !== "Identifier") return;
+							if (!decl.init.type.endsWith("FunctionExpression")) return;
+
+							let hasAnnotation = false;
+							// Before the VariableDeclaration (only for const)
+							if (statement.kind === "const") {
+								const commentsStart = parser.prevStatement
+									? /** @type {Range} */ (parser.prevStatement.range)[1]
+									: 0;
+								hasAnnotation = hasNoSideEffectsNotation(
+									parser,
+									commentsStart,
+									/** @type {Range} */ (statement.range)[0]
+								);
+							}
+
+							if (!hasAnnotation) {
+								hasAnnotation = hasNoSideEffectsNotation(
+									parser,
+									/** @type {Range} */ (decl.id.range)[1],
+									/** @type {Range} */ (decl.init.range)[0]
+								);
+							}
+							if (hasAnnotation) {
+								noSideEffectsFnNames.add(decl.id.name);
+							}
+						});
+
+						// Mark calls to annotated functions as pure
+						parser.hooks.isPure
+							.for("CallExpression")
+							.tap(PLUGIN_NAME, (expression, commentsStartPos) => {
+								const expr = /** @type {CallExpression} */ (expression);
+								if (expr.callee.type !== "Identifier") return;
+								if (!noSideEffectsFnNames.has(expr.callee.name)) return;
+								commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
+								for (const arg of expr.arguments) {
+									if (arg.type === "SpreadElement") return;
+									if (!parser.isPure(arg, commentsStartPos)) return;
+									commentsStartPos = /** @type {Range} */ (arg.range)[1];
+								}
+								return true;
+							});
+					};
+
+					for (const key of [
+						JAVASCRIPT_MODULE_TYPE_AUTO,
+						JAVASCRIPT_MODULE_TYPE_ESM,
+						JAVASCRIPT_MODULE_TYPE_DYNAMIC
+					]) {
+						normalModuleFactory.hooks.parser
+							.for(key)
+							.tap(PLUGIN_NAME, (parser) => {
+								applyNoSideEffectsNotationHandler(parser);
+								applySideEffectsStmtHandler(parser);
+							});
+					}
+				}
+				compilation.hooks.optimizeDependencies.tap(
+					{
+						name: PLUGIN_NAME,
+						stage: STAGE_DEFAULT
+					},
+					(modules) => {
+						const logger = compilation.getLogger(
+							"webpack.SideEffectsFlagPlugin"
+						);
+
+						logger.time("update dependencies");
+
+						/** @type {Set<Module>} */
+						const optimizedModules = new Set();
+
+						/**
+						 * Optimize incoming connections.
+						 * @param {Module} module module
+						 */
+						const optimizeIncomingConnections = (module) => {
+							if (optimizedModules.has(module)) return;
+							optimizedModules.add(module);
+							if (module.getSideEffectsConnectionState(moduleGraph) === false) {
+								const exportsInfo = moduleGraph.getExportsInfo(module);
+								for (const connection of moduleGraph.getIncomingConnections(
+									module
+								)) {
+									const dep = connection.dependency;
+									/** @type {boolean} */
+									let isReexport;
+									if (
+										(isReexport =
+											dep instanceof
+											HarmonyExportImportedSpecifierDependency) ||
+										(dep instanceof HarmonyImportSpecifierDependency &&
+											!dep.namespaceObjectAsContext)
+									) {
+										if (connection.originModule !== null) {
+											optimizeIncomingConnections(connection.originModule);
+										}
+										// TODO improve for export *
+										if (isReexport && dep.name) {
+											const exportInfo = moduleGraph.getExportInfo(
+												/** @type {Module} */ (connection.originModule),
+												dep.name
+											);
+											exportInfo.moveTarget(
+												moduleGraph,
+												({ module }) =>
+													module.getSideEffectsConnectionState(moduleGraph) ===
+													false,
+												({
+													module: newModule,
+													export: exportName,
+													connection: targetConnection
+												}) => {
+													moduleGraph.updateModule(dep, newModule);
+													moduleGraph.updateParent(
+														dep,
+														targetConnection,
+														/** @type {Module} */ (connection.originModule)
+													);
+													moduleGraph.addExplanation(
+														dep,
+														"(skipped side-effect-free modules)"
+													);
+													const ids = dep.getIds(moduleGraph);
+													dep.setIds(
+														moduleGraph,
+														exportName
+															? [...exportName, ...ids.slice(1)]
+															: ids.slice(1)
+													);
+													return /** @type {ModuleGraphConnection} */ (
+														moduleGraph.getConnection(dep)
+													);
+												}
+											);
+											continue;
+										}
+										// TODO improve for nested imports
+										const ids = dep.getIds(moduleGraph);
+										if (ids.length > 0) {
+											const exportInfo = exportsInfo.getExportInfo(ids[0]);
+											const target = exportInfo.getTarget(
+												moduleGraph,
+												({ module }) =>
+													module.getSideEffectsConnectionState(moduleGraph) ===
+													false
+											);
+											if (!target) continue;
+
+											moduleGraph.updateModule(dep, target.module);
+											moduleGraph.updateParent(
+												dep,
+												/** @type {ModuleGraphConnection} */ (
+													target.connection
+												),
+												/** @type {Module} */ (connection.originModule)
+											);
+											moduleGraph.addExplanation(
+												dep,
+												"(skipped side-effect-free modules)"
+											);
+											dep.setIds(
+												moduleGraph,
+												target.export
+													? [...target.export, ...ids.slice(1)]
+													: ids.slice(1)
+											);
+										}
+									}
+								}
+							}
+						};
+
+						for (const module of modules) {
+							optimizeIncomingConnections(module);
+						}
+						moduleGraph.finishUpdateParent();
+						logger.timeEnd("update dependencies");
+					}
+				);
+			}
+		);
+	}
+
+	/**
+	 * Module has side effects.
+	 * @param {string} moduleName the module name
+	 * @param {SideEffectsFlagValue} flagValue the flag value
+	 * @param {CacheItem} cache cache for glob to regexp
+	 * @returns {boolean | undefined} true, when the module has side effects, undefined or false when not
+	 */
+	static moduleHasSideEffects(moduleName, flagValue, cache) {
+		switch (typeof flagValue) {
+			case "undefined":
+				return true;
+			case "boolean":
+				return flagValue;
+			case "string":
+				return globToRegexp(flagValue, cache).test(moduleName);
+			case "object":
+				return flagValue.some((glob) =>
+					SideEffectsFlagPlugin.moduleHasSideEffects(moduleName, glob, cache)
+				);
+		}
+	}
+}
+
+module.exports = SideEffectsFlagPlugin;
Index: frontend/node_modules/webpack/lib/optimize/SplitChunksPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/optimize/SplitChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/optimize/SplitChunksPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1884 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Chunk = require("../Chunk");
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+const WebpackError = require("../errors/WebpackError");
+const { requestToId } = require("../ids/IdHelpers");
+const { isSubset } = require("../util/SetHelpers");
+const SortableSet = require("../util/SortableSet");
+const {
+	compareIterables,
+	compareModulesByIdentifier
+} = require("../util/comparators");
+const createHash = require("../util/createHash");
+const deterministicGrouping = require("../util/deterministicGrouping");
+const { makePathsRelative } = require("../util/identifier");
+const memoize = require("../util/memoize");
+const MinMaxSizeWarning = require("./MinMaxSizeWarning");
+
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksCacheGroup} OptimizationSplitChunksCacheGroup */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksSizes} OptimizationSplitChunksSizes */
+/** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
+/** @typedef {import("../Chunk").ChunkName} ChunkName */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../Chunk").ChunkFilenameTemplate} ChunkFilenameTemplate */
+/** @typedef {import("../util/deterministicGrouping").GroupedItems<Module>} DeterministicGroupingGroupedItemsForModule */
+/** @typedef {import("../util/deterministicGrouping").Options<Module>} DeterministicGroupingOptionsForModule */
+/** @typedef {import("../util/deterministicGrouping").Sizes} Sizes */
+
+/**
+ * Defines the chunk filter fn callback.
+ * @callback ChunkFilterFn
+ * @param {Chunk} chunk
+ * @returns {boolean | undefined}
+ */
+
+/** @typedef {number} Priority */
+/** @typedef {number} Size */
+/** @typedef {number} CountOfChunk */
+/** @typedef {number} CountOfRequest */
+
+/**
+ * Defines the combine size function callback.
+ * @callback CombineSizeFunction
+ * @param {Size} a
+ * @param {Size} b
+ * @returns {Size}
+ */
+
+/** @typedef {SourceType[]} SourceTypes */
+/** @typedef {SourceType[]} DefaultSizeTypes */
+/** @typedef {Record<SourceType, Size>} SplitChunksSizes */
+
+/**
+ * Defines the cache group source type used by this module.
+ * @typedef {object} CacheGroupSource
+ * @property {string} key
+ * @property {Priority=} priority
+ * @property {GetNameFn=} getName
+ * @property {ChunkFilterFn=} chunksFilter
+ * @property {boolean=} enforce
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} minSizeReduction
+ * @property {SplitChunksSizes} minRemainingSize
+ * @property {SplitChunksSizes} enforceSizeThreshold
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {CountOfChunk=} minChunks
+ * @property {CountOfRequest=} maxAsyncRequests
+ * @property {CountOfRequest=} maxInitialRequests
+ * @property {ChunkFilenameTemplate=} filename
+ * @property {string=} idHint
+ * @property {string=} automaticNameDelimiter
+ * @property {boolean=} reuseExistingChunk
+ * @property {boolean=} usedExports
+ */
+
+/**
+ * Defines the cache group type used by this module.
+ * @typedef {object} CacheGroup
+ * @property {string} key
+ * @property {Priority} priority
+ * @property {GetNameFn=} getName
+ * @property {ChunkFilterFn} chunksFilter
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} minSizeReduction
+ * @property {SplitChunksSizes} minRemainingSize
+ * @property {SplitChunksSizes} enforceSizeThreshold
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {CountOfChunk} minChunks
+ * @property {CountOfRequest} maxAsyncRequests
+ * @property {CountOfRequest} maxInitialRequests
+ * @property {ChunkFilenameTemplate=} filename
+ * @property {string} idHint
+ * @property {string} automaticNameDelimiter
+ * @property {boolean} reuseExistingChunk
+ * @property {boolean} usedExports
+ * @property {boolean} _validateSize
+ * @property {boolean} _validateRemainingSize
+ * @property {SplitChunksSizes} _minSizeForMaxSize
+ * @property {boolean} _conditionalEnforce
+ */
+
+/**
+ * Defines the fallback cache group type used by this module.
+ * @typedef {object} FallbackCacheGroup
+ * @property {ChunkFilterFn} chunksFilter
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {string} automaticNameDelimiter
+ */
+
+/**
+ * Defines the cache groups context type used by this module.
+ * @typedef {object} CacheGroupsContext
+ * @property {ModuleGraph} moduleGraph
+ * @property {ChunkGraph} chunkGraph
+ */
+
+/** @typedef {(module: Module) => OptimizationSplitChunksCacheGroup | OptimizationSplitChunksCacheGroup[] | void} RawGetCacheGroups */
+
+/**
+ * Defines the get cache groups callback.
+ * @callback GetCacheGroups
+ * @param {Module} module
+ * @param {CacheGroupsContext} context
+ * @returns {CacheGroupSource[] | null}
+ */
+
+/**
+ * Defines the get name fn callback.
+ * @callback GetNameFn
+ * @param {Module} module
+ * @param {Chunk[]} chunks
+ * @param {string} key
+ * @returns {string | undefined}
+ */
+
+/**
+ * Defines the split chunks options type used by this module.
+ * @typedef {object} SplitChunksOptions
+ * @property {ChunkFilterFn} chunksFilter
+ * @property {DefaultSizeTypes} defaultSizeTypes
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} minSizeReduction
+ * @property {SplitChunksSizes} minRemainingSize
+ * @property {SplitChunksSizes} enforceSizeThreshold
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {CountOfChunk} minChunks
+ * @property {CountOfRequest} maxAsyncRequests
+ * @property {CountOfRequest} maxInitialRequests
+ * @property {boolean} hidePathInfo
+ * @property {ChunkFilenameTemplate=} filename
+ * @property {string} automaticNameDelimiter
+ * @property {GetCacheGroups} getCacheGroups
+ * @property {GetNameFn} getName
+ * @property {boolean} usedExports
+ * @property {FallbackCacheGroup} fallbackCacheGroup
+ */
+
+/** @typedef {Set<Chunk>} ChunkSet  */
+
+/**
+ * Defines the chunks info item type used by this module.
+ * @typedef {object} ChunksInfoItem
+ * @property {SortableSet<Module>} modules
+ * @property {CacheGroup} cacheGroup
+ * @property {number} cacheGroupIndex
+ * @property {string=} name
+ * @property {SplitChunksSizes} sizes
+ * @property {ChunkSet} chunks
+ * @property {ChunkSet} reusableChunks
+ * @property {Set<bigint | Chunk>} chunksKeys
+ */
+
+/** @type {GetNameFn} */
+const defaultGetName = () => undefined;
+
+const deterministicGroupingForModules =
+	/** @type {(options: DeterministicGroupingOptionsForModule) => DeterministicGroupingGroupedItemsForModule[]} */
+	(deterministicGrouping);
+
+/** @type {WeakMap<Module, string>} */
+const getKeyCache = new WeakMap();
+
+/**
+ * Returns hashed filename.
+ * @param {string} name a filename to hash
+ * @param {OutputOptions} outputOptions hash function used
+ * @returns {string} hashed filename
+ */
+const hashFilename = (name, outputOptions) => {
+	const digest =
+		/** @type {string} */
+		(
+			createHash(outputOptions.hashFunction)
+				.update(name)
+				.digest(outputOptions.hashDigest)
+		);
+	return digest.slice(0, 8);
+};
+
+/**
+ * Returns the number of requests.
+ * @param {Chunk} chunk the chunk
+ * @returns {CountOfRequest} the number of requests
+ */
+const getRequests = (chunk) => {
+	let requests = 0;
+	for (const chunkGroup of chunk.groupsIterable) {
+		requests = Math.max(requests, chunkGroup.chunks.length);
+	}
+	return requests;
+};
+
+/**
+ * Returns result.
+ * @template {object} T
+ * @template {object} R
+ * @param {T} obj obj an object
+ * @param {(obj: T[keyof T], key: keyof T) => T[keyof T]} fn fn
+ * @returns {T} result
+ */
+const mapObject = (obj, fn) => {
+	/** @type {T} */
+	const newObj = Object.create(null);
+	for (const key of Object.keys(obj)) {
+		newObj[/** @type {keyof T} */ (key)] = fn(
+			obj[/** @type {keyof T} */ (key)],
+			/** @type {keyof T} */
+			(key)
+		);
+	}
+	return newObj;
+};
+
+/**
+ * Checks whether this object is overlap.
+ * @template T
+ * @param {Set<T>} a set
+ * @param {Set<T>} b other set
+ * @returns {boolean} true if at least one item of a is in b
+ */
+const isOverlap = (a, b) => {
+	for (const item of a) {
+		if (b.has(item)) return true;
+	}
+	return false;
+};
+
+const compareModuleIterables = compareIterables(compareModulesByIdentifier);
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @param {ChunksInfoItem} a item
+ * @param {ChunksInfoItem} b item
+ * @returns {number} compare result
+ */
+const compareEntries = (a, b) => {
+	// 1. by priority
+	const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority;
+	if (diffPriority) return diffPriority;
+	// 2. by number of chunks
+	const diffCount = a.chunks.size - b.chunks.size;
+	if (diffCount) return diffCount;
+	// 3. by size reduction
+	const aSizeReduce = totalSize(a.sizes) * (a.chunks.size - 1);
+	const bSizeReduce = totalSize(b.sizes) * (b.chunks.size - 1);
+	const diffSizeReduce = aSizeReduce - bSizeReduce;
+	if (diffSizeReduce) return diffSizeReduce;
+	// 4. by cache group index
+	const indexDiff = b.cacheGroupIndex - a.cacheGroupIndex;
+	if (indexDiff) return indexDiff;
+	// 5. by number of modules (to be able to compare by identifier)
+	const modulesA = a.modules;
+	const modulesB = b.modules;
+	const diff = modulesA.size - modulesB.size;
+	if (diff) return diff;
+	// 6. by module identifiers
+	modulesA.sort();
+	modulesB.sort();
+	return compareModuleIterables(modulesA, modulesB);
+};
+
+/**
+ * Initial chunk filter.
+ * @param {Chunk} chunk the chunk
+ * @returns {boolean} true, if the chunk is an entry chunk
+ */
+const INITIAL_CHUNK_FILTER = (chunk) => chunk.canBeInitial();
+/**
+ * Async chunk filter.
+ * @param {Chunk} chunk the chunk
+ * @returns {boolean} true, if the chunk is an async chunk
+ */
+const ASYNC_CHUNK_FILTER = (chunk) => !chunk.canBeInitial();
+/**
+ * Returns always true.
+ * @param {Chunk} _chunk the chunk
+ * @returns {boolean} always true
+ */
+const ALL_CHUNK_FILTER = (_chunk) => true;
+
+/**
+ * Returns normalized representation.
+ * @param {OptimizationSplitChunksSizes | undefined} value the sizes
+ * @param {DefaultSizeTypes} defaultSizeTypes the default size types
+ * @returns {SplitChunksSizes} normalized representation
+ */
+const normalizeSizes = (value, defaultSizeTypes) => {
+	if (typeof value === "number") {
+		/** @type {SplitChunksSizes} */
+		const o = {};
+		for (const sizeType of defaultSizeTypes) o[sizeType] = value;
+		return o;
+	} else if (typeof value === "object" && value !== null) {
+		return { ...value };
+	}
+	return {};
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @param {...(SplitChunksSizes | undefined)} sizes the sizes
+ * @returns {SplitChunksSizes} the merged sizes
+ */
+const mergeSizes = (...sizes) => {
+	/** @type {SplitChunksSizes} */
+	let merged = {};
+	for (let i = sizes.length - 1; i >= 0; i--) {
+		merged = Object.assign(merged, sizes[i]);
+	}
+	return merged;
+};
+
+/**
+ * Checks whether this object contains the size.
+ * @param {SplitChunksSizes} sizes the sizes
+ * @returns {boolean} true, if there are sizes > 0
+ */
+const hasNonZeroSizes = (sizes) => {
+	for (const key of /** @type {SourceType[]} */ (Object.keys(sizes))) {
+		if (sizes[key] > 0) return true;
+	}
+	return false;
+};
+
+/**
+ * Returns the combine sizes.
+ * @param {SplitChunksSizes} a first sizes
+ * @param {SplitChunksSizes} b second sizes
+ * @param {CombineSizeFunction} combine a function to combine sizes
+ * @returns {SplitChunksSizes} the combine sizes
+ */
+const combineSizes = (a, b, combine) => {
+	const aKeys = /** @type {Set<SourceType>} */ (new Set(Object.keys(a)));
+	const bKeys = /** @type {Set<SourceType>} */ (new Set(Object.keys(b)));
+	/** @type {SplitChunksSizes} */
+	const result = {};
+	for (const key of aKeys) {
+		result[key] = bKeys.has(key) ? combine(a[key], b[key]) : a[key];
+	}
+	for (const key of bKeys) {
+		if (!aKeys.has(key)) {
+			result[key] = b[key];
+		}
+	}
+	return result;
+};
+
+/**
+ * Checks true if there are sizes and all existing sizes are at least minSize.
+ * @param {SplitChunksSizes} sizes the sizes
+ * @param {SplitChunksSizes} minSize the min sizes
+ * @returns {boolean} true if there are sizes and all existing sizes are at least `minSize`
+ */
+const checkMinSize = (sizes, minSize) => {
+	for (const key of /** @type {SourceType[]} */ (Object.keys(minSize))) {
+		const size = sizes[key];
+		if (size === undefined || size === 0) continue;
+		if (size < minSize[key]) return false;
+	}
+	return true;
+};
+
+/**
+ * Checks min size reduction.
+ * @param {SplitChunksSizes} sizes the sizes
+ * @param {SplitChunksSizes} minSizeReduction the min sizes
+ * @param {CountOfChunk} chunkCount number of chunks
+ * @returns {boolean} true if there are sizes and all existing sizes are at least `minSizeReduction`
+ */
+const checkMinSizeReduction = (sizes, minSizeReduction, chunkCount) => {
+	for (const key of /** @type {SourceType[]} */ (
+		Object.keys(minSizeReduction)
+	)) {
+		const size = sizes[key];
+		if (size === undefined || size === 0) continue;
+		if (size * chunkCount < minSizeReduction[key]) return false;
+	}
+	return true;
+};
+
+/**
+ * Gets violating min sizes.
+ * @param {SplitChunksSizes} sizes the sizes
+ * @param {SplitChunksSizes} minSize the min sizes
+ * @returns {undefined | SourceTypes} list of size types that are below min size
+ */
+const getViolatingMinSizes = (sizes, minSize) => {
+	/** @type {SourceTypes | undefined} */
+	let list;
+	for (const key of /** @type {SourceType[]} */ (Object.keys(minSize))) {
+		const size = sizes[key];
+		if (size === undefined || size === 0) continue;
+		if (size < minSize[key]) {
+			if (list === undefined) list = [key];
+			else list.push(key);
+		}
+	}
+	return list;
+};
+
+/**
+ * Returns the total size.
+ * @param {SplitChunksSizes} sizes the sizes
+ * @returns {Size} the total size
+ */
+const totalSize = (sizes) => {
+	let size = 0;
+	for (const key of /** @type {SourceType[]} */ (Object.keys(sizes))) {
+		size += sizes[key];
+	}
+	return size;
+};
+
+/**
+ * Returns a function to get the name of the chunk.
+ * @param {OptimizationSplitChunksCacheGroup["name"]} name the chunk name
+ * @returns {GetNameFn | undefined} a function to get the name of the chunk
+ */
+const normalizeName = (name) => {
+	if (typeof name === "string") {
+		return () => name;
+	}
+	if (typeof name === "function") {
+		return /** @type {GetNameFn} */ (name);
+	}
+};
+
+/**
+ * Normalizes chunks filter.
+ * @param {OptimizationSplitChunksCacheGroup["chunks"]} chunks the chunk filter option
+ * @returns {ChunkFilterFn | undefined} the chunk filter function
+ */
+const normalizeChunksFilter = (chunks) => {
+	if (chunks === "initial") {
+		return INITIAL_CHUNK_FILTER;
+	}
+	if (chunks === "async") {
+		return ASYNC_CHUNK_FILTER;
+	}
+	if (chunks === "all") {
+		return ALL_CHUNK_FILTER;
+	}
+	if (chunks instanceof RegExp) {
+		return (chunk) => (chunk.name ? chunks.test(chunk.name) : false);
+	}
+	if (typeof chunks === "function") {
+		return chunks;
+	}
+};
+
+/**
+ * Normalizes cache groups.
+ * @param {undefined | GetCacheGroups | Record<string, false | string | RegExp | RawGetCacheGroups | OptimizationSplitChunksCacheGroup>} cacheGroups the cache group options
+ * @param {DefaultSizeTypes} defaultSizeTypes the default size types
+ * @returns {GetCacheGroups} a function to get the cache groups
+ */
+const normalizeCacheGroups = (cacheGroups, defaultSizeTypes) => {
+	if (typeof cacheGroups === "function") {
+		return cacheGroups;
+	}
+	if (typeof cacheGroups === "object" && cacheGroups !== null) {
+		/** @type {((module: Module, context: CacheGroupsContext, results: CacheGroupSource[]) => void)[]} */
+		const handlers = [];
+		for (const key of Object.keys(cacheGroups)) {
+			const option = cacheGroups[key];
+			if (option === false) {
+				continue;
+			}
+			if (typeof option === "string" || option instanceof RegExp) {
+				const source = createCacheGroupSource({}, key, defaultSizeTypes);
+				handlers.push((module, context, results) => {
+					if (checkTest(option, module, context)) {
+						results.push(source);
+					}
+				});
+			} else if (typeof option === "function") {
+				/** @type {WeakMap<OptimizationSplitChunksCacheGroup, CacheGroupSource>} */
+				const cache = new WeakMap();
+				handlers.push((module, context, results) => {
+					const result = option(module);
+					if (result) {
+						const groups = Array.isArray(result) ? result : [result];
+						for (const group of groups) {
+							const cachedSource = cache.get(group);
+							if (cachedSource !== undefined) {
+								results.push(cachedSource);
+							} else {
+								const source = createCacheGroupSource(
+									group,
+									key,
+									defaultSizeTypes
+								);
+								cache.set(group, source);
+								results.push(source);
+							}
+						}
+					}
+				});
+			} else {
+				const source = createCacheGroupSource(option, key, defaultSizeTypes);
+				handlers.push((module, context, results) => {
+					if (
+						checkTest(option.test, module, context) &&
+						checkModuleType(option.type, module) &&
+						checkModuleLayer(option.layer, module)
+					) {
+						results.push(source);
+					}
+				});
+			}
+		}
+		/**
+		 * Returns the matching cache groups.
+		 * @param {Module} module the current module
+		 * @param {CacheGroupsContext} context the current context
+		 * @returns {CacheGroupSource[]} the matching cache groups
+		 */
+		const fn = (module, context) => {
+			/** @type {CacheGroupSource[]} */
+			const results = [];
+			for (const fn of handlers) {
+				fn(module, context, results);
+			}
+			return results;
+		};
+		return fn;
+	}
+	return () => null;
+};
+
+/** @typedef {(module: Module, context: CacheGroupsContext) => boolean} CheckTestFn */
+
+/**
+ * Checks true, if the module should be selected.
+ * @param {OptimizationSplitChunksCacheGroup["test"]} test test option
+ * @param {Module} module the module
+ * @param {CacheGroupsContext} context context object
+ * @returns {boolean} true, if the module should be selected
+ */
+const checkTest = (test, module, context) => {
+	if (test === undefined) return true;
+	if (typeof test === "function") {
+		return test(module, context);
+	}
+	if (typeof test === "boolean") return test;
+	if (typeof test === "string") {
+		const name = module.nameForCondition();
+		return name ? name.startsWith(test) : false;
+	}
+	if (test instanceof RegExp) {
+		const name = module.nameForCondition();
+		return name ? test.test(name) : false;
+	}
+	return false;
+};
+
+/** @typedef {(type: string) => boolean} CheckModuleTypeFn */
+
+/**
+ * Checks module type.
+ * @param {OptimizationSplitChunksCacheGroup["type"]} test type option
+ * @param {Module} module the module
+ * @returns {boolean} true, if the module should be selected
+ */
+const checkModuleType = (test, module) => {
+	if (test === undefined) return true;
+	if (typeof test === "function") {
+		return test(module.type);
+	}
+	if (typeof test === "string") {
+		const type = module.type;
+		return test === type;
+	}
+	if (test instanceof RegExp) {
+		const type = module.type;
+		return test.test(type);
+	}
+	return false;
+};
+
+/** @typedef {(layer: string | null) => boolean} CheckModuleLayerFn */
+
+/**
+ * Checks module layer.
+ * @param {OptimizationSplitChunksCacheGroup["layer"]} test type option
+ * @param {Module} module the module
+ * @returns {boolean} true, if the module should be selected
+ */
+const checkModuleLayer = (test, module) => {
+	if (test === undefined) return true;
+	if (typeof test === "function") {
+		return test(module.layer);
+	}
+	if (typeof test === "string") {
+		const layer = module.layer;
+		return test === "" ? !layer : layer ? layer.startsWith(test) : false;
+	}
+	if (test instanceof RegExp) {
+		const layer = module.layer;
+		return layer ? test.test(layer) : false;
+	}
+	return false;
+};
+
+/**
+ * Creates a cache group source.
+ * @param {OptimizationSplitChunksCacheGroup} options the group options
+ * @param {string} key key of cache group
+ * @param {DefaultSizeTypes} defaultSizeTypes the default size types
+ * @returns {CacheGroupSource} the normalized cached group
+ */
+const createCacheGroupSource = (options, key, defaultSizeTypes) => {
+	const minSize = normalizeSizes(options.minSize, defaultSizeTypes);
+	const minSizeReduction = normalizeSizes(
+		options.minSizeReduction,
+		defaultSizeTypes
+	);
+	const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes);
+	return {
+		key,
+		priority: options.priority,
+		getName: normalizeName(options.name),
+		chunksFilter: normalizeChunksFilter(options.chunks),
+		enforce: options.enforce,
+		minSize,
+		minSizeReduction,
+		minRemainingSize: mergeSizes(
+			normalizeSizes(options.minRemainingSize, defaultSizeTypes),
+			minSize
+		),
+		enforceSizeThreshold: normalizeSizes(
+			options.enforceSizeThreshold,
+			defaultSizeTypes
+		),
+		maxAsyncSize: mergeSizes(
+			normalizeSizes(options.maxAsyncSize, defaultSizeTypes),
+			maxSize
+		),
+		maxInitialSize: mergeSizes(
+			normalizeSizes(options.maxInitialSize, defaultSizeTypes),
+			maxSize
+		),
+		minChunks: options.minChunks,
+		maxAsyncRequests: options.maxAsyncRequests,
+		maxInitialRequests: options.maxInitialRequests,
+		filename: options.filename,
+		idHint: options.idHint,
+		automaticNameDelimiter: options.automaticNameDelimiter,
+		reuseExistingChunk: options.reuseExistingChunk,
+		usedExports: options.usedExports
+	};
+};
+
+const PLUGIN_NAME = "SplitChunksPlugin";
+
+module.exports = class SplitChunksPlugin {
+	/**
+	 * Creates an instance of SplitChunksPlugin.
+	 * @param {OptimizationSplitChunksOptions=} options plugin options
+	 */
+	constructor(options = {}) {
+		const defaultSizeTypes = options.defaultSizeTypes || [
+			"javascript",
+			"unknown"
+		];
+		const fallbackCacheGroup = options.fallbackCacheGroup || {};
+		const minSize = normalizeSizes(options.minSize, defaultSizeTypes);
+		const minSizeReduction = normalizeSizes(
+			options.minSizeReduction,
+			defaultSizeTypes
+		);
+		const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes);
+
+		/** @type {SplitChunksOptions} */
+		this.options = {
+			chunksFilter:
+				/** @type {ChunkFilterFn} */
+				(normalizeChunksFilter(options.chunks || "all")),
+			defaultSizeTypes,
+			minSize,
+			minSizeReduction,
+			minRemainingSize: mergeSizes(
+				normalizeSizes(options.minRemainingSize, defaultSizeTypes),
+				minSize
+			),
+			enforceSizeThreshold: normalizeSizes(
+				options.enforceSizeThreshold,
+				defaultSizeTypes
+			),
+			maxAsyncSize: mergeSizes(
+				normalizeSizes(options.maxAsyncSize, defaultSizeTypes),
+				maxSize
+			),
+			maxInitialSize: mergeSizes(
+				normalizeSizes(options.maxInitialSize, defaultSizeTypes),
+				maxSize
+			),
+			minChunks: options.minChunks || 1,
+			maxAsyncRequests: options.maxAsyncRequests || 1,
+			maxInitialRequests: options.maxInitialRequests || 1,
+			hidePathInfo: options.hidePathInfo || false,
+			filename: options.filename || undefined,
+			getCacheGroups: normalizeCacheGroups(
+				options.cacheGroups,
+				defaultSizeTypes
+			),
+			getName: options.name
+				? /** @type {GetNameFn} */ (normalizeName(options.name))
+				: defaultGetName,
+			automaticNameDelimiter: options.automaticNameDelimiter || "-",
+			usedExports: options.usedExports || false,
+			fallbackCacheGroup: {
+				chunksFilter:
+					/** @type {ChunkFilterFn} */
+					(
+						normalizeChunksFilter(
+							fallbackCacheGroup.chunks || options.chunks || "all"
+						)
+					),
+				minSize: mergeSizes(
+					normalizeSizes(fallbackCacheGroup.minSize, defaultSizeTypes),
+					minSize
+				),
+				maxAsyncSize: mergeSizes(
+					normalizeSizes(fallbackCacheGroup.maxAsyncSize, defaultSizeTypes),
+					normalizeSizes(fallbackCacheGroup.maxSize, defaultSizeTypes),
+					normalizeSizes(options.maxAsyncSize, defaultSizeTypes),
+					normalizeSizes(options.maxSize, defaultSizeTypes)
+				),
+				maxInitialSize: mergeSizes(
+					normalizeSizes(fallbackCacheGroup.maxInitialSize, defaultSizeTypes),
+					normalizeSizes(fallbackCacheGroup.maxSize, defaultSizeTypes),
+					normalizeSizes(options.maxInitialSize, defaultSizeTypes),
+					normalizeSizes(options.maxSize, defaultSizeTypes)
+				),
+				automaticNameDelimiter:
+					fallbackCacheGroup.automaticNameDelimiter ||
+					options.automaticNameDelimiter ||
+					"~"
+			}
+		};
+
+		/** @type {WeakMap<CacheGroupSource, CacheGroup>} */
+		this._cacheGroupCache = new WeakMap();
+	}
+
+	/**
+	 * Returns the cache group (cached).
+	 * @param {CacheGroupSource} cacheGroupSource source
+	 * @returns {CacheGroup} the cache group (cached)
+	 */
+	_getCacheGroup(cacheGroupSource) {
+		const cacheEntry = this._cacheGroupCache.get(cacheGroupSource);
+		if (cacheEntry !== undefined) return cacheEntry;
+		const minSize = mergeSizes(
+			cacheGroupSource.minSize,
+			cacheGroupSource.enforce ? undefined : this.options.minSize
+		);
+		const minSizeReduction = mergeSizes(
+			cacheGroupSource.minSizeReduction,
+			cacheGroupSource.enforce ? undefined : this.options.minSizeReduction
+		);
+		const minRemainingSize = mergeSizes(
+			cacheGroupSource.minRemainingSize,
+			cacheGroupSource.enforce ? undefined : this.options.minRemainingSize
+		);
+		const enforceSizeThreshold = mergeSizes(
+			cacheGroupSource.enforceSizeThreshold,
+			cacheGroupSource.enforce ? undefined : this.options.enforceSizeThreshold
+		);
+		/** @type {CacheGroup} */
+		const cacheGroup = {
+			key: cacheGroupSource.key,
+			priority: cacheGroupSource.priority || 0,
+			chunksFilter: cacheGroupSource.chunksFilter || this.options.chunksFilter,
+			minSize,
+			minSizeReduction,
+			minRemainingSize,
+			enforceSizeThreshold,
+			maxAsyncSize: mergeSizes(
+				cacheGroupSource.maxAsyncSize,
+				cacheGroupSource.enforce ? undefined : this.options.maxAsyncSize
+			),
+			maxInitialSize: mergeSizes(
+				cacheGroupSource.maxInitialSize,
+				cacheGroupSource.enforce ? undefined : this.options.maxInitialSize
+			),
+			minChunks:
+				cacheGroupSource.minChunks !== undefined
+					? cacheGroupSource.minChunks
+					: cacheGroupSource.enforce
+						? 1
+						: this.options.minChunks,
+			maxAsyncRequests:
+				cacheGroupSource.maxAsyncRequests !== undefined
+					? cacheGroupSource.maxAsyncRequests
+					: cacheGroupSource.enforce
+						? Infinity
+						: this.options.maxAsyncRequests,
+			maxInitialRequests:
+				cacheGroupSource.maxInitialRequests !== undefined
+					? cacheGroupSource.maxInitialRequests
+					: cacheGroupSource.enforce
+						? Infinity
+						: this.options.maxInitialRequests,
+			getName:
+				cacheGroupSource.getName !== undefined
+					? cacheGroupSource.getName
+					: this.options.getName,
+			usedExports:
+				cacheGroupSource.usedExports !== undefined
+					? cacheGroupSource.usedExports
+					: this.options.usedExports,
+			filename:
+				cacheGroupSource.filename !== undefined
+					? cacheGroupSource.filename
+					: this.options.filename,
+			automaticNameDelimiter:
+				cacheGroupSource.automaticNameDelimiter !== undefined
+					? cacheGroupSource.automaticNameDelimiter
+					: this.options.automaticNameDelimiter,
+			idHint:
+				cacheGroupSource.idHint !== undefined
+					? cacheGroupSource.idHint
+					: cacheGroupSource.key,
+			reuseExistingChunk: cacheGroupSource.reuseExistingChunk || false,
+			_validateSize: hasNonZeroSizes(minSize),
+			_validateRemainingSize: hasNonZeroSizes(minRemainingSize),
+			_minSizeForMaxSize: mergeSizes(
+				cacheGroupSource.minSize,
+				this.options.minSize
+			),
+			_conditionalEnforce: hasNonZeroSizes(enforceSizeThreshold)
+		};
+		this._cacheGroupCache.set(cacheGroupSource, cacheGroup);
+		return cacheGroup;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const cachedMakePathsRelative = makePathsRelative.bindContextCache(
+			compiler.context,
+			compiler.root
+		);
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const logger = compilation.getLogger(`webpack.${PLUGIN_NAME}`);
+			let alreadyOptimized = false;
+			compilation.hooks.unseal.tap(PLUGIN_NAME, () => {
+				alreadyOptimized = false;
+			});
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: PLUGIN_NAME,
+					stage: STAGE_ADVANCED
+				},
+				(chunks) => {
+					if (alreadyOptimized) return;
+					alreadyOptimized = true;
+					logger.time("prepare");
+					const chunkGraph = compilation.chunkGraph;
+					const moduleGraph = compilation.moduleGraph;
+					// Give each selected chunk an index (to create strings from chunks)
+					/** @type {Map<Chunk, bigint>} */
+					const chunkIndexMap = new Map();
+					const ZERO = BigInt("0");
+					const ONE = BigInt("1");
+					const START = ONE << BigInt("31");
+					let index = START;
+					for (const chunk of chunks) {
+						chunkIndexMap.set(
+							chunk,
+							index | BigInt((Math.random() * 0x7fffffff) | 0)
+						);
+						index <<= ONE;
+					}
+					/**
+					 * Returns key of the chunks.
+					 * @param {Iterable<Chunk, undefined, undefined>} chunks list of chunks
+					 * @returns {bigint | Chunk} key of the chunks
+					 */
+					const getKey = (chunks) => {
+						const iterator = chunks[Symbol.iterator]();
+						let result = iterator.next();
+						if (result.done) return ZERO;
+						const first = result.value;
+						result = iterator.next();
+						if (result.done) return first;
+						let key =
+							/** @type {bigint} */ (chunkIndexMap.get(first)) |
+							/** @type {bigint} */ (chunkIndexMap.get(result.value));
+						while (!(result = iterator.next()).done) {
+							const raw = chunkIndexMap.get(result.value);
+							key ^= /** @type {bigint} */ (raw);
+						}
+						return key;
+					};
+					/**
+					 * Returns stringified key.
+					 * @param {bigint | Chunk} key key of the chunks
+					 * @returns {string} stringified key
+					 */
+					const keyToString = (key) => {
+						if (typeof key === "bigint") return key.toString(16);
+						return /** @type {bigint} */ (chunkIndexMap.get(key)).toString(16);
+					};
+
+					const getChunkSetsInGraph = memoize(() => {
+						/** @type {Map<bigint, ChunkSet>} */
+						const chunkSetsInGraph = new Map();
+						/** @type {ChunkSet} */
+						const singleChunkSets = new Set();
+						for (const module of compilation.modules) {
+							const chunks = chunkGraph.getModuleChunksIterable(module);
+							const chunksKey = getKey(chunks);
+							if (typeof chunksKey === "bigint") {
+								if (!chunkSetsInGraph.has(chunksKey)) {
+									chunkSetsInGraph.set(chunksKey, new Set(chunks));
+								}
+							} else {
+								singleChunkSets.add(chunksKey);
+							}
+						}
+						return { chunkSetsInGraph, singleChunkSets };
+					});
+
+					/**
+					 * Group chunks by exports.
+					 * @param {Module} module the module
+					 * @returns {Iterable<Chunk[]>} groups of chunks with equal exports
+					 */
+					const groupChunksByExports = (module) => {
+						const exportsInfo = moduleGraph.getExportsInfo(module);
+						/** @type {Map<string, Chunk[]>} */
+						const groupedByUsedExports = new Map();
+						for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
+							const key = exportsInfo.getUsageKey(chunk.runtime);
+							const list = groupedByUsedExports.get(key);
+							if (list !== undefined) {
+								list.push(chunk);
+							} else {
+								groupedByUsedExports.set(key, [chunk]);
+							}
+						}
+						return groupedByUsedExports.values();
+					};
+
+					/** @type {Map<Module, Iterable<Chunk[]>>} */
+					const groupedByExportsMap = new Map();
+
+					/** @typedef {Map<bigint | Chunk, ChunkSet>} ChunkSetsInGraph */
+
+					const getExportsChunkSetsInGraph = memoize(() => {
+						/** @type {ChunkSetsInGraph} */
+						const chunkSetsInGraph = new Map();
+						/** @type {ChunkSet} */
+						const singleChunkSets = new Set();
+						for (const module of compilation.modules) {
+							const groupedChunks = [...groupChunksByExports(module)];
+							groupedByExportsMap.set(module, groupedChunks);
+							for (const chunks of groupedChunks) {
+								if (chunks.length === 1) {
+									singleChunkSets.add(chunks[0]);
+								} else {
+									const chunksKey = getKey(chunks);
+									if (!chunkSetsInGraph.has(chunksKey)) {
+										chunkSetsInGraph.set(chunksKey, new Set(chunks));
+									}
+								}
+							}
+						}
+						return { chunkSetsInGraph, singleChunkSets };
+					});
+
+					/** @typedef {Map<CountOfChunk, ChunkSet[]>} ChunkSetsByCount */
+
+					// group these set of chunks by count
+					// to allow to check less sets via isSubset
+					// (only smaller sets can be subset)
+					/**
+					 * Group chunk sets by count.
+					 * @param {IterableIterator<ChunkSet>} chunkSets set of sets of chunks
+					 * @returns {ChunkSetsByCount} map of sets of chunks by count
+					 */
+					const groupChunkSetsByCount = (chunkSets) => {
+						/** @type {ChunkSetsByCount} */
+						const chunkSetsByCount = new Map();
+						for (const chunksSet of chunkSets) {
+							const count = chunksSet.size;
+							let array = chunkSetsByCount.get(count);
+							if (array === undefined) {
+								array = [];
+								chunkSetsByCount.set(count, array);
+							}
+							array.push(chunksSet);
+						}
+						return chunkSetsByCount;
+					};
+					const getChunkSetsByCount = memoize(() =>
+						groupChunkSetsByCount(
+							getChunkSetsInGraph().chunkSetsInGraph.values()
+						)
+					);
+					const getExportsChunkSetsByCount = memoize(() =>
+						groupChunkSetsByCount(
+							getExportsChunkSetsInGraph().chunkSetsInGraph.values()
+						)
+					);
+
+					/** @typedef {(ChunkSet | Chunk)[]} Combinations */
+
+					// Create a list of possible combinations
+					/**
+					 * Creates a get combinations.
+					 * @param {ChunkSetsInGraph} chunkSets chunk sets
+					 * @param {ChunkSet} singleChunkSets single chunks sets
+					 * @param {ChunkSetsByCount} chunkSetsByCount chunk sets by count
+					 * @returns {(key: bigint | Chunk) => Combinations} combinations
+					 */
+					const createGetCombinations = (
+						chunkSets,
+						singleChunkSets,
+						chunkSetsByCount
+					) => {
+						/** @type {Map<bigint | Chunk, Combinations>} */
+						const combinationsCache = new Map();
+
+						return (key) => {
+							const cacheEntry = combinationsCache.get(key);
+							if (cacheEntry !== undefined) return cacheEntry;
+							if (key instanceof Chunk) {
+								const result = [key];
+								combinationsCache.set(key, result);
+								return result;
+							}
+							const chunksSet =
+								/** @type {ChunkSet} */
+								(chunkSets.get(key));
+							/** @type {Combinations} */
+							const array = [chunksSet];
+							for (const [count, setArray] of chunkSetsByCount) {
+								// "equal" is not needed because they would have been merge in the first step
+								if (count < chunksSet.size) {
+									for (const set of setArray) {
+										if (isSubset(chunksSet, set)) {
+											array.push(set);
+										}
+									}
+								}
+							}
+							for (const chunk of singleChunkSets) {
+								if (chunksSet.has(chunk)) {
+									array.push(chunk);
+								}
+							}
+							combinationsCache.set(key, array);
+							return array;
+						};
+					};
+
+					const getCombinationsFactory = memoize(() => {
+						const { chunkSetsInGraph, singleChunkSets } = getChunkSetsInGraph();
+						return createGetCombinations(
+							chunkSetsInGraph,
+							singleChunkSets,
+							getChunkSetsByCount()
+						);
+					});
+
+					/**
+					 * Returns combinations by key.
+					 * @param {bigint | Chunk} key key
+					 * @returns {Combinations} combinations by key
+					 */
+					const getCombinations = (key) => getCombinationsFactory()(key);
+
+					const getExportsCombinationsFactory = memoize(() => {
+						const { chunkSetsInGraph, singleChunkSets } =
+							getExportsChunkSetsInGraph();
+						return createGetCombinations(
+							chunkSetsInGraph,
+							singleChunkSets,
+							getExportsChunkSetsByCount()
+						);
+					});
+					/**
+					 * Gets exports combinations.
+					 * @param {bigint | Chunk} key key
+					 * @returns {Combinations} exports combinations by key
+					 */
+					const getExportsCombinations = (key) =>
+						getExportsCombinationsFactory()(key);
+
+					/**
+					 * Defines the selected chunks result type used by this module.
+					 * @typedef {object} SelectedChunksResult
+					 * @property {Chunk[]} chunks the list of chunks
+					 * @property {bigint | Chunk} key a key of the list
+					 */
+
+					/** @typedef {WeakMap<ChunkFilterFn, SelectedChunksResult>} ChunkMap */
+					/** @type {WeakMap<ChunkSet | Chunk, ChunkMap>} */
+					const selectedChunksCacheByChunksSet = new WeakMap();
+
+					/**
+					 * get list and key by applying the filter function to the list
+					 * It is cached for performance reasons
+					 * @param {ChunkSet | Chunk} chunks list of chunks
+					 * @param {ChunkFilterFn} chunkFilter filter function for chunks
+					 * @returns {SelectedChunksResult} list and key
+					 */
+					const getSelectedChunks = (chunks, chunkFilter) => {
+						let entry = selectedChunksCacheByChunksSet.get(chunks);
+						if (entry === undefined) {
+							/** @type {ChunkMap} */
+							entry = new WeakMap();
+							selectedChunksCacheByChunksSet.set(chunks, entry);
+						}
+						let entry2 =
+							/** @type {SelectedChunksResult} */
+							(entry.get(chunkFilter));
+						if (entry2 === undefined) {
+							/** @type {Chunk[]} */
+							const selectedChunks = [];
+							if (chunks instanceof Chunk) {
+								if (chunkFilter(chunks)) selectedChunks.push(chunks);
+							} else {
+								for (const chunk of chunks) {
+									if (chunkFilter(chunk)) selectedChunks.push(chunk);
+								}
+							}
+							entry2 = {
+								chunks: selectedChunks,
+								key: getKey(selectedChunks)
+							};
+							entry.set(chunkFilter, entry2);
+						}
+						return entry2;
+					};
+
+					/** @type {Map<string, boolean>} */
+					const alreadyValidatedParents = new Map();
+					/** @type {Set<string>} */
+					const alreadyReportedErrors = new Set();
+
+					// Map a list of chunks to a list of modules
+					// For the key the chunk "index" is used, the value is a SortableSet of modules
+					/** @type {Map<string, ChunksInfoItem>} */
+					const chunksInfoMap = new Map();
+
+					/**
+					 * Adds module to chunks info map.
+					 * @param {CacheGroup} cacheGroup the current cache group
+					 * @param {number} cacheGroupIndex the index of the cache group of ordering
+					 * @param {Chunk[]} selectedChunks chunks selected for this module
+					 * @param {bigint | Chunk} selectedChunksKey a key of selectedChunks
+					 * @param {Module} module the current module
+					 * @returns {void}
+					 */
+					const addModuleToChunksInfoMap = (
+						cacheGroup,
+						cacheGroupIndex,
+						selectedChunks,
+						selectedChunksKey,
+						module
+					) => {
+						// Break if minimum number of chunks is not reached
+						if (selectedChunks.length < cacheGroup.minChunks) return;
+						// Determine name for split chunk
+
+						const name =
+							/** @type {GetNameFn} */
+							(cacheGroup.getName)(module, selectedChunks, cacheGroup.key);
+						// Check if the name is ok
+						const existingChunk = name && compilation.namedChunks.get(name);
+						if (existingChunk) {
+							const parentValidationKey = `${name}|${
+								typeof selectedChunksKey === "bigint"
+									? selectedChunksKey
+									: selectedChunksKey.debugId
+							}`;
+							const valid = alreadyValidatedParents.get(parentValidationKey);
+							if (valid === false) return;
+							if (valid === undefined) {
+								// Module can only be moved into the existing chunk if the existing chunk
+								// is a parent of all selected chunks
+								let isInAllParents = true;
+								/** @type {Set<ChunkGroup>} */
+								const queue = new Set();
+								for (const chunk of selectedChunks) {
+									for (const group of chunk.groupsIterable) {
+										queue.add(group);
+									}
+								}
+								for (const group of queue) {
+									if (existingChunk.isInGroup(group)) continue;
+									let hasParent = false;
+									for (const parent of group.parentsIterable) {
+										hasParent = true;
+										queue.add(parent);
+									}
+									if (!hasParent) {
+										isInAllParents = false;
+									}
+								}
+								const valid = isInAllParents;
+								alreadyValidatedParents.set(parentValidationKey, valid);
+								if (!valid) {
+									if (!alreadyReportedErrors.has(name)) {
+										alreadyReportedErrors.add(name);
+										compilation.errors.push(
+											new WebpackError(
+												`${PLUGIN_NAME}\n` +
+													`Cache group "${cacheGroup.key}" conflicts with existing chunk.\n` +
+													`Both have the same name "${name}" and existing chunk is not a parent of the selected modules.\n` +
+													"Use a different name for the cache group or make sure that the existing chunk is a parent (e. g. via dependOn).\n" +
+													'HINT: You can omit "name" to automatically create a name.\n' +
+													"BREAKING CHANGE: webpack < 5 used to allow to use an entrypoint as splitChunk. " +
+													"This is no longer allowed when the entrypoint is not a parent of the selected modules.\n" +
+													"Remove this entrypoint and add modules to cache group's 'test' instead. " +
+													"If you need modules to be evaluated on startup, add them to the existing entrypoints (make them arrays). " +
+													"See migration guide of more info."
+											)
+										);
+									}
+									return;
+								}
+							}
+						}
+						// Create key for maps
+						// When it has a name we use the name as key
+						// Otherwise we create the key from chunks and cache group key
+						// This automatically merges equal names
+						const key =
+							cacheGroup.key +
+							(name
+								? ` name:${name}`
+								: ` chunks:${keyToString(selectedChunksKey)}`);
+						// Add module to maps
+						let info = chunksInfoMap.get(key);
+						if (info === undefined) {
+							chunksInfoMap.set(
+								key,
+								(info = {
+									modules: new SortableSet(
+										undefined,
+										compareModulesByIdentifier
+									),
+									cacheGroup,
+									cacheGroupIndex,
+									name,
+									sizes: {},
+									chunks: new Set(),
+									reusableChunks: new Set(),
+									chunksKeys: new Set()
+								})
+							);
+						}
+						const oldSize = info.modules.size;
+						info.modules.add(module);
+						if (info.modules.size !== oldSize) {
+							for (const type of module.getSourceTypes()) {
+								info.sizes[type] = (info.sizes[type] || 0) + module.size(type);
+							}
+						}
+						const oldChunksKeysSize = info.chunksKeys.size;
+						info.chunksKeys.add(selectedChunksKey);
+						if (oldChunksKeysSize !== info.chunksKeys.size) {
+							for (const chunk of selectedChunks) {
+								info.chunks.add(chunk);
+							}
+						}
+					};
+
+					const context = {
+						moduleGraph,
+						chunkGraph
+					};
+
+					logger.timeEnd("prepare");
+
+					logger.time("modules");
+
+					// Walk through all modules
+					for (const module of compilation.modules) {
+						// Get cache group
+						const cacheGroups = this.options.getCacheGroups(module, context);
+						if (!Array.isArray(cacheGroups) || cacheGroups.length === 0) {
+							continue;
+						}
+
+						// Prepare some values (usedExports = false)
+						const getCombs = memoize(() => {
+							const chunks = chunkGraph.getModuleChunksIterable(module);
+							const chunksKey = getKey(chunks);
+							return getCombinations(chunksKey);
+						});
+
+						// Prepare some values (usedExports = true)
+						const getCombsByUsedExports = memoize(() => {
+							// fill the groupedByExportsMap
+							getExportsChunkSetsInGraph();
+							/** @type {Set<ChunkSet | Chunk>} */
+							const set = new Set();
+							const groupedByUsedExports =
+								/** @type {Iterable<Chunk[]>} */
+								(groupedByExportsMap.get(module));
+							for (const chunks of groupedByUsedExports) {
+								const chunksKey = getKey(chunks);
+								for (const comb of getExportsCombinations(chunksKey)) {
+									set.add(comb);
+								}
+							}
+							return set;
+						});
+
+						let cacheGroupIndex = 0;
+						for (const cacheGroupSource of cacheGroups) {
+							const cacheGroup = this._getCacheGroup(cacheGroupSource);
+
+							const combs = cacheGroup.usedExports
+								? getCombsByUsedExports()
+								: getCombs();
+							// For all combination of chunk selection
+							for (const chunkCombination of combs) {
+								// Break if minimum number of chunks is not reached
+								const count =
+									chunkCombination instanceof Chunk ? 1 : chunkCombination.size;
+								if (count < cacheGroup.minChunks) continue;
+								// Select chunks by configuration
+								const { chunks: selectedChunks, key: selectedChunksKey } =
+									getSelectedChunks(
+										chunkCombination,
+										/** @type {ChunkFilterFn} */
+										(cacheGroup.chunksFilter)
+									);
+
+								addModuleToChunksInfoMap(
+									cacheGroup,
+									cacheGroupIndex,
+									selectedChunks,
+									selectedChunksKey,
+									module
+								);
+							}
+							cacheGroupIndex++;
+						}
+					}
+
+					logger.timeEnd("modules");
+
+					logger.time("queue");
+
+					/**
+					 * Removes modules with source type.
+					 * @param {ChunksInfoItem} info entry
+					 * @param {SourceTypes} sourceTypes source types to be removed
+					 */
+					const removeModulesWithSourceType = (info, sourceTypes) => {
+						for (const module of info.modules) {
+							const types = module.getSourceTypes();
+							if (sourceTypes.some((type) => types.has(type))) {
+								info.modules.delete(module);
+								for (const type of types) {
+									info.sizes[type] -= module.size(type);
+								}
+							}
+						}
+					};
+
+					/**
+					 * Removes min size violating modules.
+					 * @param {ChunksInfoItem} info entry
+					 * @returns {boolean} true, if entry become empty
+					 */
+					const removeMinSizeViolatingModules = (info) => {
+						if (!info.cacheGroup._validateSize) return false;
+						const violatingSizes = getViolatingMinSizes(
+							info.sizes,
+							info.cacheGroup.minSize
+						);
+						if (violatingSizes === undefined) return false;
+						removeModulesWithSourceType(info, violatingSizes);
+						return info.modules.size === 0;
+					};
+
+					// Filter items were size < minSize
+					for (const [key, info] of chunksInfoMap) {
+						if (removeMinSizeViolatingModules(info)) {
+							chunksInfoMap.delete(key);
+						} else if (
+							!checkMinSizeReduction(
+								info.sizes,
+								info.cacheGroup.minSizeReduction,
+								info.chunks.size
+							)
+						) {
+							chunksInfoMap.delete(key);
+						}
+					}
+
+					/**
+					 * Defines the max size queue item type used by this module.
+					 * @typedef {object} MaxSizeQueueItem
+					 * @property {SplitChunksSizes} minSize
+					 * @property {SplitChunksSizes} maxAsyncSize
+					 * @property {SplitChunksSizes} maxInitialSize
+					 * @property {string} automaticNameDelimiter
+					 * @property {string[]} keys
+					 */
+
+					/** @type {Map<Chunk, MaxSizeQueueItem>} */
+					const maxSizeQueueMap = new Map();
+
+					while (chunksInfoMap.size > 0) {
+						// Find best matching entry
+						/** @type {undefined | string} */
+						let bestEntryKey;
+						/** @type {undefined | ChunksInfoItem} */
+						let bestEntry;
+						for (const pair of chunksInfoMap) {
+							const key = pair[0];
+							const info = pair[1];
+							if (
+								bestEntry === undefined ||
+								compareEntries(bestEntry, info) < 0
+							) {
+								bestEntry = info;
+								bestEntryKey = key;
+							}
+						}
+
+						const item = /** @type {ChunksInfoItem} */ (bestEntry);
+						chunksInfoMap.delete(/** @type {string} */ (bestEntryKey));
+
+						/** @type {ChunkName | undefined} */
+						let chunkName = item.name;
+						// Variable for the new chunk (lazy created)
+						/** @type {Chunk | undefined} */
+						let newChunk;
+						// When no chunk name, check if we can reuse a chunk instead of creating a new one
+						let isExistingChunk = false;
+						let isReusedWithAllModules = false;
+						if (chunkName) {
+							const chunkByName = compilation.namedChunks.get(chunkName);
+							if (chunkByName !== undefined) {
+								newChunk = chunkByName;
+								const oldSize = item.chunks.size;
+								item.chunks.delete(newChunk);
+								isExistingChunk = item.chunks.size !== oldSize;
+							}
+						} else if (item.cacheGroup.reuseExistingChunk) {
+							outer: for (const chunk of item.chunks) {
+								if (
+									chunkGraph.getNumberOfChunkModules(chunk) !==
+									item.modules.size
+								) {
+									continue;
+								}
+								if (
+									item.chunks.size > 1 &&
+									chunkGraph.getNumberOfEntryModules(chunk) > 0
+								) {
+									continue;
+								}
+								for (const module of item.modules) {
+									if (!chunkGraph.isModuleInChunk(module, chunk)) {
+										continue outer;
+									}
+								}
+								if (!newChunk || !newChunk.name) {
+									newChunk = chunk;
+								} else if (
+									chunk.name &&
+									chunk.name.length < newChunk.name.length
+								) {
+									newChunk = chunk;
+								} else if (
+									chunk.name &&
+									chunk.name.length === newChunk.name.length &&
+									chunk.name < newChunk.name
+								) {
+									newChunk = chunk;
+								}
+							}
+							if (newChunk) {
+								item.chunks.delete(newChunk);
+								chunkName = undefined;
+								isExistingChunk = true;
+								isReusedWithAllModules = true;
+							}
+						}
+
+						const enforced =
+							item.cacheGroup._conditionalEnforce &&
+							checkMinSize(item.sizes, item.cacheGroup.enforceSizeThreshold);
+
+						/** @type {Set<Chunk>} */
+						const usedChunks = new Set(item.chunks);
+
+						// Check if maxRequests condition can be fulfilled
+						if (
+							!enforced &&
+							(Number.isFinite(item.cacheGroup.maxInitialRequests) ||
+								Number.isFinite(item.cacheGroup.maxAsyncRequests))
+						) {
+							for (const chunk of usedChunks) {
+								// respect max requests
+								const maxRequests = chunk.isOnlyInitial()
+									? item.cacheGroup.maxInitialRequests
+									: chunk.canBeInitial()
+										? Math.min(
+												item.cacheGroup.maxInitialRequests,
+												item.cacheGroup.maxAsyncRequests
+											)
+										: item.cacheGroup.maxAsyncRequests;
+								if (
+									Number.isFinite(maxRequests) &&
+									getRequests(chunk) >= maxRequests
+								) {
+									usedChunks.delete(chunk);
+								}
+							}
+						}
+
+						outer: for (const chunk of usedChunks) {
+							for (const module of item.modules) {
+								if (chunkGraph.isModuleInChunk(module, chunk)) continue outer;
+							}
+							usedChunks.delete(chunk);
+						}
+
+						// Were some (invalid) chunks removed from usedChunks?
+						// => readd all modules to the queue, as things could have been changed
+						if (usedChunks.size < item.chunks.size) {
+							if (isExistingChunk) {
+								usedChunks.add(/** @type {Chunk} */ (newChunk));
+							}
+							if (usedChunks.size >= item.cacheGroup.minChunks) {
+								const chunksArr = [...usedChunks];
+								for (const module of item.modules) {
+									addModuleToChunksInfoMap(
+										item.cacheGroup,
+										item.cacheGroupIndex,
+										chunksArr,
+										getKey(usedChunks),
+										module
+									);
+								}
+							}
+							continue;
+						}
+
+						// Validate minRemainingSize constraint when a single chunk is left over
+						if (
+							!enforced &&
+							item.cacheGroup._validateRemainingSize &&
+							usedChunks.size === 1
+						) {
+							const [chunk] = usedChunks;
+							/** @type {SplitChunksSizes} */
+							const chunkSizes = Object.create(null);
+							for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+								if (!item.modules.has(module)) {
+									for (const type of module.getSourceTypes()) {
+										chunkSizes[type] =
+											(chunkSizes[type] || 0) + module.size(type);
+									}
+								}
+							}
+							const violatingSizes = getViolatingMinSizes(
+								chunkSizes,
+								item.cacheGroup.minRemainingSize
+							);
+							if (violatingSizes !== undefined) {
+								const oldModulesSize = item.modules.size;
+								removeModulesWithSourceType(item, violatingSizes);
+								if (
+									item.modules.size > 0 &&
+									item.modules.size !== oldModulesSize
+								) {
+									// queue this item again to be processed again
+									// without violating modules
+									chunksInfoMap.set(/** @type {string} */ (bestEntryKey), item);
+								}
+								continue;
+							}
+						}
+
+						// Create the new chunk if not reusing one
+						if (newChunk === undefined) {
+							newChunk = compilation.addChunk(chunkName);
+						}
+						// Walk through all chunks
+						for (const chunk of usedChunks) {
+							// Add graph connections for splitted chunk
+							chunk.split(newChunk);
+						}
+
+						// Add a note to the chunk
+						newChunk.chunkReason =
+							(newChunk.chunkReason ? `${newChunk.chunkReason}, ` : "") +
+							(isReusedWithAllModules
+								? "reused as split chunk"
+								: "split chunk");
+						if (item.cacheGroup.key) {
+							newChunk.chunkReason += ` (cache group: ${item.cacheGroup.key})`;
+						}
+						if (chunkName) {
+							newChunk.chunkReason += ` (name: ${chunkName})`;
+						}
+						if (item.cacheGroup.filename) {
+							newChunk.filenameTemplate = item.cacheGroup.filename;
+						}
+						if (item.cacheGroup.idHint) {
+							newChunk.idNameHints.add(item.cacheGroup.idHint);
+						}
+						if (!isReusedWithAllModules) {
+							// Add all modules to the new chunk
+							for (const module of item.modules) {
+								if (!module.chunkCondition(newChunk, compilation)) continue;
+								// Add module to new chunk
+								chunkGraph.connectChunkAndModule(newChunk, module);
+								// Remove module from used chunks
+								for (const chunk of usedChunks) {
+									chunkGraph.disconnectChunkAndModule(chunk, module);
+								}
+							}
+						} else {
+							// Remove all modules from used chunks
+							for (const module of item.modules) {
+								for (const chunk of usedChunks) {
+									chunkGraph.disconnectChunkAndModule(chunk, module);
+								}
+							}
+						}
+
+						if (
+							Object.keys(item.cacheGroup.maxAsyncSize).length > 0 ||
+							Object.keys(item.cacheGroup.maxInitialSize).length > 0
+						) {
+							const oldMaxSizeSettings = maxSizeQueueMap.get(newChunk);
+							maxSizeQueueMap.set(newChunk, {
+								minSize: oldMaxSizeSettings
+									? combineSizes(
+											oldMaxSizeSettings.minSize,
+											item.cacheGroup._minSizeForMaxSize,
+											Math.max
+										)
+									: item.cacheGroup.minSize,
+								maxAsyncSize: oldMaxSizeSettings
+									? combineSizes(
+											oldMaxSizeSettings.maxAsyncSize,
+											item.cacheGroup.maxAsyncSize,
+											Math.min
+										)
+									: item.cacheGroup.maxAsyncSize,
+								maxInitialSize: oldMaxSizeSettings
+									? combineSizes(
+											oldMaxSizeSettings.maxInitialSize,
+											item.cacheGroup.maxInitialSize,
+											Math.min
+										)
+									: item.cacheGroup.maxInitialSize,
+								automaticNameDelimiter: item.cacheGroup.automaticNameDelimiter,
+								keys: oldMaxSizeSettings
+									? [...oldMaxSizeSettings.keys, item.cacheGroup.key]
+									: [item.cacheGroup.key]
+							});
+						}
+
+						// remove all modules from other entries and update size
+						for (const [key, info] of chunksInfoMap) {
+							if (isOverlap(info.chunks, usedChunks)) {
+								// update modules and total size
+								// may remove it from the map when < minSize
+								let updated = false;
+								for (const module of item.modules) {
+									if (info.modules.has(module)) {
+										// remove module
+										info.modules.delete(module);
+										// update size
+										for (const key of module.getSourceTypes()) {
+											info.sizes[key] -= module.size(key);
+										}
+										updated = true;
+									}
+								}
+								if (updated) {
+									if (info.modules.size === 0) {
+										chunksInfoMap.delete(key);
+										continue;
+									}
+									if (
+										removeMinSizeViolatingModules(info) ||
+										!checkMinSizeReduction(
+											info.sizes,
+											info.cacheGroup.minSizeReduction,
+											info.chunks.size
+										)
+									) {
+										chunksInfoMap.delete(key);
+										continue;
+									}
+								}
+							}
+						}
+					}
+
+					logger.timeEnd("queue");
+
+					logger.time("maxSize");
+
+					/** @type {Set<string>} */
+					const incorrectMinMaxSizeSet = new Set();
+
+					const { outputOptions } = compilation;
+
+					// Make sure that maxSize is fulfilled
+					const { fallbackCacheGroup } = this.options;
+					for (const chunk of compilation.chunks) {
+						const chunkConfig = maxSizeQueueMap.get(chunk);
+						const {
+							minSize,
+							maxAsyncSize,
+							maxInitialSize,
+							automaticNameDelimiter
+						} = chunkConfig || fallbackCacheGroup;
+						if (!chunkConfig && !fallbackCacheGroup.chunksFilter(chunk)) {
+							continue;
+						}
+						/** @type {SplitChunksSizes} */
+						let maxSize;
+						if (chunk.isOnlyInitial()) {
+							maxSize = maxInitialSize;
+						} else if (chunk.canBeInitial()) {
+							maxSize = combineSizes(maxAsyncSize, maxInitialSize, Math.min);
+						} else {
+							maxSize = maxAsyncSize;
+						}
+						if (Object.keys(maxSize).length === 0) {
+							continue;
+						}
+						for (const key of /** @type {SourceType[]} */ (
+							Object.keys(maxSize)
+						)) {
+							const maxSizeValue = maxSize[key];
+							const minSizeValue = minSize[key];
+							if (
+								typeof minSizeValue === "number" &&
+								minSizeValue > maxSizeValue
+							) {
+								const keys = chunkConfig && chunkConfig.keys;
+								const warningKey = `${
+									keys && keys.join()
+								} ${minSizeValue} ${maxSizeValue}`;
+								if (!incorrectMinMaxSizeSet.has(warningKey)) {
+									incorrectMinMaxSizeSet.add(warningKey);
+									compilation.warnings.push(
+										new MinMaxSizeWarning(keys, minSizeValue, maxSizeValue)
+									);
+								}
+							}
+						}
+						const results = deterministicGroupingForModules({
+							minSize,
+							maxSize: mapObject(maxSize, (value, key) => {
+								const minSizeValue = minSize[key];
+								return typeof minSizeValue === "number"
+									? Math.max(value, minSizeValue)
+									: value;
+							}),
+							items: chunkGraph.getChunkModulesIterable(chunk),
+							getKey(module) {
+								const cache = getKeyCache.get(module);
+								if (cache !== undefined) return cache;
+								const ident = cachedMakePathsRelative(module.identifier());
+								const nameForCondition =
+									module.nameForCondition && module.nameForCondition();
+								const name = nameForCondition
+									? cachedMakePathsRelative(nameForCondition)
+									: ident.replace(/^.*!|\?[^?!]*$/g, "");
+								const fullKey =
+									name +
+									automaticNameDelimiter +
+									hashFilename(ident, outputOptions);
+								const key = requestToId(fullKey);
+								getKeyCache.set(module, key);
+								return key;
+							},
+							getSize(module) {
+								/** @type {Sizes} */
+								const size = Object.create(null);
+								for (const key of module.getSourceTypes()) {
+									size[key] = module.size(key);
+								}
+								return size;
+							}
+						});
+						if (results.length <= 1) {
+							continue;
+						}
+						for (let i = 0; i < results.length; i++) {
+							const group = results[i];
+							const key = this.options.hidePathInfo
+								? hashFilename(group.key, outputOptions)
+								: group.key;
+							let name = chunk.name
+								? chunk.name + automaticNameDelimiter + key
+								: null;
+							if (name && name.length > 100) {
+								name =
+									name.slice(0, 100) +
+									automaticNameDelimiter +
+									hashFilename(name, outputOptions);
+							}
+							if (i !== results.length - 1) {
+								const newPart = compilation.addChunk(name);
+								chunk.split(newPart);
+								newPart.chunkReason = chunk.chunkReason;
+								if (chunk.filenameTemplate) {
+									newPart.filenameTemplate = chunk.filenameTemplate;
+								}
+								// Add all modules to the new chunk
+								for (const module of group.items) {
+									if (!module.chunkCondition(newPart, compilation)) {
+										continue;
+									}
+									// Add module to new chunk
+									chunkGraph.connectChunkAndModule(newPart, module);
+									// Remove module from used chunks
+									chunkGraph.disconnectChunkAndModule(chunk, module);
+								}
+							} else {
+								// change the chunk to be a part
+								chunk.name = name;
+							}
+						}
+					}
+					logger.timeEnd("maxSize");
+				}
+			);
+		});
+	}
+};
Index: frontend/node_modules/webpack/lib/performance/AssetsOverSizeLimitWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/performance/AssetsOverSizeLimitWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/performance/AssetsOverSizeLimitWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const formatSize = require("../util/formatSize");
+
+/** @typedef {import("./SizeLimitsPlugin").AssetDetails} AssetDetails */
+
+class AssetsOverSizeLimitWarning extends WebpackError {
+	/**
+	 * Creates an instance of AssetsOverSizeLimitWarning.
+	 * @param {AssetDetails[]} assetsOverSizeLimit the assets
+	 * @param {number} assetLimit the size limit
+	 */
+	constructor(assetsOverSizeLimit, assetLimit) {
+		const assetLists = assetsOverSizeLimit
+			.map((asset) => `\n  ${asset.name} (${formatSize(asset.size)})`)
+			.join("");
+
+		super(`asset size limit: The following asset(s) exceed the recommended size limit (${formatSize(
+			assetLimit
+		)}).
+This can impact web performance.
+Assets: ${assetLists}`);
+
+		/** @type {string} */
+		this.name = "AssetsOverSizeLimitWarning";
+		/** @type {AssetDetails[]} */
+		this.assets = assetsOverSizeLimit;
+	}
+}
+
+/** @type {typeof AssetsOverSizeLimitWarning} */
+module.exports = AssetsOverSizeLimitWarning;
Index: frontend/node_modules/webpack/lib/performance/EntrypointsOverSizeLimitWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/performance/EntrypointsOverSizeLimitWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/performance/EntrypointsOverSizeLimitWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+const formatSize = require("../util/formatSize");
+
+/** @typedef {import("./SizeLimitsPlugin").EntrypointDetails} EntrypointDetails */
+
+class EntrypointsOverSizeLimitWarning extends WebpackError {
+	/**
+	 * Creates an instance of EntrypointsOverSizeLimitWarning.
+	 * @param {EntrypointDetails[]} entrypoints the entrypoints
+	 * @param {number} entrypointLimit the size limit
+	 */
+	constructor(entrypoints, entrypointLimit) {
+		const entrypointList = entrypoints
+			.map(
+				(entrypoint) =>
+					`\n  ${entrypoint.name} (${formatSize(
+						entrypoint.size
+					)})\n${entrypoint.files.map((asset) => `      ${asset}`).join("\n")}`
+			)
+			.join("");
+		super(`entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (${formatSize(
+			entrypointLimit
+		)}). This can impact web performance.
+Entrypoints:${entrypointList}\n`);
+
+		/** @type {string} */
+		this.name = "EntrypointsOverSizeLimitWarning";
+		/** @type {EntrypointDetails[]} */
+		this.entrypoints = entrypoints;
+	}
+}
+
+/** @type {typeof EntrypointsOverSizeLimitWarning} */
+module.exports = EntrypointsOverSizeLimitWarning;
Index: frontend/node_modules/webpack/lib/performance/NoAsyncChunksWarning.js
===================================================================
--- frontend/node_modules/webpack/lib/performance/NoAsyncChunksWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/performance/NoAsyncChunksWarning.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+
+class NoAsyncChunksWarning extends WebpackError {
+	constructor() {
+		super(
+			"webpack performance recommendations: \n" +
+				"You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.\n" +
+				"For more info visit https://webpack.js.org/guides/code-splitting/"
+		);
+
+		/** @type {string} */
+		this.name = "NoAsyncChunksWarning";
+	}
+}
+
+module.exports = NoAsyncChunksWarning;
Index: frontend/node_modules/webpack/lib/performance/SizeLimitsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/performance/SizeLimitsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/performance/SizeLimitsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,189 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+const { find } = require("../util/SetHelpers");
+const AssetsOverSizeLimitWarning = require("./AssetsOverSizeLimitWarning");
+const EntrypointsOverSizeLimitWarning = require("./EntrypointsOverSizeLimitWarning");
+const NoAsyncChunksWarning = require("./NoAsyncChunksWarning");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").PerformanceOptions} PerformanceOptions */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compilation").Asset} Asset */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+
+/**
+ * Defines the asset details type used by this module.
+ * @typedef {object} AssetDetails
+ * @property {string} name
+ * @property {number} size
+ */
+
+/**
+ * Defines the entrypoint details type used by this module.
+ * @typedef {object} EntrypointDetails
+ * @property {string} name
+ * @property {number} size
+ * @property {string[]} files
+ */
+
+/** @type {WeakSet<Entrypoint | ChunkGroup | Source>} */
+const isOverSizeLimitSet = new WeakSet();
+
+/** @typedef {(name: Asset["name"], source: Asset["source"], assetInfo: Asset["info"]) => boolean} AssetFilter */
+
+/** @type {AssetFilter} */
+const excludeSourceMap = (name, source, info) => !info.development;
+
+const PLUGIN_NAME = "SizeLimitsPlugin";
+
+module.exports = class SizeLimitsPlugin {
+	/**
+	 * Creates an instance of SizeLimitsPlugin.
+	 * @param {PerformanceOptions} options the plugin options
+	 */
+	constructor(options) {
+		/** @type {PerformanceOptions["hints"]} */
+		this.hints = options.hints;
+		/** @type {number | undefined} */
+		this.maxAssetSize = options.maxAssetSize;
+		/** @type {number | undefined} */
+		this.maxEntrypointSize = options.maxEntrypointSize;
+		/** @type {AssetFilter | undefined} */
+		this.assetFilter = options.assetFilter;
+	}
+
+	/**
+	 * Checks whether this size limits plugin is over size limit.
+	 * @param {Entrypoint | ChunkGroup | Source} thing the resource to test
+	 * @returns {boolean} true if over the limit
+	 */
+	static isOverSizeLimit(thing) {
+		return isOverSizeLimitSet.has(thing);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const entrypointSizeLimit = this.maxEntrypointSize;
+		const assetSizeLimit = this.maxAssetSize;
+		const hints = this.hints;
+		const assetFilter = this.assetFilter || excludeSourceMap;
+
+		compiler.hooks.afterEmit.tap(PLUGIN_NAME, (compilation) => {
+			/** @type {WebpackError[]} */
+			const warnings = [];
+
+			/**
+			 * Gets entrypoint size.
+			 * @param {Entrypoint} entrypoint an entrypoint
+			 * @returns {number} the size of the entrypoint
+			 */
+			const getEntrypointSize = (entrypoint) => {
+				let size = 0;
+				for (const file of entrypoint.getFiles()) {
+					const asset = compilation.getAsset(file);
+					if (
+						asset &&
+						assetFilter(asset.name, asset.source, asset.info) &&
+						asset.source
+					) {
+						size += asset.info.size || asset.source.size();
+					}
+				}
+				return size;
+			};
+
+			/** @type {AssetDetails[]} */
+			const assetsOverSizeLimit = [];
+			for (const { name, source, info } of compilation.getAssets()) {
+				if (!assetFilter(name, source, info) || !source) {
+					continue;
+				}
+
+				const size = info.size || source.size();
+				if (size > /** @type {number} */ (assetSizeLimit)) {
+					assetsOverSizeLimit.push({
+						name,
+						size
+					});
+					isOverSizeLimitSet.add(source);
+				}
+			}
+
+			/**
+			 * Returns result.
+			 * @param {Asset["name"]} name the name
+			 * @returns {boolean | undefined} result
+			 */
+			const fileFilter = (name) => {
+				const asset = compilation.getAsset(name);
+				return asset && assetFilter(asset.name, asset.source, asset.info);
+			};
+
+			/** @type {EntrypointDetails[]} */
+			const entrypointsOverLimit = [];
+			for (const [name, entry] of compilation.entrypoints) {
+				const size = getEntrypointSize(entry);
+
+				if (size > /** @type {number} */ (entrypointSizeLimit)) {
+					entrypointsOverLimit.push({
+						name,
+						size,
+						files: entry.getFiles().filter(fileFilter)
+					});
+					isOverSizeLimitSet.add(entry);
+				}
+			}
+
+			if (hints) {
+				// 1. Individual Chunk: Size < 250kb
+				// 2. Collective Initial Chunks [entrypoint] (Each Set?): Size < 250kb
+				// 3. No Async Chunks
+				// if !1, then 2, if !2 return
+				if (assetsOverSizeLimit.length > 0) {
+					warnings.push(
+						new AssetsOverSizeLimitWarning(
+							assetsOverSizeLimit,
+							/** @type {number} */ (assetSizeLimit)
+						)
+					);
+				}
+				if (entrypointsOverLimit.length > 0) {
+					warnings.push(
+						new EntrypointsOverSizeLimitWarning(
+							entrypointsOverLimit,
+							/** @type {number} */ (entrypointSizeLimit)
+						)
+					);
+				}
+
+				if (warnings.length > 0) {
+					const someAsyncChunk = find(
+						compilation.chunks,
+						(chunk) => !chunk.canBeInitial()
+					);
+
+					if (!someAsyncChunk) {
+						warnings.push(new NoAsyncChunksWarning());
+					}
+
+					if (hints === "error") {
+						compilation.errors.push(...warnings);
+					} else {
+						compilation.warnings.push(...warnings);
+					}
+				}
+			}
+		});
+	}
+};
Index: frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {"prefetch" | "preload"} type "prefetch" or "preload" chunk type function
+	 * @param {string} runtimeFunction the runtime function name
+	 * @param {string} runtimeHandlers the runtime handlers
+	 */
+	constructor(type, runtimeFunction, runtimeHandlers) {
+		super(`chunk ${type} function`);
+		/** @type {string} */
+		this.runtimeFunction = runtimeFunction;
+		/** @type {string} */
+		this.runtimeHandlers = runtimeHandlers;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { runtimeFunction, runtimeHandlers } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		return Template.asString([
+			`${runtimeHandlers} = {};`,
+			`${runtimeFunction} = ${runtimeTemplate.basicFunction("chunkId", [
+				// map is shorter than forEach
+				`Object.keys(${runtimeHandlers}).map(${runtimeTemplate.basicFunction(
+					"key",
+					`${runtimeHandlers}[key](chunkId);`
+				)});`
+			])}`
+		]);
+	}
+}
+
+module.exports = ChunkPrefetchFunctionRuntimeModule;
Index: frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchPreloadPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchPreloadPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchPreloadPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,101 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const ChunkPrefetchFunctionRuntimeModule = require("./ChunkPrefetchFunctionRuntimeModule");
+const ChunkPrefetchStartupRuntimeModule = require("./ChunkPrefetchStartupRuntimeModule");
+const ChunkPrefetchTriggerRuntimeModule = require("./ChunkPrefetchTriggerRuntimeModule");
+const ChunkPreloadTriggerRuntimeModule = require("./ChunkPreloadTriggerRuntimeModule");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "ChunkPrefetchPreloadPlugin";
+
+/**
+ * Adds runtime support for chunk prefetch and preload relationships discovered
+ * in the chunk graph.
+ */
+class ChunkPrefetchPreloadPlugin {
+	/**
+	 * Registers compilation hooks that emit the runtime modules responsible for
+	 * scheduling chunk prefetch and preload requests.
+	 * @param {Compiler} compiler the compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.additionalChunkRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph }) => {
+					if (chunkGraph.getNumberOfEntryModules(chunk) === 0) return;
+					const startupChildChunks = chunk.getChildrenOfTypeInOrder(
+						chunkGraph,
+						"prefetchOrder"
+					);
+					if (startupChildChunks) {
+						set.add(RuntimeGlobals.prefetchChunk);
+						set.add(RuntimeGlobals.onChunksLoaded);
+						set.add(RuntimeGlobals.exports);
+						compilation.addRuntimeModule(
+							chunk,
+							new ChunkPrefetchStartupRuntimeModule(startupChildChunks)
+						);
+					}
+				}
+			);
+			compilation.hooks.additionalTreeRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph }) => {
+					const chunkMap = chunk.getChildIdsByOrdersMap(chunkGraph);
+
+					if (chunkMap.prefetch) {
+						set.add(RuntimeGlobals.prefetchChunk);
+						compilation.addRuntimeModule(
+							chunk,
+							new ChunkPrefetchTriggerRuntimeModule(chunkMap.prefetch)
+						);
+					}
+					if (chunkMap.preload) {
+						set.add(RuntimeGlobals.preloadChunk);
+						compilation.addRuntimeModule(
+							chunk,
+							new ChunkPreloadTriggerRuntimeModule(chunkMap.preload)
+						);
+					}
+				}
+			);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.prefetchChunk)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new ChunkPrefetchFunctionRuntimeModule(
+							"prefetch",
+							RuntimeGlobals.prefetchChunk,
+							RuntimeGlobals.prefetchChunkHandlers
+						)
+					);
+					set.add(RuntimeGlobals.prefetchChunkHandlers);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.preloadChunk)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					compilation.addRuntimeModule(
+						chunk,
+						new ChunkPrefetchFunctionRuntimeModule(
+							"preload",
+							RuntimeGlobals.preloadChunk,
+							RuntimeGlobals.preloadChunkHandlers
+						)
+					);
+					set.add(RuntimeGlobals.preloadChunkHandlers);
+				});
+		});
+	}
+}
+
+module.exports = ChunkPrefetchPreloadPlugin;
Index: frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,57 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkChildOfTypeInOrder} ChunkChildOfTypeInOrder */
+/** @typedef {import("../Compilation")} Compilation */
+
+class ChunkPrefetchStartupRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {ChunkChildOfTypeInOrder[]} startupChunks chunk ids to trigger when chunks are loaded
+	 */
+	constructor(startupChunks) {
+		super("startup prefetch", RuntimeModule.STAGE_TRIGGER);
+		/** @type {ChunkChildOfTypeInOrder[]} */
+		this.startupChunks = startupChunks;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { startupChunks } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { runtimeTemplate } = compilation;
+		return Template.asString(
+			startupChunks.map(
+				({ onChunks, chunks }) =>
+					`${RuntimeGlobals.onChunksLoaded}(0, ${JSON.stringify(
+						// This need to include itself to delay execution after this chunk has been fully loaded
+						onChunks.filter((c) => c === chunk).map((c) => c.id)
+					)}, ${runtimeTemplate.basicFunction(
+						"",
+						chunks.size < 3
+							? Array.from(
+									chunks,
+									(c) =>
+										`${RuntimeGlobals.prefetchChunk}(${JSON.stringify(c.id)});`
+								)
+							: `${JSON.stringify(Array.from(chunks, (c) => c.id))}.map(${
+									RuntimeGlobals.prefetchChunk
+								});`
+					)}, 5);`
+			)
+		);
+	}
+}
+
+module.exports = ChunkPrefetchStartupRuntimeModule;
Index: frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,56 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Chunk").ChunkChildIdsByOrdersMap} ChunkChildIdsByOrdersMap */
+
+class ChunkPrefetchTriggerRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {ChunkChildIdsByOrdersMap} chunkMap map from chunk to
+	 */
+	constructor(chunkMap) {
+		super("chunk prefetch trigger", RuntimeModule.STAGE_TRIGGER);
+		/** @type {ChunkChildIdsByOrdersMap} */
+		this.chunkMap = chunkMap;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { chunkMap } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const body = [
+			"var chunks = chunkToChildrenMap[chunkId];",
+			`Array.isArray(chunks) && chunks.map(${RuntimeGlobals.prefetchChunk});`
+		];
+		return Template.asString([
+			Template.asString([
+				`var chunkToChildrenMap = ${JSON.stringify(chunkMap, null, "\t")};`,
+				`${
+					RuntimeGlobals.ensureChunkHandlers
+				}.prefetch = ${runtimeTemplate.expressionFunction(
+					// Prefetch is best-effort; silence rejections so a failed chunk
+					// load (e.g. chunkLoadTimeout) doesn't surface as an unhandled
+					// rejection through this dangling Promise.all chain.
+					`Promise.all(promises).then(${runtimeTemplate.basicFunction(
+						"",
+						body
+					)}, ${runtimeTemplate.basicFunction("", "")})`,
+					"chunkId, promises"
+				)};`
+			])
+		]);
+	}
+}
+
+module.exports = ChunkPrefetchTriggerRuntimeModule;
Index: frontend/node_modules/webpack/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Chunk").ChunkChildIdsByOrdersMap} ChunkChildIdsByOrdersMap */
+
+class ChunkPreloadTriggerRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {ChunkChildIdsByOrdersMap} chunkMap map from chunk to chunks
+	 */
+	constructor(chunkMap) {
+		super("chunk preload trigger", RuntimeModule.STAGE_TRIGGER);
+		/** @type {ChunkChildIdsByOrdersMap} */
+		this.chunkMap = chunkMap;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { chunkMap } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const body = [
+			"var chunks = chunkToChildrenMap[chunkId];",
+			`Array.isArray(chunks) && chunks.map(${RuntimeGlobals.preloadChunk});`
+		];
+		return Template.asString([
+			Template.asString([
+				`var chunkToChildrenMap = ${JSON.stringify(chunkMap, null, "\t")};`,
+				`${
+					RuntimeGlobals.ensureChunkHandlers
+				}.preload = ${runtimeTemplate.basicFunction("chunkId", body)};`
+			])
+		]);
+	}
+}
+
+module.exports = ChunkPreloadTriggerRuntimeModule;
Index: frontend/node_modules/webpack/lib/rules/BasicEffectRulePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/rules/BasicEffectRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/rules/BasicEffectRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,59 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
+
+/**
+ * Defines the keys of types type used by this module.
+ * @template T
+ * @template {T[keyof T]} V
+ * @typedef {import("./RuleSetCompiler").KeysOfTypes<T, V>} KeysOfTypes
+ */
+
+/** @typedef {KeysOfTypes<RuleSetRule, string | boolean | { [k: string]: EXPECTED_ANY }>} BasicEffectRuleKeys */
+
+const PLUGIN_NAME = "BasicEffectRulePlugin";
+
+class BasicEffectRulePlugin {
+	/**
+	 * Creates an instance of BasicEffectRulePlugin.
+	 * @param {BasicEffectRuleKeys} ruleProperty the rule property
+	 * @param {string=} effectType the effect type
+	 */
+	constructor(ruleProperty, effectType) {
+		/** @type {BasicEffectRuleKeys} */
+		this.ruleProperty = ruleProperty;
+		/** @type {string | BasicEffectRuleKeys} */
+		this.effectType = effectType || ruleProperty;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {RuleSetCompiler} ruleSetCompiler the rule set compiler
+	 * @returns {void}
+	 */
+	apply(ruleSetCompiler) {
+		ruleSetCompiler.hooks.rule.tap(
+			PLUGIN_NAME,
+			(path, rule, unhandledProperties, result) => {
+				if (unhandledProperties.has(this.ruleProperty)) {
+					unhandledProperties.delete(this.ruleProperty);
+
+					const value = rule[this.ruleProperty];
+
+					result.effects.push({
+						type: this.effectType,
+						value
+					});
+				}
+			}
+		);
+	}
+}
+
+module.exports = BasicEffectRulePlugin;
Index: frontend/node_modules/webpack/lib/rules/BasicMatcherRulePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/rules/BasicMatcherRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/rules/BasicMatcherRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetConditionOrConditions} RuleSetConditionOrConditions */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetConditionOrConditionsAbsolute} RuleSetConditionOrConditionsAbsolute */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
+
+/**
+ * Defines the keys of types type used by this module.
+ * @template T
+ * @template {T[keyof T]} V
+ * @typedef {import("./RuleSetCompiler").KeysOfTypes<T, V>} KeysOfTypes
+ */
+
+/** @typedef {KeysOfTypes<RuleSetRule, RuleSetConditionOrConditions | RuleSetConditionOrConditionsAbsolute>} BasicMatcherRuleKeys */
+
+const PLUGIN_NAME = "BasicMatcherRulePlugin";
+
+class BasicMatcherRulePlugin {
+	/**
+	 * Creates an instance of BasicMatcherRulePlugin.
+	 * @param {BasicMatcherRuleKeys} ruleProperty the rule property
+	 * @param {string=} dataProperty the data property
+	 * @param {boolean=} invert if true, inverts the condition
+	 */
+	constructor(ruleProperty, dataProperty, invert) {
+		/** @type {BasicMatcherRuleKeys} */
+		this.ruleProperty = ruleProperty;
+		/** @type {string | BasicMatcherRuleKeys} */
+		this.dataProperty = dataProperty || ruleProperty;
+		/** @type {boolean} */
+		this.invert = invert || false;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {RuleSetCompiler} ruleSetCompiler the rule set compiler
+	 * @returns {void}
+	 */
+	apply(ruleSetCompiler) {
+		ruleSetCompiler.hooks.rule.tap(
+			PLUGIN_NAME,
+			(path, rule, unhandledProperties, result) => {
+				if (unhandledProperties.has(this.ruleProperty)) {
+					unhandledProperties.delete(this.ruleProperty);
+					const value = rule[this.ruleProperty];
+					const condition = ruleSetCompiler.compileCondition(
+						`${path}.${this.ruleProperty}`,
+						/** @type {RuleSetConditionOrConditions | RuleSetConditionOrConditionsAbsolute} */
+						(value)
+					);
+					const fn = condition.fn;
+					result.conditions.push({
+						property: this.dataProperty,
+						matchWhenEmpty: this.invert
+							? !condition.matchWhenEmpty
+							: condition.matchWhenEmpty,
+						fn: this.invert ? (v) => !fn(v) : fn
+					});
+				}
+			}
+		);
+	}
+}
+
+module.exports = BasicMatcherRulePlugin;
Index: frontend/node_modules/webpack/lib/rules/ObjectMatcherRulePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/rules/ObjectMatcherRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/rules/ObjectMatcherRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,82 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetConditionOrConditions} RuleSetConditionOrConditions */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
+/** @typedef {import("./RuleSetCompiler").EffectData} EffectData */
+/** @typedef {import("./RuleSetCompiler").RuleConditionFunction} RuleConditionFunction */
+
+/**
+ * Defines the keys of types type used by this module.
+ * @template T
+ * @template {T[keyof T]} V
+ * @typedef {import("./RuleSetCompiler").KeysOfTypes<T, V>} KeysOfTypes
+ */
+
+/** @typedef {KeysOfTypes<RuleSetRule, { [k: string]: RuleSetConditionOrConditions }>} ObjectMatcherRuleKeys */
+/** @typedef {keyof EffectData} DataProperty */
+
+const PLUGIN_NAME = "ObjectMatcherRulePlugin";
+
+class ObjectMatcherRulePlugin {
+	/**
+	 * Creates an instance of ObjectMatcherRulePlugin.
+	 * @param {ObjectMatcherRuleKeys} ruleProperty the rule property
+	 * @param {DataProperty=} dataProperty the data property
+	 * @param {RuleConditionFunction=} additionalConditionFunction need to check
+	 */
+	constructor(ruleProperty, dataProperty, additionalConditionFunction) {
+		/** @type {ObjectMatcherRuleKeys} */
+		this.ruleProperty = ruleProperty;
+		/** @type {DataProperty | ObjectMatcherRuleKeys} */
+		this.dataProperty = dataProperty || ruleProperty;
+		/** @type {RuleConditionFunction | undefined} */
+		this.additionalConditionFunction = additionalConditionFunction;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {RuleSetCompiler} ruleSetCompiler the rule set compiler
+	 * @returns {void}
+	 */
+	apply(ruleSetCompiler) {
+		const { ruleProperty, dataProperty } = this;
+		ruleSetCompiler.hooks.rule.tap(
+			PLUGIN_NAME,
+			(path, rule, unhandledProperties, result) => {
+				if (unhandledProperties.has(ruleProperty)) {
+					unhandledProperties.delete(ruleProperty);
+					const value =
+						/** @type {Record<string, RuleSetConditionOrConditions>} */
+						(rule[ruleProperty]);
+					for (const property of Object.keys(value)) {
+						const nestedDataProperties = property.split(".");
+						const condition = ruleSetCompiler.compileCondition(
+							`${path}.${ruleProperty}.${property}`,
+							value[property]
+						);
+						if (this.additionalConditionFunction) {
+							result.conditions.push({
+								property: [dataProperty],
+								matchWhenEmpty: condition.matchWhenEmpty,
+								fn: this.additionalConditionFunction
+							});
+						}
+						result.conditions.push({
+							property: [dataProperty, ...nestedDataProperties],
+							matchWhenEmpty: condition.matchWhenEmpty,
+							fn: condition.fn
+						});
+					}
+				}
+			}
+		);
+	}
+}
+
+module.exports = ObjectMatcherRulePlugin;
Index: frontend/node_modules/webpack/lib/rules/RuleSetCompiler.js
===================================================================
--- frontend/node_modules/webpack/lib/rules/RuleSetCompiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/rules/RuleSetCompiler.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,466 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncHook } = require("tapable");
+
+/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
+/** @typedef {import("../../declarations/WebpackOptions").Falsy} Falsy */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoaderOptions} RuleSetLoaderOptions */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+
+/** @typedef {(Falsy | RuleSetRule)[]} RuleSetRules */
+
+/**
+ * Defines the rule condition function type used by this module.
+ * @typedef {(value: EffectData[keyof EffectData]) => boolean} RuleConditionFunction
+ */
+
+/**
+ * Defines the rule condition type used by this module.
+ * @typedef {object} RuleCondition
+ * @property {string | string[]} property
+ * @property {boolean} matchWhenEmpty
+ * @property {RuleConditionFunction} fn
+ */
+
+/**
+ * Defines the condition type used by this module.
+ * @typedef {object} Condition
+ * @property {boolean} matchWhenEmpty
+ * @property {RuleConditionFunction} fn
+ */
+
+/**
+ * Defines the effect data type used by this module.
+ * @typedef {object} EffectData
+ * @property {string=} resource
+ * @property {string=} realResource
+ * @property {string=} resourceQuery
+ * @property {string=} resourceFragment
+ * @property {string=} scheme
+ * @property {ImportAttributes=} attributes
+ * @property {string=} mimetype
+ * @property {string} dependency
+ * @property {ResolveRequest["descriptionFileData"]=} descriptionData
+ * @property {string=} compiler
+ * @property {string} issuer
+ * @property {string} issuerLayer
+ * @property {string=} phase
+ */
+
+/**
+ * Defines the compiled rule type used by this module.
+ * @typedef {object} CompiledRule
+ * @property {RuleCondition[]} conditions
+ * @property {(Effect | ((effectData: EffectData) => Effect[]))[]} effects
+ * @property {CompiledRule[]=} rules
+ * @property {CompiledRule[]=} oneOf
+ */
+
+/** @typedef {"use" | "use-pre" | "use-post"} EffectUseType */
+
+/**
+ * Defines the effect use type used by this module.
+ * @typedef {object} EffectUse
+ * @property {EffectUseType} type
+ * @property {{ loader: string, options?: string | null | Record<string, EXPECTED_ANY>, ident?: string }} value
+ */
+
+/**
+ * Defines the effect basic type used by this module.
+ * @typedef {object} EffectBasic
+ * @property {string} type
+ * @property {EXPECTED_ANY} value
+ */
+
+/** @typedef {EffectUse | EffectBasic} Effect */
+
+/** @typedef {Map<string, RuleSetLoaderOptions>} References */
+
+/**
+ * Defines the rule set type used by this module.
+ * @typedef {object} RuleSet
+ * @property {References} references map of references in the rule set (may grow over time)
+ * @property {(effectData: EffectData) => Effect[]} exec execute the rule set
+ */
+
+/**
+ * Defines the keys of types type used by this module.
+ * @template T
+ * @template {T[keyof T]} V
+ * @typedef {({ [key in keyof Required<T>]: Required<T>[key] extends V ? key : never })[keyof T]} KeysOfTypes
+ */
+
+/** @typedef {Set<string>} UnhandledProperties */
+
+/** @typedef {(data: EffectData) => (RuleSetUseItem | (Falsy | RuleSetUseItem)[])} RuleSetUseFn */
+/** @typedef {(value: string) => boolean} RuleSetConditionFn */
+
+/** @typedef {{ apply: (ruleSetCompiler: RuleSetCompiler) => void }} RuleSetPlugin */
+
+class RuleSetCompiler {
+	/**
+	 * Creates an instance of RuleSetCompiler.
+	 * @param {RuleSetPlugin[]} plugins plugins
+	 */
+	constructor(plugins) {
+		this.hooks = Object.freeze({
+			/** @type {SyncHook<[string, RuleSetRule, UnhandledProperties, CompiledRule, References]>} */
+			rule: new SyncHook([
+				"path",
+				"rule",
+				"unhandledProperties",
+				"compiledRule",
+				"references"
+			])
+		});
+		if (plugins) {
+			for (const plugin of plugins) {
+				plugin.apply(this);
+			}
+		}
+	}
+
+	/**
+	 * Returns compiled RuleSet.
+	 * @param {RuleSetRules} ruleSet raw user provided rules
+	 * @returns {RuleSet} compiled RuleSet
+	 */
+	compile(ruleSet) {
+		/** @type {References} */
+		const refs = new Map();
+		const rules = this.compileRules("ruleSet", ruleSet, refs);
+
+		/**
+		 * Returns true, if the rule has matched.
+		 * @param {EffectData} data data passed in
+		 * @param {CompiledRule} rule the compiled rule
+		 * @param {Effect[]} effects an array where effects are pushed to
+		 * @returns {boolean} true, if the rule has matched
+		 */
+		const execRule = (data, rule, effects) => {
+			for (const condition of rule.conditions) {
+				const p = condition.property;
+				if (Array.isArray(p)) {
+					/** @type {EXPECTED_ANY} */
+					let current = data;
+					for (const subProperty of p) {
+						if (
+							current &&
+							typeof current === "object" &&
+							Object.prototype.hasOwnProperty.call(current, subProperty)
+						) {
+							current = current[/** @type {keyof EffectData} */ (subProperty)];
+						} else {
+							current = undefined;
+							break;
+						}
+					}
+					if (current !== undefined) {
+						if (!condition.fn(current)) return false;
+						continue;
+					}
+				} else if (p in data) {
+					const value = data[/** @type {keyof EffectData} */ (p)];
+					if (value !== undefined) {
+						if (!condition.fn(value)) return false;
+						continue;
+					}
+				}
+				if (!condition.matchWhenEmpty) {
+					return false;
+				}
+			}
+			for (const effect of rule.effects) {
+				if (typeof effect === "function") {
+					const returnedEffects = effect(data);
+					for (const effect of returnedEffects) {
+						effects.push(effect);
+					}
+				} else {
+					effects.push(effect);
+				}
+			}
+			if (rule.rules) {
+				for (const childRule of rule.rules) {
+					execRule(data, childRule, effects);
+				}
+			}
+			if (rule.oneOf) {
+				for (const childRule of rule.oneOf) {
+					if (execRule(data, childRule, effects)) {
+						break;
+					}
+				}
+			}
+			return true;
+		};
+
+		return {
+			references: refs,
+			exec: (data) => {
+				/** @type {Effect[]} */
+				const effects = [];
+				for (const rule of rules) {
+					execRule(data, rule, effects);
+				}
+				return effects;
+			}
+		};
+	}
+
+	/**
+	 * Returns rules.
+	 * @param {string} path current path
+	 * @param {RuleSetRules} rules the raw rules provided by user
+	 * @param {References} refs references
+	 * @returns {CompiledRule[]} rules
+	 */
+	compileRules(path, rules, refs) {
+		return rules
+			.filter(Boolean)
+			.map((rule, i) =>
+				this.compileRule(
+					`${path}[${i}]`,
+					/** @type {RuleSetRule} */ (rule),
+					refs
+				)
+			);
+	}
+
+	/**
+	 * Returns normalized and compiled rule for processing.
+	 * @param {string} path current path
+	 * @param {RuleSetRule} rule the raw rule provided by user
+	 * @param {References} refs references
+	 * @returns {CompiledRule} normalized and compiled rule for processing
+	 */
+	compileRule(path, rule, refs) {
+		/** @type {UnhandledProperties} */
+		const unhandledProperties = new Set(
+			Object.keys(rule).filter(
+				(key) => rule[/** @type {keyof RuleSetRule} */ (key)] !== undefined
+			)
+		);
+
+		/** @type {CompiledRule} */
+		const compiledRule = {
+			conditions: [],
+			effects: [],
+			rules: undefined,
+			oneOf: undefined
+		};
+
+		this.hooks.rule.call(path, rule, unhandledProperties, compiledRule, refs);
+
+		if (unhandledProperties.has("rules")) {
+			unhandledProperties.delete("rules");
+			const rules = rule.rules;
+			if (!Array.isArray(rules)) {
+				throw this.error(path, rules, "Rule.rules must be an array of rules");
+			}
+			compiledRule.rules = this.compileRules(`${path}.rules`, rules, refs);
+		}
+
+		if (unhandledProperties.has("oneOf")) {
+			unhandledProperties.delete("oneOf");
+			const oneOf = rule.oneOf;
+			if (!Array.isArray(oneOf)) {
+				throw this.error(path, oneOf, "Rule.oneOf must be an array of rules");
+			}
+			compiledRule.oneOf = this.compileRules(`${path}.oneOf`, oneOf, refs);
+		}
+
+		if (unhandledProperties.size > 0) {
+			throw this.error(
+				path,
+				rule,
+				`Properties ${[...unhandledProperties].join(", ")} are unknown`
+			);
+		}
+
+		return compiledRule;
+	}
+
+	/**
+	 * Returns compiled condition.
+	 * @param {string} path current path
+	 * @param {RuleSetLoaderOptions} condition user provided condition value
+	 * @returns {Condition} compiled condition
+	 */
+	compileCondition(path, condition) {
+		if (condition === "") {
+			return {
+				matchWhenEmpty: true,
+				fn: (str) => str === ""
+			};
+		}
+		if (!condition) {
+			throw this.error(
+				path,
+				condition,
+				"Expected condition but got falsy value"
+			);
+		}
+		if (typeof condition === "string") {
+			return {
+				matchWhenEmpty: condition.length === 0,
+				fn: (str) => typeof str === "string" && str.startsWith(condition)
+			};
+		}
+		if (typeof condition === "function") {
+			try {
+				return {
+					matchWhenEmpty: condition(""),
+					fn: /** @type {RuleConditionFunction} */ (condition)
+				};
+			} catch (_err) {
+				throw this.error(
+					path,
+					condition,
+					"Evaluation of condition function threw error"
+				);
+			}
+		}
+		if (condition instanceof RegExp) {
+			return {
+				matchWhenEmpty: condition.test(""),
+				fn: (v) => typeof v === "string" && condition.test(v)
+			};
+		}
+		if (Array.isArray(condition)) {
+			const items = condition.map((c, i) =>
+				this.compileCondition(`${path}[${i}]`, c)
+			);
+			return this.combineConditionsOr(items);
+		}
+
+		if (typeof condition !== "object") {
+			throw this.error(
+				path,
+				condition,
+				`Unexpected ${typeof condition} when condition was expected`
+			);
+		}
+
+		/** @type {Condition[]} */
+		const conditions = [];
+		for (const key of Object.keys(condition)) {
+			const value = condition[key];
+			switch (key) {
+				case "or":
+					if (value) {
+						if (!Array.isArray(value)) {
+							throw this.error(
+								`${path}.or`,
+								condition.or,
+								"Expected array of conditions"
+							);
+						}
+						conditions.push(this.compileCondition(`${path}.or`, value));
+					}
+					break;
+				case "and":
+					if (value) {
+						if (!Array.isArray(value)) {
+							throw this.error(
+								`${path}.and`,
+								condition.and,
+								"Expected array of conditions"
+							);
+						}
+						let i = 0;
+						for (const item of value) {
+							conditions.push(this.compileCondition(`${path}.and[${i}]`, item));
+							i++;
+						}
+					}
+					break;
+				case "not":
+					if (value) {
+						const matcher = this.compileCondition(`${path}.not`, value);
+						const fn = matcher.fn;
+						conditions.push({
+							matchWhenEmpty: !matcher.matchWhenEmpty,
+							fn: /** @type {RuleConditionFunction} */ ((v) => !fn(v))
+						});
+					}
+					break;
+				default:
+					throw this.error(
+						`${path}.${key}`,
+						condition[key],
+						`Unexpected property ${key} in condition`
+					);
+			}
+		}
+		if (conditions.length === 0) {
+			throw this.error(
+				path,
+				condition,
+				"Expected condition, but got empty thing"
+			);
+		}
+		return this.combineConditionsAnd(conditions);
+	}
+
+	/**
+	 * Combine conditions or.
+	 * @param {Condition[]} conditions some conditions
+	 * @returns {Condition} merged condition
+	 */
+	combineConditionsOr(conditions) {
+		if (conditions.length === 0) {
+			return {
+				matchWhenEmpty: false,
+				fn: () => false
+			};
+		} else if (conditions.length === 1) {
+			return conditions[0];
+		}
+		return {
+			matchWhenEmpty: conditions.some((c) => c.matchWhenEmpty),
+			fn: (v) => conditions.some((c) => c.fn(v))
+		};
+	}
+
+	/**
+	 * Combine conditions and.
+	 * @param {Condition[]} conditions some conditions
+	 * @returns {Condition} merged condition
+	 */
+	combineConditionsAnd(conditions) {
+		if (conditions.length === 0) {
+			return {
+				matchWhenEmpty: false,
+				fn: () => false
+			};
+		} else if (conditions.length === 1) {
+			return conditions[0];
+		}
+		return {
+			matchWhenEmpty: conditions.every((c) => c.matchWhenEmpty),
+			fn: (v) => conditions.every((c) => c.fn(v))
+		};
+	}
+
+	/**
+	 * Returns an error object.
+	 * @param {string} path current path
+	 * @param {EXPECTED_ANY} value value at the error location
+	 * @param {string} message message explaining the problem
+	 * @returns {Error} an error object
+	 */
+	error(path, value, message) {
+		return new Error(
+			`Compiling RuleSet failed: ${message} (at ${path}: ${value})`
+		);
+	}
+}
+
+module.exports = RuleSetCompiler;
Index: frontend/node_modules/webpack/lib/rules/UseEffectRulePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/rules/UseEffectRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/rules/UseEffectRulePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,243 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+
+/** @typedef {import("../../declarations/WebpackOptions").Falsy} Falsy */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoader} RuleSetLoader */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoaderOptions} RuleSetLoaderOptions */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetUse} RuleSetUse */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */
+/** @typedef {import("../../declarations/WebpackOptions").RuleSetUseFunction} RuleSetUseFunction */
+/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
+/** @typedef {import("./RuleSetCompiler").Effect} Effect */
+/** @typedef {import("./RuleSetCompiler").EffectData} EffectData */
+/** @typedef {import("./RuleSetCompiler").EffectUseType} EffectUseType */
+
+const PLUGIN_NAME = "UseEffectRulePlugin";
+
+class UseEffectRulePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {RuleSetCompiler} ruleSetCompiler the rule set compiler
+	 * @returns {void}
+	 */
+	apply(ruleSetCompiler) {
+		ruleSetCompiler.hooks.rule.tap(
+			PLUGIN_NAME,
+			(path, rule, unhandledProperties, result, references) => {
+				/**
+				 * Processes the provided property.
+				 * @param {keyof RuleSetRule} property property
+				 * @param {string} correctProperty correct property
+				 */
+				const conflictWith = (property, correctProperty) => {
+					if (unhandledProperties.has(property)) {
+						throw ruleSetCompiler.error(
+							`${path}.${property}`,
+							rule[property],
+							`A Rule must not have a '${property}' property when it has a '${correctProperty}' property`
+						);
+					}
+				};
+
+				if (unhandledProperties.has("use")) {
+					unhandledProperties.delete("use");
+					unhandledProperties.delete("enforce");
+
+					conflictWith("loader", "use");
+					conflictWith("options", "use");
+
+					const use = /** @type {RuleSetUse} */ (rule.use);
+					const enforce = rule.enforce;
+
+					const type =
+						/** @type {EffectUseType} */
+						(enforce ? `use-${enforce}` : "use");
+
+					/**
+					 * Returns effect.
+					 * @param {string} path options path
+					 * @param {string} defaultIdent default ident when none is provided
+					 * @param {RuleSetUseItem} item user provided use value
+					 * @returns {(Effect | ((effectData: EffectData) => Effect[]))} effect
+					 */
+					const useToEffect = (path, defaultIdent, item) => {
+						if (typeof item === "function") {
+							return (data) =>
+								useToEffectsWithoutIdent(
+									path,
+									/** @type {RuleSetUseItem | RuleSetUseItem[]} */
+									(item(data))
+								);
+						}
+						return useToEffectRaw(path, defaultIdent, item);
+					};
+
+					/**
+					 * Returns effect.
+					 * @param {string} path options path
+					 * @param {string} defaultIdent default ident when none is provided
+					 * @param {Exclude<NonNullable<RuleSetUseItem>, RuleSetUseFunction>} item user provided use value
+					 * @returns {Effect} effect
+					 */
+					const useToEffectRaw = (path, defaultIdent, item) => {
+						if (typeof item === "string") {
+							return {
+								type,
+								value: {
+									loader: item,
+									options: undefined,
+									ident: undefined
+								}
+							};
+						}
+						const loader = /** @type {string} */ (item.loader);
+						const options = item.options;
+						let ident = item.ident;
+						if (options && typeof options === "object") {
+							if (!ident) ident = defaultIdent;
+							references.set(ident, options);
+						}
+						if (typeof options === "string") {
+							util.deprecate(
+								() => {},
+								`Using a string as loader options is deprecated (${path}.options)`,
+								"DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING"
+							)();
+						}
+						return {
+							type: enforce ? `use-${enforce}` : "use",
+							value: {
+								loader,
+								options,
+								ident
+							}
+						};
+					};
+
+					/**
+					 * Use to effects without ident.
+					 * @param {string} path options path
+					 * @param {RuleSetUseItem | (Falsy | RuleSetUseItem)[]} items user provided use value
+					 * @returns {Effect[]} effects
+					 */
+					const useToEffectsWithoutIdent = (path, items) => {
+						if (Array.isArray(items)) {
+							return items.filter(Boolean).map((item, idx) =>
+								useToEffectRaw(
+									`${path}[${idx}]`,
+									"[[missing ident]]",
+									/** @type {Exclude<RuleSetUseItem, RuleSetUseFunction>} */
+									(item)
+								)
+							);
+						}
+						return [
+							useToEffectRaw(
+								path,
+								"[[missing ident]]",
+								/** @type {Exclude<RuleSetUseItem, RuleSetUseFunction>} */
+								(items)
+							)
+						];
+					};
+
+					/**
+					 * Returns effects.
+					 * @param {string} path current path
+					 * @param {RuleSetUse} items user provided use value
+					 * @returns {(Effect | ((effectData: EffectData) => Effect[]))[]} effects
+					 */
+					const useToEffects = (path, items) => {
+						if (Array.isArray(items)) {
+							return items.filter(Boolean).map((item, idx) => {
+								const subPath = `${path}[${idx}]`;
+								return useToEffect(
+									subPath,
+									subPath,
+									/** @type {RuleSetUseItem} */
+									(item)
+								);
+							});
+						}
+						return [
+							useToEffect(path, path, /** @type {RuleSetUseItem} */ (items))
+						];
+					};
+
+					if (typeof use === "function") {
+						result.effects.push((data) =>
+							useToEffectsWithoutIdent(`${path}.use`, use(data))
+						);
+					} else {
+						for (const effect of useToEffects(`${path}.use`, use)) {
+							result.effects.push(effect);
+						}
+					}
+				}
+
+				if (unhandledProperties.has("loader")) {
+					unhandledProperties.delete("loader");
+					unhandledProperties.delete("options");
+					unhandledProperties.delete("enforce");
+
+					const loader = /** @type {RuleSetLoader} */ (rule.loader);
+					const options = rule.options;
+					const enforce = rule.enforce;
+
+					if (loader.includes("!")) {
+						throw ruleSetCompiler.error(
+							`${path}.loader`,
+							loader,
+							"Exclamation mark separated loader lists has been removed in favor of the 'use' property with arrays"
+						);
+					}
+
+					if (loader.includes("?")) {
+						throw ruleSetCompiler.error(
+							`${path}.loader`,
+							loader,
+							"Query arguments on 'loader' has been removed in favor of the 'options' property"
+						);
+					}
+
+					if (typeof options === "string") {
+						util.deprecate(
+							() => {},
+							`Using a string as loader options is deprecated (${path}.options)`,
+							"DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING"
+						)();
+					}
+
+					const ident =
+						options && typeof options === "object" ? path : undefined;
+
+					if (ident) {
+						references.set(
+							ident,
+							/** @type {RuleSetLoaderOptions} */
+							(options)
+						);
+					}
+
+					result.effects.push({
+						type: enforce ? `use-${enforce}` : "use",
+						value: {
+							loader,
+							options,
+							ident
+						}
+					});
+				}
+			}
+		);
+	}
+}
+
+module.exports = UseEffectRulePlugin;
Index: frontend/node_modules/webpack/lib/runtime/AsyncModuleRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/AsyncModuleRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/AsyncModuleRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,200 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class AsyncModuleRuntimeModule extends HelperRuntimeModule {
+	/**
+	 * @param {boolean=} deferInterop if defer import is used.
+	 */
+	constructor(deferInterop = false) {
+		super("async module");
+		/** @type {boolean} */
+		this._deferInterop = deferInterop;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.asyncModule;
+		const defer = this._deferInterop;
+		return Template.asString([
+			'var hasSymbol = typeof Symbol === "function";',
+			'var webpackQueues = hasSymbol ? Symbol("webpack queues") : "__webpack_queues__";',
+			`var webpackExports = ${
+				defer ? `${RuntimeGlobals.asyncModuleExportSymbol}= ` : ""
+			}hasSymbol ? Symbol("webpack exports") : "${RuntimeGlobals.exports}";`,
+			'var webpackError = hasSymbol ? Symbol("webpack error") : "__webpack_error__";',
+			defer
+				? Template.asString([
+						`var webpackDone = ${RuntimeGlobals.asyncModuleDoneSymbol} = hasSymbol ? Symbol("webpack done") : "__webpack_done__";`,
+						`var webpackDefer = ${RuntimeGlobals.deferredModuleAsyncTransitiveDependenciesSymbol} = hasSymbol ? Symbol("webpack defer") : "__webpack_defer__";`,
+						`${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies} = ${runtimeTemplate.basicFunction(
+							"asyncDeps",
+							[
+								Template.indent([
+									"var hasUnresolvedAsyncSubgraph = asyncDeps.some((id) => {",
+									Template.indent([
+										"var cache = __webpack_module_cache__[id];",
+										"return !cache || cache[webpackDone] === false;"
+									]),
+									"});",
+									"if (hasUnresolvedAsyncSubgraph) {",
+									Template.indent([
+										"return ({ then(onFulfilled, onRejected) { return Promise.all(asyncDeps.map(__webpack_require__)).then(onFulfilled, onRejected) } })"
+									]),
+									"}"
+								])
+							]
+						)}`
+					])
+				: "",
+			`var resolveQueue = ${runtimeTemplate.basicFunction("queue", [
+				"if(queue && queue.d < 1) {",
+				Template.indent([
+					"queue.d = 1;",
+					`queue.forEach(${runtimeTemplate.expressionFunction(
+						"fn.r--",
+						"fn"
+					)});`,
+					`queue.forEach(${runtimeTemplate.expressionFunction(
+						"fn.r-- ? fn.r++ : fn()",
+						"fn"
+					)});`
+				]),
+				"}"
+			])}`,
+			`var wrapDeps = ${runtimeTemplate.returningFunction(
+				`deps.map(${runtimeTemplate.basicFunction("dep", [
+					'if(dep !== null && typeof dep === "object") {',
+					Template.indent([
+						defer
+							? Template.asString([
+									"if(!dep[webpackQueues] && dep[webpackDefer]) {",
+									Template.indent([
+										`var asyncDeps = ${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies}(dep[webpackDefer]);`,
+										"if (asyncDeps) {",
+										Template.indent([
+											"var d = dep;",
+											"dep = {",
+											Template.indent([
+												"then(onFulfilled, onRejected) {",
+												Template.indent([
+													`asyncDeps.then(${runtimeTemplate.returningFunction(
+														"onFulfilled(d)"
+													)}, onRejected);`
+												]),
+												"}"
+											]),
+											"};"
+										]),
+										"} else return dep;"
+									]),
+									"}"
+								])
+							: "",
+						"if(dep[webpackQueues]) return dep;",
+						"if(dep.then) {",
+						Template.indent([
+							"var queue = [];",
+							"queue.d = 0;",
+							`dep.then(${runtimeTemplate.basicFunction("r", [
+								"obj[webpackExports] = r;",
+								"resolveQueue(queue);"
+							])}, ${runtimeTemplate.basicFunction("e", [
+								"obj[webpackError] = e;",
+								"resolveQueue(queue);"
+							])});`,
+							"var obj = {};",
+							defer ? "obj[webpackDefer] = false;" : "",
+							`obj[webpackQueues] = ${runtimeTemplate.expressionFunction(
+								"fn(queue)",
+								"fn"
+							)};`,
+							"return obj;"
+						]),
+						"}"
+					]),
+					"}",
+					"var ret = {};",
+					`ret[webpackQueues] = ${runtimeTemplate.emptyFunction()};`,
+					"ret[webpackExports] = dep;",
+					"return ret;"
+				])})`,
+				"deps"
+			)};`,
+			`${fn} = ${runtimeTemplate.basicFunction("module, body, hasAwait", [
+				"var queue;",
+				"hasAwait && ((queue = []).d = -1);",
+				"var depQueues = new Set();",
+				"var exports = module.exports;",
+				"var currentDeps;",
+				"var outerResolve;",
+				"var reject;",
+				`var promise = new Promise(${runtimeTemplate.basicFunction(
+					"resolve, rej",
+					["reject = rej;", "outerResolve = resolve;"]
+				)});`,
+				"promise[webpackExports] = exports;",
+				`promise[webpackQueues] = ${runtimeTemplate.expressionFunction(
+					`queue && fn(queue), depQueues.forEach(fn), promise["catch"](${runtimeTemplate.emptyFunction()})`,
+					"fn"
+				)};`,
+				"module.exports = promise;",
+				`var handle = ${runtimeTemplate.basicFunction("deps", [
+					"currentDeps = wrapDeps(deps);",
+					"var fn;",
+					`var getResult = ${runtimeTemplate.returningFunction(
+						`currentDeps.map(${runtimeTemplate.basicFunction("d", [
+							defer ? "if(d[webpackDefer]) return d;" : "",
+							"if(d[webpackError]) throw d[webpackError];",
+							"return d[webpackExports];"
+						])})`
+					)}`,
+					`var promise = new Promise(${runtimeTemplate.basicFunction(
+						"resolve",
+						[
+							`fn = ${runtimeTemplate.expressionFunction(
+								"resolve(getResult)",
+								""
+							)};`,
+							"fn.r = 0;",
+							`var fnQueue = ${runtimeTemplate.expressionFunction(
+								"q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))",
+								"q"
+							)};`,
+							`currentDeps.map(${runtimeTemplate.expressionFunction(
+								`${
+									defer ? "dep[webpackDefer]||" : ""
+								}dep[webpackQueues](fnQueue)`,
+								"dep"
+							)});`
+						]
+					)});`,
+					"return fn.r ? promise : getResult();"
+				])}`,
+				`var done = ${runtimeTemplate.expressionFunction(
+					`(err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)${
+						defer ? ", promise[webpackDone] = true" : ""
+					}`,
+					"err"
+				)}`,
+				"body(handle, done);",
+				"queue && queue.d < 0 && (queue.d = 0);"
+			])};`
+		]);
+	}
+}
+
+module.exports = AsyncModuleRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+
+class AutoPublicPathRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("publicPath", RuntimeModule.STAGE_BASIC);
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { scriptType, importMetaName, path, environment } =
+			compilation.outputOptions;
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const chunkName = compilation.getPath(
+			JavascriptModulesPlugin.getChunkFilenameTemplate(
+				chunk,
+				compilation.outputOptions
+			),
+			{
+				chunk,
+				contentHashType: "javascript"
+			}
+		);
+		const undoPath = getUndoPath(
+			chunkName,
+			/** @type {string} */ (path),
+			false
+		);
+
+		const global = environment.globalThis
+			? "globalThis"
+			: RuntimeGlobals.global;
+
+		return Template.asString([
+			"var scriptUrl;",
+			scriptType === "module"
+				? `if (typeof ${importMetaName}.url === "string") scriptUrl = ${importMetaName}.url`
+				: Template.asString([
+						`if (${global}.importScripts) scriptUrl = ${global}.location + "";`,
+						`var document = ${global}.document;`,
+						"if (!scriptUrl && document) {",
+						Template.indent([
+							// Technically we could use `document.currentScript instanceof window.HTMLScriptElement`,
+							// but an attacker could try to inject `<script>HTMLScriptElement = HTMLImageElement</script>`
+							// and use `<img name="currentScript" src="https://attacker.controlled.server/"></img>`
+							"if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')",
+							Template.indent("scriptUrl = document.currentScript.src;"),
+							"if (!scriptUrl) {",
+							Template.indent([
+								'var scripts = document.getElementsByTagName("script");',
+								"if(scripts.length) {",
+								Template.indent([
+									"var i = scripts.length - 1;",
+									"while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;"
+								]),
+								"}"
+							]),
+							"}"
+						]),
+						"}"
+					]),
+			"// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration",
+			'// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.',
+			'if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");',
+			'scriptUrl = scriptUrl.replace(/^blob:/, "").replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");',
+			!undoPath
+				? `${RuntimeGlobals.publicPath} = scriptUrl;`
+				: `${RuntimeGlobals.publicPath} = scriptUrl + ${JSON.stringify(
+						undoPath
+					)};`
+		]);
+	}
+}
+
+module.exports = AutoPublicPathRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/BaseUriRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/BaseUriRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/BaseUriRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+/** @typedef {import("../../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescription */
+/** @typedef {import("../Chunk")} Chunk */
+
+class BaseUriRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("base uri", RuntimeModule.STAGE_ATTACH);
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const options =
+			/** @type {EntryDescription} */
+			(chunk.getEntryOptions());
+		return `${RuntimeGlobals.baseURI} = ${
+			options.baseUri === undefined
+				? "undefined"
+				: JSON.stringify(options.baseUri)
+		};`;
+	}
+}
+
+module.exports = BaseUriRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/ChunkNameRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/ChunkNameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/ChunkNameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,29 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+class ChunkNameRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {string} chunkName the chunk's name
+	 */
+	constructor(chunkName) {
+		super("chunkName");
+		/** @type {string} */
+		this.chunkName = chunkName;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return `${RuntimeGlobals.chunkName} = ${JSON.stringify(this.chunkName)};`;
+	}
+}
+
+module.exports = ChunkNameRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/CompatGetDefaultExportRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/CompatGetDefaultExportRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/CompatGetDefaultExportRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class CompatGetDefaultExportRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("compat get default export");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.compatGetDefaultExport;
+		return Template.asString([
+			"// getDefaultExport function for compatibility with non-harmony modules",
+			`${fn} = ${runtimeTemplate.basicFunction("module", [
+				"var getter = module && module.__esModule ?",
+				Template.indent([
+					`${runtimeTemplate.returningFunction("module['default']")} :`,
+					`${runtimeTemplate.returningFunction("module")};`
+				]),
+				`${RuntimeGlobals.definePropertyGetters}(getter, { a: getter });`,
+				"return getter;"
+			])};`
+		]);
+	}
+}
+
+module.exports = CompatGetDefaultExportRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/CompatRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/CompatRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/CompatRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+
+class CompatRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("compat", RuntimeModule.STAGE_ATTACH);
+		/** @type {boolean} */
+		this.fullHash = true;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const {
+			runtimeTemplate,
+			mainTemplate,
+			moduleTemplates,
+			dependencyTemplates
+		} = compilation;
+		const bootstrap = mainTemplate.hooks.bootstrap.call(
+			"",
+			chunk,
+			compilation.hash || "XXXX",
+			moduleTemplates.javascript,
+			dependencyTemplates
+		);
+		const localVars = mainTemplate.hooks.localVars.call(
+			"",
+			chunk,
+			compilation.hash || "XXXX"
+		);
+		const requireExtensions = mainTemplate.hooks.requireExtensions.call(
+			"",
+			chunk,
+			compilation.hash || "XXXX"
+		);
+		const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
+		let requireEnsure = "";
+		if (runtimeRequirements.has(RuntimeGlobals.ensureChunk)) {
+			const requireEnsureHandler = mainTemplate.hooks.requireEnsure.call(
+				"",
+				chunk,
+				compilation.hash || "XXXX",
+				"chunkId"
+			);
+			if (requireEnsureHandler) {
+				requireEnsure = `${
+					RuntimeGlobals.ensureChunkHandlers
+				}.compat = ${runtimeTemplate.basicFunction(
+					"chunkId, promises",
+					requireEnsureHandler
+				)};`;
+			}
+		}
+		return [bootstrap, localVars, requireEnsure, requireExtensions]
+			.filter(Boolean)
+			.join("\n");
+	}
+
+	/**
+	 * Returns true, if the runtime module should get it's own scope.
+	 * @returns {boolean} true, if the runtime module should get it's own scope
+	 */
+	shouldIsolate() {
+		// We avoid isolating this to have better backward-compat
+		return false;
+	}
+}
+
+module.exports = CompatRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class CreateFakeNamespaceObjectRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("create fake namespace object");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.createFakeNamespaceObject;
+		return Template.asString([
+			`var getProto = Object.getPrototypeOf ? ${runtimeTemplate.returningFunction(
+				"Object.getPrototypeOf(obj)",
+				"obj"
+			)} : ${runtimeTemplate.returningFunction("obj.__proto__", "obj")};`,
+			"var leafPrototypes;",
+			"// create a fake namespace object",
+			"// mode & 1: value is a module id, require it",
+			"// mode & 2: merge all properties of value into the ns",
+			"// mode & 4: return value when already ns object",
+			"// mode & 16: return value when it's Promise-like",
+			"// mode & 8|1: behave like require",
+			// Note: must be a function (not arrow), because this is used in body!
+			`${fn} = function(value, mode) {`,
+			Template.indent([
+				"if(mode & 1) value = this(value);",
+				"if(mode & 8) return value;",
+				"if(typeof value === 'object' && value) {",
+				Template.indent([
+					"if((mode & 4) && value.__esModule) return value;",
+					"if((mode & 16) && typeof value.then === 'function') return value;"
+				]),
+				"}",
+				"var ns = Object.create(null);",
+				`${RuntimeGlobals.makeNamespaceObject}(ns);`,
+				"var def = {};",
+				"leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];",
+				"for(var current = mode & 2 && value; (typeof current == 'object' || typeof current == 'function') && !~leafPrototypes.indexOf(current); current = getProto(current)) {",
+				Template.indent([
+					`Object.getOwnPropertyNames(current).forEach(${runtimeTemplate.expressionFunction(
+						`def[key] = ${runtimeTemplate.returningFunction("value[key]", "")}`,
+						"key"
+					)});`
+				]),
+				"}",
+				`def['default'] = ${runtimeTemplate.returningFunction("value", "")};`,
+				`${RuntimeGlobals.definePropertyGetters}(ns, def);`,
+				"return ns;"
+			]),
+			"};"
+		]);
+	}
+}
+
+module.exports = CreateFakeNamespaceObjectRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/CreateScriptRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/CreateScriptRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/CreateScriptRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class CreateScriptRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("trusted types script");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate, outputOptions } = compilation;
+		const { trustedTypes } = outputOptions;
+		const fn = RuntimeGlobals.createScript;
+
+		return Template.asString(
+			`${fn} = ${runtimeTemplate.returningFunction(
+				trustedTypes
+					? `${RuntimeGlobals.getTrustedTypesPolicy}().createScript(script)`
+					: "script",
+				"script"
+			)};`
+		);
+	}
+}
+
+module.exports = CreateScriptRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/CreateScriptUrlRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/CreateScriptUrlRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/CreateScriptUrlRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class CreateScriptUrlRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("trusted types script url");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate, outputOptions } = compilation;
+		const { trustedTypes } = outputOptions;
+		const fn = RuntimeGlobals.createScriptUrl;
+
+		return Template.asString(
+			`${fn} = ${runtimeTemplate.returningFunction(
+				trustedTypes
+					? `${RuntimeGlobals.getTrustedTypesPolicy}().createScriptURL(url)`
+					: "url",
+				"url"
+			)};`
+		);
+	}
+}
+
+module.exports = CreateScriptUrlRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class DefinePropertyGettersRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("define property getters");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.definePropertyGetters;
+		return Template.asString([
+			"// define getter functions for harmony exports",
+			`${fn} = ${runtimeTemplate.basicFunction("exports, definition", [
+				"for(var key in definition) {",
+				Template.indent([
+					`if(${RuntimeGlobals.hasOwnProperty}(definition, key) && !${RuntimeGlobals.hasOwnProperty}(exports, key)) {`,
+					Template.indent([
+						"Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });"
+					]),
+					"}"
+				]),
+				"}"
+			])};`
+		]);
+	}
+}
+
+module.exports = DefinePropertyGettersRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/EnsureChunkRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/EnsureChunkRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/EnsureChunkRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+class EnsureChunkRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("ensure chunk");
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this.runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		// Check if there are non initial chunks which need to be imported using require-ensure
+		if (this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)) {
+			const withFetchPriority = this.runtimeRequirements.has(
+				RuntimeGlobals.hasFetchPriority
+			);
+			const handlers = RuntimeGlobals.ensureChunkHandlers;
+			return Template.asString([
+				`${handlers} = {};`,
+				"// This file contains only the entry chunk.",
+				"// The chunk loading function for additional chunks",
+				`${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.basicFunction(
+					`chunkId${withFetchPriority ? ", fetchPriority" : ""}`,
+					[
+						`return Promise.all(Object.keys(${handlers}).reduce(${runtimeTemplate.basicFunction(
+							"promises, key",
+							[
+								`${handlers}[key](chunkId, promises${
+									withFetchPriority ? ", fetchPriority" : ""
+								});`,
+								"return promises;"
+							]
+						)}, []));`
+					]
+				)};`
+			]);
+		}
+		// There ensureChunk is used somewhere in the tree, so we need an empty requireEnsure
+		// function. This can happen with multiple entrypoints.
+		return Template.asString([
+			"// The chunk loading function for additional chunks",
+			"// Since all referenced chunks are already included",
+			"// in this file, this function is empty here.",
+			`${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.returningFunction(
+				"Promise.resolve()"
+			)};`
+		]);
+	}
+}
+
+module.exports = EnsureChunkRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/GetChunkFilenameRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/GetChunkFilenameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/GetChunkFilenameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,300 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const { first } = require("../util/SetHelpers");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").HashWithLengthFunction} HashWithLengthFunction */
+/** @typedef {import("../Chunk").ChunkFilenameTemplate} ChunkFilenameTemplate */
+
+class GetChunkFilenameRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {string} contentType the contentType to use the content hash for
+	 * @param {string} name kind of filename
+	 * @param {string} global function name to be assigned
+	 * @param {(chunk: Chunk) => ChunkFilenameTemplate | false} getFilenameForChunk functor to get the filename or function
+	 * @param {boolean} allChunks when false, only async chunks are included
+	 */
+	constructor(contentType, name, global, getFilenameForChunk, allChunks) {
+		super(`get ${name} chunk filename`);
+		/** @type {string} */
+		this.contentType = contentType;
+		/** @type {string} */
+		this.global = global;
+		/** @type {(chunk: Chunk) => ChunkFilenameTemplate | false} */
+		this.getFilenameForChunk = getFilenameForChunk;
+		/** @type {boolean} */
+		this.allChunks = allChunks;
+		/** @type {boolean} */
+		this.dependentHash = true;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { global, contentType, getFilenameForChunk, allChunks } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { runtimeTemplate } = compilation;
+
+		/** @type {Map<ChunkFilenameTemplate, Set<Chunk>>} */
+		const chunkFilenames = new Map();
+		let maxChunks = 0;
+		/** @type {string | undefined} */
+		let dynamicFilename;
+
+		/**
+		 * @param {Chunk} c the chunk
+		 * @returns {void}
+		 */
+		const addChunk = (c) => {
+			const chunkFilename = getFilenameForChunk(c);
+			if (chunkFilename) {
+				let set = chunkFilenames.get(chunkFilename);
+				if (set === undefined) {
+					chunkFilenames.set(chunkFilename, (set = new Set()));
+				}
+				set.add(c);
+				if (typeof chunkFilename === "string") {
+					if (set.size < maxChunks) return;
+					if (set.size === maxChunks) {
+						if (
+							chunkFilename.length <
+							/** @type {string} */ (dynamicFilename).length
+						) {
+							return;
+						}
+
+						if (
+							chunkFilename.length ===
+								/** @type {string} */ (dynamicFilename).length &&
+							chunkFilename < /** @type {string} */ (dynamicFilename)
+						) {
+							return;
+						}
+					}
+					maxChunks = set.size;
+					dynamicFilename = chunkFilename;
+				}
+			}
+		};
+
+		/** @type {string[]} */
+		const includedChunksMessages = [];
+		if (allChunks) {
+			includedChunksMessages.push("all chunks");
+			for (const c of chunk.getAllReferencedChunks()) {
+				addChunk(c);
+			}
+		} else {
+			includedChunksMessages.push("async chunks");
+			for (const c of chunk.getAllAsyncChunks()) {
+				addChunk(c);
+			}
+			const includeEntries = chunkGraph
+				.getTreeRuntimeRequirements(chunk)
+				.has(RuntimeGlobals.ensureChunkIncludeEntries);
+			if (includeEntries) {
+				includedChunksMessages.push("chunks that the entrypoint depends on");
+				for (const c of chunkGraph.getRuntimeChunkDependentChunksIterable(
+					chunk
+				)) {
+					addChunk(c);
+				}
+			}
+		}
+		for (const entrypoint of chunk.getAllReferencedAsyncEntrypoints()) {
+			addChunk(entrypoint.chunks[entrypoint.chunks.length - 1]);
+		}
+
+		/** @type {Map<string, Set<string | number | null>>} */
+		const staticUrls = new Map();
+		/** @type {Set<Chunk>} */
+		const dynamicUrlChunks = new Set();
+
+		/**
+		 * @param {Chunk} c the chunk
+		 * @param {ChunkFilenameTemplate} chunkFilename the filename template for the chunk
+		 * @returns {void}
+		 */
+		const addStaticUrl = (c, chunkFilename) => {
+			/**
+			 * @param {ChunkId} value a value
+			 * @returns {string} string to put in quotes
+			 */
+			const unquotedStringify = (value) => {
+				const str = `${value}`;
+				if (str.length >= 5 && str === `${c.id}`) {
+					// This is shorter and generates the same result
+					return '" + chunkId + "';
+				}
+				const s = JSON.stringify(str);
+				return s.slice(1, -1);
+			};
+			/**
+			 * @param {string} value string
+			 * @returns {HashWithLengthFunction} string to put in quotes with length
+			 */
+			const unquotedStringifyWithLength = (value) => (length) =>
+				unquotedStringify(`${value}`.slice(0, length));
+			const chunkFilenameValue =
+				typeof chunkFilename === "function"
+					? JSON.stringify(
+							chunkFilename({
+								chunk: c,
+								contentHashType: contentType
+							})
+						)
+					: JSON.stringify(chunkFilename);
+			const staticChunkFilename = compilation.getPath(chunkFilenameValue, {
+				hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+				hashWithLength: (length) =>
+					`" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`,
+				chunk: {
+					id: unquotedStringify(/** @type {ChunkId} */ (c.id)),
+					hash: unquotedStringify(/** @type {string} */ (c.renderedHash)),
+					hashWithLength: unquotedStringifyWithLength(
+						/** @type {string} */ (c.renderedHash)
+					),
+					name: unquotedStringify(c.name || /** @type {ChunkId} */ (c.id)),
+					contentHash: {
+						[contentType]: unquotedStringify(c.contentHash[contentType])
+					},
+					contentHashWithLength: {
+						[contentType]: unquotedStringifyWithLength(
+							c.contentHash[contentType]
+						)
+					}
+				},
+				contentHashType: contentType
+			});
+			let set = staticUrls.get(staticChunkFilename);
+			if (set === undefined) {
+				staticUrls.set(staticChunkFilename, (set = new Set()));
+			}
+			set.add(c.id);
+		};
+
+		for (const [filename, chunks] of chunkFilenames) {
+			if (filename !== dynamicFilename) {
+				for (const c of chunks) addStaticUrl(c, filename);
+			} else {
+				for (const c of chunks) dynamicUrlChunks.add(c);
+			}
+		}
+
+		/**
+		 * @param {(chunk: Chunk) => string | number} fn function from chunk to value
+		 * @returns {string} code with static mapping of results of fn
+		 */
+		const createMap = (fn) => {
+			/** @type {Record<ChunkId, ChunkId>} */
+			const obj = {};
+			let useId = false;
+			/** @type {ChunkId | undefined} */
+			let lastKey;
+			let entries = 0;
+			for (const c of dynamicUrlChunks) {
+				const value = fn(c);
+				if (value === c.id) {
+					useId = true;
+				} else {
+					obj[/** @type {ChunkId} */ (c.id)] = value;
+					lastKey = /** @type {ChunkId} */ (c.id);
+					entries++;
+				}
+			}
+			if (entries === 0) return "chunkId";
+			if (entries === 1) {
+				return useId
+					? `(chunkId === ${JSON.stringify(lastKey)} ? ${JSON.stringify(
+							obj[/** @type {ChunkId} */ (lastKey)]
+						)} : chunkId)`
+					: JSON.stringify(obj[/** @type {ChunkId} */ (lastKey)]);
+			}
+			return useId
+				? `(${JSON.stringify(obj)}[chunkId] || chunkId)`
+				: `${JSON.stringify(obj)}[chunkId]`;
+		};
+
+		/**
+		 * @param {(chunk: Chunk) => string | number} fn function from chunk to value
+		 * @returns {string} code with static mapping of results of fn for including in quoted string
+		 */
+		const mapExpr = (fn) => `" + ${createMap(fn)} + "`;
+
+		/**
+		 * @param {(chunk: Chunk) => string | number} fn function from chunk to value
+		 * @returns {HashWithLengthFunction} function which generates code with static mapping of results of fn for including in quoted string for specific length
+		 */
+		const mapExprWithLength = (fn) => (length) =>
+			`" + ${createMap((c) => `${fn(c)}`.slice(0, length))} + "`;
+
+		const url =
+			dynamicFilename &&
+			compilation.getPath(JSON.stringify(dynamicFilename), {
+				hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+				hashWithLength: (length) =>
+					`" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`,
+				chunk: {
+					id: '" + chunkId + "',
+					hash: mapExpr((c) => /** @type {string} */ (c.renderedHash)),
+					hashWithLength: mapExprWithLength(
+						(c) => /** @type {string} */ (c.renderedHash)
+					),
+					name: mapExpr((c) => c.name || /** @type {ChunkId} */ (c.id)),
+					contentHash: {
+						[contentType]: mapExpr((c) => c.contentHash[contentType])
+					},
+					contentHashWithLength: {
+						[contentType]: mapExprWithLength((c) => c.contentHash[contentType])
+					}
+				},
+				contentHashType: contentType
+			});
+
+		return Template.asString([
+			`// This function allow to reference ${includedChunksMessages.join(
+				" and "
+			)}`,
+			`${global} = ${runtimeTemplate.basicFunction(
+				"chunkId",
+
+				staticUrls.size > 0
+					? [
+							"// return url for filenames not based on template",
+							// it minimizes to `x===1?"...":x===2?"...":"..."`
+							Template.asString(
+								Array.from(staticUrls, ([url, ids]) => {
+									const condition =
+										ids.size === 1
+											? `chunkId === ${JSON.stringify(first(ids))}`
+											: `{${Array.from(
+													ids,
+													(id) => `${JSON.stringify(id)}:1`
+												).join(",")}}[chunkId]`;
+									return `if (${condition}) return ${url};`;
+								})
+							),
+							"// return url for filenames based on template",
+							`return ${url};`
+						]
+					: ["// return url for filenames based on template", `return ${url};`]
+			)};`
+		]);
+	}
+}
+
+module.exports = GetChunkFilenameRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/GetFullHashRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/GetFullHashRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/GetFullHashRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,32 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class GetFullHashRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("getFullHash");
+		/** @type {boolean} */
+		this.fullHash = true;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		return `${RuntimeGlobals.getFullHash} = ${runtimeTemplate.returningFunction(
+			JSON.stringify(compilation.hash || "XXXX")
+		)}`;
+	}
+}
+
+module.exports = GetFullHashRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/GetMainFilenameRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/GetMainFilenameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/GetMainFilenameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,50 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+
+class GetMainFilenameRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {string} name readable name
+	 * @param {string} global global object binding
+	 * @param {string} filename main file name
+	 */
+	constructor(name, global, filename) {
+		super(`get ${name} filename`);
+		/** @type {string} */
+		this.global = global;
+		/** @type {string} */
+		this.filename = filename;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { global, filename } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { runtimeTemplate } = compilation;
+		const url = compilation.getPath(JSON.stringify(filename), {
+			hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+			hashWithLength: (length) =>
+				`" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`,
+			chunk,
+			runtime: chunk.runtime
+		});
+		return Template.asString([
+			`${global} = ${runtimeTemplate.returningFunction(url)};`
+		]);
+	}
+}
+
+module.exports = GetMainFilenameRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+class GetTrustedTypesPolicyRuntimeModule extends HelperRuntimeModule {
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("trusted types policy");
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this.runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate, outputOptions } = compilation;
+		const { trustedTypes } = outputOptions;
+		const fn = RuntimeGlobals.getTrustedTypesPolicy;
+		const wrapPolicyCreationInTryCatch = trustedTypes
+			? trustedTypes.onPolicyCreationFailure === "continue"
+			: false;
+
+		return Template.asString([
+			"var policy;",
+			`${fn} = ${runtimeTemplate.basicFunction("", [
+				"// Create Trusted Type policy if Trusted Types are available and the policy doesn't exist yet.",
+				"if (policy === undefined) {",
+				Template.indent([
+					"policy = {",
+					Template.indent(
+						[
+							...(this.runtimeRequirements.has(RuntimeGlobals.createScript)
+								? [
+										`createScript: ${runtimeTemplate.returningFunction(
+											"script",
+											"script"
+										)}`
+									]
+								: []),
+							...(this.runtimeRequirements.has(RuntimeGlobals.createScriptUrl)
+								? [
+										`createScriptURL: ${runtimeTemplate.returningFunction(
+											"url",
+											"url"
+										)}`
+									]
+								: [])
+						].join(",\n")
+					),
+					"};",
+					...(trustedTypes
+						? [
+								'if (typeof trustedTypes !== "undefined" && trustedTypes.createPolicy) {',
+								Template.indent([
+									...(wrapPolicyCreationInTryCatch ? ["try {"] : []),
+									...[
+										`policy = trustedTypes.createPolicy(${JSON.stringify(
+											trustedTypes.policyName
+										)}, policy);`
+									].map((line) =>
+										wrapPolicyCreationInTryCatch ? Template.indent(line) : line
+									),
+									...(wrapPolicyCreationInTryCatch
+										? [
+												"} catch (e) {",
+												Template.indent([
+													`console.warn('Could not create trusted-types policy ${JSON.stringify(
+														trustedTypes.policyName
+													)}');`
+												]),
+												"}"
+											]
+										: [])
+								]),
+								"}"
+							]
+						: [])
+				]),
+				"}",
+				"return policy;"
+			])};`
+		]);
+	}
+}
+
+module.exports = GetTrustedTypesPolicyRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/GlobalRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/GlobalRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/GlobalRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,48 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+class GlobalRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("global");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return Template.asString([
+			`${RuntimeGlobals.global} = (function() {`,
+			Template.indent([
+				"if (typeof globalThis === 'object') return globalThis;",
+				"try {",
+				Template.indent(
+					// This works in non-strict mode
+					// or
+					// This works if eval is allowed (see CSP)
+					"return this || new Function('return this')();"
+				),
+				"} catch (e) {",
+				Template.indent(
+					// This works if the window reference is available
+					"if (typeof window === 'object') return window;"
+				),
+				"}"
+				// It can still be `undefined`, but nothing to do about it...
+				// We return `undefined`, instead of nothing here, so it's
+				// easier to handle this case:
+				//   if (!global) { … }
+			]),
+			"})();"
+		]);
+	}
+}
+
+module.exports = GlobalRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class HasOwnPropertyRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("hasOwnProperty shorthand");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+
+		return Template.asString([
+			`${RuntimeGlobals.hasOwnProperty} = ${runtimeTemplate.returningFunction(
+				"Object.prototype.hasOwnProperty.call(obj, prop)",
+				"obj, prop"
+			)}`
+		]);
+	}
+}
+
+module.exports = HasOwnPropertyRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/HelperRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/HelperRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/HelperRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeModule = require("../RuntimeModule");
+
+/**
+ * Base class for runtime modules that only emit helper functions and do not
+ * need special staging or attachment behavior beyond `RuntimeModule`.
+ */
+class HelperRuntimeModule extends RuntimeModule {
+	/**
+	 * Creates a helper runtime module with the provided readable name.
+	 * @param {string} name a readable name
+	 */
+	constructor(name) {
+		super(name);
+	}
+}
+
+module.exports = HelperRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/LoadScriptRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/LoadScriptRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/LoadScriptRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,175 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+
+/**
+ * @typedef {object} LoadScriptCompilationHooks
+ * @property {SyncWaterfallHook<[string, Chunk]>} createScript
+ */
+
+/** @type {WeakMap<Compilation, LoadScriptCompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class LoadScriptRuntimeModule extends HelperRuntimeModule {
+	/**
+	 * @param {Compilation} compilation the compilation
+	 * @returns {LoadScriptCompilationHooks} hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				createScript: new SyncWaterfallHook(["source", "chunk"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * @param {boolean=} withCreateScriptUrl use create script url for trusted types
+	 * @param {boolean=} withFetchPriority use `fetchPriority` attribute
+	 */
+	constructor(withCreateScriptUrl, withFetchPriority) {
+		super("load script");
+		/** @type {boolean | undefined} */
+		this._withCreateScriptUrl = withCreateScriptUrl;
+		/** @type {boolean | undefined} */
+		this._withFetchPriority = withFetchPriority;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate, outputOptions } = compilation;
+		const {
+			scriptType,
+			chunkLoadTimeout: loadTimeout,
+			crossOriginLoading,
+			uniqueName,
+			charset
+		} = outputOptions;
+		const fn = RuntimeGlobals.loadScript;
+
+		const { createScript } =
+			LoadScriptRuntimeModule.getCompilationHooks(compilation);
+
+		const code = Template.asString([
+			"script = document.createElement('script');",
+			scriptType ? `script.type = ${JSON.stringify(scriptType)};` : "",
+			charset ? "script.charset = 'utf-8';" : "",
+			`if (${RuntimeGlobals.scriptNonce}) {`,
+			Template.indent(
+				`script.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+			),
+			"}",
+			uniqueName
+				? 'script.setAttribute("data-webpack", dataWebpackPrefix + key);'
+				: "",
+			this._withFetchPriority
+				? Template.asString([
+						"if(fetchPriority) {",
+						Template.indent(
+							'script.setAttribute("fetchpriority", fetchPriority);'
+						),
+						"}"
+					])
+				: "",
+			`script.src = ${
+				this._withCreateScriptUrl
+					? `${RuntimeGlobals.createScriptUrl}(url)`
+					: "url"
+			};`,
+			crossOriginLoading
+				? crossOriginLoading === "use-credentials"
+					? 'script.crossOrigin = "use-credentials";'
+					: Template.asString([
+							"if (script.src.indexOf(window.location.origin + '/') !== 0) {",
+							Template.indent(
+								`script.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
+							),
+							"}"
+						])
+				: ""
+		]);
+
+		return Template.asString([
+			"var inProgress = {};",
+			uniqueName
+				? `var dataWebpackPrefix = ${JSON.stringify(`${uniqueName}:`)};`
+				: "// data-webpack is not used as build has no uniqueName",
+			"// loadScript function to load a script via script tag",
+			`${fn} = ${runtimeTemplate.basicFunction(
+				`url, done, key, chunkId${
+					this._withFetchPriority ? ", fetchPriority" : ""
+				}`,
+				[
+					"if(inProgress[url]) { inProgress[url].push(done); return; }",
+					"var script, needAttach;",
+					"if(key !== undefined) {",
+					Template.indent([
+						'var scripts = document.getElementsByTagName("script");',
+						"for(var i = 0; i < scripts.length; i++) {",
+						Template.indent([
+							"var s = scripts[i];",
+							`if(s.getAttribute("src") == url${
+								uniqueName
+									? ' || s.getAttribute("data-webpack") == dataWebpackPrefix + key'
+									: ""
+							}) { script = s; break; }`
+						]),
+						"}"
+					]),
+					"}",
+					"if(!script) {",
+					Template.indent([
+						"needAttach = true;",
+						createScript.call(code, /** @type {Chunk} */ (this.chunk))
+					]),
+					"}",
+					"inProgress[url] = [done];",
+					`var onScriptComplete = ${runtimeTemplate.basicFunction(
+						"prev, event",
+						Template.asString([
+							"// avoid mem leaks in IE.",
+							"script.onerror = script.onload = null;",
+							"clearTimeout(timeout);",
+							"var doneFns = inProgress[url];",
+							"delete inProgress[url];",
+							"script.parentNode && script.parentNode.removeChild(script);",
+							`doneFns && doneFns.forEach(${runtimeTemplate.returningFunction(
+								"fn(event)",
+								"fn"
+							)});`,
+							"if(prev) return prev(event);"
+						])
+					)}`,
+					`var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), ${loadTimeout});`,
+					"script.onerror = onScriptComplete.bind(null, script.onerror);",
+					"script.onload = onScriptComplete.bind(null, script.onload);",
+					"needAttach && document.head.appendChild(script);"
+				]
+			)};`
+		]);
+	}
+}
+
+module.exports = LoadScriptRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/MakeDeferredNamespaceObjectRuntime.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/MakeDeferredNamespaceObjectRuntime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/MakeDeferredNamespaceObjectRuntime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,340 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+/** @typedef {import("../Module").ExportsType} ExportsType */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+
+/**
+ * @param {ExportsType} exportsType exports type
+ * @returns {string} mode
+ */
+function getMakeDeferredNamespaceModeFromExportsType(exportsType) {
+	// number is from createFakeNamespaceObject mode ^ 1
+	if (exportsType === "namespace") return `/* ${exportsType} */ 8`;
+	if (exportsType === "default-only") return `/* ${exportsType} */ 0`;
+	if (exportsType === "default-with-named") return `/* ${exportsType} */ 2`;
+	if (exportsType === "dynamic") return `/* ${exportsType} */ 6`;
+	throw new Error(`Unknown exports type: ${exportsType}`);
+}
+
+/**
+ * @param {string} moduleId moduleId
+ * @param {ExportsType} exportsType exportsType
+ * @param {(ModuleId | null)[]} asyncDepsIds asyncDepsIds
+ * @param {RuntimeRequirements} runtimeRequirements runtime requirements
+ * @returns {string} call make optimized deferred namespace object
+ */
+function getOptimizedDeferredModule(
+	moduleId,
+	exportsType,
+	asyncDepsIds,
+	runtimeRequirements
+) {
+	runtimeRequirements.add(RuntimeGlobals.makeOptimizedDeferredNamespaceObject);
+	const mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
+	return `${RuntimeGlobals.makeOptimizedDeferredNamespaceObject}(${moduleId}, ${mode}${
+		asyncDepsIds.length > 0
+			? `, ${JSON.stringify(asyncDepsIds.filter((x) => x !== null))}`
+			: ""
+	})`;
+}
+
+class MakeOptimizedDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
+	/**
+	 * @param {boolean} hasAsyncRuntime if async module is used.
+	 */
+	constructor(hasAsyncRuntime) {
+		super("make optimized deferred namespace object");
+		/** @type {boolean} */
+		this.hasAsyncRuntime = hasAsyncRuntime;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		if (!this.compilation) return null;
+		const fn = RuntimeGlobals.makeOptimizedDeferredNamespaceObject;
+		const hasAsync = this.hasAsyncRuntime;
+		return Template.asString([
+			// Note: must be a function (not arrow), because this is used in body!
+			`${fn} = function(moduleId, mode${hasAsync ? ", asyncDeps" : ""}) {`,
+			Template.indent([
+				"var r = this;",
+				hasAsync ? "var isAsync = asyncDeps && asyncDeps.length;" : "",
+				"var obj = {",
+				Template.indent([
+					"get a() {",
+					Template.indent([
+						"var exports = r(moduleId);",
+						hasAsync
+							? `if(isAsync) exports = exports[${RuntimeGlobals.asyncModuleExportSymbol}];`
+							: "",
+						// if exportsType is "namespace" we can generate the most optimized code,
+						// on the second access, we can avoid trigger the getter.
+						// we can also do this if exportsType is "dynamic" and there is a "__esModule" property on it.
+						'if(mode & 8 || (mode & 4 && exports.__esModule)) Object.defineProperty(this, "a", { value: exports });',
+						"return exports;"
+					]),
+					"}"
+				]),
+				"};",
+				hasAsync
+					? `if(isAsync) obj[${RuntimeGlobals.deferredModuleAsyncTransitiveDependenciesSymbol}] = asyncDeps;`
+					: "",
+				"return obj;"
+			]),
+			"};"
+		]);
+	}
+}
+
+class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
+	/**
+	 * @param {boolean} hasAsyncRuntime if async module is used.
+	 */
+	constructor(hasAsyncRuntime) {
+		super("make deferred namespace object");
+		/** @type {boolean} */
+		this.hasAsyncRuntime = hasAsyncRuntime;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		if (!this.compilation) return null;
+		const { runtimeTemplate } = this.compilation;
+		const fn = RuntimeGlobals.makeDeferredNamespaceObject;
+		const hasAsync = this.hasAsyncRuntime;
+		const init = runtimeTemplate.supportsOptionalChaining()
+			? "init?.();"
+			: "if (init) init();";
+		return `${fn} = ${runtimeTemplate.basicFunction("moduleId, mode", [
+			// Per the TC39 import-defer spec, deferred namespaces are
+			// distinct from their eager counterparts and the same module
+			// referenced from multiple defer-import sites must yield the
+			// same object. Cache the Proxy / fake namespace per-moduleId so
+			// repeated calls (including across files) share identity.
+			//
+			// Bit 16 (`createFakeNamespaceObject`'s "return value when
+			// it's Promise-like" flag added by
+			// `RuntimeTemplate.moduleNamespacePromise` for dynamic
+			// imports) is irrelevant for deferred namespaces — the value
+			// passed into `createFakeNamespaceObject` here is always the
+			// resolved module exports (after unwrapping the async-module
+			// export symbol when present), never a Promise. Strip it
+			// once so all downstream behavior, the cache key, and the
+			// `createFakeNamespaceObject` call below see the same shape
+			// mode. This keeps static defer (mode 8) and dynamic
+			// `await import.defer` (mode 8 | 16) sharing the same
+			// Deferred Module Namespace object, while still keying by
+			// `(moduleId, mode)` so distinct exports-type shapes
+			// (e.g. one importer treats a CJS module as
+			// "default-with-named", another as "namespace") get
+			// distinct cache entries.
+			"mode &= ~16;",
+			"var byMode = __webpack_module_deferred_namespace_cache__[moduleId];",
+			"if (byMode && byMode[mode] !== undefined) return byMode[mode];",
+			"if (!byMode) byMode = __webpack_module_deferred_namespace_cache__[moduleId] = {};",
+			"var cachedModule = __webpack_module_cache__[moduleId];",
+			"if (cachedModule && cachedModule.error === undefined && !(mode & 8)) {",
+			Template.indent([
+				"var exports = cachedModule.exports;",
+				hasAsync
+					? `if (${RuntimeGlobals.asyncModuleExportSymbol} in exports) exports = exports[${RuntimeGlobals.asyncModuleExportSymbol}];`
+					: "",
+				`return byMode[mode] = ${RuntimeGlobals.createFakeNamespaceObject}(exports, mode);`
+			]),
+			"}",
+			"",
+			`var init = ${runtimeTemplate.basicFunction("", [
+				`ns = ${RuntimeGlobals.require}(moduleId);`,
+				hasAsync
+					? `if (${RuntimeGlobals.asyncModuleExportSymbol} in ns) ns = ns[${RuntimeGlobals.asyncModuleExportSymbol}];`
+					: "",
+				"init = null;",
+				"if (mode & 8 || mode & 4 && ns.__esModule && typeof ns === 'object') {",
+				Template.indent([
+					// Drop only the read-side traps after init: with the
+					// resolved namespace's own keys mirrored onto
+					// `ns_target` below, the default `Reflect` behavior
+					// returns the right values via the live-binding
+					// getters, so we no longer need to intercept `get` /
+					// `has` / `ownKeys` / `getOwnPropertyDescriptor`.
+					//
+					// The mutation traps (`set`, `deleteProperty`,
+					// `defineProperty`) are kept because per the TC39
+					// import-defer spec, `[[Set]]` / `[[Delete]]` /
+					// `[[DefineOwnProperty]]` on a Deferred Module
+					// Namespace Exotic Object never succeed — and the
+					// proxy target itself remains extensible
+					// (architecturally we cannot freeze it up-front),
+					// so without these traps `ns.notExported = "x"`
+					// after evaluation would silently create a property
+					// on the target instead of returning false.
+					"delete handler.get;",
+					"delete handler.has;",
+					"delete handler.ownKeys;",
+					"delete handler.getOwnPropertyDescriptor;"
+				]),
+				"} else {",
+				Template.indent([
+					`ns = ${RuntimeGlobals.createFakeNamespaceObject}(ns, mode);`
+				]),
+				"}",
+				// Mirror own properties from the resolved namespace onto the proxy
+				// target so that proxy invariants hold for callers that structurally
+				// introspect via `Object.keys` / `Object.getOwnPropertyNames` /
+				// `Object.getOwnPropertyDescriptor`: when our trap reports a
+				// non-configurable descriptor for a key, the target must also have
+				// that key with a matching descriptor.
+				//
+				// `__esModule` and `Symbol.toStringTag` are intentionally skipped:
+				// the proxy synthesizes "Deferred Module" / true regardless of what
+				// the underlying namespace exposes (per the TC39 import-defer
+				// proposal, the [[StringTag]] of a Deferred Module Namespace
+				// Exotic Object is "Deferred Module"), and the target was already
+				// pre-populated with those values below.
+				"var keys = Reflect.ownKeys(ns);",
+				"for (var i = 0; i < keys.length; i++) {",
+				Template.indent([
+					"var k = keys[i];",
+					'if (k === "__esModule" || k === Symbol.toStringTag) continue;',
+					"if (!Object.prototype.hasOwnProperty.call(ns_target, k)) {",
+					Template.indent([
+						"try { Object.defineProperty(ns_target, k, Reflect.getOwnPropertyDescriptor(ns, k)); } catch (_) {}"
+					]),
+					"}"
+				]),
+				"}"
+			])};`,
+			"",
+			// The proxy target is a fresh placeholder, separate from
+			// `__webpack_module_deferred_exports__[moduleId]` (which is reused
+			// by `__webpack_require__` as `module.exports` for deferred-loaded
+			// modules and would conflict with our pre-populated synthetic
+			// `__esModule` / `Symbol.toStringTag` non-configurable properties).
+			// Using a dedicated target keeps the proxy invariant-compliant
+			// without interfering with the module's own exports object.
+			"var ns_target = { __proto__: null };",
+			// Pre-populate the synthetic deferred-namespace properties with
+			// fully non-configurable, non-writable, non-enumerable descriptors
+			// (matching the TC39 import-defer spec for Module Namespace
+			// Exotic Objects). The trap returns the same descriptors below.
+			'Object.defineProperty(ns_target, "__esModule", { value: true });',
+			'Object.defineProperty(ns_target, Symbol.toStringTag, { value: "Deferred Module" });',
+			"var ns = ns_target;",
+			"var handler = {",
+			Template.indent([
+				"__proto__: null,",
+				// Per the TC39 import-defer proposal, `IsSymbolLikeNamespaceKey`
+				// returns true for any Symbol-keyed access (and for "then"); such
+				// accesses go through `OrdinaryGetOwnProperty` and must not
+				// trigger evaluation of the deferred module. The Symbol checks
+				// below short-circuit to the pre-populated target without
+				// running `init()`.
+				`get: ${runtimeTemplate.basicFunction("_, name", [
+					"switch (name) {",
+					Template.indent([
+						'case "__esModule": return true;',
+						'case Symbol.toStringTag: return "Deferred Module";',
+						'case "then": return undefined;'
+					]),
+					"}",
+					'if (typeof name === "symbol") return ns_target[name];',
+					init,
+					"return ns[name];"
+				])},`,
+				`has: ${runtimeTemplate.basicFunction("_, name", [
+					"switch (name) {",
+					Template.indent(
+						[
+							'case "__esModule":',
+							"case Symbol.toStringTag:",
+							hasAsync
+								? `case ${RuntimeGlobals.deferredModuleAsyncTransitiveDependenciesSymbol}:`
+								: "",
+							Template.indent("return true;"),
+							'case "then":',
+							Template.indent("return false;")
+						].filter(Boolean)
+					),
+					"}",
+					'if (typeof name === "symbol") return name in ns_target;',
+					init,
+					"return name in ns;"
+				])},`,
+				`ownKeys: ${runtimeTemplate.basicFunction("", [
+					init,
+					`var keys = Reflect.ownKeys(ns).filter(${runtimeTemplate.expressionFunction('x !== "then" && x !== Symbol.toStringTag', "x")}).concat([Symbol.toStringTag]);`,
+					"return keys;"
+				])},`,
+				`getOwnPropertyDescriptor: ${runtimeTemplate.basicFunction("_, name", [
+					"switch (name) {",
+					Template.indent([
+						// Match the descriptors actually defined on `ns_target`
+						// (non-configurable, non-writable, non-enumerable) so the
+						// proxy invariant holds for both the trap result and any
+						// post-init forwarding via the deleted-handler path.
+						'case "__esModule": return { value: true, writable: false, enumerable: false, configurable: false };',
+						'case Symbol.toStringTag: return { value: "Deferred Module", writable: false, enumerable: false, configurable: false };',
+						'case "then": return undefined;'
+					]),
+					"}",
+					'if (typeof name === "symbol") return Reflect.getOwnPropertyDescriptor(ns_target, name);',
+					init,
+					"var desc = Reflect.getOwnPropertyDescriptor(ns, name);",
+					'if (mode & 2 && name == "default" && !desc) {',
+					Template.indent("desc = { value: ns, configurable: true };"),
+					"}",
+					"return desc;"
+				])},`,
+				// `defineProperty` always rejects, but per the TC39 spec it
+				// must still trigger evaluation for string keys (the spec
+				// algorithm calls `[[GetOwnProperty]]` first, which forces
+				// evaluation on a deferred namespace). Symbol keys go through
+				// OrdinaryDefineOwnProperty and do not trigger eval.
+				`defineProperty: ${runtimeTemplate.basicFunction("_, name", [
+					'if (typeof name === "symbol" || name === "then") return false;',
+					init,
+					"return false;"
+				])},`,
+				// `deleteProperty` rejects, but per the TC39 spec it must
+				// still trigger evaluation for string keys (the spec
+				// algorithm calls `GetModuleExportsList` for non-symbol-like
+				// keys, forcing evaluation on a deferred namespace).
+				`deleteProperty: ${runtimeTemplate.basicFunction("_, name", [
+					'if (typeof name === "symbol" || name === "then") return false;',
+					init,
+					"return false;"
+				])},`,
+				// `set` always returns false without triggering evaluation —
+				// the spec [[Set]] algorithm for Module Namespaces is just
+				// "return false" (no [[GetOwnProperty]], no eval).
+				`set: ${runtimeTemplate.returningFunction("false")},`
+			]),
+			"}",
+			// we don't fully emulate ES Module semantics in this Proxy to align with normal webpack esm namespace object.
+			"return byMode[mode] = new Proxy(ns_target, handler);"
+		])};`;
+	}
+}
+
+module.exports.MakeDeferredNamespaceObjectRuntimeModule =
+	MakeDeferredNamespaceObjectRuntimeModule;
+module.exports.MakeOptimizedDeferredNamespaceObjectRuntimeModule =
+	MakeOptimizedDeferredNamespaceObjectRuntimeModule;
+module.exports.getMakeDeferredNamespaceModeFromExportsType =
+	getMakeDeferredNamespaceModeFromExportsType;
+module.exports.getOptimizedDeferredModule = getOptimizedDeferredModule;
Index: frontend/node_modules/webpack/lib/runtime/MakeNamespaceObjectRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/MakeNamespaceObjectRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/MakeNamespaceObjectRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class MakeNamespaceObjectRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("make namespace object");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.makeNamespaceObject;
+		return Template.asString([
+			"// define __esModule on exports",
+			`${fn} = ${runtimeTemplate.basicFunction("exports", [
+				"if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {",
+				Template.indent([
+					"Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });"
+				]),
+				"}",
+				"Object.defineProperty(exports, '__esModule', { value: true });"
+			])};`
+		]);
+	}
+}
+
+module.exports = MakeNamespaceObjectRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/NonceRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/NonceRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/NonceRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,25 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+class NonceRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("nonce", RuntimeModule.STAGE_ATTACH);
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return `${RuntimeGlobals.scriptNonce} = undefined;`;
+	}
+}
+
+module.exports = NonceRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/OnChunksLoadedRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/OnChunksLoadedRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/OnChunksLoadedRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,79 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class OnChunksLoadedRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("chunk loaded");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		return Template.asString([
+			"var deferred = [];",
+			`${RuntimeGlobals.onChunksLoaded} = ${runtimeTemplate.basicFunction(
+				"result, chunkIds, fn, priority",
+				[
+					"if(chunkIds) {",
+					Template.indent([
+						"priority = priority || 0;",
+						"for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];",
+						"deferred[i] = [chunkIds, fn, priority];",
+						"return;"
+					]),
+					"}",
+					"var notFulfilled = Infinity;",
+					"for (var i = 0; i < deferred.length; i++) {",
+					Template.indent([
+						runtimeTemplate.destructureArray(
+							["chunkIds", "fn", "priority"],
+							"deferred[i]"
+						),
+						"var fulfilled = true;",
+						"for (var j = 0; j < chunkIds.length; j++) {",
+						Template.indent([
+							`if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(${
+								RuntimeGlobals.onChunksLoaded
+							}).every(${runtimeTemplate.returningFunction(
+								`${RuntimeGlobals.onChunksLoaded}[key](chunkIds[j])`,
+								"key"
+							)})) {`,
+							Template.indent(["chunkIds.splice(j--, 1);"]),
+							"} else {",
+							Template.indent([
+								"fulfilled = false;",
+								"if(priority < notFulfilled) notFulfilled = priority;"
+							]),
+							"}"
+						]),
+						"}",
+						"if(fulfilled) {",
+						Template.indent([
+							"deferred.splice(i--, 1)",
+							"var r = fn();",
+							"if (r !== undefined) result = r;"
+						]),
+						"}"
+					]),
+					"}",
+					"return result;"
+				]
+			)};`
+		]);
+	}
+}
+
+module.exports = OnChunksLoadedRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/PublicPathRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/PublicPathRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/PublicPathRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+/** @typedef {import("../../declarations/WebpackOptions").PublicPath} PublicPath */
+/** @typedef {import("../Compilation")} Compilation */
+
+class PublicPathRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {PublicPath} publicPath public path
+	 */
+	constructor(publicPath) {
+		super("publicPath", RuntimeModule.STAGE_BASIC);
+		/** @type {PublicPath} */
+		this.publicPath = publicPath;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const { publicPath } = this;
+		const compilation = /** @type {Compilation} */ (this.compilation);
+
+		return `${RuntimeGlobals.publicPath} = ${JSON.stringify(
+			compilation.getPath(publicPath || "", {
+				hash: compilation.hash || "XXXX"
+			})
+		)};`;
+	}
+}
+
+module.exports = PublicPathRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/RelativeUrlRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/RelativeUrlRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/RelativeUrlRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,45 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class RelativeUrlRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("relative url");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		return Template.asString([
+			`${RuntimeGlobals.relativeUrl} = function RelativeURL(url) {`,
+			Template.indent([
+				'var realUrl = new URL(url, "x:/");',
+				"var values = {};",
+				"for (var key in realUrl) values[key] = realUrl[key];",
+				"values.href = url;",
+				'values.pathname = url.replace(/[?#].*/, "");',
+				'values.origin = values.protocol = "";',
+				`values.toString = values.toJSON = ${runtimeTemplate.returningFunction(
+					"url"
+				)};`,
+				"for (var key in values) Object.defineProperty(this, key, { enumerable: true, configurable: true, value: values[key] });"
+			]),
+			"};",
+			`${RuntimeGlobals.relativeUrl}.prototype = URL.prototype;`
+		]);
+	}
+}
+
+module.exports = RelativeUrlRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/RuntimeIdRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/RuntimeIdRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/RuntimeIdRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+
+class RuntimeIdRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("runtimeId");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const runtime = chunk.runtime;
+		if (typeof runtime !== "string") {
+			throw new Error("RuntimeIdRuntimeModule must be in a single runtime");
+		}
+		const id = chunkGraph.getRuntimeId(runtime);
+		return `${RuntimeGlobals.runtimeId} = ${JSON.stringify(id)};`;
+	}
+}
+
+module.exports = RuntimeIdRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HelperRuntimeModule = require("./HelperRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class SetAnonymousDefaultNameRuntimeModule extends HelperRuntimeModule {
+	constructor() {
+		super("set anonymous default export name");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.setAnonymousDefaultName;
+		return Template.asString([
+			"// set .name for anonymous default exports per ES spec",
+			`${fn} = ${runtimeTemplate.basicFunction("x", [
+				'(Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });'
+			])};`
+		]);
+	}
+}
+
+module.exports = SetAnonymousDefaultNameRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/StartupChunkDependenciesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/StartupChunkDependenciesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/StartupChunkDependenciesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const StartupChunkDependenciesRuntimeModule = require("./StartupChunkDependenciesRuntimeModule");
+const StartupEntrypointRuntimeModule = require("./StartupEntrypointRuntimeModule");
+
+/** @typedef {import("../../declarations/WebpackOptions").ChunkLoadingType} ChunkLoadingType */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Options that describe which chunk loading backend should receive startup
+ * dependency handling and whether the runtime should wait for those chunks
+ * asynchronously.
+ * @typedef {object} Options
+ * @property {ChunkLoadingType} chunkLoading
+ * @property {boolean=} asyncChunkLoading
+ */
+
+const PLUGIN_NAME = "StartupChunkDependenciesPlugin";
+
+/**
+ * Adds runtime modules that delay entry startup until entry-dependent chunks
+ * required by the selected chunk loading strategy have been loaded.
+ */
+class StartupChunkDependenciesPlugin {
+	/**
+	 * Configures which chunk loading implementation this plugin should enhance
+	 * and whether startup waits should use promises or synchronous ensures.
+	 * @param {Options} options options
+	 */
+	constructor(options) {
+		/** @type {ChunkLoadingType} */
+		this.chunkLoading = options.chunkLoading;
+		/** @type {boolean} */
+		this.asyncChunkLoading =
+			typeof options.asyncChunkLoading === "boolean"
+				? options.asyncChunkLoading
+				: true;
+	}
+
+	/**
+	 * Registers compilation hooks that attach the startup dependency runtime
+	 * modules to entry chunks using the configured chunk loading mechanism.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalChunkLoading = compilation.outputOptions.chunkLoading;
+			/**
+			 * Determines whether a chunk uses the chunk loading backend that this
+			 * plugin is responsible for augmenting.
+			 * @param {Chunk} chunk chunk to check
+			 * @returns {boolean} true, when the plugin is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const chunkLoading =
+					options && options.chunkLoading !== undefined
+						? options.chunkLoading
+						: globalChunkLoading;
+				return chunkLoading === this.chunkLoading;
+			};
+			compilation.hooks.additionalTreeRuntimeRequirements.tap(
+				PLUGIN_NAME,
+				(chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (chunkGraph.hasChunkEntryDependentChunks(chunk)) {
+						set.add(RuntimeGlobals.startup);
+						set.add(RuntimeGlobals.ensureChunk);
+						set.add(RuntimeGlobals.ensureChunkIncludeEntries);
+						compilation.addRuntimeModule(
+							chunk,
+							new StartupChunkDependenciesRuntimeModule(this.asyncChunkLoading)
+						);
+					}
+				}
+			);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.startupEntrypoint)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.require);
+					set.add(RuntimeGlobals.ensureChunk);
+					set.add(RuntimeGlobals.ensureChunkIncludeEntries);
+					compilation.addRuntimeModule(
+						chunk,
+						new StartupEntrypointRuntimeModule(this.asyncChunkLoading)
+					);
+				});
+		});
+	}
+}
+
+module.exports = StartupChunkDependenciesPlugin;
Index: frontend/node_modules/webpack/lib/runtime/StartupChunkDependenciesRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/StartupChunkDependenciesRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/StartupChunkDependenciesRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,78 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+
+class StartupChunkDependenciesRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {boolean} asyncChunkLoading use async chunk loading
+	 */
+	constructor(asyncChunkLoading) {
+		super("startup chunk dependencies", RuntimeModule.STAGE_TRIGGER);
+		/** @type {boolean} */
+		this.asyncChunkLoading = asyncChunkLoading;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const chunkIds = [
+			...chunkGraph.getChunkEntryDependentChunksIterable(chunk)
+		].map((chunk) => chunk.id);
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		return Template.asString([
+			`var next = ${RuntimeGlobals.startup};`,
+			`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
+				"",
+				!this.asyncChunkLoading
+					? [
+							...chunkIds.map(
+								(id) => `${RuntimeGlobals.ensureChunk}(${JSON.stringify(id)});`
+							),
+							"return next();"
+						]
+					: chunkIds.length === 1
+						? `return ${RuntimeGlobals.ensureChunk}(${JSON.stringify(
+								chunkIds[0]
+							)}).then(next);`
+						: chunkIds.length > 2
+							? [
+									// using map is shorter for 3 or more chunks
+									`return Promise.all(${JSON.stringify(chunkIds)}.map(${
+										RuntimeGlobals.ensureChunk
+									}, ${RuntimeGlobals.require})).then(next);`
+								]
+							: [
+									// calling ensureChunk directly is shorter for 0 - 2 chunks
+									"return Promise.all([",
+									Template.indent(
+										chunkIds
+											.map(
+												(id) =>
+													`${RuntimeGlobals.ensureChunk}(${JSON.stringify(id)})`
+											)
+											.join(",\n")
+									),
+									"]).then(next);"
+								]
+			)};`
+		]);
+	}
+}
+
+module.exports = StartupChunkDependenciesRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/StartupEntrypointRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/StartupEntrypointRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/StartupEntrypointRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,55 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class StartupEntrypointRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {boolean} asyncChunkLoading use async chunk loading
+	 */
+	constructor(asyncChunkLoading) {
+		super("startup entrypoint");
+		/** @type {boolean} */
+		this.asyncChunkLoading = asyncChunkLoading;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { runtimeTemplate } = compilation;
+		return `${
+			RuntimeGlobals.startupEntrypoint
+		} = ${runtimeTemplate.basicFunction("result, chunkIds, fn", [
+			"// arguments: chunkIds, moduleId are deprecated",
+			"var moduleId = chunkIds;",
+			`if(!fn) chunkIds = result, fn = ${runtimeTemplate.returningFunction(
+				`${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)`
+			)};`,
+			...(this.asyncChunkLoading
+				? [
+						`return Promise.all(chunkIds.map(${RuntimeGlobals.ensureChunk}, ${
+							RuntimeGlobals.require
+						})).then(${runtimeTemplate.basicFunction("", [
+							"var r = fn();",
+							"return r === undefined ? result : r;"
+						])})`
+					]
+				: [
+						`chunkIds.map(${RuntimeGlobals.ensureChunk}, ${RuntimeGlobals.require})`,
+						"var r = fn();",
+						"return r === undefined ? result : r;"
+					])
+		])}`;
+	}
+}
+
+module.exports = StartupEntrypointRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/SystemContextRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/SystemContextRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/SystemContextRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,24 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+
+class SystemContextRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("__system_context__");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		return `${RuntimeGlobals.systemContext} = __system_context__;`;
+	}
+}
+
+module.exports = SystemContextRuntimeModule;
Index: frontend/node_modules/webpack/lib/runtime/ToBinaryRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/runtime/ToBinaryRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/runtime/ToBinaryRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,73 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Compilation")} Compilation */
+
+class ToBinaryRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("to binary");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const fn = RuntimeGlobals.toBinary;
+		const { runtimeTemplate } = compilation;
+
+		// Inspired by esbuild
+
+		const isNodePlatform = compilation.compiler.platform.node;
+		const isWebPlatform = compilation.compiler.platform.web;
+		const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
+		const toImmutableBytes = runtimeTemplate.basicFunction("value", [
+			runtimeTemplate.destructureObject(["buffer"], "value"),
+			`${runtimeTemplate.renderConst()} throwErr = ${runtimeTemplate.basicFunction("", ["throw new TypeError('ArrayBuffer is immutable');"])};`,
+			"Object.defineProperties(buffer, { immutable: { value: true },  resize: { value: throwErr }, transfer: { value: throwErr }, transferToFixedLength: { value: throwErr } });",
+			"Object.freeze(buffer);",
+			"return value;"
+		]);
+
+		return Template.asString([
+			"// define to binary helper",
+			`${runtimeTemplate.renderConst()} toImmutableBytes = ${toImmutableBytes}`,
+			`${fn} = ${isNeutralPlatform ? "typeof Buffer !== 'undefined' ? " : ""}${
+				isNodePlatform || isNeutralPlatform
+					? `${runtimeTemplate.returningFunction("toImmutableBytes(new Uint8Array(Buffer.from(base64, 'base64')))", "base64")}`
+					: ""
+			} ${isNeutralPlatform ? ": " : ""}${
+				isWebPlatform || isNeutralPlatform
+					? `(${runtimeTemplate.basicFunction("", [
+							`${runtimeTemplate.renderConst()} table = new Uint8Array(128);`,
+							"for (var i = 0; i < 64; i++) table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i;",
+							`return ${runtimeTemplate.basicFunction("base64", [
+								`${runtimeTemplate.renderConst()} n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == '=') - (base64[n - 2] == '=')) * 3 / 4 | 0);`,
+								"for (var i = 0, j = 0; i < n;) {",
+								Template.indent([
+									`${runtimeTemplate.renderConst()} c0 = table[base64.charCodeAt(i++)], c1 = table[base64.charCodeAt(i++)];`,
+									`${runtimeTemplate.renderConst()} c2 = table[base64.charCodeAt(i++)], c3 = table[base64.charCodeAt(i++)];`,
+									"bytes[j++] = (c0 << 2) | (c1 >> 4);",
+									"bytes[j++] = (c1 << 4) | (c2 >> 2);",
+									"bytes[j++] = (c2 << 6) | c3;"
+								]),
+								"}",
+								"return toImmutableBytes(bytes)"
+							])}`
+						])})();`
+					: ""
+			}`
+		]);
+	}
+}
+
+module.exports = ToBinaryRuntimeModule;
Index: frontend/node_modules/webpack/lib/schemes/DataUriPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/schemes/DataUriPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/schemes/DataUriPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,59 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const NormalModule = require("../NormalModule");
+const { URIRegEx, decodeDataURI } = require("../util/dataURL");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "DataUriPlugin";
+
+class DataUriPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				normalModuleFactory.hooks.resolveForScheme
+					.for("data")
+					.tap(PLUGIN_NAME, (resourceData, resolveData) => {
+						const match = URIRegEx.exec(resourceData.resource);
+						if (match) {
+							resourceData.data.mimetype = match[1] || "";
+							resourceData.data.parameters = match[2] || "";
+							resourceData.data.encoding = /** @type {"base64" | false} */ (
+								match[3] || false
+							);
+							resourceData.data.encodedContent = match[4] || "";
+						}
+						// Inherit the issuer's resolution context so any nested
+						// dependencies discovered while parsing the data URI's body
+						// (e.g. `url(...)` / `@import` inside an inline CSS data
+						// URI) resolve relative to where the URI was referenced
+						// from, instead of against the synthetic `data:.../` path
+						// that `getContext("data:…")` would otherwise infer.
+						if (
+							resourceData.context === undefined &&
+							resolveData.context !== undefined
+						) {
+							resourceData.context = resolveData.context;
+						}
+					});
+
+				NormalModule.getCompilationHooks(compilation)
+					.readResourceForScheme.for("data")
+					.tap(PLUGIN_NAME, (resource) => decodeDataURI(resource));
+			}
+		);
+	}
+}
+
+module.exports = DataUriPlugin;
Index: frontend/node_modules/webpack/lib/schemes/FileUriPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/schemes/FileUriPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/schemes/FileUriPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,54 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { fileURLToPath } = require("url");
+const { NormalModule } = require("..");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "FileUriPlugin";
+
+class FileUriPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				normalModuleFactory.hooks.resolveForScheme
+					.for("file")
+					.tap(PLUGIN_NAME, (resourceData) => {
+						const url = new URL(resourceData.resource);
+						const path = fileURLToPath(url);
+						const query = url.search;
+						const fragment = url.hash;
+						resourceData.path = path;
+						resourceData.query = query;
+						resourceData.fragment = fragment;
+						resourceData.resource = path + query + fragment;
+						return true;
+					});
+				const hooks = NormalModule.getCompilationHooks(compilation);
+				hooks.readResource
+					.for(undefined)
+					.tapAsync(PLUGIN_NAME, (loaderContext, callback) => {
+						const { resourcePath } = loaderContext;
+						loaderContext.fs.readFile(resourcePath, (err, result) => {
+							if (err) return callback(err);
+							loaderContext.addDependency(resourcePath);
+							callback(null, result);
+						});
+					});
+			}
+		);
+	}
+}
+
+module.exports = FileUriPlugin;
Index: frontend/node_modules/webpack/lib/schemes/HttpUriPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/schemes/HttpUriPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/schemes/HttpUriPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1461 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const EventEmitter = require("events");
+const { basename, extname } = require("path");
+const {
+	// eslint-disable-next-line n/no-unsupported-features/node-builtins
+	createBrotliDecompress,
+	createGunzip,
+	createInflate
+} = require("zlib");
+const NormalModule = require("../NormalModule");
+const createHash = require("../util/createHash");
+const { dirname, join, mkdirp } = require("../util/fs");
+const memoize = require("../util/memoize");
+
+/** @typedef {import("http").IncomingMessage} IncomingMessage */
+/** @typedef {import("http").OutgoingHttpHeaders} OutgoingHttpHeaders */
+/** @typedef {import("http").RequestOptions} RequestOptions */
+/** @typedef {import("net").Socket} Socket */
+/** @typedef {import("stream").Readable} Readable */
+/** @typedef {import("../../declarations/plugins/schemes/HttpUriPlugin").HttpUriPluginOptions} HttpUriPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../NormalModuleFactory").ResourceDataWithData} ResourceDataWithData */
+/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
+
+const getHttp = memoize(() => require("http"));
+const getHttps = memoize(() => require("https"));
+
+const MAX_REDIRECTS = 5;
+
+/** @typedef {(url: URL, requestOptions: RequestOptions, callback: (incomingMessage: IncomingMessage) => void) => EventEmitter} Fetch */
+
+/**
+ * Defines the events map type used by this module.
+ * @typedef {object} EventsMap
+ * @property {[Error]} error
+ */
+
+/**
+ * Returns fn.
+ * @param {typeof import("http") | typeof import("https")} request request
+ * @param {string | URL | undefined} proxy proxy
+ * @returns {Fetch} fn
+ */
+const proxyFetch = (request, proxy) => (url, options, callback) => {
+	/** @type {EventEmitter<EventsMap>} */
+	const eventEmitter = new EventEmitter();
+
+	/**
+	 * Processes the provided socket.
+	 * @param {Socket=} socket socket
+	 * @returns {void}
+	 */
+	const doRequest = (socket) => {
+		request
+			.get(url, { ...options, ...(socket && { socket }) }, callback)
+			.on("error", eventEmitter.emit.bind(eventEmitter, "error"));
+	};
+
+	if (proxy) {
+		const { hostname: host, port } = new URL(proxy);
+
+		getHttp()
+			.request({
+				host, // IP address of proxy server
+				port, // port of proxy server
+				method: "CONNECT",
+				path: url.host
+			})
+			.on("connect", (res, socket) => {
+				if (res.statusCode === 200) {
+					// connected to proxy server
+					doRequest(socket);
+				} else {
+					eventEmitter.emit(
+						"error",
+						new Error(
+							`Failed to connect to proxy server "${proxy}": ${res.statusCode} ${res.statusMessage}`
+						)
+					);
+				}
+			})
+			.on("error", (err) => {
+				eventEmitter.emit(
+					"error",
+					new Error(
+						`Failed to connect to proxy server "${proxy}": ${err.message}`
+					)
+				);
+			})
+			.end();
+	} else {
+		doRequest();
+	}
+
+	return eventEmitter;
+};
+
+/** @typedef {() => void} InProgressWriteItem */
+/** @type {InProgressWriteItem[] | undefined} */
+let inProgressWrite;
+
+/**
+ * Returns safe path.
+ * @param {string} str path
+ * @returns {string} safe path
+ */
+const toSafePath = (str) =>
+	str.replace(/^[^a-z0-9]+|[^a-z0-9]+$/gi, "").replace(/[^a-z0-9._-]+/gi, "_");
+
+/**
+ * Returns integrity.
+ * @param {Buffer} content content
+ * @returns {string} integrity
+ */
+const computeIntegrity = (content) => {
+	const hash = createHash("sha512");
+	hash.update(content);
+	const integrity = `sha512-${hash.digest("base64")}`;
+	return integrity;
+};
+
+/**
+ * Returns true, if integrity matches.
+ * @param {Buffer} content content
+ * @param {string} integrity integrity
+ * @returns {boolean} true, if integrity matches
+ */
+const verifyIntegrity = (content, integrity) => {
+	if (integrity === "ignore") return true;
+	return computeIntegrity(content) === integrity;
+};
+
+/**
+ * Parses key value pairs.
+ * @param {string} str input
+ * @returns {Record<string, string>} parsed
+ */
+const parseKeyValuePairs = (str) => {
+	/** @type {Record<string, string>} */
+	const result = {};
+	for (const item of str.split(",")) {
+		const i = item.indexOf("=");
+		if (i >= 0) {
+			const key = item.slice(0, i).trim();
+			const value = item.slice(i + 1).trim();
+			result[key] = value;
+		} else {
+			const key = item.trim();
+			if (!key) continue;
+			result[key] = key;
+		}
+	}
+	return result;
+};
+
+/**
+ * Parses cache control.
+ * @param {string | undefined} cacheControl Cache-Control header
+ * @param {number} requestTime timestamp of request
+ * @returns {{ storeCache: boolean, storeLock: boolean, validUntil: number }} Logic for storing in cache and lockfile cache
+ */
+const parseCacheControl = (cacheControl, requestTime) => {
+	// When false resource is not stored in cache
+	let storeCache = true;
+	// When false resource is not stored in lockfile cache
+	let storeLock = true;
+	// Resource is only revalidated, after that timestamp and when upgrade is chosen
+	let validUntil = 0;
+	if (cacheControl) {
+		const parsed = parseKeyValuePairs(cacheControl);
+		if (parsed["no-cache"]) storeCache = storeLock = false;
+		if (parsed["max-age"] && !Number.isNaN(Number(parsed["max-age"]))) {
+			validUntil = requestTime + Number(parsed["max-age"]) * 1000;
+		}
+		if (parsed["must-revalidate"]) validUntil = 0;
+	}
+	return {
+		storeLock,
+		storeCache,
+		validUntil
+	};
+};
+
+/**
+ * Defines the lockfile entry type used by this module.
+ * @typedef {object} LockfileEntry
+ * @property {string} resolved
+ * @property {string} integrity
+ * @property {string} contentType
+ */
+
+/**
+ * Are lockfile entries equal.
+ * @param {LockfileEntry} a first lockfile entry
+ * @param {LockfileEntry} b second lockfile entry
+ * @returns {boolean} true when equal, otherwise false
+ */
+const areLockfileEntriesEqual = (a, b) =>
+	a.resolved === b.resolved &&
+	a.integrity === b.integrity &&
+	a.contentType === b.contentType;
+
+/**
+ * Returns , integrity: ${string}, contentType: ${string}`} stringified entry.
+ * @param {LockfileEntry} entry lockfile entry
+ * @returns {`resolved: ${string}, integrity: ${string}, contentType: ${string}`} stringified entry
+ */
+const entryToString = (entry) =>
+	`resolved: ${entry.resolved}, integrity: ${entry.integrity}, contentType: ${entry.contentType}`;
+
+/**
+ * Sanitize URL for inclusion in error messages
+ * @param {string} href URL string to sanitize
+ * @returns {string} sanitized URL text for logs/errors
+ */
+const sanitizeUrlForError = (href) => {
+	try {
+		const u = new URL(href);
+		return `${u.protocol}//${u.host}`;
+	} catch (_err) {
+		return String(href)
+			.slice(0, 200)
+			.replace(/[\r\n]/g, "");
+	}
+};
+
+class Lockfile {
+	constructor() {
+		/** @type {number} */
+		this.version = 1;
+		/** @type {Map<string, LockfileEntry | "ignore" | "no-cache">} */
+		this.entries = new Map();
+	}
+
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string} content content of the lockfile
+	 * @returns {Lockfile} lockfile
+	 */
+	static parse(content) {
+		// TODO handle merge conflicts
+		const data = JSON.parse(content);
+		if (data.version !== 1) {
+			throw new Error(`Unsupported lockfile version ${data.version}`);
+		}
+		const lockfile = new Lockfile();
+		for (const key of Object.keys(data)) {
+			if (key === "version") continue;
+			const entry = data[key];
+			lockfile.entries.set(
+				key,
+				typeof entry === "string"
+					? entry
+					: {
+							resolved: key,
+							...entry
+						}
+			);
+		}
+		return lockfile;
+	}
+
+	/**
+	 * Returns a string representation.
+	 * @returns {string} stringified lockfile
+	 */
+	toString() {
+		let str = "{\n";
+		const entries = [...this.entries].sort(([a], [b]) => (a < b ? -1 : 1));
+		for (const [key, entry] of entries) {
+			if (typeof entry === "string") {
+				str += `  ${JSON.stringify(key)}: ${JSON.stringify(entry)},\n`;
+			} else {
+				str += `  ${JSON.stringify(key)}: { `;
+				if (entry.resolved !== key) {
+					str += `"resolved": ${JSON.stringify(entry.resolved)}, `;
+				}
+				str += `"integrity": ${JSON.stringify(
+					entry.integrity
+				)}, "contentType": ${JSON.stringify(entry.contentType)} },\n`;
+			}
+		}
+		str += `  "version": ${this.version}\n}\n`;
+		return str;
+	}
+}
+
+/**
+ * Defines the fn without key callback type used by this module.
+ * @template R
+ * @typedef {(err: Error | null, result?: R) => void}  FnWithoutKeyCallback
+ */
+
+/**
+ * Defines the fn without key type used by this module.
+ * @template R
+ * @typedef {(callback: FnWithoutKeyCallback<R>) => void} FnWithoutKey
+ */
+
+/**
+ * Caches d without key.
+ * @template R
+ * @param {FnWithoutKey<R>} fn function
+ * @returns {FnWithoutKey<R>} cached function
+ */
+const cachedWithoutKey = (fn) => {
+	let inFlight = false;
+	/** @type {Error | undefined} */
+	let cachedError;
+	/** @type {R | undefined} */
+	let cachedResult;
+	/** @type {FnWithoutKeyCallback<R>[] | undefined} */
+	let cachedCallbacks;
+	return (callback) => {
+		if (inFlight) {
+			if (cachedResult !== undefined) return callback(null, cachedResult);
+			if (cachedError !== undefined) return callback(cachedError);
+			if (cachedCallbacks === undefined) cachedCallbacks = [callback];
+			else cachedCallbacks.push(callback);
+			return;
+		}
+		inFlight = true;
+		fn((err, result) => {
+			if (err) cachedError = err;
+			else cachedResult = result;
+			const callbacks = cachedCallbacks;
+			cachedCallbacks = undefined;
+			callback(err, result);
+			if (callbacks !== undefined) for (const cb of callbacks) cb(err, result);
+		});
+	};
+};
+
+/**
+ * Defines the fn with key callback type used by this module.
+ * @template R
+ * @typedef {(err: Error | null, result?: R) => void} FnWithKeyCallback
+ */
+
+/**
+ * Defines the fn with key type used by this module.
+ * @template T
+ * @template R
+ * @typedef {(item: T, callback: FnWithKeyCallback<R>) => void} FnWithKey
+ */
+
+/**
+ * Returns } cached function.
+ * @template T
+ * @template R
+ * @param {FnWithKey<T, R>} fn function
+ * @param {FnWithKey<T, R>=} forceFn function for the second try
+ * @returns {FnWithKey<T, R> & { force: FnWithKey<T, R> }} cached function
+ */
+const cachedWithKey = (fn, forceFn = fn) => {
+	/**
+	 * Defines the cache entry type used by this module.
+	 * @template R
+	 * @typedef {{ result?: R, error?: Error, callbacks?: FnWithKeyCallback<R>[], force?: true }} CacheEntry
+	 */
+	/** @type {Map<T, CacheEntry<R>>} */
+	const cache = new Map();
+	/**
+	 * Processes the provided arg.
+	 * @param {T} arg arg
+	 * @param {FnWithKeyCallback<R>} callback callback
+	 * @returns {void}
+	 */
+	const resultFn = (arg, callback) => {
+		const cacheEntry = cache.get(arg);
+		if (cacheEntry !== undefined) {
+			if (cacheEntry.result !== undefined) {
+				return callback(null, cacheEntry.result);
+			}
+			if (cacheEntry.error !== undefined) return callback(cacheEntry.error);
+			if (cacheEntry.callbacks === undefined) cacheEntry.callbacks = [callback];
+			else cacheEntry.callbacks.push(callback);
+			return;
+		}
+		/** @type {CacheEntry<R>} */
+		const newCacheEntry = {
+			result: undefined,
+			error: undefined,
+			callbacks: undefined
+		};
+		cache.set(arg, newCacheEntry);
+		fn(arg, (err, result) => {
+			if (err) newCacheEntry.error = err;
+			else newCacheEntry.result = result;
+			const callbacks = newCacheEntry.callbacks;
+			newCacheEntry.callbacks = undefined;
+			callback(err, result);
+			if (callbacks !== undefined) for (const cb of callbacks) cb(err, result);
+		});
+	};
+	/**
+	 * Processes the provided arg.
+	 * @param {T} arg arg
+	 * @param {FnWithKeyCallback<R>} callback callback
+	 * @returns {void}
+	 */
+	resultFn.force = (arg, callback) => {
+		const cacheEntry = cache.get(arg);
+		if (cacheEntry !== undefined && cacheEntry.force) {
+			if (cacheEntry.result !== undefined) {
+				return callback(null, cacheEntry.result);
+			}
+			if (cacheEntry.error !== undefined) return callback(cacheEntry.error);
+			if (cacheEntry.callbacks === undefined) cacheEntry.callbacks = [callback];
+			else cacheEntry.callbacks.push(callback);
+			return;
+		}
+		/** @type {CacheEntry<R>} */
+		const newCacheEntry = {
+			result: undefined,
+			error: undefined,
+			callbacks: undefined,
+			force: true
+		};
+		cache.set(arg, newCacheEntry);
+		forceFn(arg, (err, result) => {
+			if (err) newCacheEntry.error = err;
+			else newCacheEntry.result = result;
+			const callbacks = newCacheEntry.callbacks;
+			newCacheEntry.callbacks = undefined;
+			callback(err, result);
+			if (callbacks !== undefined) for (const cb of callbacks) cb(err, result);
+		});
+	};
+	return resultFn;
+};
+
+/**
+ * Defines the lockfile cache type used by this module.
+ * @typedef {object} LockfileCache
+ * @property {Lockfile} lockfile lockfile
+ * @property {Snapshot} snapshot snapshot
+ */
+
+/**
+ * Defines the resolve content result type used by this module.
+ * @typedef {object} ResolveContentResult
+ * @property {LockfileEntry} entry lockfile entry
+ * @property {Buffer} content content
+ * @property {boolean} storeLock need store lockfile
+ */
+
+/** @typedef {{ storeCache: boolean, storeLock: boolean, validUntil: number, etag: string | undefined, fresh: boolean }} FetchResultMeta */
+/** @typedef {FetchResultMeta & { location: string }} RedirectFetchResult */
+/** @typedef {FetchResultMeta & { entry: LockfileEntry, content: Buffer }} ContentFetchResult */
+/** @typedef {RedirectFetchResult | ContentFetchResult} FetchResult */
+
+/** @typedef {(uri: string) => boolean} AllowedUriFn */
+
+const PLUGIN_NAME = "HttpUriPlugin";
+
+class HttpUriPlugin {
+	/**
+	 * Creates an instance of HttpUriPlugin.
+	 * @param {HttpUriPluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {HttpUriPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/schemes/HttpUriPlugin.json"),
+				this.options,
+				{
+					name: "Http Uri Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/schemes/HttpUriPlugin.check")(options)
+			);
+		});
+
+		const proxy =
+			this.options.proxy || process.env.http_proxy || process.env.HTTP_PROXY;
+		/**
+		 * @type {{ scheme: "http" | "https", fetch: Fetch }[]}
+		 */
+		const schemes = [
+			{
+				scheme: "http",
+				fetch: proxyFetch(getHttp(), proxy)
+			},
+			{
+				scheme: "https",
+				fetch: proxyFetch(getHttps(), proxy)
+			}
+		];
+		/** @type {LockfileCache} */
+		let lockfileCache;
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const intermediateFs =
+					/** @type {IntermediateFileSystem} */
+					(compiler.intermediateFileSystem);
+				const fs = compilation.inputFileSystem;
+				const cache = compilation.getCache(`webpack.${PLUGIN_NAME}`);
+				const logger = compilation.getLogger(`webpack.${PLUGIN_NAME}`);
+				/** @type {string} */
+				const lockfileLocation =
+					this.options.lockfileLocation ||
+					join(
+						intermediateFs,
+						compiler.context,
+						compiler.name
+							? `${toSafePath(compiler.name)}.webpack.lock`
+							: "webpack.lock"
+					);
+				/** @type {string | false} */
+				const cacheLocation =
+					this.options.cacheLocation !== undefined
+						? this.options.cacheLocation
+						: `${lockfileLocation}.data`;
+				const upgrade = this.options.upgrade || false;
+				const frozen = this.options.frozen || false;
+				const hashFunction = "sha512";
+				const hashDigest = "hex";
+				const hashDigestLength = 20;
+				const allowedUris = this.options.allowedUris;
+
+				let warnedAboutEol = false;
+
+				/** @type {Map<string, string>} */
+				const cacheKeyCache = new Map();
+				/**
+				 * Returns the key.
+				 * @param {string} url the url
+				 * @returns {string} the key
+				 */
+				const getCacheKey = (url) => {
+					const cachedResult = cacheKeyCache.get(url);
+					if (cachedResult !== undefined) return cachedResult;
+					const result = _getCacheKey(url);
+					cacheKeyCache.set(url, result);
+					return result;
+				};
+
+				/**
+				 * Returns the key.
+				 * @param {string} url the url
+				 * @returns {string} the key
+				 */
+				const _getCacheKey = (url) => {
+					const parsedUrl = new URL(url);
+					const folder = toSafePath(parsedUrl.origin);
+					const name = toSafePath(parsedUrl.pathname);
+					const query = toSafePath(parsedUrl.search);
+					let ext = extname(name);
+					if (ext.length > 20) ext = "";
+					const basename = ext ? name.slice(0, -ext.length) : name;
+					const hash = createHash(hashFunction);
+					hash.update(url);
+					const digest = hash.digest(hashDigest).slice(0, hashDigestLength);
+					return `${folder.slice(-50)}/${`${basename}${
+						query ? `_${query}` : ""
+					}`.slice(0, 150)}_${digest}${ext}`;
+				};
+
+				const getLockfile = cachedWithoutKey(
+					/**
+					 * Handles the callback logic for this hook.
+					 * @param {(err: Error | null, lockfile?: Lockfile) => void} callback callback
+					 * @returns {void}
+					 */
+					(callback) => {
+						const readLockfile = () => {
+							intermediateFs.readFile(lockfileLocation, (err, buffer) => {
+								if (err && err.code !== "ENOENT") {
+									compilation.missingDependencies.add(lockfileLocation);
+									return callback(err);
+								}
+								compilation.fileDependencies.add(lockfileLocation);
+								compilation.fileSystemInfo.createSnapshot(
+									compiler.fsStartTime,
+									buffer ? [lockfileLocation] : [],
+									[],
+									buffer ? [] : [lockfileLocation],
+									{ timestamp: true },
+									(err, s) => {
+										if (err) return callback(err);
+										const lockfile = buffer
+											? Lockfile.parse(buffer.toString("utf8"))
+											: new Lockfile();
+										lockfileCache = {
+											lockfile,
+											snapshot: /** @type {Snapshot} */ (s)
+										};
+										callback(null, lockfile);
+									}
+								);
+							});
+						};
+						if (lockfileCache) {
+							compilation.fileSystemInfo.checkSnapshotValid(
+								lockfileCache.snapshot,
+								(err, valid) => {
+									if (err) return callback(err);
+									if (!valid) return readLockfile();
+									callback(null, lockfileCache.lockfile);
+								}
+							);
+						} else {
+							readLockfile();
+						}
+					}
+				);
+
+				/** @typedef {Map<string, LockfileEntry | "ignore" | "no-cache">} LockfileUpdates */
+
+				/** @type {LockfileUpdates | undefined} */
+				let lockfileUpdates;
+
+				/**
+				 * Stores the provided lockfile.
+				 * @param {Lockfile} lockfile lockfile instance
+				 * @param {string} url url to store
+				 * @param {LockfileEntry | "ignore" | "no-cache"} entry lockfile entry
+				 */
+				const storeLockEntry = (lockfile, url, entry) => {
+					const oldEntry = lockfile.entries.get(url);
+					if (lockfileUpdates === undefined) lockfileUpdates = new Map();
+					lockfileUpdates.set(url, entry);
+					lockfile.entries.set(url, entry);
+					if (!oldEntry) {
+						logger.log(`${url} added to lockfile`);
+					} else if (typeof oldEntry === "string") {
+						if (typeof entry === "string") {
+							logger.log(`${url} updated in lockfile: ${oldEntry} -> ${entry}`);
+						} else {
+							logger.log(
+								`${url} updated in lockfile: ${oldEntry} -> ${entry.resolved}`
+							);
+						}
+					} else if (typeof entry === "string") {
+						logger.log(
+							`${url} updated in lockfile: ${oldEntry.resolved} -> ${entry}`
+						);
+					} else if (oldEntry.resolved !== entry.resolved) {
+						logger.log(
+							`${url} updated in lockfile: ${oldEntry.resolved} -> ${entry.resolved}`
+						);
+					} else if (oldEntry.integrity !== entry.integrity) {
+						logger.log(`${url} updated in lockfile: content changed`);
+					} else if (oldEntry.contentType !== entry.contentType) {
+						logger.log(
+							`${url} updated in lockfile: ${oldEntry.contentType} -> ${entry.contentType}`
+						);
+					} else {
+						logger.log(`${url} updated in lockfile`);
+					}
+				};
+
+				/**
+				 * Stores the provided lockfile.
+				 * @param {Lockfile} lockfile lockfile
+				 * @param {string} url url
+				 * @param {ResolveContentResult} result result
+				 * @param {(err: Error | null, result?: ResolveContentResult) => void} callback callback
+				 * @returns {void}
+				 */
+				const storeResult = (lockfile, url, result, callback) => {
+					if (result.storeLock) {
+						storeLockEntry(lockfile, url, result.entry);
+						if (!cacheLocation || !result.content) {
+							return callback(null, result);
+						}
+						const key = getCacheKey(result.entry.resolved);
+						const filePath = join(intermediateFs, cacheLocation, key);
+						mkdirp(intermediateFs, dirname(intermediateFs, filePath), (err) => {
+							if (err) return callback(err);
+							intermediateFs.writeFile(filePath, result.content, (err) => {
+								if (err) return callback(err);
+								callback(null, result);
+							});
+						});
+					} else {
+						storeLockEntry(lockfile, url, "no-cache");
+						callback(null, result);
+					}
+				};
+
+				for (const { scheme, fetch } of schemes) {
+					/**
+					 * Validate redirect location.
+					 * @param {string} location Location header value (relative or absolute)
+					 * @param {string} base current absolute URL
+					 * @returns {string} absolute, validated redirect target
+					 */
+					const validateRedirectLocation = (location, base) => {
+						/** @type {URL} */
+						let nextUrl;
+						try {
+							nextUrl = new URL(location, base);
+						} catch (err) {
+							throw new Error(
+								`Invalid redirect URL: ${sanitizeUrlForError(location)}`,
+								{ cause: err }
+							);
+						}
+						if (nextUrl.protocol !== "http:" && nextUrl.protocol !== "https:") {
+							throw new Error(
+								`Redirected URL uses disallowed protocol: ${sanitizeUrlForError(nextUrl.href)}`
+							);
+						}
+						if (!isAllowed(nextUrl.href)) {
+							throw new Error(
+								`${nextUrl.href} doesn't match the allowedUris policy after redirect. These URIs are allowed:\n${allowedUris
+									.map((uri) => ` - ${uri}`)
+									.join("\n")}`
+							);
+						}
+						return nextUrl.href;
+					};
+					/**
+					 * Processes the provided url.
+					 * @param {string} url URL
+					 * @param {string | null} integrity integrity
+					 * @param {(err: Error | null, resolveContentResult?: ResolveContentResult) => void} callback callback
+					 * @param {number=} redirectCount number of followed redirects
+					 */
+					const resolveContent = (
+						url,
+						integrity,
+						callback,
+						redirectCount = 0
+					) => {
+						/**
+						 * Processes the provided err.
+						 * @param {Error | null} err error
+						 * @param {FetchResult=} _result fetch result
+						 * @returns {void}
+						 */
+						const handleResult = (err, _result) => {
+							if (err) return callback(err);
+
+							const result = /** @type {FetchResult} */ (_result);
+
+							if ("location" in result) {
+								// Validate redirect target before following
+								/** @type {string} */
+								let absolute;
+								try {
+									absolute = validateRedirectLocation(result.location, url);
+								} catch (err_) {
+									return callback(/** @type {Error} */ (err_));
+								}
+								if (redirectCount >= MAX_REDIRECTS) {
+									return callback(new Error("Too many redirects"));
+								}
+								return resolveContent(
+									absolute,
+									integrity,
+									(err, innerResult) => {
+										if (err) return callback(err);
+										const { entry, content, storeLock } =
+											/** @type {ResolveContentResult} */ (innerResult);
+										callback(null, {
+											entry,
+											content,
+											storeLock: storeLock && result.storeLock
+										});
+									},
+									redirectCount + 1
+								);
+							}
+
+							if (
+								!result.fresh &&
+								integrity &&
+								result.entry.integrity !== integrity &&
+								!verifyIntegrity(result.content, integrity)
+							) {
+								return fetchContent.force(url, handleResult);
+							}
+
+							return callback(null, {
+								entry: result.entry,
+								content: result.content,
+								storeLock: result.storeLock
+							});
+						};
+
+						fetchContent(url, handleResult);
+					};
+
+					/**
+					 * Processes the provided url.
+					 * @param {string} url URL
+					 * @param {FetchResult | RedirectFetchResult | undefined} cachedResult result from cache
+					 * @param {(err: Error | null, fetchResult?: FetchResult) => void} callback callback
+					 * @returns {void}
+					 */
+					const fetchContentRaw = (url, cachedResult, callback) => {
+						const requestTime = Date.now();
+						/** @type {OutgoingHttpHeaders} */
+						const headers = {
+							"accept-encoding": "gzip, deflate, br",
+							"user-agent": "webpack"
+						};
+
+						if (cachedResult && cachedResult.etag) {
+							headers["if-none-match"] = cachedResult.etag;
+						}
+
+						fetch(new URL(url), { headers }, (res) => {
+							const etag = res.headers.etag;
+							const location = res.headers.location;
+							const cacheControl = res.headers["cache-control"];
+							const { storeLock, storeCache, validUntil } = parseCacheControl(
+								cacheControl,
+								requestTime
+							);
+							/**
+							 * Processes the provided partial result.
+							 * @param {Partial<Pick<FetchResultMeta, "fresh">> & (Pick<RedirectFetchResult, "location"> | Pick<ContentFetchResult, "content" | "entry">)} partialResult result
+							 * @returns {void}
+							 */
+							const finishWith = (partialResult) => {
+								if ("location" in partialResult) {
+									logger.debug(
+										`GET ${url} [${res.statusCode}] -> ${partialResult.location}`
+									);
+								} else {
+									logger.debug(
+										`GET ${url} [${res.statusCode}] ${Math.ceil(
+											partialResult.content.length / 1024
+										)} kB${!storeLock ? " no-cache" : ""}`
+									);
+								}
+								const result = {
+									...partialResult,
+									fresh: true,
+									storeLock,
+									storeCache,
+									validUntil,
+									etag
+								};
+								if (!storeCache) {
+									logger.log(
+										`${url} can't be stored in cache, due to Cache-Control header: ${cacheControl}`
+									);
+									return callback(null, result);
+								}
+								cache.store(
+									url,
+									null,
+									{
+										...result,
+										fresh: false
+									},
+									(err) => {
+										if (err) {
+											logger.warn(
+												`${url} can't be stored in cache: ${err.message}`
+											);
+											logger.debug(err.stack);
+										}
+										callback(null, result);
+									}
+								);
+							};
+							if (res.statusCode === 304) {
+								const result = /** @type {FetchResult} */ (cachedResult);
+								if (
+									result.validUntil < validUntil ||
+									result.storeLock !== storeLock ||
+									result.storeCache !== storeCache ||
+									result.etag !== etag
+								) {
+									return finishWith(result);
+								}
+								logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
+								return callback(null, { ...result, fresh: true });
+							}
+							if (
+								location &&
+								res.statusCode &&
+								res.statusCode >= 301 &&
+								res.statusCode <= 308
+							) {
+								/** @type {string} */
+								let absolute;
+								try {
+									absolute = validateRedirectLocation(location, url);
+								} catch (err) {
+									logger.log(
+										`GET ${url} [${res.statusCode}] -> ${String(location)} (rejected: ${/** @type {Error} */ (err).message})`
+									);
+									return callback(/** @type {Error} */ (err));
+								}
+								const result = { location: absolute };
+								if (
+									!cachedResult ||
+									!("location" in cachedResult) ||
+									cachedResult.location !== result.location ||
+									cachedResult.validUntil < validUntil ||
+									cachedResult.storeLock !== storeLock ||
+									cachedResult.storeCache !== storeCache ||
+									cachedResult.etag !== etag
+								) {
+									return finishWith(result);
+								}
+								logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
+								return callback(null, {
+									...result,
+									fresh: true,
+									storeLock,
+									storeCache,
+									validUntil,
+									etag
+								});
+							}
+							const contentType = res.headers["content-type"] || "";
+							/** @type {Buffer[]} */
+							const bufferArr = [];
+
+							const contentEncoding = res.headers["content-encoding"];
+							/** @type {Readable} */
+							let stream = res;
+							if (contentEncoding === "gzip") {
+								stream = stream.pipe(createGunzip());
+							} else if (contentEncoding === "br") {
+								stream = stream.pipe(createBrotliDecompress());
+							} else if (contentEncoding === "deflate") {
+								stream = stream.pipe(createInflate());
+							}
+
+							stream.on(
+								"data",
+								/**
+								 * Handles the callback logic for this hook.
+								 * @param {Buffer} chunk chunk
+								 */
+								(chunk) => {
+									bufferArr.push(chunk);
+								}
+							);
+
+							stream.on("end", () => {
+								if (!res.complete) {
+									logger.log(`GET ${url} [${res.statusCode}] (terminated)`);
+									return callback(new Error(`${url} request was terminated`));
+								}
+
+								const content = Buffer.concat(bufferArr);
+
+								if (res.statusCode !== 200) {
+									logger.log(`GET ${url} [${res.statusCode}]`);
+									return callback(
+										new Error(
+											`${url} request status code = ${
+												res.statusCode
+											}\n${content.toString("utf8")}`
+										)
+									);
+								}
+
+								const integrity = computeIntegrity(content);
+								const entry = { resolved: url, integrity, contentType };
+
+								finishWith({
+									entry,
+									content
+								});
+							});
+						}).on("error", (err) => {
+							logger.log(`GET ${url} (error)`);
+							err.message += `\nwhile fetching ${url}`;
+							callback(err);
+						});
+					};
+
+					const fetchContent = cachedWithKey(
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {string} url URL
+						 * @param {(err: Error | null, result?: FetchResult) => void} callback callback
+						 * @returns {void}
+						 */
+						(url, callback) => {
+							cache.get(url, null, (err, cachedResult) => {
+								if (err) return callback(err);
+								if (cachedResult) {
+									const isValid = cachedResult.validUntil >= Date.now();
+									if (isValid) return callback(null, cachedResult);
+								}
+								fetchContentRaw(url, cachedResult, callback);
+							});
+						},
+						(url, callback) => fetchContentRaw(url, undefined, callback)
+					);
+
+					/**
+					 * Checks whether this http uri plugin is allowed.
+					 * @param {string} uri uri
+					 * @returns {boolean} true when allowed, otherwise false
+					 */
+					const isAllowed = (uri) => {
+						/** @type {URL} */
+						let parsedUri;
+						try {
+							// Parse the URI to prevent userinfo bypass attacks
+							// (e.g., http://allowed@malicious/path where @malicious is the actual host)
+							parsedUri = new URL(uri);
+						} catch (_err) {
+							return false;
+						}
+						for (const allowed of allowedUris) {
+							if (typeof allowed === "string") {
+								/** @type {URL} */
+								let parsedAllowed;
+								try {
+									parsedAllowed = new URL(allowed);
+								} catch (_err) {
+									continue;
+								}
+								if (parsedUri.href.startsWith(parsedAllowed.href)) {
+									return true;
+								}
+							} else if (typeof allowed === "function") {
+								if (allowed(parsedUri.href)) return true;
+							} else if (allowed.test(parsedUri.href)) {
+								return true;
+							}
+						}
+						return false;
+					};
+
+					/** @typedef {{ entry: LockfileEntry, content: Buffer }} Info */
+
+					const getInfo = cachedWithKey(
+						/**
+						 * Processes the provided url.
+						 * @param {string} url the url
+						 * @param {(err: Error | null, info?: Info) => void} callback callback
+						 * @returns {void}
+						 */
+						// eslint-disable-next-line no-loop-func
+						(url, callback) => {
+							if (!isAllowed(url)) {
+								return callback(
+									new Error(
+										`${url} doesn't match the allowedUris policy. These URIs are allowed:\n${allowedUris
+											.map((uri) => ` - ${uri}`)
+											.join("\n")}`
+									)
+								);
+							}
+							getLockfile((err, _lockfile) => {
+								if (err) return callback(err);
+								const lockfile = /** @type {Lockfile} */ (_lockfile);
+								const entryOrString = lockfile.entries.get(url);
+								if (!entryOrString) {
+									if (frozen) {
+										return callback(
+											new Error(
+												`${url} has no lockfile entry and lockfile is frozen`
+											)
+										);
+									}
+									resolveContent(url, null, (err, result) => {
+										if (err) return callback(err);
+										storeResult(
+											/** @type {Lockfile} */
+											(lockfile),
+											url,
+											/** @type {ResolveContentResult} */
+											(result),
+											callback
+										);
+									});
+									return;
+								}
+								if (typeof entryOrString === "string") {
+									const entryTag = entryOrString;
+									resolveContent(url, null, (err, _result) => {
+										if (err) return callback(err);
+										const result =
+											/** @type {ResolveContentResult} */
+											(_result);
+										if (!result.storeLock || entryTag === "ignore") {
+											return callback(null, result);
+										}
+										if (frozen) {
+											return callback(
+												new Error(
+													`${url} used to have ${entryTag} lockfile entry and has content now, but lockfile is frozen`
+												)
+											);
+										}
+										if (!upgrade) {
+											return callback(
+												new Error(
+													`${url} used to have ${entryTag} lockfile entry and has content now.
+This should be reflected in the lockfile, so this lockfile entry must be upgraded, but upgrading is not enabled.
+Remove this line from the lockfile to force upgrading.`
+												)
+											);
+										}
+										storeResult(lockfile, url, result, callback);
+									});
+									return;
+								}
+								let entry = entryOrString;
+								/**
+								 * Processes the provided locked content.
+								 * @param {Buffer=} lockedContent locked content
+								 */
+								const doFetch = (lockedContent) => {
+									resolveContent(url, entry.integrity, (err, _result) => {
+										if (err) {
+											if (lockedContent) {
+												logger.warn(
+													`Upgrade request to ${url} failed: ${err.message}`
+												);
+												logger.debug(err.stack);
+												return callback(null, {
+													entry,
+													content: lockedContent
+												});
+											}
+											return callback(err);
+										}
+										const result =
+											/** @type {ResolveContentResult} */
+											(_result);
+										if (!result.storeLock) {
+											// When the lockfile entry should be no-cache
+											// we need to update the lockfile
+											if (frozen) {
+												return callback(
+													new Error(
+														`${url} has a lockfile entry and is no-cache now, but lockfile is frozen\nLockfile: ${entryToString(
+															entry
+														)}`
+													)
+												);
+											}
+											storeResult(lockfile, url, result, callback);
+											return;
+										}
+										if (!areLockfileEntriesEqual(result.entry, entry)) {
+											// When the lockfile entry is outdated
+											// we need to update the lockfile
+											if (frozen) {
+												return callback(
+													new Error(
+														`${url} has an outdated lockfile entry, but lockfile is frozen\nLockfile: ${entryToString(
+															entry
+														)}\nExpected: ${entryToString(result.entry)}`
+													)
+												);
+											}
+											storeResult(lockfile, url, result, callback);
+											return;
+										}
+										if (!lockedContent && cacheLocation) {
+											// When the lockfile cache content is missing
+											// we need to update the lockfile
+											if (frozen) {
+												return callback(
+													new Error(
+														`${url} is missing content in the lockfile cache, but lockfile is frozen\nLockfile: ${entryToString(
+															entry
+														)}`
+													)
+												);
+											}
+											storeResult(lockfile, url, result, callback);
+											return;
+										}
+										return callback(null, result);
+									});
+								};
+								if (cacheLocation) {
+									// When there is a lockfile cache
+									// we read the content from there
+									const key = getCacheKey(entry.resolved);
+									const filePath = join(intermediateFs, cacheLocation, key);
+									fs.readFile(filePath, (err, result) => {
+										if (err) {
+											if (err.code === "ENOENT") return doFetch();
+											return callback(err);
+										}
+										const content = /** @type {Buffer} */ (result);
+										/**
+										 * Continue with cached content.
+										 * @param {Buffer | undefined} _result result
+										 * @returns {void}
+										 */
+										const continueWithCachedContent = (_result) => {
+											if (!upgrade) {
+												// When not in upgrade mode, we accept the result from the lockfile cache
+												return callback(null, { entry, content });
+											}
+											return doFetch(content);
+										};
+										if (!verifyIntegrity(content, entry.integrity)) {
+											/** @type {Buffer | undefined} */
+											let contentWithChangedEol;
+											let isEolChanged = false;
+											try {
+												contentWithChangedEol = Buffer.from(
+													content.toString("utf8").replace(/\r\n/g, "\n")
+												);
+												isEolChanged = verifyIntegrity(
+													contentWithChangedEol,
+													entry.integrity
+												);
+											} catch (_err) {
+												// ignore
+											}
+											if (isEolChanged) {
+												if (!warnedAboutEol) {
+													const explainer = `Incorrect end of line sequence was detected in the lockfile cache.
+The lockfile cache is protected by integrity checks, so any external modification will lead to a corrupted lockfile cache.
+When using git make sure to configure .gitattributes correctly for the lockfile cache:
+  **/*webpack.lock.data/** -text
+This will avoid that the end of line sequence is changed by git on Windows.`;
+													if (frozen) {
+														logger.error(explainer);
+													} else {
+														logger.warn(explainer);
+														logger.info(
+															"Lockfile cache will be automatically fixed now, but when lockfile is frozen this would result in an error."
+														);
+													}
+													warnedAboutEol = true;
+												}
+												if (!frozen) {
+													// "fix" the end of line sequence of the lockfile content
+													logger.log(
+														`${filePath} fixed end of line sequence (\\r\\n instead of \\n).`
+													);
+													intermediateFs.writeFile(
+														filePath,
+														/** @type {Buffer} */
+														(contentWithChangedEol),
+														(err) => {
+															if (err) return callback(err);
+															continueWithCachedContent(
+																/** @type {Buffer} */
+																(contentWithChangedEol)
+															);
+														}
+													);
+													return;
+												}
+											}
+											if (frozen) {
+												return callback(
+													new Error(
+														`${
+															entry.resolved
+														} integrity mismatch, expected content with integrity ${
+															entry.integrity
+														} but got ${computeIntegrity(content)}.
+Lockfile corrupted (${
+															isEolChanged
+																? "end of line sequence was unexpectedly changed"
+																: "incorrectly merged? changed by other tools?"
+														}).
+Run build with un-frozen lockfile to automatically fix lockfile.`
+													)
+												);
+											}
+											// "fix" the lockfile entry to the correct integrity
+											// the content has priority over the integrity value
+											entry = {
+												...entry,
+												integrity: computeIntegrity(content)
+											};
+											storeLockEntry(lockfile, url, entry);
+										}
+										continueWithCachedContent(result);
+									});
+								} else {
+									doFetch();
+								}
+							});
+						}
+					);
+
+					/**
+					 * Respond with url module.
+					 * @param {URL} url url
+					 * @param {ResourceDataWithData} resourceData resource data
+					 * @param {(err: Error | null, result: true | void) => void} callback callback
+					 */
+					const respondWithUrlModule = (url, resourceData, callback) => {
+						getInfo(url.href, (err, _result) => {
+							if (err) return callback(err);
+							const result = /** @type {Info} */ (_result);
+							resourceData.resource = url.href;
+							resourceData.path = url.origin + url.pathname;
+							resourceData.query = url.search;
+							resourceData.fragment = url.hash;
+							resourceData.context = new URL(
+								".",
+								result.entry.resolved
+							).href.slice(0, -1);
+							resourceData.data.mimetype = result.entry.contentType;
+							callback(null, true);
+						});
+					};
+					normalModuleFactory.hooks.resolveForScheme
+						.for(scheme)
+						.tapAsync(PLUGIN_NAME, (resourceData, resolveData, callback) => {
+							respondWithUrlModule(
+								new URL(resourceData.resource),
+								resourceData,
+								callback
+							);
+						});
+					normalModuleFactory.hooks.resolveInScheme
+						.for(scheme)
+						.tapAsync(PLUGIN_NAME, (resourceData, data, callback) => {
+							// Only handle relative urls (./xxx, ../xxx, /xxx, //xxx)
+							if (
+								data.dependencyType !== "url" &&
+								!/^\.{0,2}\//.test(resourceData.resource)
+							) {
+								return callback();
+							}
+							respondWithUrlModule(
+								new URL(resourceData.resource, `${data.context}/`),
+								resourceData,
+								callback
+							);
+						});
+					const hooks = NormalModule.getCompilationHooks(compilation);
+					hooks.readResourceForScheme
+						.for(scheme)
+						.tapAsync(PLUGIN_NAME, (resource, module, callback) =>
+							getInfo(resource, (err, _result) => {
+								if (err) return callback(err);
+								const result = /** @type {Info} */ (_result);
+								if (module) {
+									/** @type {BuildInfo} */
+									(module.buildInfo).resourceIntegrity = result.entry.integrity;
+								}
+								callback(null, result.content);
+							})
+						);
+					hooks.needBuild.tapAsync(PLUGIN_NAME, (module, context, callback) => {
+						if (module.resource && module.resource.startsWith(`${scheme}://`)) {
+							getInfo(module.resource, (err, _result) => {
+								if (err) return callback(err);
+								const result = /** @type {Info} */ (_result);
+								if (
+									result.entry.integrity !==
+									/** @type {BuildInfo} */
+									(module.buildInfo).resourceIntegrity
+								) {
+									return callback(null, true);
+								}
+								callback();
+							});
+						} else {
+							return callback();
+						}
+					});
+				}
+				compilation.hooks.finishModules.tapAsync(
+					PLUGIN_NAME,
+					(modules, callback) => {
+						if (!lockfileUpdates) return callback();
+						const ext = extname(lockfileLocation);
+						const tempFile = join(
+							intermediateFs,
+							dirname(intermediateFs, lockfileLocation),
+							`.${basename(lockfileLocation, ext)}.${
+								(Math.random() * 10000) | 0
+							}${ext}`
+						);
+
+						const writeDone = () => {
+							const nextOperation =
+								/** @type {InProgressWriteItem[]} */
+								(inProgressWrite).shift();
+							if (nextOperation) {
+								nextOperation();
+							} else {
+								inProgressWrite = undefined;
+							}
+						};
+						const runWrite = () => {
+							intermediateFs.readFile(lockfileLocation, (err, buffer) => {
+								if (err && err.code !== "ENOENT") {
+									writeDone();
+									return callback(err);
+								}
+								const lockfile = buffer
+									? Lockfile.parse(buffer.toString("utf8"))
+									: new Lockfile();
+								for (const [key, value] of /** @type {LockfileUpdates} */ (
+									lockfileUpdates
+								)) {
+									lockfile.entries.set(key, value);
+								}
+								intermediateFs.writeFile(
+									tempFile,
+									lockfile.toString(),
+									(err) => {
+										if (err) {
+											writeDone();
+											return (
+												/** @type {NonNullable<IntermediateFileSystem["unlink"]>} */
+												(intermediateFs.unlink)(tempFile, () => callback(err))
+											);
+										}
+										intermediateFs.rename(tempFile, lockfileLocation, (err) => {
+											if (err) {
+												writeDone();
+												return (
+													/** @type {NonNullable<IntermediateFileSystem["unlink"]>} */
+													(intermediateFs.unlink)(tempFile, () => callback(err))
+												);
+											}
+											writeDone();
+											callback();
+										});
+									}
+								);
+							});
+						};
+						if (inProgressWrite) {
+							inProgressWrite.push(runWrite);
+						} else {
+							inProgressWrite = [];
+							runWrite();
+						}
+					}
+				);
+			}
+		);
+	}
+}
+
+module.exports = HttpUriPlugin;
Index: frontend/node_modules/webpack/lib/schemes/VirtualUrlPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/schemes/VirtualUrlPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/schemes/VirtualUrlPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,300 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+const { getContext } = require("loader-runner");
+
+const NormalModule = require("../NormalModule");
+const ModuleNotFoundError = require("../errors/ModuleNotFoundError");
+const { isAbsolute, join } = require("../util/fs");
+const { parseResourceWithoutFragment } = require("../util/identifier");
+
+const DEFAULT_SCHEME = "virtual";
+
+const PLUGIN_NAME = "VirtualUrlPlugin";
+
+/**
+ * Defines the compiler type used by this module.
+ * @typedef {import("../Compiler")} Compiler
+ * @typedef {import("../../declarations/plugins/schemes/VirtualUrlPlugin").VirtualModule} VirtualModuleConfig
+ * @typedef {import("../../declarations/plugins/schemes/VirtualUrlPlugin").VirtualModuleContent} VirtualModuleInput
+ * @typedef {import("../../declarations/plugins/schemes/VirtualUrlPlugin").VirtualUrlOptions} VirtualUrlOptions
+ */
+
+/** @typedef {(loaderContext: LoaderContext<EXPECTED_ANY>) => Promise<string | Buffer> | string | Buffer} SourceFn */
+/** @typedef {() => string} VersionFn */
+/** @typedef {{ [key: string]: VirtualModuleInput }} VirtualModules */
+
+/**
+ * Defines the loader context type used by this module.
+ * @template T
+ * @typedef {import("../../declarations/LoaderContext").LoaderContext<T>} LoaderContext
+ */
+
+/**
+ * Normalizes a virtual module definition into a standard format
+ * @param {VirtualModuleInput} virtualConfig The virtual module to normalize
+ * @returns {VirtualModuleConfig} The normalized virtual module
+ */
+function normalizeModule(virtualConfig) {
+	if (typeof virtualConfig === "string") {
+		return {
+			type: "",
+			source() {
+				return virtualConfig;
+			}
+		};
+	} else if (typeof virtualConfig === "function") {
+		return {
+			type: "",
+			source: virtualConfig
+		};
+	}
+	return virtualConfig;
+}
+
+/** @typedef {{ [key: string]: VirtualModuleConfig }} NormalizedModules */
+
+/**
+ * Normalizes all virtual modules with the given scheme
+ * @param {VirtualModules} virtualConfigs The virtual modules to normalize
+ * @param {string} scheme The URL scheme to use
+ * @returns {NormalizedModules} The normalized virtual modules
+ */
+function normalizeModules(virtualConfigs, scheme) {
+	return Object.keys(virtualConfigs).reduce((pre, id) => {
+		pre[toVid(id, scheme)] = normalizeModule(virtualConfigs[id]);
+		return pre;
+	}, /** @type {NormalizedModules} */ ({}));
+}
+
+/**
+ * Converts a module id and scheme to a virtual module id
+ * @param {string} id The module id
+ * @param {string} scheme The URL scheme
+ * @returns {string} The virtual module id
+ */
+function toVid(id, scheme) {
+	return `${scheme}:${id}`;
+}
+
+/**
+ * Converts a virtual module id to a module id
+ * @param {string} vid The virtual module id
+ * @param {string} scheme The URL scheme
+ * @returns {string} The module id
+ */
+function fromVid(vid, scheme) {
+	return vid.replace(`${scheme}:`, "");
+}
+
+const VALUE_DEP_VERSION = `webpack/${PLUGIN_NAME}/version`;
+
+/**
+ * Converts a module id and scheme to a cache key
+ * @param {string} id The module id
+ * @param {string} scheme The URL scheme
+ * @returns {string} The cache key
+ */
+function toCacheKey(id, scheme) {
+	return `${VALUE_DEP_VERSION}/${toVid(id, scheme)}`;
+}
+
+class VirtualUrlPlugin {
+	/**
+	 * Creates an instance of VirtualUrlPlugin.
+	 * @param {VirtualModules} modules The virtual modules
+	 * @param {Omit<VirtualUrlOptions, "modules"> | string=} schemeOrOptions The URL scheme to use
+	 */
+	constructor(modules, schemeOrOptions) {
+		/** @type {VirtualUrlOptions} */
+		this.options = {
+			modules,
+			...(typeof schemeOrOptions === "string"
+				? { scheme: schemeOrOptions }
+				: schemeOrOptions || {})
+		};
+
+		/** @type {string} */
+		this.scheme = this.options.scheme || DEFAULT_SCHEME;
+		/** @type {VirtualUrlOptions["context"]} */
+		this.context = this.options.context || "auto";
+		/** @type {NormalizedModules} */
+		this.modules = normalizeModules(this.options.modules, this.scheme);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/schemes/VirtualUrlPlugin.json"),
+				this.options,
+				{
+					name: "Virtual Url Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/schemes/VirtualUrlPlugin.check")(
+						options
+					)
+			);
+		});
+
+		const scheme = this.scheme;
+		const cachedParseResourceWithoutFragment =
+			parseResourceWithoutFragment.bindCache(compiler.root);
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.hooks.assetPath.tap(
+					{ name: PLUGIN_NAME, before: "TemplatedPathPlugin" },
+					(path, data) => {
+						if (data.filename && this.modules[data.filename]) {
+							/**
+							 * Returns safe path.
+							 * @param {string} str path
+							 * @returns {string} safe path
+							 */
+							const toSafePath = (str) =>
+								`__${str
+									.replace(/:/g, "__")
+									.replace(/^[^a-z0-9]+|[^a-z0-9]+$/gi, "")
+									.replace(/[^a-z0-9._-]+/gi, "_")}`;
+
+							// filename: virtual:logo.svg -> __virtual__logo.svg
+							data.filename = toSafePath(data.filename);
+						}
+						return path;
+					}
+				);
+
+				normalModuleFactory.hooks.resolveForScheme
+					.for(scheme)
+					.tap(PLUGIN_NAME, (resourceData) => {
+						const virtualConfig = this.findVirtualModuleConfigById(
+							resourceData.resource
+						);
+						const url = cachedParseResourceWithoutFragment(
+							resourceData.resource
+						);
+						const path = url.path;
+						const type = virtualConfig.type || "";
+						const context = virtualConfig.context || this.context;
+
+						resourceData.path = path + type;
+						resourceData.resource = path;
+
+						if (context === "auto") {
+							const context = getContext(path);
+							if (context === path) {
+								resourceData.context = compiler.context;
+							} else {
+								const resolvedContext = fromVid(context, scheme);
+								resourceData.context = isAbsolute(resolvedContext)
+									? resolvedContext
+									: join(
+											/** @type {import("..").InputFileSystem} */
+											(compiler.inputFileSystem),
+											compiler.context,
+											resolvedContext
+										);
+							}
+						} else if (context && typeof context === "string") {
+							resourceData.context = context;
+						} else {
+							resourceData.context = compiler.context;
+						}
+
+						if (virtualConfig.version) {
+							const cacheKey = toCacheKey(resourceData.resource, scheme);
+							const cacheVersion = this.getCacheVersion(virtualConfig.version);
+							compilation.valueCacheVersions.set(
+								cacheKey,
+								/** @type {string} */ (cacheVersion)
+							);
+						}
+
+						return true;
+					});
+
+				const hooks = NormalModule.getCompilationHooks(compilation);
+				hooks.readResource
+					.for(scheme)
+					.tapAsync(PLUGIN_NAME, async (loaderContext, callback) => {
+						const { resourcePath } = loaderContext;
+						const module = /** @type {NormalModule} */ (loaderContext._module);
+						const cacheKey = toCacheKey(resourcePath, scheme);
+
+						const addVersionValueDependency = () => {
+							if (!module || !module.buildInfo) return;
+
+							const buildInfo = module.buildInfo;
+							if (!buildInfo.valueDependencies) {
+								buildInfo.valueDependencies = new Map();
+							}
+
+							const cacheVersion = compilation.valueCacheVersions.get(cacheKey);
+							if (compilation.valueCacheVersions.has(cacheKey)) {
+								buildInfo.valueDependencies.set(
+									cacheKey,
+									/** @type {string} */ (cacheVersion)
+								);
+							}
+						};
+
+						try {
+							const virtualConfig =
+								this.findVirtualModuleConfigById(resourcePath);
+							const content = await virtualConfig.source(loaderContext);
+							addVersionValueDependency();
+							callback(null, content);
+						} catch (err) {
+							callback(/** @type {Error} */ (err));
+						}
+					});
+			}
+		);
+	}
+
+	/**
+	 * Finds virtual module config by id.
+	 * @param {string} id The module id
+	 * @returns {VirtualModuleConfig} The virtual module config
+	 */
+	findVirtualModuleConfigById(id) {
+		const config = this.modules[id];
+		if (!config) {
+			throw new ModuleNotFoundError(
+				null,
+				new Error(`Can't resolve virtual module ${id}`),
+				{
+					name: `virtual module ${id}`
+				}
+			);
+		}
+		return config;
+	}
+
+	/**
+	 * Get the cache version for a given version value
+	 * @param {VersionFn | true | string} version The version value or function
+	 * @returns {string | undefined} The cache version
+	 */
+	getCacheVersion(version) {
+		return version === true
+			? undefined
+			: (typeof version === "function" ? version() : version) || "unset";
+	}
+}
+
+VirtualUrlPlugin.DEFAULT_SCHEME = DEFAULT_SCHEME;
+
+module.exports = VirtualUrlPlugin;
Index: frontend/node_modules/webpack/lib/serialization/AggregateErrorSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/AggregateErrorSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/AggregateErrorSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {Error & { cause?: unknown, errors: EXPECTED_ANY[] }} AggregateError */
+
+class AggregateErrorSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {AggregateError} obj error
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		context.write(obj.errors);
+		context.write(obj.message);
+		context.write(obj.stack);
+		context.write(obj.cause);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {AggregateError} error
+	 */
+	deserialize(context) {
+		const errors = context.read();
+		// eslint-disable-next-line n/no-unsupported-features/es-builtins, n/no-unsupported-features/es-syntax, unicorn/error-message
+		const err = new AggregateError(errors);
+
+		err.message = context.read();
+		err.stack = context.read();
+		err.cause = context.read();
+
+		return err;
+	}
+}
+
+module.exports = AggregateErrorSerializer;
Index: frontend/node_modules/webpack/lib/serialization/ArraySerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/ArraySerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/ArraySerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ArraySerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @template T
+	 * @param {T[]} array array
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(array, context) {
+		context.write(array.length);
+		for (const item of array) context.write(item);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @template T
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {T[]} array
+	 */
+	deserialize(context) {
+		/** @type {number} */
+		const length = context.read();
+		/** @type {T[]} */
+		const array = [];
+		for (let i = 0; i < length; i++) {
+			array.push(context.read());
+		}
+		return array;
+	}
+}
+
+module.exports = ArraySerializer;
Index: frontend/node_modules/webpack/lib/serialization/BinaryMiddleware.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/BinaryMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/BinaryMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1183 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const memoize = require("../util/memoize");
+const SerializerMiddleware = require("./SerializerMiddleware");
+
+/** @typedef {import("./types").BufferSerializableType} BufferSerializableType */
+/** @typedef {import("./types").PrimitiveSerializableType} PrimitiveSerializableType */
+
+/*
+Format:
+
+File -> Section*
+
+Section -> NullsSection |
+					 BooleansSection |
+					 F64NumbersSection |
+					 I32NumbersSection |
+					 I8NumbersSection |
+					 ShortStringSection |
+					 BigIntSection |
+					 I32BigIntSection |
+					 I8BigIntSection
+					 StringSection |
+					 BufferSection |
+					 NopSection
+
+
+
+NullsSection ->
+	NullHeaderByte | Null2HeaderByte | Null3HeaderByte |
+	Nulls8HeaderByte 0xnn (n:count - 4) |
+	Nulls32HeaderByte n:ui32 (n:count - 260) |
+BooleansSection -> TrueHeaderByte | FalseHeaderByte | BooleansSectionHeaderByte BooleansCountAndBitsByte
+F64NumbersSection -> F64NumbersSectionHeaderByte f64*
+I32NumbersSection -> I32NumbersSectionHeaderByte i32*
+I8NumbersSection -> I8NumbersSectionHeaderByte i8*
+ShortStringSection -> ShortStringSectionHeaderByte ascii-byte*
+StringSection -> StringSectionHeaderByte i32:length utf8-byte*
+BufferSection -> BufferSectionHeaderByte i32:length byte*
+NopSection --> NopSectionHeaderByte
+BigIntSection -> BigIntSectionHeaderByte i32:length ascii-byte*
+I32BigIntSection -> I32BigIntSectionHeaderByte i32
+I8BigIntSection -> I8BigIntSectionHeaderByte i8
+
+ShortStringSectionHeaderByte -> 0b1nnn_nnnn (n:length)
+
+F64NumbersSectionHeaderByte -> 0b001n_nnnn (n:count - 1)
+I32NumbersSectionHeaderByte -> 0b010n_nnnn (n:count - 1)
+I8NumbersSectionHeaderByte -> 0b011n_nnnn (n:count - 1)
+
+NullsSectionHeaderByte -> 0b0001_nnnn (n:count - 1)
+BooleansCountAndBitsByte ->
+	0b0000_1xxx (count = 3) |
+	0b0001_xxxx (count = 4) |
+	0b001x_xxxx (count = 5) |
+	0b01xx_xxxx (count = 6) |
+	0b1nnn_nnnn (n:count - 7, 7 <= count <= 133)
+	0xff n:ui32 (n:count, 134 <= count < 2^32)
+
+StringSectionHeaderByte -> 0b0000_1110
+BufferSectionHeaderByte -> 0b0000_1111
+NopSectionHeaderByte -> 0b0000_1011
+BigIntSectionHeaderByte -> 0b0001_1010
+I32BigIntSectionHeaderByte -> 0b0001_1100
+I8BigIntSectionHeaderByte -> 0b0001_1011
+FalseHeaderByte -> 0b0000_1100
+TrueHeaderByte -> 0b0000_1101
+
+RawNumber -> n (n <= 10)
+
+*/
+
+const LAZY_HEADER = 0x0b;
+const TRUE_HEADER = 0x0c;
+const FALSE_HEADER = 0x0d;
+const BOOLEANS_HEADER = 0x0e;
+const NULL_HEADER = 0x10;
+const NULL2_HEADER = 0x11;
+const NULL3_HEADER = 0x12;
+const NULLS8_HEADER = 0x13;
+const NULLS32_HEADER = 0x14;
+const NULL_AND_I8_HEADER = 0x15;
+const NULL_AND_I32_HEADER = 0x16;
+const NULL_AND_TRUE_HEADER = 0x17;
+const NULL_AND_FALSE_HEADER = 0x18;
+const BIGINT_HEADER = 0x1a;
+const BIGINT_I8_HEADER = 0x1b;
+const BIGINT_I32_HEADER = 0x1c;
+const STRING_HEADER = 0x1e;
+const BUFFER_HEADER = 0x1f;
+const I8_HEADER = 0x60;
+const I32_HEADER = 0x40;
+const F64_HEADER = 0x20;
+const SHORT_STRING_HEADER = 0x80;
+
+/** Uplift high-order bits */
+const NUMBERS_HEADER_MASK = 0xe0; // 0b1010_0000
+const NUMBERS_COUNT_MASK = 0x1f; // 0b0001_1111
+const SHORT_STRING_LENGTH_MASK = 0x7f; // 0b0111_1111
+
+const HEADER_SIZE = 1;
+const I8_SIZE = 1;
+const I32_SIZE = 4;
+const F64_SIZE = 8;
+
+const MEASURE_START_OPERATION = Symbol("MEASURE_START_OPERATION");
+const MEASURE_END_OPERATION = Symbol("MEASURE_END_OPERATION");
+
+/** @typedef {typeof MEASURE_START_OPERATION} MEASURE_START_OPERATION_TYPE */
+/** @typedef {typeof MEASURE_END_OPERATION} MEASURE_END_OPERATION_TYPE */
+
+/**
+ * Returns type of number for serialization.
+ * @param {number} n number
+ * @returns {0 | 1 | 2} type of number for serialization
+ */
+const identifyNumber = (n) => {
+	if (n === (n | 0)) {
+		if (n <= 127 && n >= -128) return 0;
+		if (n <= 2147483647 && n >= -2147483648) return 1;
+	}
+	return 2;
+};
+
+/**
+ * Returns type of bigint for serialization.
+ * @param {bigint} n bigint
+ * @returns {0 | 1 | 2} type of bigint for serialization
+ */
+const identifyBigInt = (n) => {
+	if (n <= BigInt(127) && n >= BigInt(-128)) return 0;
+	if (n <= BigInt(2147483647) && n >= BigInt(-2147483648)) return 1;
+	return 2;
+};
+
+/** @typedef {PrimitiveSerializableType[]} DeserializedType */
+/** @typedef {BufferSerializableType[]} SerializedType} */
+/** @typedef {{ retainedBuffer?: (x: Buffer) => Buffer }} Context} */
+
+/**
+ * Defines the lazy function type used by this module.
+ * @template LazyInputValue
+ * @template LazyOutputValue
+ * @typedef {import("./SerializerMiddleware").LazyFunction<LazyInputValue, LazyOutputValue, BinaryMiddleware, undefined>} LazyFunction
+ */
+
+/**
+ * Represents BinaryMiddleware.
+ * @extends {SerializerMiddleware<DeserializedType, SerializedType, Context>}
+ */
+class BinaryMiddleware extends SerializerMiddleware {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {DeserializedType} data data
+	 * @param {Context} context context object
+	 * @returns {SerializedType | Promise<SerializedType> | null} serialized data
+	 */
+	serialize(data, context) {
+		return this._serialize(data, context);
+	}
+
+	/**
+	 * Returns new lazy.
+	 * @param {LazyFunction<DeserializedType, SerializedType>} fn lazy function
+	 * @param {Context} context serialize function
+	 * @returns {LazyFunction<SerializedType, DeserializedType>} new lazy
+	 */
+	_serializeLazy(fn, context) {
+		return SerializerMiddleware.serializeLazy(fn, (data) =>
+			this._serialize(data, context)
+		);
+	}
+
+	/**
+	 * Returns serialized data.
+	 * @param {DeserializedType} data data
+	 * @param {Context} context context object
+	 * @param {{ leftOverBuffer: Buffer | null, allocationSize: number, increaseCounter: number }} allocationScope allocation scope
+	 * @returns {SerializedType} serialized data
+	 */
+	_serialize(
+		data,
+		context,
+		allocationScope = {
+			allocationSize: 1024,
+			increaseCounter: 0,
+			leftOverBuffer: null
+		}
+	) {
+		/** @type {Buffer | null} */
+		let leftOverBuffer = null;
+		/** @type {BufferSerializableType[]} */
+		let buffers = [];
+		/** @type {Buffer | null} */
+		let currentBuffer = allocationScope ? allocationScope.leftOverBuffer : null;
+		allocationScope.leftOverBuffer = null;
+		let currentPosition = 0;
+		if (currentBuffer === null) {
+			currentBuffer = Buffer.allocUnsafe(allocationScope.allocationSize);
+		}
+		/**
+		 * Processes the provided bytes needed.
+		 * @param {number} bytesNeeded bytes needed
+		 */
+		const allocate = (bytesNeeded) => {
+			if (currentBuffer !== null) {
+				if (currentBuffer.length - currentPosition >= bytesNeeded) return;
+				flush();
+			}
+			if (leftOverBuffer && leftOverBuffer.length >= bytesNeeded) {
+				currentBuffer = leftOverBuffer;
+				leftOverBuffer = null;
+			} else {
+				currentBuffer = Buffer.allocUnsafe(
+					Math.max(bytesNeeded, allocationScope.allocationSize)
+				);
+				if (
+					!(allocationScope.increaseCounter =
+						(allocationScope.increaseCounter + 1) % 4) &&
+					allocationScope.allocationSize < 16777216
+				) {
+					allocationScope.allocationSize <<= 1;
+				}
+			}
+		};
+		const flush = () => {
+			if (currentBuffer !== null) {
+				if (currentPosition > 0) {
+					buffers.push(
+						Buffer.from(
+							currentBuffer.buffer,
+							currentBuffer.byteOffset,
+							currentPosition
+						)
+					);
+				}
+				if (
+					!leftOverBuffer ||
+					leftOverBuffer.length < currentBuffer.length - currentPosition
+				) {
+					leftOverBuffer = Buffer.from(
+						currentBuffer.buffer,
+						currentBuffer.byteOffset + currentPosition,
+						currentBuffer.byteLength - currentPosition
+					);
+				}
+
+				currentBuffer = null;
+				currentPosition = 0;
+			}
+		};
+		/**
+		 * Processes the provided byte.
+		 * @param {number} byte byte
+		 */
+		const writeU8 = (byte) => {
+			/** @type {Buffer} */
+			(currentBuffer).writeUInt8(byte, currentPosition++);
+		};
+		/**
+		 * Processes the provided ui32.
+		 * @param {number} ui32 ui32
+		 */
+		const writeU32 = (ui32) => {
+			/** @type {Buffer} */
+			(currentBuffer).writeUInt32LE(ui32, currentPosition);
+			currentPosition += 4;
+		};
+		/** @type {number[]} */
+		const measureStack = [];
+		const measureStart = () => {
+			measureStack.push(buffers.length, currentPosition);
+		};
+		/**
+		 * Returns size.
+		 * @returns {number} size
+		 */
+		const measureEnd = () => {
+			const oldPos = /** @type {number} */ (measureStack.pop());
+			const buffersIndex = /** @type {number} */ (measureStack.pop());
+			let size = currentPosition - oldPos;
+			for (let i = buffersIndex; i < buffers.length; i++) {
+				size += buffers[i].length;
+			}
+			return size;
+		};
+		for (let i = 0; i < data.length; i++) {
+			const thing = data[i];
+			switch (typeof thing) {
+				case "function": {
+					if (!SerializerMiddleware.isLazy(thing)) {
+						throw new Error(`Unexpected function ${thing}`);
+					}
+					/** @type {SerializedType | LazyFunction<SerializedType, DeserializedType> | undefined} */
+					let serializedData =
+						SerializerMiddleware.getLazySerializedValue(thing);
+					if (serializedData === undefined) {
+						if (SerializerMiddleware.isLazy(thing, this)) {
+							flush();
+							allocationScope.leftOverBuffer = leftOverBuffer;
+							const result =
+								/** @type {PrimitiveSerializableType[]} */
+								(thing());
+							const data = this._serialize(result, context, allocationScope);
+							leftOverBuffer = allocationScope.leftOverBuffer;
+							allocationScope.leftOverBuffer = null;
+							SerializerMiddleware.setLazySerializedValue(thing, data);
+							serializedData = data;
+						} else {
+							serializedData = this._serializeLazy(thing, context);
+							flush();
+							buffers.push(serializedData);
+							break;
+						}
+					} else if (typeof serializedData === "function") {
+						flush();
+						buffers.push(serializedData);
+						break;
+					}
+					/** @type {number[]} */
+					const lengths = [];
+					for (const item of serializedData) {
+						/** @type {undefined | number} */
+						let last;
+						if (typeof item === "function") {
+							lengths.push(0);
+						} else if (item.length === 0) {
+							// ignore
+						} else if (
+							lengths.length > 0 &&
+							(last = lengths[lengths.length - 1]) !== 0
+						) {
+							const remaining = 0xffffffff - last;
+							if (remaining >= item.length) {
+								lengths[lengths.length - 1] += item.length;
+							} else {
+								lengths.push(item.length - remaining);
+								lengths[lengths.length - 2] = 0xffffffff;
+							}
+						} else {
+							lengths.push(item.length);
+						}
+					}
+					allocate(5 + lengths.length * 4);
+					writeU8(LAZY_HEADER);
+					writeU32(lengths.length);
+					for (const l of lengths) {
+						writeU32(l);
+					}
+					flush();
+					for (const item of serializedData) {
+						buffers.push(item);
+					}
+					break;
+				}
+				case "string": {
+					const len = Buffer.byteLength(thing);
+					if (len >= 128 || len !== thing.length) {
+						allocate(len + HEADER_SIZE + I32_SIZE);
+						writeU8(STRING_HEADER);
+						writeU32(len);
+						currentBuffer.write(thing, currentPosition);
+						currentPosition += len;
+					} else if (len >= 70) {
+						allocate(len + HEADER_SIZE);
+						writeU8(SHORT_STRING_HEADER | len);
+
+						currentBuffer.write(thing, currentPosition, "latin1");
+						currentPosition += len;
+					} else {
+						allocate(len + HEADER_SIZE);
+						writeU8(SHORT_STRING_HEADER | len);
+
+						for (let i = 0; i < len; i++) {
+							currentBuffer[currentPosition++] = thing.charCodeAt(i);
+						}
+					}
+					break;
+				}
+				case "bigint": {
+					const type = identifyBigInt(thing);
+					if (type === 0 && thing >= 0 && thing <= BigInt(10)) {
+						// shortcut for very small bigints
+						allocate(HEADER_SIZE + I8_SIZE);
+						writeU8(BIGINT_I8_HEADER);
+						writeU8(Number(thing));
+						break;
+					}
+
+					switch (type) {
+						case 0: {
+							let n = 1;
+							allocate(HEADER_SIZE + I8_SIZE * n);
+							writeU8(BIGINT_I8_HEADER | (n - 1));
+							while (n > 0) {
+								currentBuffer.writeInt8(
+									Number(/** @type {bigint} */ (data[i])),
+									currentPosition
+								);
+								currentPosition += I8_SIZE;
+								n--;
+								i++;
+							}
+							i--;
+							break;
+						}
+						case 1: {
+							let n = 1;
+							allocate(HEADER_SIZE + I32_SIZE * n);
+							writeU8(BIGINT_I32_HEADER | (n - 1));
+							while (n > 0) {
+								currentBuffer.writeInt32LE(
+									Number(/** @type {bigint} */ (data[i])),
+									currentPosition
+								);
+								currentPosition += I32_SIZE;
+								n--;
+								i++;
+							}
+							i--;
+							break;
+						}
+						default: {
+							const value = thing.toString();
+							const len = Buffer.byteLength(value);
+							allocate(len + HEADER_SIZE + I32_SIZE);
+							writeU8(BIGINT_HEADER);
+							writeU32(len);
+							currentBuffer.write(value, currentPosition);
+							currentPosition += len;
+							break;
+						}
+					}
+					break;
+				}
+				case "number": {
+					const type = identifyNumber(thing);
+					if (type === 0 && thing >= 0 && thing <= 10) {
+						// shortcut for very small numbers
+						allocate(I8_SIZE);
+						writeU8(thing);
+						break;
+					}
+					/**
+					 * amount of numbers to write
+					 * @type {number}
+					 */
+					let n = 1;
+					for (; n < 32 && i + n < data.length; n++) {
+						const item = data[i + n];
+						if (typeof item !== "number") break;
+						if (identifyNumber(item) !== type) break;
+					}
+					switch (type) {
+						case 0:
+							allocate(HEADER_SIZE + I8_SIZE * n);
+							writeU8(I8_HEADER | (n - 1));
+							while (n > 0) {
+								currentBuffer.writeInt8(
+									/** @type {number} */ (data[i]),
+									currentPosition
+								);
+								currentPosition += I8_SIZE;
+								n--;
+								i++;
+							}
+							break;
+						case 1:
+							allocate(HEADER_SIZE + I32_SIZE * n);
+							writeU8(I32_HEADER | (n - 1));
+							while (n > 0) {
+								currentBuffer.writeInt32LE(
+									/** @type {number} */ (data[i]),
+									currentPosition
+								);
+								currentPosition += I32_SIZE;
+								n--;
+								i++;
+							}
+							break;
+						case 2:
+							allocate(HEADER_SIZE + F64_SIZE * n);
+							writeU8(F64_HEADER | (n - 1));
+							while (n > 0) {
+								currentBuffer.writeDoubleLE(
+									/** @type {number} */ (data[i]),
+									currentPosition
+								);
+								currentPosition += F64_SIZE;
+								n--;
+								i++;
+							}
+							break;
+					}
+
+					i--;
+					break;
+				}
+				case "boolean": {
+					let lastByte = thing === true ? 1 : 0;
+					/** @type {number[]} */
+					const bytes = [];
+					let count = 1;
+					/** @type {undefined | number} */
+					let n;
+					for (n = 1; n < 0xffffffff && i + n < data.length; n++) {
+						const item = data[i + n];
+						if (typeof item !== "boolean") break;
+						const pos = count & 0x7;
+						if (pos === 0) {
+							bytes.push(lastByte);
+							lastByte = item === true ? 1 : 0;
+						} else if (item === true) {
+							lastByte |= 1 << pos;
+						}
+						count++;
+					}
+					i += count - 1;
+					if (count === 1) {
+						allocate(HEADER_SIZE);
+						writeU8(lastByte === 1 ? TRUE_HEADER : FALSE_HEADER);
+					} else if (count === 2) {
+						allocate(HEADER_SIZE * 2);
+						writeU8(lastByte & 1 ? TRUE_HEADER : FALSE_HEADER);
+						writeU8(lastByte & 2 ? TRUE_HEADER : FALSE_HEADER);
+					} else if (count <= 6) {
+						allocate(HEADER_SIZE + I8_SIZE);
+						writeU8(BOOLEANS_HEADER);
+						writeU8((1 << count) | lastByte);
+					} else if (count <= 133) {
+						allocate(HEADER_SIZE + I8_SIZE + I8_SIZE * bytes.length + I8_SIZE);
+						writeU8(BOOLEANS_HEADER);
+						writeU8(0x80 | (count - 7));
+						for (const byte of bytes) writeU8(byte);
+						writeU8(lastByte);
+					} else {
+						allocate(
+							HEADER_SIZE +
+								I8_SIZE +
+								I32_SIZE +
+								I8_SIZE * bytes.length +
+								I8_SIZE
+						);
+						writeU8(BOOLEANS_HEADER);
+						writeU8(0xff);
+						writeU32(count);
+						for (const byte of bytes) writeU8(byte);
+						writeU8(lastByte);
+					}
+					break;
+				}
+				case "object": {
+					if (thing === null) {
+						/** @type {number} */
+						let n;
+						for (n = 1; n < 0x100000104 && i + n < data.length; n++) {
+							const item = data[i + n];
+							if (item !== null) break;
+						}
+						i += n - 1;
+						if (n === 1) {
+							if (i + 1 < data.length) {
+								const next = data[i + 1];
+								if (next === true) {
+									allocate(HEADER_SIZE);
+									writeU8(NULL_AND_TRUE_HEADER);
+									i++;
+								} else if (next === false) {
+									allocate(HEADER_SIZE);
+									writeU8(NULL_AND_FALSE_HEADER);
+									i++;
+								} else if (typeof next === "number") {
+									const type = identifyNumber(next);
+									if (type === 0) {
+										allocate(HEADER_SIZE + I8_SIZE);
+										writeU8(NULL_AND_I8_HEADER);
+										currentBuffer.writeInt8(next, currentPosition);
+										currentPosition += I8_SIZE;
+										i++;
+									} else if (type === 1) {
+										allocate(HEADER_SIZE + I32_SIZE);
+										writeU8(NULL_AND_I32_HEADER);
+										currentBuffer.writeInt32LE(next, currentPosition);
+										currentPosition += I32_SIZE;
+										i++;
+									} else {
+										allocate(HEADER_SIZE);
+										writeU8(NULL_HEADER);
+									}
+								} else {
+									allocate(HEADER_SIZE);
+									writeU8(NULL_HEADER);
+								}
+							} else {
+								allocate(HEADER_SIZE);
+								writeU8(NULL_HEADER);
+							}
+						} else if (n === 2) {
+							allocate(HEADER_SIZE);
+							writeU8(NULL2_HEADER);
+						} else if (n === 3) {
+							allocate(HEADER_SIZE);
+							writeU8(NULL3_HEADER);
+						} else if (n < 260) {
+							allocate(HEADER_SIZE + I8_SIZE);
+							writeU8(NULLS8_HEADER);
+							writeU8(n - 4);
+						} else {
+							allocate(HEADER_SIZE + I32_SIZE);
+							writeU8(NULLS32_HEADER);
+							writeU32(n - 260);
+						}
+					} else if (Buffer.isBuffer(thing)) {
+						if (thing.length < 8192) {
+							allocate(HEADER_SIZE + I32_SIZE + thing.length);
+							writeU8(BUFFER_HEADER);
+							writeU32(thing.length);
+							thing.copy(currentBuffer, currentPosition);
+							currentPosition += thing.length;
+						} else {
+							allocate(HEADER_SIZE + I32_SIZE);
+							writeU8(BUFFER_HEADER);
+							writeU32(thing.length);
+							flush();
+							buffers.push(thing);
+						}
+					}
+					break;
+				}
+				case "symbol": {
+					if (thing === MEASURE_START_OPERATION) {
+						measureStart();
+					} else if (thing === MEASURE_END_OPERATION) {
+						const size = measureEnd();
+						allocate(HEADER_SIZE + I32_SIZE);
+						writeU8(I32_HEADER);
+						currentBuffer.writeInt32LE(size, currentPosition);
+						currentPosition += I32_SIZE;
+					}
+					break;
+				}
+				default: {
+					throw new Error(
+						`Unknown typeof "${typeof thing}" in binary middleware`
+					);
+				}
+			}
+		}
+		flush();
+
+		allocationScope.leftOverBuffer = leftOverBuffer;
+
+		// avoid leaking memory
+		currentBuffer = null;
+		leftOverBuffer = null;
+		allocationScope = /** @type {EXPECTED_ANY} */ (undefined);
+		const _buffers = buffers;
+		buffers = /** @type {EXPECTED_ANY} */ (undefined);
+		return _buffers;
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {SerializedType} data data
+	 * @param {Context} context context object
+	 * @returns {DeserializedType | Promise<DeserializedType>} deserialized data
+	 */
+	deserialize(data, context) {
+		return this._deserialize(data, context);
+	}
+
+	/**
+	 * Create lazy deserialized.
+	 * @private
+	 * @param {SerializedType} content content
+	 * @param {Context} context context object
+	 * @returns {LazyFunction<DeserializedType, SerializedType>} lazy function
+	 */
+	_createLazyDeserialized(content, context) {
+		return SerializerMiddleware.createLazy(
+			memoize(() => this._deserialize(content, context)),
+			this,
+			undefined,
+			content
+		);
+	}
+
+	/**
+	 * Returns new lazy.
+	 * @private
+	 * @param {LazyFunction<SerializedType, DeserializedType>} fn lazy function
+	 * @param {Context} context context object
+	 * @returns {LazyFunction<DeserializedType, SerializedType>} new lazy
+	 */
+	_deserializeLazy(fn, context) {
+		return SerializerMiddleware.deserializeLazy(fn, (data) =>
+			this._deserialize(data, context)
+		);
+	}
+
+	/**
+	 * Returns deserialized data.
+	 * @param {SerializedType} data data
+	 * @param {Context} context context object
+	 * @returns {DeserializedType} deserialized data
+	 */
+	_deserialize(data, context) {
+		let currentDataItem = 0;
+		/** @type {BufferSerializableType | null} */
+		let currentBuffer = data[0];
+		let currentIsBuffer = Buffer.isBuffer(currentBuffer);
+		let currentPosition = 0;
+
+		const retainedBuffer = context.retainedBuffer || ((x) => x);
+
+		const checkOverflow = () => {
+			if (currentPosition >= /** @type {Buffer} */ (currentBuffer).length) {
+				currentPosition = 0;
+				currentDataItem++;
+				currentBuffer =
+					currentDataItem < data.length ? data[currentDataItem] : null;
+				currentIsBuffer = Buffer.isBuffer(currentBuffer);
+			}
+		};
+		/**
+		 * Checks whether this binary middleware is in current buffer.
+		 * @param {number} n n
+		 * @returns {boolean} true when in current buffer, otherwise false
+		 */
+		const isInCurrentBuffer = (n) =>
+			currentIsBuffer &&
+			n + currentPosition <= /** @type {Buffer} */ (currentBuffer).length;
+		const ensureBuffer = () => {
+			if (!currentIsBuffer) {
+				throw new Error(
+					currentBuffer === null
+						? "Unexpected end of stream"
+						: "Unexpected lazy element in stream"
+				);
+			}
+		};
+		/**
+		 * Returns buffer with bytes.
+		 * @param {number} n amount of bytes to read
+		 * @returns {Buffer} buffer with bytes
+		 */
+		const read = (n) => {
+			ensureBuffer();
+			const rem =
+				/** @type {Buffer} */ (currentBuffer).length - currentPosition;
+			if (rem < n) {
+				const buffers = [read(rem)];
+				n -= rem;
+				ensureBuffer();
+				while (/** @type {Buffer} */ (currentBuffer).length < n) {
+					const b = /** @type {Buffer} */ (currentBuffer);
+					buffers.push(b);
+					n -= b.length;
+					currentDataItem++;
+					currentBuffer =
+						currentDataItem < data.length ? data[currentDataItem] : null;
+					currentIsBuffer = Buffer.isBuffer(currentBuffer);
+					ensureBuffer();
+				}
+				buffers.push(read(n));
+				return Buffer.concat(buffers);
+			}
+			const b = /** @type {Buffer} */ (currentBuffer);
+			const res = Buffer.from(b.buffer, b.byteOffset + currentPosition, n);
+			currentPosition += n;
+			checkOverflow();
+			return res;
+		};
+		/**
+		 * Reads up to n bytes
+		 * @param {number} n amount of bytes to read
+		 * @returns {Buffer} buffer with bytes
+		 */
+		const readUpTo = (n) => {
+			ensureBuffer();
+			const rem =
+				/** @type {Buffer} */
+				(currentBuffer).length - currentPosition;
+			if (rem < n) {
+				n = rem;
+			}
+			const b = /** @type {Buffer} */ (currentBuffer);
+			const res = Buffer.from(b.buffer, b.byteOffset + currentPosition, n);
+			currentPosition += n;
+			checkOverflow();
+			return res;
+		};
+		/**
+		 * Returns u8.
+		 * @returns {number} U8
+		 */
+		const readU8 = () => {
+			ensureBuffer();
+			/**
+			 * There is no need to check remaining buffer size here
+			 * since {@link checkOverflow} guarantees at least one byte remaining
+			 */
+			const byte =
+				/** @type {Buffer} */
+				(currentBuffer).readUInt8(currentPosition);
+			currentPosition += I8_SIZE;
+			checkOverflow();
+			return byte;
+		};
+		/**
+		 * Returns u32.
+		 * @returns {number} U32
+		 */
+		const readU32 = () => read(I32_SIZE).readUInt32LE(0);
+		/**
+		 * Processes the provided data.
+		 * @param {number} data data
+		 * @param {number} n n
+		 */
+		const readBits = (data, n) => {
+			let mask = 1;
+			while (n !== 0) {
+				result.push((data & mask) !== 0);
+				mask <<= 1;
+				n--;
+			}
+		};
+		const dispatchTable = Array.from({ length: 256 }).map((_, header) => {
+			switch (header) {
+				case LAZY_HEADER:
+					return () => {
+						const count = readU32();
+						const lengths = Array.from({ length: count }).map(() => readU32());
+						/** @type {(Buffer | LazyFunction<SerializedType, DeserializedType>)[]} */
+						const content = [];
+						for (let l of lengths) {
+							if (l === 0) {
+								if (typeof currentBuffer !== "function") {
+									throw new Error("Unexpected non-lazy element in stream");
+								}
+								content.push(currentBuffer);
+								currentDataItem++;
+								currentBuffer =
+									currentDataItem < data.length ? data[currentDataItem] : null;
+								currentIsBuffer = Buffer.isBuffer(currentBuffer);
+							} else {
+								do {
+									const buf = readUpTo(l);
+									l -= buf.length;
+									content.push(retainedBuffer(buf));
+								} while (l > 0);
+							}
+						}
+						result.push(this._createLazyDeserialized(content, context));
+					};
+				case BUFFER_HEADER:
+					return () => {
+						const len = readU32();
+						result.push(retainedBuffer(read(len)));
+					};
+				case TRUE_HEADER:
+					return () => result.push(true);
+				case FALSE_HEADER:
+					return () => result.push(false);
+				case NULL3_HEADER:
+					return () => result.push(null, null, null);
+				case NULL2_HEADER:
+					return () => result.push(null, null);
+				case NULL_HEADER:
+					return () => result.push(null);
+				case NULL_AND_TRUE_HEADER:
+					return () => result.push(null, true);
+				case NULL_AND_FALSE_HEADER:
+					return () => result.push(null, false);
+				case NULL_AND_I8_HEADER:
+					return () => {
+						if (currentIsBuffer) {
+							result.push(
+								null,
+								/** @type {Buffer} */ (currentBuffer).readInt8(currentPosition)
+							);
+							currentPosition += I8_SIZE;
+							checkOverflow();
+						} else {
+							result.push(null, read(I8_SIZE).readInt8(0));
+						}
+					};
+				case NULL_AND_I32_HEADER:
+					return () => {
+						result.push(null);
+						if (isInCurrentBuffer(I32_SIZE)) {
+							result.push(
+								/** @type {Buffer} */ (currentBuffer).readInt32LE(
+									currentPosition
+								)
+							);
+							currentPosition += I32_SIZE;
+							checkOverflow();
+						} else {
+							result.push(read(I32_SIZE).readInt32LE(0));
+						}
+					};
+				case NULLS8_HEADER:
+					return () => {
+						const len = readU8() + 4;
+						for (let i = 0; i < len; i++) {
+							result.push(null);
+						}
+					};
+				case NULLS32_HEADER:
+					return () => {
+						const len = readU32() + 260;
+						for (let i = 0; i < len; i++) {
+							result.push(null);
+						}
+					};
+				case BOOLEANS_HEADER:
+					return () => {
+						const innerHeader = readU8();
+						if ((innerHeader & 0xf0) === 0) {
+							readBits(innerHeader, 3);
+						} else if ((innerHeader & 0xe0) === 0) {
+							readBits(innerHeader, 4);
+						} else if ((innerHeader & 0xc0) === 0) {
+							readBits(innerHeader, 5);
+						} else if ((innerHeader & 0x80) === 0) {
+							readBits(innerHeader, 6);
+						} else if (innerHeader !== 0xff) {
+							let count = (innerHeader & 0x7f) + 7;
+							while (count > 8) {
+								readBits(readU8(), 8);
+								count -= 8;
+							}
+							readBits(readU8(), count);
+						} else {
+							let count = readU32();
+							while (count > 8) {
+								readBits(readU8(), 8);
+								count -= 8;
+							}
+							readBits(readU8(), count);
+						}
+					};
+				case STRING_HEADER:
+					return () => {
+						const len = readU32();
+						if (isInCurrentBuffer(len) && currentPosition + len < 0x7fffffff) {
+							result.push(
+								/** @type {Buffer} */
+								(currentBuffer).toString(
+									undefined,
+									currentPosition,
+									currentPosition + len
+								)
+							);
+							currentPosition += len;
+							checkOverflow();
+						} else {
+							result.push(read(len).toString());
+						}
+					};
+				case SHORT_STRING_HEADER:
+					return () => result.push("");
+				case SHORT_STRING_HEADER | 1:
+					return () => {
+						if (currentIsBuffer && currentPosition < 0x7ffffffe) {
+							result.push(
+								/** @type {Buffer} */
+								(currentBuffer).toString(
+									"latin1",
+									currentPosition,
+									currentPosition + 1
+								)
+							);
+							currentPosition++;
+							checkOverflow();
+						} else {
+							result.push(read(1).toString("latin1"));
+						}
+					};
+				case I8_HEADER:
+					return () => {
+						if (currentIsBuffer) {
+							result.push(
+								/** @type {Buffer} */ (currentBuffer).readInt8(currentPosition)
+							);
+							currentPosition++;
+							checkOverflow();
+						} else {
+							result.push(read(1).readInt8(0));
+						}
+					};
+				case BIGINT_I8_HEADER: {
+					const len = 1;
+					return () => {
+						const need = I8_SIZE * len;
+
+						if (isInCurrentBuffer(need)) {
+							for (let i = 0; i < len; i++) {
+								const value =
+									/** @type {Buffer} */
+									(currentBuffer).readInt8(currentPosition);
+								result.push(BigInt(value));
+								currentPosition += I8_SIZE;
+							}
+							checkOverflow();
+						} else {
+							const buf = read(need);
+							for (let i = 0; i < len; i++) {
+								const value = buf.readInt8(i * I8_SIZE);
+								result.push(BigInt(value));
+							}
+						}
+					};
+				}
+				case BIGINT_I32_HEADER: {
+					const len = 1;
+					return () => {
+						const need = I32_SIZE * len;
+						if (isInCurrentBuffer(need)) {
+							for (let i = 0; i < len; i++) {
+								const value = /** @type {Buffer} */ (currentBuffer).readInt32LE(
+									currentPosition
+								);
+								result.push(BigInt(value));
+								currentPosition += I32_SIZE;
+							}
+							checkOverflow();
+						} else {
+							const buf = read(need);
+							for (let i = 0; i < len; i++) {
+								const value = buf.readInt32LE(i * I32_SIZE);
+								result.push(BigInt(value));
+							}
+						}
+					};
+				}
+				case BIGINT_HEADER: {
+					return () => {
+						const len = readU32();
+						if (isInCurrentBuffer(len) && currentPosition + len < 0x7fffffff) {
+							const value =
+								/** @type {Buffer} */
+								(currentBuffer).toString(
+									undefined,
+									currentPosition,
+									currentPosition + len
+								);
+
+							result.push(BigInt(value));
+							currentPosition += len;
+							checkOverflow();
+						} else {
+							const value = read(len).toString();
+							result.push(BigInt(value));
+						}
+					};
+				}
+				default:
+					if (header <= 10) {
+						return () => result.push(header);
+					} else if ((header & SHORT_STRING_HEADER) === SHORT_STRING_HEADER) {
+						const len = header & SHORT_STRING_LENGTH_MASK;
+						return () => {
+							if (
+								isInCurrentBuffer(len) &&
+								currentPosition + len < 0x7fffffff
+							) {
+								result.push(
+									/** @type {Buffer} */
+									(currentBuffer).toString(
+										"latin1",
+										currentPosition,
+										currentPosition + len
+									)
+								);
+								currentPosition += len;
+								checkOverflow();
+							} else {
+								result.push(read(len).toString("latin1"));
+							}
+						};
+					} else if ((header & NUMBERS_HEADER_MASK) === F64_HEADER) {
+						const len = (header & NUMBERS_COUNT_MASK) + 1;
+						return () => {
+							const need = F64_SIZE * len;
+							if (isInCurrentBuffer(need)) {
+								for (let i = 0; i < len; i++) {
+									result.push(
+										/** @type {Buffer} */ (currentBuffer).readDoubleLE(
+											currentPosition
+										)
+									);
+									currentPosition += F64_SIZE;
+								}
+								checkOverflow();
+							} else {
+								const buf = read(need);
+								for (let i = 0; i < len; i++) {
+									result.push(buf.readDoubleLE(i * F64_SIZE));
+								}
+							}
+						};
+					} else if ((header & NUMBERS_HEADER_MASK) === I32_HEADER) {
+						const len = (header & NUMBERS_COUNT_MASK) + 1;
+						return () => {
+							const need = I32_SIZE * len;
+							if (isInCurrentBuffer(need)) {
+								for (let i = 0; i < len; i++) {
+									result.push(
+										/** @type {Buffer} */ (currentBuffer).readInt32LE(
+											currentPosition
+										)
+									);
+									currentPosition += I32_SIZE;
+								}
+								checkOverflow();
+							} else {
+								const buf = read(need);
+								for (let i = 0; i < len; i++) {
+									result.push(buf.readInt32LE(i * I32_SIZE));
+								}
+							}
+						};
+					} else if ((header & NUMBERS_HEADER_MASK) === I8_HEADER) {
+						const len = (header & NUMBERS_COUNT_MASK) + 1;
+						return () => {
+							const need = I8_SIZE * len;
+							if (isInCurrentBuffer(need)) {
+								for (let i = 0; i < len; i++) {
+									result.push(
+										/** @type {Buffer} */ (currentBuffer).readInt8(
+											currentPosition
+										)
+									);
+									currentPosition += I8_SIZE;
+								}
+								checkOverflow();
+							} else {
+								const buf = read(need);
+								for (let i = 0; i < len; i++) {
+									result.push(buf.readInt8(i * I8_SIZE));
+								}
+							}
+						};
+					}
+					return () => {
+						throw new Error(`Unexpected header byte 0x${header.toString(16)}`);
+					};
+			}
+		});
+
+		/** @type {DeserializedType} */
+		let result = [];
+		while (currentBuffer !== null) {
+			if (typeof currentBuffer === "function") {
+				result.push(this._deserializeLazy(currentBuffer, context));
+				currentDataItem++;
+				currentBuffer =
+					currentDataItem < data.length ? data[currentDataItem] : null;
+				currentIsBuffer = Buffer.isBuffer(currentBuffer);
+			} else {
+				const header = readU8();
+				dispatchTable[header]();
+			}
+		}
+
+		// avoid leaking memory in context
+		// eslint-disable-next-line prefer-const
+		let _result = result;
+		result = /** @type {EXPECTED_ANY} */ (undefined);
+		return _result;
+	}
+}
+
+module.exports = BinaryMiddleware;
+
+module.exports.MEASURE_END_OPERATION = MEASURE_END_OPERATION;
+module.exports.MEASURE_START_OPERATION = MEASURE_START_OPERATION;
Index: frontend/node_modules/webpack/lib/serialization/DateObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/DateObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/DateObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class DateObjectSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {Date} obj date
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		context.write(obj.getTime());
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {Date} date
+	 */
+	deserialize(context) {
+		return new Date(context.read());
+	}
+}
+
+module.exports = DateObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/ErrorObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/ErrorObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/ErrorObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,52 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {Error & { cause?: unknown }} ErrorWithCause */
+
+class ErrorObjectSerializer {
+	/**
+	 * Creates an instance of ErrorObjectSerializer.
+	 * @param {ErrorConstructor | EvalErrorConstructor | RangeErrorConstructor | ReferenceErrorConstructor | SyntaxErrorConstructor | TypeErrorConstructor} Type error type
+	 */
+	constructor(Type) {
+		this.Type = Type;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError} obj error
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		context.write(obj.message);
+		context.write(obj.stack);
+		context.write(
+			/** @type {ErrorWithCause} */
+			(obj).cause
+		);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError} error
+	 */
+	deserialize(context) {
+		const err = new this.Type();
+
+		err.message = context.read();
+		err.stack = context.read();
+		/** @type {ErrorWithCause} */
+		(err).cause = context.read();
+
+		return err;
+	}
+}
+
+module.exports = ErrorObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/FileMiddleware.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/FileMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/FileMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,787 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { constants } = require("buffer");
+const { pipeline } = require("stream");
+const {
+	constants: zConstants,
+	// eslint-disable-next-line n/no-unsupported-features/node-builtins
+	createBrotliCompress,
+	// eslint-disable-next-line n/no-unsupported-features/node-builtins
+	createBrotliDecompress,
+	createGunzip,
+	createGzip
+} = require("zlib");
+const { DEFAULTS } = require("../config/defaults");
+const createHash = require("../util/createHash");
+const { dirname, join, mkdirp } = require("../util/fs");
+const memoize = require("../util/memoize");
+const SerializerMiddleware = require("./SerializerMiddleware");
+
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+/** @typedef {import("../util/fs").IStats} IStats */
+/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
+/** @typedef {import("./types").BufferSerializableType} BufferSerializableType */
+
+/*
+Format:
+
+File -> Header Section*
+
+Version -> u32
+AmountOfSections -> u32
+SectionSize -> i32 (if less than zero represents lazy value)
+
+Header -> Version AmountOfSections SectionSize*
+
+Buffer -> n bytes
+Section -> Buffer
+
+*/
+
+// "wpc" + 1 in little-endian
+const VERSION = 0x01637077;
+const WRITE_LIMIT_TOTAL = 0x7fff0000;
+const WRITE_LIMIT_CHUNK = 511 * 1024 * 1024;
+
+/**
+ * Returns hash.
+ * @param {Buffer[]} buffers buffers
+ * @param {HashFunction} hashFunction hash function to use
+ * @returns {string} hash
+ */
+const hashForName = (buffers, hashFunction) => {
+	const hash = createHash(hashFunction);
+	for (const buf of buffers) hash.update(buf);
+	return hash.digest("hex");
+};
+
+const COMPRESSION_CHUNK_SIZE = 100 * 1024 * 1024;
+const DECOMPRESSION_CHUNK_SIZE = 100 * 1024 * 1024;
+
+/** @type {(buffer: Buffer, value: number, offset: number) => void} */
+const writeUInt64LE = Buffer.prototype.writeBigUInt64LE
+	? (buf, value, offset) => {
+			buf.writeBigUInt64LE(BigInt(value), offset);
+		}
+	: (buf, value, offset) => {
+			const low = value % 0x100000000;
+			const high = (value - low) / 0x100000000;
+			buf.writeUInt32LE(low, offset);
+			buf.writeUInt32LE(high, offset + 4);
+		};
+
+/** @type {(buffer: Buffer, offset: number) => void} */
+const readUInt64LE = Buffer.prototype.readBigUInt64LE
+	? (buf, offset) => Number(buf.readBigUInt64LE(offset))
+	: (buf, offset) => {
+			const low = buf.readUInt32LE(offset);
+			const high = buf.readUInt32LE(offset + 4);
+			return high * 0x100000000 + low;
+		};
+
+/** @typedef {Promise<void | void[]>} BackgroundJob */
+
+/**
+ * Defines the serialize result type used by this module.
+ * @typedef {object} SerializeResult
+ * @property {string | false} name
+ * @property {number} size
+ * @property {BackgroundJob=} backgroundJob
+ */
+
+/** @typedef {{ name: string, size: number }} LazyOptions */
+/**
+ * Defines the lazy function type used by this module.
+ * @typedef {import("./SerializerMiddleware").LazyFunction<BufferSerializableType[], Buffer, FileMiddleware, LazyOptions>} LazyFunction
+ */
+
+/**
+ * Serializes this instance into the provided serializer context.
+ * @param {FileMiddleware} middleware this
+ * @param {(BufferSerializableType | LazyFunction)[]} data data to be serialized
+ * @param {string | boolean} name file base name
+ * @param {(name: string | false, buffers: Buffer[], size: number) => Promise<void>} writeFile writes a file
+ * @param {HashFunction=} hashFunction hash function to use
+ * @returns {Promise<SerializeResult>} resulting file pointer and promise
+ */
+const serialize = async (
+	middleware,
+	data,
+	name,
+	writeFile,
+	hashFunction = DEFAULTS.HASH_FUNCTION
+) => {
+	/** @type {(Buffer[] | Buffer | Promise<SerializeResult>)[]} */
+	const processedData = [];
+	/** @type {WeakMap<SerializeResult, LazyFunction>} */
+	const resultToLazy = new WeakMap();
+	/** @type {Buffer[] | undefined} */
+	let lastBuffers;
+	for (const item of await data) {
+		if (typeof item === "function") {
+			if (!SerializerMiddleware.isLazy(item)) {
+				throw new Error("Unexpected function");
+			}
+			if (!SerializerMiddleware.isLazy(item, middleware)) {
+				throw new Error(
+					"Unexpected lazy value with non-this target (can't pass through lazy values)"
+				);
+			}
+			lastBuffers = undefined;
+			const serializedInfo = SerializerMiddleware.getLazySerializedValue(item);
+			if (serializedInfo) {
+				if (typeof serializedInfo === "function") {
+					throw new Error(
+						"Unexpected lazy value with non-this target (can't pass through lazy values)"
+					);
+				} else {
+					processedData.push(serializedInfo);
+				}
+			} else {
+				const content = item();
+				if (content) {
+					const options = SerializerMiddleware.getLazyOptions(item);
+					processedData.push(
+						serialize(
+							middleware,
+							/** @type {BufferSerializableType[]} */
+							(content),
+							(options && options.name) || true,
+							writeFile,
+							hashFunction
+						).then((result) => {
+							/** @type {LazyOptions} */
+							(item.options).size = result.size;
+							resultToLazy.set(result, item);
+							return result;
+						})
+					);
+				} else {
+					throw new Error(
+						"Unexpected falsy value returned by lazy value function"
+					);
+				}
+			}
+		} else if (item) {
+			if (lastBuffers) {
+				lastBuffers.push(item);
+			} else {
+				lastBuffers = [item];
+				processedData.push(lastBuffers);
+			}
+		} else {
+			throw new Error("Unexpected falsy value in items array");
+		}
+	}
+	/** @type {BackgroundJob[]} */
+	const backgroundJobs = [];
+	const resolvedData = (await Promise.all(processedData)).map((item) => {
+		if (Array.isArray(item) || Buffer.isBuffer(item)) return item;
+
+		backgroundJobs.push(
+			/** @type {BackgroundJob} */
+			(item.backgroundJob)
+		);
+		// create pointer buffer from size and name
+		const name = /** @type {string} */ (item.name);
+		const nameBuffer = Buffer.from(name);
+		const buf = Buffer.allocUnsafe(8 + nameBuffer.length);
+		writeUInt64LE(buf, item.size, 0);
+		nameBuffer.copy(buf, 8, 0);
+		const lazy =
+			/** @type {LazyFunction} */
+			(resultToLazy.get(item));
+		SerializerMiddleware.setLazySerializedValue(lazy, buf);
+		return buf;
+	});
+	/** @type {number[]} */
+	const lengths = [];
+	for (const item of resolvedData) {
+		if (Array.isArray(item)) {
+			let l = 0;
+			for (const b of item) l += b.length;
+			while (l > 0x7fffffff) {
+				lengths.push(0x7fffffff);
+				l -= 0x7fffffff;
+			}
+			lengths.push(l);
+		} else if (item) {
+			lengths.push(-item.length);
+		} else {
+			throw new Error(`Unexpected falsy value in resolved data ${item}`);
+		}
+	}
+	const header = Buffer.allocUnsafe(8 + lengths.length * 4);
+	header.writeUInt32LE(VERSION, 0);
+	header.writeUInt32LE(lengths.length, 4);
+	for (let i = 0; i < lengths.length; i++) {
+		header.writeInt32LE(lengths[i], 8 + i * 4);
+	}
+	/** @type {Buffer[]} */
+	const buf = [header];
+	for (const item of resolvedData) {
+		if (Array.isArray(item)) {
+			for (const b of item) buf.push(b);
+		} else if (item) {
+			buf.push(item);
+		}
+	}
+	if (name === true) {
+		name = hashForName(buf, hashFunction);
+	}
+	let size = 0;
+	for (const b of buf) size += b.length;
+	backgroundJobs.push(writeFile(name, buf, size));
+	return {
+		size,
+		name,
+		backgroundJob:
+			backgroundJobs.length === 1
+				? backgroundJobs[0]
+				: /** @type {BackgroundJob} */ (Promise.all(backgroundJobs))
+	};
+};
+
+/**
+ * Restores this instance from the provided deserializer context.
+ * @param {FileMiddleware} middleware this
+ * @param {string | false} name filename
+ * @param {(name: string | false) => Promise<Buffer[]>} readFile read content of a file
+ * @returns {Promise<BufferSerializableType[]>} deserialized data
+ */
+const deserialize = async (middleware, name, readFile) => {
+	const contents = await readFile(name);
+	if (contents.length === 0) throw new Error(`Empty file ${name}`);
+	let contentsIndex = 0;
+	let contentItem = contents[0];
+	let contentItemLength = contentItem.length;
+	let contentPosition = 0;
+	if (contentItemLength === 0) throw new Error(`Empty file ${name}`);
+	const nextContent = () => {
+		contentsIndex++;
+		contentItem = contents[contentsIndex];
+		contentItemLength = contentItem.length;
+		contentPosition = 0;
+	};
+	/**
+	 * Processes the provided n.
+	 * @param {number} n number of bytes to ensure
+	 */
+	const ensureData = (n) => {
+		if (contentPosition === contentItemLength) {
+			nextContent();
+		}
+		while (contentItemLength - contentPosition < n) {
+			const remaining = contentItem.subarray(contentPosition);
+			let lengthFromNext = n - remaining.length;
+			/** @type {Buffer[]} */
+			const buffers = [remaining];
+			for (let i = contentsIndex + 1; i < contents.length; i++) {
+				const l = contents[i].length;
+				if (l > lengthFromNext) {
+					buffers.push(contents[i].subarray(0, lengthFromNext));
+					contents[i] = contents[i].subarray(lengthFromNext);
+					lengthFromNext = 0;
+					break;
+				} else {
+					buffers.push(contents[i]);
+					contentsIndex = i;
+					lengthFromNext -= l;
+				}
+			}
+			if (lengthFromNext > 0) throw new Error("Unexpected end of data");
+			contentItem = Buffer.concat(buffers, n);
+			contentItemLength = n;
+			contentPosition = 0;
+		}
+	};
+	/**
+	 * Returns value value.
+	 * @returns {number} value value
+	 */
+	const readUInt32LE = () => {
+		ensureData(4);
+		const value = contentItem.readUInt32LE(contentPosition);
+		contentPosition += 4;
+		return value;
+	};
+	/**
+	 * Returns value value.
+	 * @returns {number} value value
+	 */
+	const readInt32LE = () => {
+		ensureData(4);
+		const value = contentItem.readInt32LE(contentPosition);
+		contentPosition += 4;
+		return value;
+	};
+	/**
+	 * Returns buffer.
+	 * @param {number} l length
+	 * @returns {Buffer} buffer
+	 */
+	const readSlice = (l) => {
+		ensureData(l);
+		if (contentPosition === 0 && contentItemLength === l) {
+			const result = contentItem;
+			if (contentsIndex + 1 < contents.length) {
+				nextContent();
+			} else {
+				contentPosition = l;
+			}
+			return result;
+		}
+		const result = contentItem.subarray(contentPosition, contentPosition + l);
+		contentPosition += l;
+		// we clone the buffer here to allow the original content to be garbage collected
+		return l * 2 < contentItem.buffer.byteLength ? Buffer.from(result) : result;
+	};
+	const version = readUInt32LE();
+	if (version !== VERSION) {
+		throw new Error("Invalid file version");
+	}
+	const sectionCount = readUInt32LE();
+	/** @type {number[]} */
+	const lengths = [];
+	let lastLengthPositive = false;
+	for (let i = 0; i < sectionCount; i++) {
+		const value = readInt32LE();
+		const valuePositive = value >= 0;
+		if (lastLengthPositive && valuePositive) {
+			lengths[lengths.length - 1] += value;
+		} else {
+			lengths.push(value);
+			lastLengthPositive = valuePositive;
+		}
+	}
+	/** @type {BufferSerializableType[]} */
+	const result = [];
+	for (let length of lengths) {
+		if (length < 0) {
+			const slice = readSlice(-length);
+			const size = Number(readUInt64LE(slice, 0));
+			const nameBuffer = slice.subarray(8);
+			const name = nameBuffer.toString();
+			const lazy =
+				/** @type {LazyFunction} */
+				(
+					SerializerMiddleware.createLazy(
+						memoize(() => deserialize(middleware, name, readFile)),
+						middleware,
+						{ name, size },
+						slice
+					)
+				);
+			result.push(lazy);
+		} else {
+			if (contentPosition === contentItemLength) {
+				nextContent();
+			} else if (contentPosition !== 0) {
+				if (length <= contentItemLength - contentPosition) {
+					result.push(
+						Buffer.from(
+							contentItem.buffer,
+							contentItem.byteOffset + contentPosition,
+							length
+						)
+					);
+					contentPosition += length;
+					length = 0;
+				} else {
+					const l = contentItemLength - contentPosition;
+					result.push(
+						Buffer.from(
+							contentItem.buffer,
+							contentItem.byteOffset + contentPosition,
+							l
+						)
+					);
+					length -= l;
+					contentPosition = contentItemLength;
+				}
+			} else if (length >= contentItemLength) {
+				result.push(contentItem);
+				length -= contentItemLength;
+				contentPosition = contentItemLength;
+			} else {
+				result.push(
+					Buffer.from(contentItem.buffer, contentItem.byteOffset, length)
+				);
+				contentPosition += length;
+				length = 0;
+			}
+			while (length > 0) {
+				nextContent();
+				if (length >= contentItemLength) {
+					result.push(contentItem);
+					length -= contentItemLength;
+					contentPosition = contentItemLength;
+				} else {
+					result.push(
+						Buffer.from(contentItem.buffer, contentItem.byteOffset, length)
+					);
+					contentPosition += length;
+					length = 0;
+				}
+			}
+		}
+	}
+	return result;
+};
+
+/** @typedef {BufferSerializableType[]} DeserializedType */
+/** @typedef {true} SerializedType */
+/** @typedef {{ filename: string, extension?: string }} Context */
+
+/**
+ * Represents FileMiddleware.
+ * @extends {SerializerMiddleware<DeserializedType, SerializedType, Context>}
+ */
+class FileMiddleware extends SerializerMiddleware {
+	/**
+	 * Creates an instance of FileMiddleware.
+	 * @param {IntermediateFileSystem} fs filesystem
+	 * @param {HashFunction} hashFunction hash function to use
+	 */
+	constructor(fs, hashFunction = DEFAULTS.HASH_FUNCTION) {
+		super();
+		/** @type {IntermediateFileSystem} */
+		this.fs = fs;
+		/** @type {HashFunction} */
+		this._hashFunction = hashFunction;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {DeserializedType} data data
+	 * @param {Context} context context object
+	 * @returns {SerializedType | Promise<SerializedType> | null} serialized data
+	 */
+	serialize(data, context) {
+		const { filename, extension = "" } = context;
+		return new Promise((resolve, reject) => {
+			mkdirp(this.fs, dirname(this.fs, filename), (err) => {
+				if (err) return reject(err);
+
+				// It's important that we don't touch existing files during serialization
+				// because serialize may read existing files (when deserializing)
+				/** @type {Set<string>} */
+				const allWrittenFiles = new Set();
+				/**
+				 * Processes the provided name.
+				 * @param {string | false} name name
+				 * @param {Buffer[]} content content
+				 * @param {number} size size
+				 * @returns {Promise<void>}
+				 */
+				const writeFile = async (name, content, size) => {
+					const file = name
+						? join(this.fs, filename, `../${name}${extension}`)
+						: filename;
+					await new Promise(
+						/**
+						 * Handles the callback logic for this hook.
+						 * @param {(value?: undefined) => void} resolve resolve
+						 * @param {(reason?: Error | null) => void} reject reject
+						 */
+						(resolve, reject) => {
+							let stream = this.fs.createWriteStream(`${file}_`);
+							/** @type {undefined | import("zlib").Gzip | import("zlib").BrotliCompress} */
+							let compression;
+							if (file.endsWith(".gz")) {
+								compression = createGzip({
+									chunkSize: COMPRESSION_CHUNK_SIZE,
+									level: zConstants.Z_BEST_SPEED
+								});
+							} else if (file.endsWith(".br")) {
+								compression = createBrotliCompress({
+									chunkSize: COMPRESSION_CHUNK_SIZE,
+									params: {
+										[zConstants.BROTLI_PARAM_MODE]: zConstants.BROTLI_MODE_TEXT,
+										[zConstants.BROTLI_PARAM_QUALITY]: 2,
+										[zConstants.BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING]: true,
+										[zConstants.BROTLI_PARAM_SIZE_HINT]: size
+									}
+								});
+							}
+							if (compression) {
+								pipeline(compression, stream, reject);
+								stream = compression;
+								stream.on("finish", () => resolve());
+							} else {
+								stream.on("error", (err) => reject(err));
+								stream.on("finish", () => resolve());
+							}
+							// split into chunks for WRITE_LIMIT_CHUNK size
+							/** @type {Buffer[]} */
+							const chunks = [];
+							for (const b of content) {
+								if (b.length < WRITE_LIMIT_CHUNK) {
+									chunks.push(b);
+								} else {
+									for (let i = 0; i < b.length; i += WRITE_LIMIT_CHUNK) {
+										chunks.push(b.subarray(i, i + WRITE_LIMIT_CHUNK));
+									}
+								}
+							}
+
+							const len = chunks.length;
+							let i = 0;
+							/**
+							 * Processes the provided err.
+							 * @param {(Error | null)=} err err
+							 */
+							const batchWrite = (err) => {
+								// will be handled in "on" error handler
+								if (err) return;
+
+								if (i === len) {
+									stream.end();
+									return;
+								}
+
+								// queue up a batch of chunks up to the write limit
+								// end is exclusive
+								let end = i;
+								let sum = chunks[end++].length;
+								while (end < len) {
+									sum += chunks[end].length;
+									if (sum > WRITE_LIMIT_TOTAL) break;
+									end++;
+								}
+								while (i < end - 1) {
+									stream.write(chunks[i++]);
+								}
+								stream.write(chunks[i++], batchWrite);
+							};
+							batchWrite();
+						}
+					);
+					if (name) allWrittenFiles.add(file);
+				};
+
+				resolve(
+					serialize(this, data, false, writeFile, this._hashFunction).then(
+						async ({ backgroundJob }) => {
+							await backgroundJob;
+
+							// Rename the index file to disallow access during inconsistent file state
+							await new Promise(
+								/**
+								 * Handles the callback logic for this hook.
+								 * @param {(value?: undefined) => void} resolve resolve
+								 */
+								(resolve) => {
+									this.fs.rename(filename, `${filename}.old`, (_err) => {
+										resolve();
+									});
+								}
+							);
+
+							// update all written files
+							await Promise.all(
+								Array.from(
+									allWrittenFiles,
+									(file) =>
+										new Promise(
+											/**
+											 * Handles the callback logic for this hook.
+											 * @param {(value?: undefined) => void} resolve resolve
+											 * @param {(reason?: Error | null) => void} reject reject
+											 * @returns {void}
+											 */
+											(resolve, reject) => {
+												this.fs.rename(`${file}_`, file, (err) => {
+													if (err) return reject(err);
+													resolve();
+												});
+											}
+										)
+								)
+							);
+
+							// As final step automatically update the index file to have a consistent pack again
+							await new Promise(
+								/**
+								 * Handles the callback logic for this hook.
+								 * @param {(value?: undefined) => void} resolve resolve
+								 * @returns {void}
+								 */
+								(resolve) => {
+									this.fs.rename(`${filename}_`, filename, (err) => {
+										if (err) return reject(err);
+										resolve();
+									});
+								}
+							);
+							return /** @type {true} */ (true);
+						}
+					)
+				);
+			});
+		});
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {SerializedType} data data
+	 * @param {Context} context context object
+	 * @returns {DeserializedType | Promise<DeserializedType>} deserialized data
+	 */
+	deserialize(data, context) {
+		const { filename, extension = "" } = context;
+		/**
+		 * Returns result.
+		 * @param {string | boolean} name name
+		 * @returns {Promise<Buffer[]>} result
+		 */
+		const readFile = (name) =>
+			new Promise((resolve, reject) => {
+				const file = name
+					? join(this.fs, filename, `../${name}${extension}`)
+					: filename;
+				this.fs.stat(file, (err, stats) => {
+					if (err) {
+						reject(err);
+						return;
+					}
+					let remaining = /** @type {IStats} */ (stats).size;
+					/** @type {Buffer | undefined} */
+					let currentBuffer;
+					/** @type {number | undefined} */
+					let currentBufferUsed;
+					/** @type {Buffer[]} */
+					const buf = [];
+					/** @type {import("zlib").Zlib & import("stream").Transform | undefined} */
+					let decompression;
+					if (file.endsWith(".gz")) {
+						decompression = createGunzip({
+							chunkSize: DECOMPRESSION_CHUNK_SIZE
+						});
+					} else if (file.endsWith(".br")) {
+						decompression = createBrotliDecompress({
+							chunkSize: DECOMPRESSION_CHUNK_SIZE
+						});
+					}
+					if (decompression) {
+						/** @typedef {(value: Buffer[] | PromiseLike<Buffer[]>) => void} NewResolve */
+						/** @typedef {(reason?: Error) => void} NewReject */
+
+						/** @type {NewResolve | undefined} */
+						let newResolve;
+						/** @type {NewReject | undefined} */
+						let newReject;
+						resolve(
+							Promise.all([
+								new Promise((rs, rj) => {
+									newResolve = rs;
+									newReject = rj;
+								}),
+								new Promise(
+									/**
+									 * Handles the chunk size callback for this hook.
+									 * @param {(value?: undefined) => void} resolve resolve
+									 * @param {(reason?: Error) => void} reject reject
+									 */
+									(resolve, reject) => {
+										decompression.on("data", (chunk) => buf.push(chunk));
+										decompression.on("end", () => resolve());
+										decompression.on("error", (err) => reject(err));
+									}
+								)
+							]).then(() => buf)
+						);
+						resolve = /** @type {NewResolve} */ (newResolve);
+						reject = /** @type {NewReject} */ (newReject);
+					}
+					this.fs.open(file, "r", (err, _fd) => {
+						if (err) {
+							reject(err);
+							return;
+						}
+						const fd = /** @type {number} */ (_fd);
+						const read = () => {
+							if (currentBuffer === undefined) {
+								currentBuffer = Buffer.allocUnsafeSlow(
+									Math.min(
+										constants.MAX_LENGTH,
+										remaining,
+										decompression ? DECOMPRESSION_CHUNK_SIZE : Infinity
+									)
+								);
+								currentBufferUsed = 0;
+							}
+							let readBuffer = currentBuffer;
+							let readOffset = /** @type {number} */ (currentBufferUsed);
+							let readLength =
+								currentBuffer.length -
+								/** @type {number} */ (currentBufferUsed);
+							// values passed to fs.read must be valid int32 values
+							if (readOffset > 0x7fffffff) {
+								readBuffer = currentBuffer.subarray(readOffset);
+								readOffset = 0;
+							}
+							if (readLength > 0x7fffffff) {
+								readLength = 0x7fffffff;
+							}
+							this.fs.read(
+								fd,
+								readBuffer,
+								readOffset,
+								readLength,
+								null,
+								(err, bytesRead) => {
+									if (err) {
+										this.fs.close(fd, () => {
+											reject(err);
+										});
+										return;
+									}
+									/** @type {number} */
+									(currentBufferUsed) += bytesRead;
+									remaining -= bytesRead;
+									if (
+										currentBufferUsed ===
+										/** @type {Buffer} */
+										(currentBuffer).length
+									) {
+										if (decompression) {
+											decompression.write(currentBuffer);
+										} else {
+											buf.push(
+												/** @type {Buffer} */
+												(currentBuffer)
+											);
+										}
+										currentBuffer = undefined;
+										if (remaining === 0) {
+											if (decompression) {
+												decompression.end();
+											}
+											this.fs.close(fd, (err) => {
+												if (err) {
+													reject(err);
+													return;
+												}
+												resolve(buf);
+											});
+											return;
+										}
+									}
+									read();
+								}
+							);
+						};
+						read();
+					});
+				});
+			});
+		return deserialize(this, false, readFile);
+	}
+}
+
+module.exports = FileMiddleware;
Index: frontend/node_modules/webpack/lib/serialization/MapObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/MapObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/MapObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,50 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class MapObjectSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @template K, V
+	 * @param {Map<K, V>} obj map
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		context.write(obj.size);
+		for (const key of obj.keys()) {
+			context.write(key);
+		}
+		for (const value of obj.values()) {
+			context.write(value);
+		}
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @template K, V
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {Map<K, V>} map
+	 */
+	deserialize(context) {
+		/** @type {number} */
+		const size = context.read();
+		/** @type {Map<K, V>} */
+		const map = new Map();
+		/** @type {K[]} */
+		const keys = [];
+		for (let i = 0; i < size; i++) {
+			keys.push(context.read());
+		}
+		for (let i = 0; i < size; i++) {
+			map.set(keys[i], context.read());
+		}
+		return map;
+	}
+}
+
+module.exports = MapObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/NullPrototypeObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/NullPrototypeObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/NullPrototypeObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,55 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {string[]} Keys */
+
+class NullPrototypeObjectSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @template {object} T
+	 * @param {T} obj null object
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		/** @type {Keys} */
+		const keys = Object.keys(obj);
+		for (const key of keys) {
+			context.write(key);
+		}
+		context.write(null);
+		for (const key of keys) {
+			context.write(obj[/** @type {keyof T} */ (key)]);
+		}
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @template {object} T
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {T} null object
+	 */
+	deserialize(context) {
+		/** @type {T} */
+		const obj = Object.create(null);
+		/** @type {Keys} */
+		const keys = [];
+		/** @type {Keys[number] | null} */
+		let key = context.read();
+		while (key !== null) {
+			keys.push(key);
+			key = context.read();
+		}
+		for (const key of keys) {
+			obj[/** @type {keyof T} */ (key)] = context.read();
+		}
+		return obj;
+	}
+}
+
+module.exports = NullPrototypeObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/ObjectMiddleware.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/ObjectMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/ObjectMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,900 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { DEFAULTS } = require("../config/defaults");
+const createHash = require("../util/createHash");
+const AggregateErrorSerializer = require("./AggregateErrorSerializer");
+const ArraySerializer = require("./ArraySerializer");
+const DateObjectSerializer = require("./DateObjectSerializer");
+const ErrorObjectSerializer = require("./ErrorObjectSerializer");
+const MapObjectSerializer = require("./MapObjectSerializer");
+const NullPrototypeObjectSerializer = require("./NullPrototypeObjectSerializer");
+const PlainObjectSerializer = require("./PlainObjectSerializer");
+const RegExpObjectSerializer = require("./RegExpObjectSerializer");
+const SerializerMiddleware = require("./SerializerMiddleware");
+const SetObjectSerializer = require("./SetObjectSerializer");
+
+/** @typedef {import("../logging/Logger").Logger} Logger */
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+/** @typedef {import("./SerializerMiddleware").LazyOptions} LazyOptions */
+/** @typedef {import("./types").ComplexSerializableType} ComplexSerializableType */
+/** @typedef {import("./types").PrimitiveSerializableType} PrimitiveSerializableType */
+
+/** @typedef {new (...params: EXPECTED_ANY[]) => EXPECTED_ANY} Constructor */
+
+/*
+
+Format:
+
+File -> Section*
+Section -> ObjectSection | ReferenceSection | EscapeSection | OtherSection
+
+ObjectSection -> ESCAPE (
+	number:relativeOffset (number > 0) |
+	string:request (string|null):export
+) Section:value* ESCAPE ESCAPE_END_OBJECT
+ReferenceSection -> ESCAPE number:relativeOffset (number < 0)
+EscapeSection -> ESCAPE ESCAPE_ESCAPE_VALUE (escaped value ESCAPE)
+EscapeSection -> ESCAPE ESCAPE_UNDEFINED (escaped value ESCAPE)
+OtherSection -> any (except ESCAPE)
+
+Why using null as escape value?
+Multiple null values can merged by the BinaryMiddleware, which makes it very efficient
+Technically any value can be used.
+
+*/
+
+/**
+ * Defines the object serializer snapshot type used by this module.
+ * @typedef {object} ObjectSerializerSnapshot
+ * @property {number} length
+ * @property {number} cycleStackSize
+ * @property {number} referenceableSize
+ * @property {number} currentPos
+ * @property {number} objectTypeLookupSize
+ * @property {number} currentPosTypeLookup
+ */
+
+/** @typedef {EXPECTED_OBJECT | string} ReferenceableItem */
+
+/**
+ * Defines the object serializer context type used by this module.
+ * @typedef {object} ObjectSerializerContext
+ * @property {(value: EXPECTED_ANY) => void} write
+ * @property {(value: ReferenceableItem) => void} setCircularReference
+ * @property {() => ObjectSerializerSnapshot} snapshot
+ * @property {(snapshot: ObjectSerializerSnapshot) => void} rollback
+ * @property {((item: EXPECTED_ANY | (() => EXPECTED_ANY)) => void)=} writeLazy
+ * @property {((item: (EXPECTED_ANY | (() => EXPECTED_ANY)), obj: LazyOptions | undefined) => import("./SerializerMiddleware").LazyFunction<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY, LazyOptions>)=} writeSeparate
+ */
+
+/**
+ * Defines the object deserializer context type used by this module.
+ * @typedef {object} ObjectDeserializerContext
+ * @property {() => EXPECTED_ANY} read
+ * @property {(value: ReferenceableItem) => void} setCircularReference
+ */
+
+/**
+ * Defines the object serializer type used by this module.
+ * @typedef {object} ObjectSerializer
+ * @property {(value: EXPECTED_ANY, context: ObjectSerializerContext) => void} serialize
+ * @property {(context: ObjectDeserializerContext) => EXPECTED_ANY} deserialize
+ */
+
+/**
+ * Updates set size using the provided set.
+ * @template T
+ * @param {Set<T>} set set
+ * @param {number} size count of items to keep
+ */
+const setSetSize = (set, size) => {
+	let i = 0;
+	for (const item of set) {
+		if (i++ >= size) {
+			set.delete(item);
+		}
+	}
+};
+
+/**
+ * Updates map size using the provided map.
+ * @template K, X
+ * @param {Map<K, X>} map map
+ * @param {number} size count of items to keep
+ */
+const setMapSize = (map, size) => {
+	let i = 0;
+	for (const item of map.keys()) {
+		if (i++ >= size) {
+			map.delete(item);
+		}
+	}
+};
+
+/**
+ * Returns hash.
+ * @param {Buffer} buffer buffer
+ * @param {HashFunction} hashFunction hash function to use
+ * @returns {string} hash
+ */
+const toHash = (buffer, hashFunction) => {
+	const hash = createHash(hashFunction);
+	hash.update(buffer);
+	return hash.digest("latin1");
+};
+
+const ESCAPE = null;
+const ESCAPE_ESCAPE_VALUE = null;
+const ESCAPE_END_OBJECT = true;
+const ESCAPE_UNDEFINED = false;
+
+const CURRENT_VERSION = 2;
+
+/** @typedef {{ request?: string, name?: string | number | null, serializer?: ObjectSerializer }} SerializerConfig */
+/** @typedef {{ request?: string, name?: string | number | null, serializer: ObjectSerializer }} SerializerConfigWithSerializer */
+
+/** @type {Map<Constructor | null, SerializerConfig>} */
+const serializers = new Map();
+/** @type {Map<string | number, ObjectSerializer>} */
+const serializerInversed = new Map();
+
+/** @type {Set<string>} */
+const loadedRequests = new Set();
+
+const NOT_SERIALIZABLE = {};
+
+/** @type {Map<Constructor | null, ObjectSerializer>} */
+const jsTypes = new Map();
+
+jsTypes.set(Object, new PlainObjectSerializer());
+jsTypes.set(Array, new ArraySerializer());
+jsTypes.set(null, new NullPrototypeObjectSerializer());
+jsTypes.set(Map, new MapObjectSerializer());
+jsTypes.set(Set, new SetObjectSerializer());
+jsTypes.set(Date, new DateObjectSerializer());
+jsTypes.set(RegExp, new RegExpObjectSerializer());
+jsTypes.set(Error, new ErrorObjectSerializer(Error));
+jsTypes.set(EvalError, new ErrorObjectSerializer(EvalError));
+jsTypes.set(RangeError, new ErrorObjectSerializer(RangeError));
+jsTypes.set(ReferenceError, new ErrorObjectSerializer(ReferenceError));
+jsTypes.set(SyntaxError, new ErrorObjectSerializer(SyntaxError));
+jsTypes.set(TypeError, new ErrorObjectSerializer(TypeError));
+
+// eslint-disable-next-line n/no-unsupported-features/es-builtins, n/no-unsupported-features/es-syntax
+if (typeof AggregateError !== "undefined") {
+	jsTypes.set(
+		// eslint-disable-next-line n/no-unsupported-features/es-builtins, n/no-unsupported-features/es-syntax
+		AggregateError,
+		new AggregateErrorSerializer()
+	);
+}
+
+// If in a sandboxed environment (e.g. jest), this escapes the sandbox and registers
+// real Object and Array types to. These types may occur in the wild too, e.g. when
+// using Structured Clone in postMessage.
+// eslint-disable-next-line n/exports-style
+if (exports.constructor !== Object) {
+	// eslint-disable-next-line n/exports-style
+	const Obj = /** @type {ObjectConstructor} */ (exports.constructor);
+	const Fn = /** @type {FunctionConstructor} */ (Obj.constructor);
+	for (const [type, config] of jsTypes) {
+		if (type) {
+			const Type = new Fn(`return ${type.name};`)();
+			jsTypes.set(Type, config);
+		}
+	}
+}
+
+{
+	let i = 1;
+	for (const [type, serializer] of jsTypes) {
+		serializers.set(type, {
+			request: "",
+			name: i++,
+			serializer
+		});
+	}
+}
+
+for (const { request, name, serializer } of serializers.values()) {
+	serializerInversed.set(
+		`${request}/${name}`,
+		/** @type {ObjectSerializer} */ (serializer)
+	);
+}
+
+/** @type {Map<RegExp, (request: string) => boolean>} */
+const loaders = new Map();
+
+/** @typedef {ComplexSerializableType[]} DeserializedType */
+/** @typedef {PrimitiveSerializableType[]} SerializedType */
+/** @typedef {{ logger: Logger }} Context */
+
+/** @typedef {(context: ObjectSerializerContext | ObjectDeserializerContext) => void} ExtendContext */
+
+/**
+ * Represents ObjectMiddleware.
+ * @extends {SerializerMiddleware<DeserializedType, SerializedType, Context>}
+ */
+class ObjectMiddleware extends SerializerMiddleware {
+	/**
+	 * Creates an instance of ObjectMiddleware.
+	 * @param {ExtendContext} extendContext context extensions
+	 * @param {HashFunction} hashFunction hash function to use
+	 */
+	constructor(extendContext, hashFunction = DEFAULTS.HASH_FUNCTION) {
+		super();
+		/** @type {ExtendContext} */
+		this.extendContext = extendContext;
+		/** @type {HashFunction} */
+		this._hashFunction = hashFunction;
+	}
+
+	/**
+	 * Processes the provided reg exp.
+	 * @param {RegExp} regExp RegExp for which the request is tested
+	 * @param {(request: string) => boolean} loader loader to load the request, returns true when successful
+	 * @returns {void}
+	 */
+	static registerLoader(regExp, loader) {
+		loaders.set(regExp, loader);
+	}
+
+	/**
+	 * Processes the provided constructor.
+	 * @param {Constructor} Constructor the constructor
+	 * @param {string} request the request which will be required when deserializing
+	 * @param {string | null} name the name to make multiple serializer unique when sharing a request
+	 * @param {ObjectSerializer} serializer the serializer
+	 * @returns {void}
+	 */
+	static register(Constructor, request, name, serializer) {
+		const key = `${request}/${name}`;
+
+		if (serializers.has(Constructor)) {
+			throw new Error(
+				`ObjectMiddleware.register: serializer for ${Constructor.name} is already registered`
+			);
+		}
+
+		if (serializerInversed.has(key)) {
+			throw new Error(
+				`ObjectMiddleware.register: serializer for ${key} is already registered`
+			);
+		}
+
+		serializers.set(Constructor, {
+			request,
+			name,
+			serializer
+		});
+
+		serializerInversed.set(key, serializer);
+	}
+
+	/**
+	 * Register not serializable.
+	 * @param {Constructor} Constructor the constructor
+	 * @returns {void}
+	 */
+	static registerNotSerializable(Constructor) {
+		if (serializers.has(Constructor)) {
+			throw new Error(
+				`ObjectMiddleware.registerNotSerializable: serializer for ${Constructor.name} is already registered`
+			);
+		}
+
+		serializers.set(Constructor, NOT_SERIALIZABLE);
+	}
+
+	/**
+	 * Gets serializer for.
+	 * @param {EXPECTED_ANY} object for serialization
+	 * @returns {SerializerConfigWithSerializer} Serializer config
+	 */
+	static getSerializerFor(object) {
+		const proto = Object.getPrototypeOf(object);
+		/** @type {null | Constructor} */
+		let c;
+		if (proto === null) {
+			// Object created with Object.create(null)
+			c = null;
+		} else {
+			c = proto.constructor;
+			if (!c) {
+				throw new Error(
+					"Serialization of objects with prototype without valid constructor property not possible"
+				);
+			}
+		}
+		const config = serializers.get(c);
+
+		if (!config) {
+			throw new Error(
+				`No serializer registered for ${/** @type {Constructor} */ (c).name}`
+			);
+		}
+		if (config === NOT_SERIALIZABLE) throw NOT_SERIALIZABLE;
+
+		return /** @type {SerializerConfigWithSerializer} */ (config);
+	}
+
+	/**
+	 * Gets deserializer for.
+	 * @param {string} request request
+	 * @param {string} name name
+	 * @returns {ObjectSerializer} serializer
+	 */
+	static getDeserializerFor(request, name) {
+		const key = `${request}/${name}`;
+		const serializer = serializerInversed.get(key);
+
+		if (serializer === undefined) {
+			throw new Error(`No deserializer registered for ${key}`);
+		}
+
+		return serializer;
+	}
+
+	/**
+	 * Get deserializer for without error.
+	 * @param {string} request request
+	 * @param {string} name name
+	 * @returns {ObjectSerializer | undefined} serializer
+	 */
+	static _getDeserializerForWithoutError(request, name) {
+		const key = `${request}/${name}`;
+		const serializer = serializerInversed.get(key);
+		return serializer;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {DeserializedType} data data
+	 * @param {Context} context context object
+	 * @returns {SerializedType | Promise<SerializedType> | null} serialized data
+	 */
+	serialize(data, context) {
+		/** @type {PrimitiveSerializableType[]} */
+		let result = [CURRENT_VERSION];
+		let currentPos = 0;
+		/** @type {Map<ReferenceableItem, number>} */
+		let referenceable = new Map();
+		/**
+		 * Adds referenceable.
+		 * @param {ReferenceableItem} item referenceable item
+		 */
+		const addReferenceable = (item) => {
+			referenceable.set(item, currentPos++);
+		};
+		/** @type {Map<number, Buffer | [Buffer, Buffer] | Map<string, Buffer>>} */
+		let bufferDedupeMap = new Map();
+		/**
+		 * Returns deduped buffer.
+		 * @param {Buffer} buf buffer
+		 * @returns {Buffer} deduped buffer
+		 */
+		const dedupeBuffer = (buf) => {
+			const len = buf.length;
+			const entry = bufferDedupeMap.get(len);
+			if (entry === undefined) {
+				bufferDedupeMap.set(len, buf);
+				return buf;
+			}
+			if (Buffer.isBuffer(entry)) {
+				if (len < 32) {
+					if (buf.equals(entry)) {
+						return entry;
+					}
+					bufferDedupeMap.set(len, [entry, buf]);
+					return buf;
+				}
+				const hash = toHash(entry, this._hashFunction);
+				/** @type {Map<string, Buffer>} */
+				const newMap = new Map();
+				newMap.set(hash, entry);
+				bufferDedupeMap.set(len, newMap);
+				const hashBuf = toHash(buf, this._hashFunction);
+				if (hash === hashBuf) {
+					return entry;
+				}
+				return buf;
+			} else if (Array.isArray(entry)) {
+				if (entry.length < 16) {
+					for (const item of entry) {
+						if (buf.equals(item)) {
+							return item;
+						}
+					}
+					entry.push(buf);
+					return buf;
+				}
+				/** @type {Map<string, Buffer>} */
+				const newMap = new Map();
+				const hash = toHash(buf, this._hashFunction);
+				/** @type {undefined | Buffer} */
+				let found;
+				for (const item of entry) {
+					const itemHash = toHash(item, this._hashFunction);
+					newMap.set(itemHash, item);
+					if (found === undefined && itemHash === hash) found = item;
+				}
+				bufferDedupeMap.set(len, newMap);
+				if (found === undefined) {
+					newMap.set(hash, buf);
+					return buf;
+				}
+				return found;
+			}
+			const hash = toHash(buf, this._hashFunction);
+			const item = entry.get(hash);
+			if (item !== undefined) {
+				return item;
+			}
+			entry.set(hash, buf);
+			return buf;
+		};
+		let currentPosTypeLookup = 0;
+		/** @type {Map<ComplexSerializableType, number>} */
+		let objectTypeLookup = new Map();
+		/** @type {Set<ComplexSerializableType>} */
+		const cycleStack = new Set();
+		/**
+		 * Returns stack.
+		 * @param {ComplexSerializableType} item item to stack
+		 * @returns {string} stack
+		 */
+		const stackToString = (item) => {
+			const arr = [...cycleStack];
+			arr.push(item);
+			return arr
+				.map((item) => {
+					if (typeof item === "string") {
+						if (item.length > 100) {
+							return `String ${JSON.stringify(item.slice(0, 100)).slice(
+								0,
+								-1
+							)}..."`;
+						}
+						return `String ${JSON.stringify(item)}`;
+					}
+					try {
+						const { request, name } = ObjectMiddleware.getSerializerFor(item);
+						if (request) {
+							return `${request}${name ? `.${name}` : ""}`;
+						}
+					} catch (_err) {
+						// ignore -> fallback
+					}
+					if (typeof item === "object" && item !== null) {
+						if (item.constructor) {
+							if (item.constructor === Object) {
+								return `Object { ${Object.keys(item).join(", ")} }`;
+							}
+							if (item.constructor === Map) {
+								return `Map { ${/** @type {Map<EXPECTED_ANY, EXPECTED_ANY>} */ (item).size} items }`;
+							}
+							if (item.constructor === Array) {
+								return `Array { ${/** @type {EXPECTED_ANY[]} */ (item).length} items }`;
+							}
+							if (item.constructor === Set) {
+								return `Set { ${/** @type {Set<EXPECTED_ANY>} */ (item).size} items }`;
+							}
+							if (item.constructor === RegExp) {
+								return /** @type {RegExp} */ (item).toString();
+							}
+							return `${item.constructor.name}`;
+						}
+						return `Object [null prototype] { ${Object.keys(item).join(
+							", "
+						)} }`;
+					}
+					if (typeof item === "bigint") {
+						return `BigInt ${item}n`;
+					}
+					try {
+						return `${item}`;
+					} catch (err) {
+						return `(${/** @type {Error} */ (err).message})`;
+					}
+				})
+				.join(" -> ");
+		};
+		/** @type {undefined | WeakSet<Error>} */
+		let hasDebugInfoAttached;
+		/** @type {ObjectSerializerContext} */
+		let ctx = {
+			write(value) {
+				try {
+					process(value);
+				} catch (err) {
+					if (err !== NOT_SERIALIZABLE) {
+						if (hasDebugInfoAttached === undefined) {
+							hasDebugInfoAttached = new WeakSet();
+						}
+						if (!hasDebugInfoAttached.has(/** @type {Error} */ (err))) {
+							/** @type {Error} */
+							(err).message += `\nwhile serializing ${stackToString(value)}`;
+							hasDebugInfoAttached.add(/** @type {Error} */ (err));
+						}
+					}
+					throw err;
+				}
+			},
+			setCircularReference(ref) {
+				addReferenceable(ref);
+			},
+			snapshot() {
+				return {
+					length: result.length,
+					cycleStackSize: cycleStack.size,
+					referenceableSize: referenceable.size,
+					currentPos,
+					objectTypeLookupSize: objectTypeLookup.size,
+					currentPosTypeLookup
+				};
+			},
+			rollback(snapshot) {
+				result.length = snapshot.length;
+				setSetSize(cycleStack, snapshot.cycleStackSize);
+				setMapSize(referenceable, snapshot.referenceableSize);
+				currentPos = snapshot.currentPos;
+				setMapSize(objectTypeLookup, snapshot.objectTypeLookupSize);
+				currentPosTypeLookup = snapshot.currentPosTypeLookup;
+			},
+			...context
+		};
+		this.extendContext(ctx);
+		/**
+		 * Processes the provided item.
+		 * @param {ComplexSerializableType} item item to serialize
+		 */
+		const process = (item) => {
+			if (Buffer.isBuffer(item)) {
+				// check if we can emit a reference
+				const ref = referenceable.get(item);
+				if (ref !== undefined) {
+					result.push(ESCAPE, ref - currentPos);
+					return;
+				}
+				const alreadyUsedBuffer = dedupeBuffer(item);
+				if (alreadyUsedBuffer !== item) {
+					const ref = referenceable.get(alreadyUsedBuffer);
+					if (ref !== undefined) {
+						referenceable.set(item, ref);
+						result.push(ESCAPE, ref - currentPos);
+						return;
+					}
+					item = alreadyUsedBuffer;
+				}
+				addReferenceable(item);
+
+				result.push(/** @type {Buffer} */ (item));
+			} else if (item === ESCAPE) {
+				result.push(ESCAPE, ESCAPE_ESCAPE_VALUE);
+			} else if (
+				typeof item === "object"
+				// We don't have to check for null as ESCAPE is null and this has been checked before
+			) {
+				// check if we can emit a reference
+				const ref = referenceable.get(item);
+				if (ref !== undefined) {
+					result.push(ESCAPE, ref - currentPos);
+					return;
+				}
+
+				if (cycleStack.has(item)) {
+					throw new Error(
+						"This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize."
+					);
+				}
+
+				const { request, name, serializer } = ObjectMiddleware.getSerializerFor(
+					/** @type {Constructor} */
+					(item)
+				);
+				const key = `${request}/${name}`;
+				const lastIndex = objectTypeLookup.get(key);
+
+				if (lastIndex === undefined) {
+					objectTypeLookup.set(key, currentPosTypeLookup++);
+
+					result.push(ESCAPE, request, name);
+				} else {
+					result.push(ESCAPE, currentPosTypeLookup - lastIndex);
+				}
+
+				cycleStack.add(item);
+
+				try {
+					serializer.serialize(item, ctx);
+				} finally {
+					cycleStack.delete(item);
+				}
+
+				result.push(ESCAPE, ESCAPE_END_OBJECT);
+
+				addReferenceable(item);
+			} else if (typeof item === "string") {
+				if (item.length > 1) {
+					// short strings are shorter when not emitting a reference (this saves 1 byte per empty string)
+					// check if we can emit a reference
+					const ref = referenceable.get(item);
+					if (ref !== undefined) {
+						result.push(ESCAPE, ref - currentPos);
+						return;
+					}
+					addReferenceable(item);
+				}
+
+				if (item.length > 102400 && context.logger) {
+					context.logger.warn(
+						`Serializing big strings (${Math.round(
+							item.length / 1024
+						)}kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)`
+					);
+				}
+
+				result.push(item);
+			} else if (typeof item === "function") {
+				if (!SerializerMiddleware.isLazy(item)) {
+					throw new Error(`Unexpected function ${item}`);
+				}
+
+				/** @type {SerializedType | undefined} */
+				const serializedData =
+					SerializerMiddleware.getLazySerializedValue(item);
+
+				if (serializedData !== undefined) {
+					if (typeof serializedData === "function") {
+						result.push(serializedData);
+					} else {
+						throw new Error("Not implemented");
+					}
+				} else if (SerializerMiddleware.isLazy(item, this)) {
+					throw new Error("Not implemented");
+				} else {
+					const data =
+						/** @type {() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>} */
+						(
+							SerializerMiddleware.serializeLazy(item, (data) =>
+								this.serialize([data], context)
+							)
+						);
+					SerializerMiddleware.setLazySerializedValue(item, data);
+					result.push(data);
+				}
+			} else if (item === undefined) {
+				result.push(ESCAPE, ESCAPE_UNDEFINED);
+			} else {
+				result.push(item);
+			}
+		};
+
+		try {
+			for (const item of data) {
+				process(item);
+			}
+			return result;
+		} catch (err) {
+			if (err === NOT_SERIALIZABLE) return null;
+
+			throw err;
+		} finally {
+			// Get rid of these references to avoid leaking memory
+			// This happens because the optimized code v8 generates
+			// is optimized for our "ctx.write" method so it will reference
+			// it from e. g. Dependency.prototype.serialize -(IC)-> ctx.write
+			data =
+				result =
+				referenceable =
+				bufferDedupeMap =
+				objectTypeLookup =
+				ctx =
+					/** @type {EXPECTED_ANY} */
+					(undefined);
+		}
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {SerializedType} data data
+	 * @param {Context} context context object
+	 * @returns {DeserializedType | Promise<DeserializedType>} deserialized data
+	 */
+	deserialize(data, context) {
+		let currentDataPos = 0;
+		const read = () => {
+			if (currentDataPos >= data.length) {
+				throw new Error("Unexpected end of stream");
+			}
+
+			return data[currentDataPos++];
+		};
+
+		if (read() !== CURRENT_VERSION) {
+			throw new Error("Version mismatch, serializer changed");
+		}
+
+		let currentPos = 0;
+		/** @type {ReferenceableItem[]} */
+		let referenceable = [];
+		/**
+		 * Adds referenceable.
+		 * @param {ReferenceableItem} item referenceable item
+		 */
+		const addReferenceable = (item) => {
+			referenceable.push(item);
+			currentPos++;
+		};
+		let currentPosTypeLookup = 0;
+		/** @type {ObjectSerializer[]} */
+		let objectTypeLookup = [];
+		/** @type {ComplexSerializableType[]} */
+		let result = [];
+		/** @type {ObjectDeserializerContext} */
+		let ctx = {
+			read() {
+				return decodeValue();
+			},
+			setCircularReference(ref) {
+				addReferenceable(ref);
+			},
+			...context
+		};
+		this.extendContext(ctx);
+		/**
+		 * Decodes the provided value.
+		 * @returns {ComplexSerializableType} deserialize value
+		 */
+		const decodeValue = () => {
+			const item = read();
+
+			if (item === ESCAPE) {
+				const nextItem = read();
+
+				if (nextItem === ESCAPE_ESCAPE_VALUE) {
+					return ESCAPE;
+				} else if (nextItem === ESCAPE_UNDEFINED) {
+					// Nothing
+				} else if (nextItem === ESCAPE_END_OBJECT) {
+					throw new Error(
+						`Unexpected end of object at position ${currentDataPos - 1}`
+					);
+				} else {
+					const request = nextItem;
+					/** @type {undefined | ObjectSerializer} */
+					let serializer;
+
+					if (typeof request === "number") {
+						if (request < 0) {
+							// relative reference
+							return referenceable[currentPos + request];
+						}
+						serializer = objectTypeLookup[currentPosTypeLookup - request];
+					} else {
+						if (typeof request !== "string") {
+							throw new Error(
+								`Unexpected type (${typeof request}) of request ` +
+									`at position ${currentDataPos - 1}`
+							);
+						}
+						const name = /** @type {string} */ (read());
+
+						serializer = ObjectMiddleware._getDeserializerForWithoutError(
+							request,
+							name
+						);
+
+						if (serializer === undefined) {
+							if (request && !loadedRequests.has(request)) {
+								let loaded = false;
+								for (const [regExp, loader] of loaders) {
+									if (regExp.test(request) && loader(request)) {
+										loaded = true;
+										break;
+									}
+								}
+								if (!loaded) {
+									require(request);
+								}
+
+								loadedRequests.add(request);
+							}
+
+							serializer = ObjectMiddleware.getDeserializerFor(request, name);
+						}
+
+						objectTypeLookup.push(serializer);
+						currentPosTypeLookup++;
+					}
+					try {
+						const item = serializer.deserialize(ctx);
+						const end1 = read();
+
+						if (end1 !== ESCAPE) {
+							throw new Error("Expected end of object");
+						}
+
+						const end2 = read();
+
+						if (end2 !== ESCAPE_END_OBJECT) {
+							throw new Error("Expected end of object");
+						}
+
+						addReferenceable(item);
+
+						return item;
+					} catch (err) {
+						// As this is only for error handling, we omit creating a Map for
+						// faster access to this information, as this would affect performance
+						// in the good case
+						/** @type {undefined | [Constructor | null, SerializerConfig]} */
+						let serializerEntry;
+						for (const entry of serializers) {
+							if (entry[1].serializer === serializer) {
+								serializerEntry = entry;
+								break;
+							}
+						}
+						const name = !serializerEntry
+							? "unknown"
+							: !serializerEntry[1].request
+								? /** @type {Constructor[]} */ (serializerEntry)[0].name
+								: serializerEntry[1].name
+									? `${serializerEntry[1].request} ${serializerEntry[1].name}`
+									: serializerEntry[1].request;
+						/** @type {Error} */
+						(err).message += `\n(during deserialization of ${name})`;
+						throw err;
+					}
+				}
+			} else if (typeof item === "string") {
+				if (item.length > 1) {
+					addReferenceable(item);
+				}
+
+				return item;
+			} else if (Buffer.isBuffer(item)) {
+				addReferenceable(item);
+
+				return item;
+			} else if (typeof item === "function") {
+				return SerializerMiddleware.deserializeLazy(
+					item,
+					(data) =>
+						/** @type {[DeserializedType]} */
+						(this.deserialize(data, context))[0]
+				);
+			} else {
+				return item;
+			}
+		};
+
+		try {
+			while (currentDataPos < data.length) {
+				result.push(decodeValue());
+			}
+			return result;
+		} finally {
+			// Get rid of these references to avoid leaking memory
+			// This happens because the optimized code v8 generates
+			// is optimized for our "ctx.read" method so it will reference
+			// it from e. g. Dependency.prototype.deserialize -(IC)-> ctx.read
+			result =
+				referenceable =
+				data =
+				objectTypeLookup =
+				ctx =
+					/** @type {EXPECTED_ANY} */
+					(undefined);
+		}
+	}
+}
+
+module.exports = ObjectMiddleware;
+module.exports.NOT_SERIALIZABLE = NOT_SERIALIZABLE;
Index: frontend/node_modules/webpack/lib/serialization/PlainObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/PlainObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/PlainObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,126 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {EXPECTED_FUNCTION} CacheAssoc */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {WeakMap<CacheAssoc, ObjectStructure<T>>}
+ */
+const cache = new WeakMap();
+
+/**
+ * Represents ObjectStructure.
+ * @template T
+ */
+class ObjectStructure {
+	constructor() {
+		/** @type {undefined | keyof T[]} */
+		this.keys = undefined;
+		/** @type {undefined | Map<keyof T, ObjectStructure<T>>} */
+		this.children = undefined;
+	}
+
+	/**
+	 * Returns keys.
+	 * @param {keyof T[]} keys keys
+	 * @returns {keyof T[]} keys
+	 */
+	getKeys(keys) {
+		if (this.keys === undefined) this.keys = keys;
+		return this.keys;
+	}
+
+	/**
+	 * Returns object structure.
+	 * @param {keyof T} key key
+	 * @returns {ObjectStructure<T>} object structure
+	 */
+	key(key) {
+		if (this.children === undefined) this.children = new Map();
+		const child = this.children.get(key);
+		if (child !== undefined) return child;
+		const newChild = new ObjectStructure();
+		this.children.set(key, newChild);
+		return newChild;
+	}
+}
+
+/**
+ * Returns keys.
+ * @template T
+ * @param {(keyof T)[]} keys keys
+ * @param {CacheAssoc} cacheAssoc cache assoc fn
+ * @returns {(keyof T)[]} keys
+ */
+const getCachedKeys = (keys, cacheAssoc) => {
+	let root = cache.get(cacheAssoc);
+	if (root === undefined) {
+		root = new ObjectStructure();
+		cache.set(cacheAssoc, root);
+	}
+	let current = root;
+	for (const key of keys) {
+		current = current.key(key);
+	}
+	return current.getKeys(keys);
+};
+
+class PlainObjectSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @template {object} T
+	 * @param {T} obj plain object
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		const keys = /** @type {(keyof T)[]} */ (Object.keys(obj));
+		if (keys.length > 128) {
+			// Objects with so many keys are unlikely to share structure
+			// with other objects
+			context.write(keys);
+			for (const key of keys) {
+				context.write(obj[key]);
+			}
+		} else if (keys.length > 1) {
+			context.write(getCachedKeys(keys, context.write));
+			for (const key of keys) {
+				context.write(obj[key]);
+			}
+		} else if (keys.length === 1) {
+			const key = keys[0];
+			context.write(key);
+			context.write(obj[key]);
+		} else {
+			context.write(null);
+		}
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @template {object} T
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {T} plain object
+	 */
+	deserialize(context) {
+		const keys = context.read();
+		const obj = /** @type {T} */ ({});
+		if (Array.isArray(keys)) {
+			for (const key of keys) {
+				obj[/** @type {keyof T} */ (key)] = context.read();
+			}
+		} else if (keys !== null) {
+			obj[/** @type {keyof T} */ (keys)] = context.read();
+		}
+		return obj;
+	}
+}
+
+module.exports = PlainObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/RegExpObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/RegExpObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/RegExpObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class RegExpObjectSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {RegExp} obj regexp
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		context.write(obj.source);
+		context.write(obj.flags);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {RegExp} regexp
+	 */
+	deserialize(context) {
+		return new RegExp(context.read(), context.read());
+	}
+}
+
+module.exports = RegExpObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/Serializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/Serializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/Serializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,87 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/**
+ * Defines the serializer middleware type used by this module.
+ * @template T, K, C
+ * @typedef {import("./SerializerMiddleware")<T, K, C>} SerializerMiddleware
+ */
+
+/**
+ * Represents Serializer.
+ * @template DeserializedValue
+ * @template SerializedValue
+ * @template Context
+ */
+class Serializer {
+	/**
+	 * Creates an instance of Serializer.
+	 * @param {SerializerMiddleware<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>[]} middlewares serializer middlewares
+	 * @param {Context=} context context
+	 */
+	constructor(middlewares, context) {
+		this.serializeMiddlewares = [...middlewares];
+		this.deserializeMiddlewares = [...middlewares].reverse();
+		this.context = context;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @template ExtendedContext
+	 * @param {DeserializedValue | Promise<DeserializedValue>} obj object
+	 * @param {Context & ExtendedContext} context context object
+	 * @returns {Promise<SerializedValue>} result
+	 */
+	serialize(obj, context) {
+		const ctx = { ...context, ...this.context };
+		let current = obj;
+		for (const middleware of this.serializeMiddlewares) {
+			if (
+				current &&
+				typeof (/** @type {Promise<DeserializedValue>} */ (current).then) ===
+					"function"
+			) {
+				current =
+					/** @type {Promise<DeserializedValue>} */
+					(current).then((data) => data && middleware.serialize(data, ctx));
+			} else if (current) {
+				try {
+					current = middleware.serialize(current, ctx);
+				} catch (err) {
+					current = Promise.reject(err);
+				}
+			} else {
+				break;
+			}
+		}
+		return /** @type {Promise<SerializedValue>} */ (current);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @template ExtendedContext
+	 * @param {SerializedValue | Promise<SerializedValue>} value value
+	 * @param {Context & ExtendedContext} context object
+	 * @returns {Promise<DeserializedValue>} result
+	 */
+	deserialize(value, context) {
+		const ctx = { ...context, ...this.context };
+		let current = value;
+		for (const middleware of this.deserializeMiddlewares) {
+			current =
+				current &&
+				typeof (/** @type {Promise<SerializedValue>} */ (current).then) ===
+					"function"
+					? /** @type {Promise<SerializedValue>} */ (current).then((data) =>
+							middleware.deserialize(data, ctx)
+						)
+					: middleware.deserialize(current, ctx);
+		}
+		return /** @type {Promise<DeserializedValue>} */ (current);
+	}
+}
+
+module.exports = Serializer;
Index: frontend/node_modules/webpack/lib/serialization/SerializerMiddleware.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/SerializerMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/SerializerMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,238 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const memoize = require("../util/memoize");
+
+const LAZY_TARGET = Symbol("lazy serialization target");
+const LAZY_SERIALIZED_VALUE = Symbol("lazy serialization data");
+
+/** @typedef {SerializerMiddleware<EXPECTED_ANY, EXPECTED_ANY, Record<string, EXPECTED_ANY>>} LazyTarget */
+/** @typedef {Record<string, EXPECTED_ANY>} LazyOptions */
+
+/**
+ * Defines the lazy function type used by this module.
+ * @template InputValue
+ * @template OutputValue
+ * @template {LazyTarget} InternalLazyTarget
+ * @template {LazyOptions | undefined} InternalLazyOptions
+ * @typedef {(() => InputValue | Promise<InputValue>) & Partial<{ [LAZY_TARGET]: InternalLazyTarget, options: InternalLazyOptions, [LAZY_SERIALIZED_VALUE]?: OutputValue | LazyFunction<OutputValue, InputValue, InternalLazyTarget, InternalLazyOptions> | undefined }>} LazyFunction
+ */
+
+/**
+ * Represents SerializerMiddleware.
+ * @template DeserializedType
+ * @template SerializedType
+ * @template Context
+ */
+class SerializerMiddleware {
+	/* istanbul ignore next */
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @abstract
+	 * @param {DeserializedType} data data
+	 * @param {Context} context context object
+	 * @returns {SerializedType | Promise<SerializedType> | null} serialized data
+	 */
+	serialize(data, context) {
+		const AbstractMethodError = require("../errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @abstract
+	 * @param {SerializedType} data data
+	 * @param {Context} context context object
+	 * @returns {DeserializedType | Promise<DeserializedType>} deserialized data
+	 */
+	deserialize(data, context) {
+		const AbstractMethodError = require("../errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/**
+	 * Creates a lazy from the provided value.
+	 * @template TLazyInputValue
+	 * @template TLazyOutputValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {LazyOptions | undefined} TLazyOptions
+	 * @param {TLazyInputValue | (() => TLazyInputValue)} value contained value or function to value
+	 * @param {TLazyTarget} target target middleware
+	 * @param {TLazyOptions=} options lazy options
+	 * @param {TLazyOutputValue=} serializedValue serialized value
+	 * @returns {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions>} lazy function
+	 */
+	static createLazy(
+		value,
+		target,
+		options = /** @type {TLazyOptions} */ ({}),
+		serializedValue = undefined
+	) {
+		if (SerializerMiddleware.isLazy(value, target)) return value;
+		const fn =
+			/** @type {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions>} */
+			(typeof value === "function" ? value : () => value);
+		fn[LAZY_TARGET] = target;
+		fn.options = options;
+		fn[LAZY_SERIALIZED_VALUE] = serializedValue;
+		return fn;
+	}
+
+	/**
+	 * Checks whether this serializer middleware is lazy.
+	 * @template {LazyTarget} TLazyTarget
+	 * @param {EXPECTED_ANY} fn lazy function
+	 * @param {TLazyTarget=} target target middleware
+	 * @returns {fn is LazyFunction<EXPECTED_ANY, EXPECTED_ANY, TLazyTarget, EXPECTED_ANY>} true, when fn is a lazy function (optionally of that target)
+	 */
+	static isLazy(fn, target) {
+		if (typeof fn !== "function") return false;
+		const t = fn[LAZY_TARGET];
+		return target ? t === target : Boolean(t);
+	}
+
+	/**
+	 * Returns options.
+	 * @template TLazyInputValue
+	 * @template TLazyOutputValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {Record<string, EXPECTED_ANY>} TLazyOptions
+	 * @param {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions>} fn lazy function
+	 * @returns {LazyOptions | undefined} options
+	 */
+	static getLazyOptions(fn) {
+		if (typeof fn !== "function") return;
+		return fn.options;
+	}
+
+	/**
+	 * Gets lazy serialized value.
+	 * @template TLazyInputValue
+	 * @template TLazyOutputValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {LazyOptions} TLazyOptions
+	 * @param {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions> | EXPECTED_ANY} fn lazy function
+	 * @returns {TLazyOutputValue | undefined} serialized value
+	 */
+	static getLazySerializedValue(fn) {
+		if (typeof fn !== "function") return;
+		return fn[LAZY_SERIALIZED_VALUE];
+	}
+
+	/**
+	 * Sets lazy serialized value.
+	 * @template TLazyInputValue
+	 * @template TLazyOutputValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {LazyOptions} TLazyOptions
+	 * @param {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions>} fn lazy function
+	 * @param {TLazyOutputValue} value serialized value
+	 * @returns {void}
+	 */
+	static setLazySerializedValue(fn, value) {
+		fn[LAZY_SERIALIZED_VALUE] = value;
+	}
+
+	/**
+	 * Returns new lazy.
+	 * @template TLazyInputValue DeserializedValue
+	 * @template TLazyOutputValue SerializedValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {LazyOptions | undefined} TLazyOptions
+	 * @param {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions>} lazy lazy function
+	 * @param {(value: TLazyInputValue) => TLazyOutputValue} serialize serialize function
+	 * @returns {LazyFunction<TLazyOutputValue, TLazyInputValue, TLazyTarget, TLazyOptions>} new lazy
+	 */
+	static serializeLazy(lazy, serialize) {
+		const fn =
+			/** @type {LazyFunction<TLazyOutputValue, TLazyInputValue, TLazyTarget, TLazyOptions>} */
+			(
+				memoize(() => {
+					const r = lazy();
+					if (
+						r &&
+						typeof (/** @type {Promise<TLazyInputValue>} */ (r).then) ===
+							"function"
+					) {
+						return (
+							/** @type {Promise<TLazyInputValue>} */
+							(r).then((data) => data && serialize(data))
+						);
+					}
+					return serialize(/** @type {TLazyInputValue} */ (r));
+				})
+			);
+		fn[LAZY_TARGET] = lazy[LAZY_TARGET];
+		fn.options = lazy.options;
+		lazy[LAZY_SERIALIZED_VALUE] = fn;
+		return fn;
+	}
+
+	/**
+	 * Returns new lazy.
+	 * @template TLazyInputValue SerializedValue
+	 * @template TLazyOutputValue DeserializedValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {LazyOptions | undefined} TLazyOptions
+	 * @param {LazyFunction<TLazyInputValue, TLazyOutputValue, TLazyTarget, TLazyOptions>} lazy lazy function
+	 * @param {(data: TLazyInputValue) => TLazyOutputValue} deserialize deserialize function
+	 * @returns {LazyFunction<TLazyOutputValue, TLazyInputValue, TLazyTarget, TLazyOptions>} new lazy
+	 */
+	static deserializeLazy(lazy, deserialize) {
+		const fn =
+			/** @type {LazyFunction<TLazyOutputValue, TLazyInputValue, TLazyTarget, TLazyOptions>} */ (
+				memoize(() => {
+					const r = lazy();
+					if (
+						r &&
+						typeof (/** @type {Promise<TLazyInputValue>} */ (r).then) ===
+							"function"
+					) {
+						return (
+							/** @type {Promise<TLazyInputValue>} */
+							(r).then((data) => deserialize(data))
+						);
+					}
+					return deserialize(/** @type {TLazyInputValue} */ (r));
+				})
+			);
+		fn[LAZY_TARGET] = lazy[LAZY_TARGET];
+		fn.options = lazy.options;
+		fn[LAZY_SERIALIZED_VALUE] = lazy;
+		return fn;
+	}
+
+	/**
+	 * Returns new lazy.
+	 * @template TLazyInputValue
+	 * @template TLazyOutputValue
+	 * @template {LazyTarget} TLazyTarget
+	 * @template {LazyOptions} TLazyOptions
+	 * @param {LazyFunction<TLazyInputValue | TLazyOutputValue, TLazyInputValue | TLazyOutputValue, TLazyTarget, TLazyOptions> | undefined} lazy lazy function
+	 * @returns {LazyFunction<TLazyInputValue | TLazyOutputValue, TLazyInputValue | TLazyOutputValue, TLazyTarget, TLazyOptions> | undefined} new lazy
+	 */
+	static unMemoizeLazy(lazy) {
+		if (!SerializerMiddleware.isLazy(lazy)) return lazy;
+		/** @type {LazyFunction<TLazyInputValue | TLazyOutputValue, TLazyInputValue | TLazyOutputValue, TLazyTarget, TLazyOptions>} */
+		const fn = () => {
+			throw new Error(
+				"A lazy value that has been unmemorized can't be called again"
+			);
+		};
+		fn[LAZY_SERIALIZED_VALUE] = SerializerMiddleware.unMemoizeLazy(
+			/** @type {LazyFunction<TLazyInputValue | TLazyOutputValue, TLazyInputValue | TLazyOutputValue, TLazyTarget, TLazyOptions>} */
+			(lazy[LAZY_SERIALIZED_VALUE])
+		);
+		fn[LAZY_TARGET] = lazy[LAZY_TARGET];
+		fn.options = lazy.options;
+		return fn;
+	}
+}
+
+module.exports = SerializerMiddleware;
Index: frontend/node_modules/webpack/lib/serialization/SetObjectSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/SetObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/SetObjectSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class SetObjectSerializer {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @template T
+	 * @param {Set<T>} obj set
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		context.write(obj.size);
+		for (const value of obj) {
+			context.write(value);
+		}
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @template T
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {Set<T>} date
+	 */
+	deserialize(context) {
+		/** @type {number} */
+		const size = context.read();
+		/** @type {Set<T>} */
+		const set = new Set();
+		for (let i = 0; i < size; i++) {
+			set.add(context.read());
+		}
+		return set;
+	}
+}
+
+module.exports = SetObjectSerializer;
Index: frontend/node_modules/webpack/lib/serialization/SingleItemMiddleware.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/SingleItemMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/SingleItemMiddleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const SerializerMiddleware = require("./SerializerMiddleware");
+
+/** @typedef {EXPECTED_ANY} DeserializedType */
+/** @typedef {EXPECTED_ANY[]} SerializedType */
+/** @typedef {EXPECTED_OBJECT} Context */
+
+/**
+ * Represents SingleItemMiddleware.
+ * @extends {SerializerMiddleware<DeserializedType, SerializedType, Context>}
+ */
+class SingleItemMiddleware extends SerializerMiddleware {
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {DeserializedType} data data
+	 * @param {Context} context context object
+	 * @returns {SerializedType | Promise<SerializedType> | null} serialized data
+	 */
+	serialize(data, context) {
+		return [data];
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {SerializedType} data data
+	 * @param {Context} context context object
+	 * @returns {DeserializedType | Promise<DeserializedType>} deserialized data
+	 */
+	deserialize(data, context) {
+		return data[0];
+	}
+}
+
+module.exports = SingleItemMiddleware;
Index: frontend/node_modules/webpack/lib/serialization/types.js
===================================================================
--- frontend/node_modules/webpack/lib/serialization/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/serialization/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/** @typedef {undefined | null | number | bigint | string | boolean | Buffer | EXPECTED_OBJECT | (() => ComplexSerializableType[] | Promise<ComplexSerializableType[]>)} ComplexSerializableType */
+
+/** @typedef {undefined | null | number | bigint | string | boolean | Buffer | (() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>)} PrimitiveSerializableType */
+
+/** @typedef {Buffer | (() => BufferSerializableType[] | Promise<BufferSerializableType[]>)} BufferSerializableType */
+
+module.exports = {};
Index: frontend/node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+class ConsumeSharedFallbackDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ConsumeSharedFallbackDependency.
+	 * @param {string} request the request
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "consume shared fallback";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	ConsumeSharedFallbackDependency,
+	"webpack/lib/sharing/ConsumeSharedFallbackDependency"
+);
+
+module.exports = ConsumeSharedFallbackDependency;
Index: frontend/node_modules/webpack/lib/sharing/ConsumeSharedModule.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ConsumeSharedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ConsumeSharedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,359 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const Module = require("../Module");
+const {
+	CONSUME_SHARED_TYPES,
+	JAVASCRIPT_TYPES
+} = require("../ModuleSourceTypeConstants");
+const {
+	WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const { rangeToString, stringifyHoley } = require("../util/semver");
+const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependency");
+
+/** @type {WeakMap<ModuleGraph, WeakMap<ConsumeSharedModule, Module | null>>} */
+const fallbackModuleCache = new WeakMap();
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../Module").ExportsType} ExportsType */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../util/semver").SemVerRange} SemVerRange */
+/** @typedef {import("../Module").BasicSourceTypes} BasicSourceTypes */
+
+/**
+ * Represents the consume shared module runtime component.
+ * @typedef {object} ConsumeOptions
+ * @property {string=} import fallback request
+ * @property {string=} importResolved resolved fallback request
+ * @property {string} shareKey global share key
+ * @property {string} shareScope share scope
+ * @property {SemVerRange | false | undefined} requiredVersion version requirement
+ * @property {string=} packageName package name to determine required version automatically
+ * @property {boolean} strictVersion don't use shared version even if version isn't valid
+ * @property {boolean} singleton use single global version
+ * @property {boolean} eager include the fallback module in a sync way
+ */
+
+class ConsumeSharedModule extends Module {
+	/**
+	 * Creates an instance of ConsumeSharedModule.
+	 * @param {string} context context
+	 * @param {ConsumeOptions} options consume options
+	 */
+	constructor(context, options) {
+		super(WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE, context);
+		this.options = options;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		const {
+			shareKey,
+			shareScope,
+			importResolved,
+			requiredVersion,
+			strictVersion,
+			singleton,
+			eager
+		} = this.options;
+		return `${WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE}|${shareScope}|${shareKey}|${
+			requiredVersion && rangeToString(requiredVersion)
+		}|${strictVersion}|${importResolved}|${singleton}|${eager}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		const {
+			shareKey,
+			shareScope,
+			importResolved,
+			requiredVersion,
+			strictVersion,
+			singleton,
+			eager
+		} = this.options;
+		return `consume shared module (${shareScope}) ${shareKey}@${
+			requiredVersion ? rangeToString(requiredVersion) : "*"
+		}${strictVersion ? " (strict)" : ""}${singleton ? " (singleton)" : ""}${
+			importResolved
+				? ` (fallback: ${requestShortener.shorten(importResolved)})`
+				: ""
+		}${eager ? " (eager)" : ""}`;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		const { shareKey, shareScope, import: request } = this.options;
+		return `${
+			this.layer ? `(${this.layer})/` : ""
+		}webpack/sharing/consume/${shareScope}/${shareKey}${
+			request ? `/${request}` : ""
+		}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		callback(null, !this.buildInfo);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {};
+		if (this.options.import) {
+			const dep = new ConsumeSharedFallbackDependency(this.options.import);
+			if (this.options.eager) {
+				this.addDependency(dep);
+			} else {
+				const block = new AsyncDependenciesBlock({});
+				block.addDependency(dep);
+				this.addBlock(block);
+			}
+		}
+		callback();
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return CONSUME_SHARED_TYPES;
+	}
+
+	/**
+	 * Basic source types are high-level categories like javascript, css, webassembly, etc.
+	 * We only have built-in knowledge about the javascript basic type here; other basic types may be
+	 * added or changed over time by generators and do not need to be handled or detected here.
+	 *
+	 * Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
+	 * from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
+	 * @returns {BasicSourceTypes} types available (do not mutate)
+	 */
+	getSourceBasicTypes() {
+		return JAVASCRIPT_TYPES;
+	}
+
+	/**
+	 * Get fallback module.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @returns {Module | null} fallback module
+	 */
+	_getFallbackModule(moduleGraph) {
+		let moduleCache = fallbackModuleCache.get(moduleGraph);
+		if (!moduleCache) {
+			moduleCache = new WeakMap();
+			fallbackModuleCache.set(moduleGraph, moduleCache);
+		}
+		const cached = moduleCache.get(this);
+		if (cached !== undefined) {
+			return cached;
+		}
+
+		/** @type {undefined | null | Module} */
+		let fallbackModule = null;
+
+		if (this.options.import) {
+			if (this.options.eager) {
+				const dep = this.dependencies[0];
+				if (dep) {
+					fallbackModule = moduleGraph.getModule(dep);
+				}
+			} else {
+				const block = this.blocks[0];
+				if (block && block.dependencies.length > 0) {
+					fallbackModule = moduleGraph.getModule(block.dependencies[0]);
+				}
+			}
+		}
+
+		moduleCache.set(this, fallbackModule);
+		return fallbackModule;
+	}
+
+	/**
+	 * Returns export type.
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {boolean | undefined} strict the importing module is strict
+	 * @returns {ExportsType} export type
+	 * "namespace": Exports is already a namespace object. namespace = exports.
+	 * "dynamic": Check at runtime if __esModule is set. When set: namespace = { ...exports, default: exports }. When not set: namespace = { default: exports }.
+	 * "default-only": Provide a namespace object with only default export. namespace = { default: exports }
+	 * "default-with-named": Provide a namespace object with named and default export. namespace = { ...exports, default: exports }
+	 */
+	getExportsType(moduleGraph, strict) {
+		const fallbackModule = this._getFallbackModule(moduleGraph);
+		if (!fallbackModule) return "dynamic";
+		return fallbackModule.getExportsType(moduleGraph, strict);
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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;
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash the hash used to track dependencies
+	 * @param {UpdateHashContext} context context
+	 * @returns {void}
+	 */
+	updateHash(hash, context) {
+		hash.update(JSON.stringify(this.options));
+		super.updateHash(hash, context);
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({ chunkGraph, runtimeTemplate }) {
+		const runtimeRequirements = new Set([RuntimeGlobals.shareScopeMap]);
+		const {
+			shareScope,
+			shareKey,
+			strictVersion,
+			requiredVersion,
+			import: request,
+			singleton,
+			eager
+		} = this.options;
+		/** @type {undefined | string} */
+		let fallbackCode;
+		if (request) {
+			if (eager) {
+				const dep = this.dependencies[0];
+				fallbackCode = runtimeTemplate.syncModuleFactory({
+					dependency: dep,
+					chunkGraph,
+					runtimeRequirements,
+					request: this.options.import
+				});
+			} else {
+				const block = this.blocks[0];
+				fallbackCode = runtimeTemplate.asyncModuleFactory({
+					block,
+					chunkGraph,
+					runtimeRequirements,
+					request: this.options.import
+				});
+			}
+		}
+
+		const args = [
+			JSON.stringify(shareScope),
+			JSON.stringify(shareKey),
+			JSON.stringify(eager)
+		];
+		if (requiredVersion) {
+			args.push(stringifyHoley(requiredVersion));
+		}
+		if (fallbackCode) {
+			args.push(fallbackCode);
+		}
+
+		/** @type {string} */
+		let fn;
+
+		if (requiredVersion) {
+			if (strictVersion) {
+				fn = singleton ? "loadStrictSingletonVersion" : "loadStrictVersion";
+			} else {
+				fn = singleton ? "loadSingletonVersion" : "loadVersion";
+			}
+		} else {
+			fn = singleton ? "loadSingleton" : "load";
+		}
+
+		const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`);
+		/** @type {Sources} */
+		const sources = new Map();
+		sources.set("consume-shared", new RawSource(code));
+		return {
+			runtimeRequirements,
+			sources
+		};
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.options);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.options = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(
+	ConsumeSharedModule,
+	"webpack/lib/sharing/ConsumeSharedModule"
+);
+
+module.exports = ConsumeSharedModule;
Index: frontend/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,386 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const { parseOptions } = require("../container/options");
+const ModuleNotFoundError = require("../errors/ModuleNotFoundError");
+const WebpackError = require("../errors/WebpackError");
+const LazySet = require("../util/LazySet");
+const { parseRange } = require("../util/semver");
+const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependency");
+const ConsumeSharedModule = require("./ConsumeSharedModule");
+const ConsumeSharedRuntimeModule = require("./ConsumeSharedRuntimeModule");
+const ProvideForSharedDependency = require("./ProvideForSharedDependency");
+const { resolveMatchedConfigs } = require("./resolveMatchedConfigs");
+const {
+	getDescriptionFile,
+	getRequiredVersionFromDescriptionFile,
+	isRequiredVersion
+} = require("./utils");
+
+/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
+/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumeSharedPluginOptions} ConsumeSharedPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Compilation").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
+/** @typedef {import("../util/semver").SemVerRange} SemVerRange */
+/** @typedef {import("./ConsumeSharedModule").ConsumeOptions} ConsumeOptions */
+/** @typedef {import("./utils").DescriptionFile} DescriptionFile */
+
+/** @type {ResolveOptionsWithDependencyType} */
+const RESOLVE_OPTIONS = { dependencyType: "esm" };
+const PLUGIN_NAME = "ConsumeSharedPlugin";
+
+class ConsumeSharedPlugin {
+	/**
+	 * Creates an instance of ConsumeSharedPlugin.
+	 * @param {ConsumeSharedPluginOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		// TODO webpack 6 remove string support
+		if (typeof this.options !== "string") {
+			compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+				compiler.validate(
+					() =>
+						require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json"),
+					this.options,
+					{
+						name: "Consume Shared Plugin",
+						baseDataPath: "options"
+					},
+					(options) =>
+						require("../../schemas/plugins/sharing/ConsumeSharedPlugin.check")(
+							options
+						)
+				);
+			});
+		}
+
+		/** @type {[string, ConsumeOptions][]} */
+		const consumes = parseOptions(
+			this.options.consumes,
+			(item, key) => {
+				if (Array.isArray(item)) throw new Error("Unexpected array in options");
+				/** @type {ConsumeOptions} */
+				const result =
+					item === key || !isRequiredVersion(item)
+						? // item is a request/key
+							{
+								import: key,
+								shareScope: this.options.shareScope || "default",
+								shareKey: key,
+								requiredVersion: undefined,
+								packageName: undefined,
+								strictVersion: false,
+								singleton: false,
+								eager: false
+							}
+						: // key is a request/key
+							// item is a version
+							{
+								import: key,
+								shareScope: this.options.shareScope || "default",
+								shareKey: key,
+								requiredVersion: parseRange(item),
+								strictVersion: true,
+								packageName: undefined,
+								singleton: false,
+								eager: false
+							};
+				return result;
+			},
+			(item, key) => ({
+				import: item.import === false ? undefined : item.import || key,
+				shareScope: item.shareScope || this.options.shareScope || "default",
+				shareKey: item.shareKey || key,
+				requiredVersion:
+					typeof item.requiredVersion === "string"
+						? parseRange(item.requiredVersion)
+						: item.requiredVersion,
+				strictVersion:
+					typeof item.strictVersion === "boolean"
+						? item.strictVersion
+						: item.import !== false && !item.singleton,
+				packageName: item.packageName,
+				singleton: Boolean(item.singleton),
+				eager: Boolean(item.eager)
+			})
+		);
+
+		compiler.hooks.thisCompilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					ConsumeSharedFallbackDependency,
+					normalModuleFactory
+				);
+
+				/** @typedef {Map<string, ConsumeOptions>} Consumes */
+
+				/** @type {Consumes} */
+				let unresolvedConsumes;
+				/** @type {Consumes} */
+				let resolvedConsumes;
+				/** @type {Consumes} */
+				let prefixedConsumes;
+				const promise = resolveMatchedConfigs(compilation, consumes).then(
+					({ resolved, unresolved, prefixed }) => {
+						resolvedConsumes = resolved;
+						unresolvedConsumes = unresolved;
+						prefixedConsumes = prefixed;
+					}
+				);
+
+				const resolver = compilation.resolverFactory.get(
+					"normal",
+					RESOLVE_OPTIONS
+				);
+
+				/**
+				 * Creates a consume shared module.
+				 * @param {string} context issuer directory
+				 * @param {string} request request
+				 * @param {ConsumeOptions} config options
+				 * @returns {Promise<ConsumeSharedModule>} create module
+				 */
+				const createConsumeSharedModule = (context, request, config) => {
+					/**
+					 * Required version warning.
+					 * @param {string} details details
+					 */
+					const requiredVersionWarning = (details) => {
+						const error = new WebpackError(
+							`No required version specified and unable to automatically determine one. ${details}`
+						);
+						error.file = `shared module ${request}`;
+						compilation.warnings.push(error);
+					};
+					const directFallback =
+						config.import &&
+						/^(?:\.\.?(?:\/|$)|\/|[A-Z]:|\\\\)/i.test(config.import);
+					return Promise.all([
+						new Promise(
+							/**
+							 * Handles the callback logic for this hook.
+							 * @param {(value?: string) => void} resolve resolve
+							 */
+							(resolve) => {
+								if (!config.import) {
+									resolve();
+									return;
+								}
+								/** @type {ResolveContext & { fileDependencies: FileSystemDependencies, contextDependencies: FileSystemDependencies, missingDependencies: FileSystemDependencies }} */
+								const resolveContext = {
+									fileDependencies: new LazySet(),
+									contextDependencies: new LazySet(),
+									missingDependencies: new LazySet()
+								};
+								resolver.resolve(
+									{},
+									directFallback ? compiler.context : context,
+									config.import,
+									resolveContext,
+									(err, result) => {
+										compilation.contextDependencies.addAll(
+											resolveContext.contextDependencies
+										);
+										compilation.fileDependencies.addAll(
+											resolveContext.fileDependencies
+										);
+										compilation.missingDependencies.addAll(
+											resolveContext.missingDependencies
+										);
+										if (err) {
+											compilation.errors.push(
+												new ModuleNotFoundError(null, err, {
+													name: `resolving fallback for shared module ${request}`
+												})
+											);
+											return resolve();
+										}
+										resolve(/** @type {string} */ (result));
+									}
+								);
+							}
+						),
+						new Promise(
+							/**
+							 * Handles the name callback for this hook.
+							 * @param {(value?: SemVerRange) => void} resolve resolve
+							 */
+							(resolve) => {
+								if (config.requiredVersion !== undefined) {
+									resolve(/** @type {SemVerRange} */ (config.requiredVersion));
+									return;
+								}
+								let packageName = config.packageName;
+								if (packageName === undefined) {
+									if (/^(?:\/|[A-Z]:|\\\\)/i.test(request)) {
+										// For relative or absolute requests we don't automatically use a packageName.
+										// If wished one can specify one with the packageName option.
+										resolve();
+										return;
+									}
+									const match = /^(?:@[^\\/]+[\\/])?[^\\/]+/.exec(request);
+									if (!match) {
+										requiredVersionWarning(
+											"Unable to extract the package name from request."
+										);
+										resolve();
+										return;
+									}
+									packageName = match[0];
+								}
+
+								getDescriptionFile(
+									compilation.inputFileSystem,
+									context,
+									["package.json"],
+									(err, result, checkedDescriptionFilePaths) => {
+										if (err) {
+											requiredVersionWarning(
+												`Unable to read description file: ${err}`
+											);
+											return resolve();
+										}
+										const { data } =
+											/** @type {DescriptionFile} */
+											(result || {});
+										if (!data) {
+											if (checkedDescriptionFilePaths) {
+												requiredVersionWarning(
+													[
+														`Unable to find required version for "${packageName}" in description file/s`,
+														checkedDescriptionFilePaths.join("\n"),
+														"It need to be in dependencies, devDependencies or peerDependencies."
+													].join("\n")
+												);
+											} else {
+												requiredVersionWarning(
+													`Unable to find description file in ${context}.`
+												);
+											}
+
+											return resolve();
+										}
+										if (data.name === packageName) {
+											// Package self-referencing
+											return resolve();
+										}
+										const requiredVersion =
+											getRequiredVersionFromDescriptionFile(data, packageName);
+
+										if (requiredVersion) {
+											return resolve(parseRange(requiredVersion));
+										}
+
+										resolve();
+									},
+									(result) => {
+										if (!result) return false;
+										const maybeRequiredVersion =
+											getRequiredVersionFromDescriptionFile(
+												result.data,
+												packageName
+											);
+										return (
+											result.data.name === packageName ||
+											typeof maybeRequiredVersion === "string"
+										);
+									}
+								);
+							}
+						)
+					]).then(
+						([importResolved, requiredVersion]) =>
+							new ConsumeSharedModule(
+								directFallback ? compiler.context : context,
+								{
+									...config,
+									importResolved,
+									import: importResolved ? config.import : undefined,
+									requiredVersion
+								}
+							)
+					);
+				};
+
+				normalModuleFactory.hooks.factorize.tapPromise(
+					PLUGIN_NAME,
+					({ context, request, dependencies }) =>
+						// wait for resolving to be complete
+						promise.then(() => {
+							if (
+								dependencies[0] instanceof ConsumeSharedFallbackDependency ||
+								dependencies[0] instanceof ProvideForSharedDependency
+							) {
+								return;
+							}
+							const match = unresolvedConsumes.get(request);
+							if (match !== undefined) {
+								return createConsumeSharedModule(context, request, match);
+							}
+							for (const [prefix, options] of prefixedConsumes) {
+								if (request.startsWith(prefix)) {
+									const remainder = request.slice(prefix.length);
+									return createConsumeSharedModule(context, request, {
+										...options,
+										import: options.import
+											? options.import + remainder
+											: undefined,
+										shareKey: options.shareKey + remainder
+									});
+								}
+							}
+						})
+				);
+				normalModuleFactory.hooks.createModule.tapPromise(
+					PLUGIN_NAME,
+					({ resource }, { context, dependencies }) => {
+						if (
+							dependencies[0] instanceof ConsumeSharedFallbackDependency ||
+							dependencies[0] instanceof ProvideForSharedDependency
+						) {
+							return Promise.resolve();
+						}
+						const options = resolvedConsumes.get(resource);
+						if (options !== undefined) {
+							return createConsumeSharedModule(context, resource, options);
+						}
+						return Promise.resolve();
+					}
+				);
+				compilation.hooks.additionalTreeRuntimeRequirements.tap(
+					PLUGIN_NAME,
+					(chunk, set) => {
+						set.add(RuntimeGlobals.module);
+						set.add(RuntimeGlobals.moduleCache);
+						set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+						set.add(RuntimeGlobals.shareScopeMap);
+						set.add(RuntimeGlobals.initializeSharing);
+						set.add(RuntimeGlobals.hasOwnProperty);
+						compilation.addRuntimeModule(
+							chunk,
+							new ConsumeSharedRuntimeModule(set)
+						);
+					}
+				);
+			}
+		);
+	}
+}
+
+module.exports = ConsumeSharedPlugin;
Index: frontend/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,363 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const { compareModulesById } = require("../util/comparators");
+const {
+	parseVersionRuntimeCode,
+	rangeToStringRuntimeCode,
+	satisfyRuntimeCode,
+	versionLtRuntimeCode
+} = require("../util/semver");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+
+class ConsumeSharedRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("consumes", RuntimeModule.STAGE_ATTACH);
+		this._runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const codeGenerationResults =
+			/** @type {CodeGenerationResults} */
+			(compilation.codeGenerationResults);
+		const { runtimeTemplate } = compilation;
+		/** @type {Record<ChunkId, ModuleId[]>} */
+		const chunkToModuleMapping = {};
+		/** @type {Map<ModuleId, Source>} */
+		const moduleIdToSourceMapping = new Map();
+		/** @type {ModuleId[]} */
+		const initialConsumes = [];
+		/**
+		 * @param {Iterable<Module>} modules modules
+		 * @param {Chunk} chunk the chunk
+		 * @param {ModuleId[]} list list of ids
+		 */
+		const addModules = (modules, chunk, list) => {
+			for (const m of modules) {
+				const module = m;
+				const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+				list.push(id);
+				moduleIdToSourceMapping.set(
+					id,
+					codeGenerationResults.getSource(
+						module,
+						chunk.runtime,
+						"consume-shared"
+					)
+				);
+			}
+		};
+		const byId = compareModulesById(chunkGraph);
+		for (const chunk of /** @type {Chunk} */ (
+			this.chunk
+		).getAllReferencedChunks()) {
+			const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
+				chunk,
+				"consume-shared",
+				byId
+			);
+			if (!modules) continue;
+			addModules(
+				modules,
+				chunk,
+				(chunkToModuleMapping[/** @type {ChunkId} */ (chunk.id)] = [])
+			);
+		}
+		for (const chunk of /** @type {Chunk} */ (
+			this.chunk
+		).getAllInitialChunks()) {
+			const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
+				chunk,
+				"consume-shared",
+				byId
+			);
+			if (!modules) continue;
+			addModules(modules, chunk, initialConsumes);
+		}
+		if (moduleIdToSourceMapping.size === 0) return null;
+		return Template.asString([
+			parseVersionRuntimeCode(runtimeTemplate),
+			versionLtRuntimeCode(runtimeTemplate),
+			rangeToStringRuntimeCode(runtimeTemplate),
+			satisfyRuntimeCode(runtimeTemplate),
+			`var exists = ${runtimeTemplate.basicFunction("scope, key", [
+				`return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key);`
+			])}`,
+			`var get = ${runtimeTemplate.basicFunction("entry", [
+				"entry.loaded = 1;",
+				"return entry.get()"
+			])};`,
+			`var eagerOnly = ${runtimeTemplate.basicFunction("versions", [
+				`return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+					"filtered, version",
+					Template.indent([
+						"if (versions[version].eager) {",
+						Template.indent(["filtered[version] = versions[version];"]),
+						"}",
+						"return filtered;"
+					])
+				)}, {});`
+			])};`,
+			`var findLatestVersion = ${runtimeTemplate.basicFunction(
+				"scope, key, eager",
+				[
+					"var versions = eager ? eagerOnly(scope[key]) : scope[key];",
+					`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+						"a, b",
+						["return !a || versionLt(a, b) ? b : a;"]
+					)}, 0);`,
+					"return key && versions[key];"
+				]
+			)};`,
+			`var findSatisfyingVersion = ${runtimeTemplate.basicFunction(
+				"scope, key, requiredVersion, eager",
+				[
+					"var versions = eager ? eagerOnly(scope[key]) : scope[key];",
+					`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+						"a, b",
+						[
+							"if (!satisfy(requiredVersion, b)) return a;",
+							"return !a || versionLt(a, b) ? b : a;"
+						]
+					)}, 0);`,
+					"return key && versions[key]"
+				]
+			)};`,
+			`var findSingletonVersionKey = ${runtimeTemplate.basicFunction(
+				"scope, key, eager",
+				[
+					"var versions = eager ? eagerOnly(scope[key]) : scope[key];",
+					`return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+						"a, b",
+						["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"]
+					)}, 0);`
+				]
+			)};`,
+			`var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction(
+				"scope, key, version, requiredVersion",
+				[
+					'return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"'
+				]
+			)};`,
+			`var getInvalidVersionMessage = ${runtimeTemplate.basicFunction(
+				"scope, scopeName, key, requiredVersion, eager",
+				[
+					"var versions = scope[key];",
+					'return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\\n" +',
+					`\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction(
+						"key",
+						['return key + " from " + versions[key].from;']
+					)}).join(", ");`
+				]
+			)};`,
+			`var fail = ${runtimeTemplate.basicFunction("msg", [
+				"throw new Error(msg);"
+			])}`,
+			`var failAsNotExist = ${runtimeTemplate.basicFunction("scopeName, key", [
+				'return fail("Shared module " + key + " doesn\'t exist in shared scope " + scopeName);'
+			])}`,
+			`var warn = /*#__PURE__*/ ${
+				compilation.outputOptions.ignoreBrowserWarnings
+					? runtimeTemplate.basicFunction("", "")
+					: runtimeTemplate.basicFunction("msg", [
+							'if (typeof console !== "undefined" && console.warn) console.warn(msg);'
+						])
+			};`,
+			`var init = ${runtimeTemplate.returningFunction(
+				Template.asString([
+					"function(scopeName, key, eager, c, d) {",
+					Template.indent([
+						`var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`,
+						// if we require eager shared, we expect it to be already loaded before it requested, no need to wait the whole scope loaded.
+						"if (promise && promise.then && !eager) { ",
+						Template.indent([
+							`return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, false, c, d));`
+						]),
+						"}",
+						`return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, eager, c, d);`
+					]),
+					"}"
+				]),
+				"fn"
+			)};`,
+			"",
+			`var useFallback = ${runtimeTemplate.basicFunction(
+				"scopeName, key, fallback",
+				["return fallback ? fallback() : failAsNotExist(scopeName, key);"]
+			)}`,
+			`var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+				"scopeName, scope, key, eager, fallback",
+				[
+					"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+					"return get(findLatestVersion(scope, key, eager));"
+				]
+			)});`,
+			`var loadVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+				"scopeName, scope, key, eager, requiredVersion, fallback",
+				[
+					"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+					"var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
+					"if (satisfyingVersion) return get(satisfyingVersion);",
+					"warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))",
+					"return get(findLatestVersion(scope, key, eager));"
+				]
+			)});`,
+			`var loadStrictVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+				"scopeName, scope, key, eager, requiredVersion, fallback",
+				[
+					"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+					"var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
+					"if (satisfyingVersion) return get(satisfyingVersion);",
+					"if (fallback) return fallback();",
+					"fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));"
+				]
+			)});`,
+			`var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+				"scopeName, scope, key, eager, fallback",
+				[
+					"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+					"var version = findSingletonVersionKey(scope, key, eager);",
+					"return get(scope[key][version]);"
+				]
+			)});`,
+			`var loadSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+				"scopeName, scope, key, eager, requiredVersion, fallback",
+				[
+					"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+					"var version = findSingletonVersionKey(scope, key, eager);",
+					"if (!satisfy(requiredVersion, version)) {",
+					Template.indent([
+						"warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
+					]),
+					"}",
+					"return get(scope[key][version]);"
+				]
+			)});`,
+			`var loadStrictSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+				"scopeName, scope, key, eager, requiredVersion, fallback",
+				[
+					"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+					"var version = findSingletonVersionKey(scope, key, eager);",
+					"if (!satisfy(requiredVersion, version)) {",
+					Template.indent([
+						"fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
+					]),
+					"}",
+					"return get(scope[key][version]);"
+				]
+			)});`,
+			"var installedModules = {};",
+			"var moduleToHandlerMapping = {",
+			Template.indent(
+				Array.from(
+					moduleIdToSourceMapping,
+					([key, source]) => `${JSON.stringify(key)}: ${source.source()}`
+				).join(",\n")
+			),
+			"};",
+
+			initialConsumes.length > 0
+				? Template.asString([
+						`var initialConsumes = ${JSON.stringify(initialConsumes)};`,
+						`initialConsumes.forEach(${runtimeTemplate.basicFunction("id", [
+							`${
+								RuntimeGlobals.moduleFactories
+							}[id] = ${runtimeTemplate.basicFunction("module", [
+								"// Handle case when module is used sync",
+								"installedModules[id] = 0;",
+								`delete ${RuntimeGlobals.moduleCache}[id];`,
+								"var factory = moduleToHandlerMapping[id]();",
+								'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);',
+								"module.exports = factory();"
+							])}`
+						])});`
+					])
+				: "// no consumes in initial chunks",
+			this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
+				? Template.asString([
+						`var chunkMapping = ${JSON.stringify(
+							chunkToModuleMapping,
+							null,
+							"\t"
+						)};`,
+						"var startedInstallModules = {};",
+						`${
+							RuntimeGlobals.ensureChunkHandlers
+						}.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [
+							`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
+							Template.indent([
+								`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction(
+									"id",
+									[
+										`if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`,
+										"if(!startedInstallModules[id]) {",
+										`var onFactory = ${runtimeTemplate.basicFunction(
+											"factory",
+											[
+												"installedModules[id] = 0;",
+												`${
+													RuntimeGlobals.moduleFactories
+												}[id] = ${runtimeTemplate.basicFunction("module", [
+													`delete ${RuntimeGlobals.moduleCache}[id];`,
+													"module.exports = factory();"
+												])}`
+											]
+										)};`,
+										"startedInstallModules[id] = true;",
+										`var onError = ${runtimeTemplate.basicFunction("error", [
+											"delete installedModules[id];",
+											`${
+												RuntimeGlobals.moduleFactories
+											}[id] = ${runtimeTemplate.basicFunction("module", [
+												`delete ${RuntimeGlobals.moduleCache}[id];`,
+												"throw error;"
+											])}`
+										])};`,
+										"try {",
+										Template.indent([
+											"var promise = moduleToHandlerMapping[id]();",
+											"if(promise.then) {",
+											Template.indent(
+												"promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));"
+											),
+											"} else onFactory(promise);"
+										]),
+										"} catch(e) { onError(e); }",
+										"}"
+									]
+								)});`
+							]),
+							"}"
+						])}`
+					])
+				: "// no chunk loading of consumes"
+		]);
+	}
+}
+
+module.exports = ConsumeSharedRuntimeModule;
Index: frontend/node_modules/webpack/lib/sharing/ProvideForSharedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ProvideForSharedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ProvideForSharedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+class ProvideForSharedDependency extends ModuleDependency {
+	/**
+	 * Creates an instance of ProvideForSharedDependency.
+	 * @param {string} request request string
+	 */
+	constructor(request) {
+		super(request);
+	}
+
+	get type() {
+		return "provide module for shared";
+	}
+
+	get category() {
+		return "esm";
+	}
+}
+
+makeSerializable(
+	ProvideForSharedDependency,
+	"webpack/lib/sharing/ProvideForSharedDependency"
+);
+
+module.exports = ProvideForSharedDependency;
Index: frontend/node_modules/webpack/lib/sharing/ProvideSharedDependency.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ProvideSharedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ProvideSharedDependency.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,84 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ProvideSharedDependency extends Dependency {
+	/**
+	 * Creates an instance of ProvideSharedDependency.
+	 * @param {string} shareScope share scope
+	 * @param {string} name module name
+	 * @param {string | false} version version
+	 * @param {string} request request
+	 * @param {boolean} eager true, if this is an eager dependency
+	 */
+	constructor(shareScope, name, version, request, eager) {
+		super();
+		this.shareScope = shareScope;
+		this.name = name;
+		this.version = version;
+		this.request = request;
+		this.eager = eager;
+	}
+
+	get type() {
+		return "provide shared module";
+	}
+
+	/**
+	 * Returns an identifier to merge equal requests.
+	 * @returns {string | null} an identifier to merge equal requests
+	 */
+	getResourceIdentifier() {
+		return `provide module (${this.shareScope}) ${this.request} as ${
+			this.name
+		} @ ${this.version}${this.eager ? " (eager)" : ""}`;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		context.write(this.shareScope);
+		context.write(this.name);
+		context.write(this.request);
+		context.write(this.version);
+		context.write(this.eager);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {ProvideSharedDependency} deserialize fallback dependency
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		const obj = new ProvideSharedDependency(
+			read(),
+			read(),
+			read(),
+			read(),
+			read()
+		);
+		this.shareScope = context.read();
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	ProvideSharedDependency,
+	"webpack/lib/sharing/ProvideSharedDependency"
+);
+
+module.exports = ProvideSharedDependency;
Index: frontend/node_modules/webpack/lib/sharing/ProvideSharedModule.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ProvideSharedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ProvideSharedModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,207 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const Module = require("../Module");
+const { SHARED_INIT_TYPES } = require("../ModuleSourceTypeConstants");
+const { WEBPACK_MODULE_TYPE_PROVIDE } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const ProvideForSharedDependency = require("./ProvideForSharedDependency");
+
+/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").BuildCallback} BuildCallback */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").LibIdent} LibIdent */
+/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").Sources} Sources */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+class ProvideSharedModule extends Module {
+	/**
+	 * Creates an instance of ProvideSharedModule.
+	 * @param {string} shareScope shared scope name
+	 * @param {string} name shared key
+	 * @param {string | false} version version
+	 * @param {string} request request to the provided module
+	 * @param {boolean} eager include the module in sync way
+	 */
+	constructor(shareScope, name, version, request, eager) {
+		super(WEBPACK_MODULE_TYPE_PROVIDE);
+		this._shareScope = shareScope;
+		this._name = name;
+		this._version = version;
+		this._request = request;
+		this._eager = eager;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return `provide module (${this._shareScope}) ${this._name}@${this._version}|${this._request}`;
+	}
+
+	/**
+	 * Returns a human-readable identifier for this module.
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `provide shared module (${this._shareScope}) ${this._name}@${
+			this._version
+		} = ${requestShortener.shorten(this._request)}`;
+	}
+
+	/**
+	 * Gets the library identifier.
+	 * @param {LibIdentOptions} options options
+	 * @returns {LibIdent | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return `${this.layer ? `(${this.layer})/` : ""}webpack/sharing/provide/${
+			this._shareScope
+		}/${this._name}`;
+	}
+
+	/**
+	 * Checks whether the module needs to be rebuilt for the current build state.
+	 * @param {NeedBuildContext} context context info
+	 * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
+	 * @returns {void}
+	 */
+	needBuild(context, callback) {
+		callback(null, !this.buildInfo);
+	}
+
+	/**
+	 * Builds the module using the provided compilation context.
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {BuildCallback} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		this.buildMeta = {};
+		this.buildInfo = {
+			strict: true
+		};
+
+		this.clearDependenciesAndBlocks();
+		const dep = new ProvideForSharedDependency(this._request);
+		if (this._eager) {
+			this.addDependency(dep);
+		} else {
+			const block = new AsyncDependenciesBlock({});
+			block.addDependency(dep);
+			this.addBlock(block);
+		}
+
+		callback();
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @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;
+	}
+
+	/**
+	 * Returns the source types this module can generate.
+	 * @returns {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return SHARED_INIT_TYPES;
+	}
+
+	/**
+	 * Generates code and runtime requirements for this module.
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({ runtimeTemplate, chunkGraph }) {
+		const runtimeRequirements = new Set([RuntimeGlobals.initializeSharing]);
+		const code = `register(${JSON.stringify(this._name)}, ${JSON.stringify(
+			this._version || "0"
+		)}, ${
+			this._eager
+				? runtimeTemplate.syncModuleFactory({
+						dependency: this.dependencies[0],
+						chunkGraph,
+						request: this._request,
+						runtimeRequirements
+					})
+				: runtimeTemplate.asyncModuleFactory({
+						block: this.blocks[0],
+						chunkGraph,
+						request: this._request,
+						runtimeRequirements
+					})
+		}${this._eager ? ", 1" : ""});`;
+		/** @type {Sources} */
+		const sources = new Map();
+		/** @type {CodeGenerationResultData} */
+		const data = new Map();
+		data.set("share-init", [
+			{
+				shareScope: this._shareScope,
+				initStage: 10,
+				init: code
+			}
+		]);
+		return { sources, data, runtimeRequirements };
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this._shareScope);
+		write(this._name);
+		write(this._version);
+		write(this._request);
+		write(this._eager);
+		super.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {ProvideSharedModule} deserialize fallback dependency
+	 */
+	static deserialize(context) {
+		const { read } = context;
+		const obj = new ProvideSharedModule(read(), read(), read(), read(), read());
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+makeSerializable(
+	ProvideSharedModule,
+	"webpack/lib/sharing/ProvideSharedModule"
+);
+
+module.exports = ProvideSharedModule;
Index: frontend/node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const ModuleFactory = require("../ModuleFactory");
+const ProvideSharedModule = require("./ProvideSharedModule");
+
+/** @typedef {import("../ModuleFactory").ModuleFactoryCallback} ModuleFactoryCallback */
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./ProvideSharedDependency")} ProvideSharedDependency */
+
+class ProvideSharedModuleFactory extends ModuleFactory {
+	/**
+	 * Processes the provided data.
+	 * @param {ModuleFactoryCreateData} data data object
+	 * @param {ModuleFactoryCallback} callback callback
+	 * @returns {void}
+	 */
+	create(data, callback) {
+		const dep =
+			/** @type {ProvideSharedDependency} */
+			(data.dependencies[0]);
+		callback(null, {
+			module: new ProvideSharedModule(
+				dep.shareScope,
+				dep.name,
+				dep.version,
+				dep.request,
+				dep.eager
+			)
+		});
+	}
+}
+
+module.exports = ProvideSharedModuleFactory;
Index: frontend/node_modules/webpack/lib/sharing/ProvideSharedPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ProvideSharedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ProvideSharedPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,255 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const { parseOptions } = require("../container/options");
+const WebpackError = require("../errors/WebpackError");
+const ProvideForSharedDependency = require("./ProvideForSharedDependency");
+const ProvideSharedDependency = require("./ProvideSharedDependency");
+const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory");
+
+/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../NormalModuleFactory").NormalModuleCreateData} NormalModuleCreateData */
+
+/**
+ * Defines the provide options type used by this module.
+ * @typedef {object} ProvideOptions
+ * @property {string} shareKey
+ * @property {string} shareScope
+ * @property {string | undefined | false} version
+ * @property {boolean} eager
+ */
+
+/** @typedef {Map<string, { config: ProvideOptions, version: string | undefined | false }>} ResolvedProvideMap */
+
+const PLUGIN_NAME = "ProvideSharedPlugin";
+
+class ProvideSharedPlugin {
+	/**
+	 * Creates an instance of ProvideSharedPlugin.
+	 * @param {ProvideSharedPluginOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"),
+				this.options,
+				{
+					name: "Provide Shared Plugin",
+					baseDataPath: "options"
+				},
+				(options) =>
+					require("../../schemas/plugins/sharing/ProvideSharedPlugin.check")(
+						options
+					)
+			);
+		});
+
+		/** @type {[string, ProvideOptions][]} */
+		const provides = parseOptions(
+			this.options.provides,
+			(item) => {
+				if (Array.isArray(item)) {
+					throw new Error("Unexpected array of provides");
+				}
+				/** @type {ProvideOptions} */
+				const result = {
+					shareKey: item,
+					version: undefined,
+					shareScope: this.options.shareScope || "default",
+					eager: false
+				};
+				return result;
+			},
+			(item) => ({
+				shareKey: /** @type {string} */ (item.shareKey),
+				version: item.version,
+				shareScope: item.shareScope || this.options.shareScope || "default",
+				eager: Boolean(item.eager)
+			})
+		).sort(([a], [b]) => {
+			if (a < b) return -1;
+			if (b < a) return 1;
+			return 0;
+		});
+
+		/** @type {WeakMap<Compilation, ResolvedProvideMap>} */
+		const compilationData = new WeakMap();
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				/** @type {ResolvedProvideMap} */
+				const resolvedProvideMap = new Map();
+				/** @type {Map<string, ProvideOptions>} */
+				const matchProvides = new Map();
+				/** @type {Map<string, ProvideOptions>} */
+				const prefixMatchProvides = new Map();
+				for (const [request, config] of provides) {
+					if (/^(?:\/|[A-Z]:\\|\\\\|\.\.?(?:\/|$))/i.test(request)) {
+						// relative request
+						resolvedProvideMap.set(request, {
+							config,
+							version: config.version
+						});
+					} else if (/^(?:\/|[A-Z]:\\|\\\\)/i.test(request)) {
+						// absolute path
+						resolvedProvideMap.set(request, {
+							config,
+							version: config.version
+						});
+					} else if (request.endsWith("/")) {
+						// module request prefix
+						prefixMatchProvides.set(request, config);
+					} else {
+						// module request
+						matchProvides.set(request, config);
+					}
+				}
+				compilationData.set(compilation, resolvedProvideMap);
+				/**
+				 * Provide shared module.
+				 * @param {string} key key
+				 * @param {ProvideOptions} config config
+				 * @param {NormalModuleCreateData["resource"]} resource resource
+				 * @param {NormalModuleCreateData["resourceResolveData"]} resourceResolveData resource resolve data
+				 */
+				const provideSharedModule = (
+					key,
+					config,
+					resource,
+					resourceResolveData
+				) => {
+					let version = config.version;
+					if (version === undefined) {
+						let details = "";
+						if (!resourceResolveData) {
+							details = "No resolve data provided from resolver.";
+						} else {
+							const descriptionFileData =
+								resourceResolveData.descriptionFileData;
+							if (!descriptionFileData) {
+								details =
+									"No description file (usually package.json) found. Add description file with name and version, or manually specify version in shared config.";
+							} else if (!descriptionFileData.version) {
+								details = `No version in description file (usually package.json). Add version to description file ${resourceResolveData.descriptionFilePath}, or manually specify version in shared config.`;
+							} else {
+								version = /** @type {string | false | undefined} */ (
+									descriptionFileData.version
+								);
+							}
+						}
+						if (!version) {
+							const error = new WebpackError(
+								`No version specified and unable to automatically determine one. ${details}`
+							);
+							error.file = `shared module ${key} -> ${resource}`;
+							compilation.warnings.push(error);
+						}
+					}
+					resolvedProvideMap.set(resource, {
+						config,
+						version
+					});
+				};
+				normalModuleFactory.hooks.module.tap(
+					PLUGIN_NAME,
+					(module, { resource, resourceResolveData }, resolveData) => {
+						if (resolvedProvideMap.has(resource)) {
+							return module;
+						}
+						const { request } = resolveData;
+						{
+							const config = matchProvides.get(request);
+							if (config !== undefined) {
+								provideSharedModule(
+									request,
+									config,
+									resource,
+									resourceResolveData
+								);
+								resolveData.cacheable = false;
+							}
+						}
+						for (const [prefix, config] of prefixMatchProvides) {
+							if (request.startsWith(prefix)) {
+								const remainder = request.slice(prefix.length);
+								provideSharedModule(
+									resource,
+									{
+										...config,
+										shareKey: config.shareKey + remainder
+									},
+									resource,
+									resourceResolveData
+								);
+								resolveData.cacheable = false;
+							}
+						}
+						return module;
+					}
+				);
+			}
+		);
+		compiler.hooks.finishMake.tapPromise(PLUGIN_NAME, (compilation) => {
+			const resolvedProvideMap = compilationData.get(compilation);
+			if (!resolvedProvideMap) return Promise.resolve();
+			return Promise.all(
+				Array.from(
+					resolvedProvideMap,
+					([resource, { config, version }]) =>
+						new Promise((resolve, reject) => {
+							compilation.addInclude(
+								compiler.context,
+								new ProvideSharedDependency(
+									config.shareScope,
+									config.shareKey,
+									version || false,
+									resource,
+									config.eager
+								),
+								{
+									name: undefined
+								},
+								(err) => {
+									if (err) return reject(err);
+									resolve(null);
+								}
+							);
+						})
+				)
+			).then(() => {});
+		});
+
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					ProvideForSharedDependency,
+					normalModuleFactory
+				);
+
+				compilation.dependencyFactories.set(
+					ProvideSharedDependency,
+					new ProvideSharedModuleFactory()
+				);
+			}
+		);
+	}
+}
+
+module.exports = ProvideSharedPlugin;
Index: frontend/node_modules/webpack/lib/sharing/SharePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/SharePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/SharePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,92 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const { parseOptions } = require("../container/options");
+const ConsumeSharedPlugin = require("./ConsumeSharedPlugin");
+const ProvideSharedPlugin = require("./ProvideSharedPlugin");
+const { isRequiredVersion } = require("./utils");
+
+/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumesConfig} ConsumesConfig */
+/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvidesConfig} ProvidesConfig */
+/** @typedef {import("../../declarations/plugins/sharing/SharePlugin").SharePluginOptions} SharePluginOptions */
+/** @typedef {import("../../declarations/plugins/sharing/SharePlugin").SharedConfig} SharedConfig */
+/** @typedef {import("../Compiler")} Compiler */
+
+class SharePlugin {
+	/**
+	 * Creates an instance of SharePlugin.
+	 * @param {SharePluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {[string, SharedConfig][]} */
+		const sharedOptions = parseOptions(
+			options.shared,
+			(item, key) => {
+				if (typeof item !== "string") {
+					throw new Error("Unexpected array in shared");
+				}
+				/** @type {SharedConfig} */
+				const config =
+					item === key || !isRequiredVersion(item)
+						? {
+								import: item
+							}
+						: {
+								import: key,
+								requiredVersion: item
+							};
+				return config;
+			},
+			(item) => item
+		);
+		/** @type {Record<string, ConsumesConfig>[]} */
+		const consumes = sharedOptions.map(([key, options]) => ({
+			[key]: {
+				import: options.import,
+				shareKey: options.shareKey || key,
+				shareScope: options.shareScope,
+				requiredVersion: options.requiredVersion,
+				strictVersion: options.strictVersion,
+				singleton: options.singleton,
+				packageName: options.packageName,
+				eager: options.eager
+			}
+		}));
+		/** @type {Record<string, ProvidesConfig>[]} */
+		const provides = sharedOptions
+			.filter(([, options]) => options.import !== false)
+			.map(([key, options]) => ({
+				[options.import || key]: {
+					shareKey: options.shareKey || key,
+					shareScope: options.shareScope,
+					version: options.version,
+					eager: options.eager
+				}
+			}));
+		this._shareScope = options.shareScope;
+		this._consumes = consumes;
+		this._provides = provides;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		new ConsumeSharedPlugin({
+			shareScope: this._shareScope,
+			consumes: this._consumes
+		}).apply(compiler);
+		new ProvideSharedPlugin({
+			shareScope: this._shareScope,
+			provides: this._provides
+		}).apply(compiler);
+	}
+}
+
+module.exports = SharePlugin;
Index: frontend/node_modules/webpack/lib/sharing/ShareRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/ShareRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/ShareRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,153 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+	compareModulesByIdentifier,
+	compareStrings
+} = require("../util/comparators");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+
+class ShareRuntimeModule extends RuntimeModule {
+	constructor() {
+		super("sharing");
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const {
+			runtimeTemplate,
+			outputOptions: { uniqueName, ignoreBrowserWarnings }
+		} = compilation;
+		const codeGenerationResults =
+			/** @type {CodeGenerationResults} */
+			(compilation.codeGenerationResults);
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		/** @type {Map<string, Map<number, Set<string>>>} */
+		const initCodePerScope = new Map();
+		for (const chunk of /** @type {Chunk} */ (
+			this.chunk
+		).getAllReferencedChunks()) {
+			const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
+				chunk,
+				"share-init",
+				compareModulesByIdentifier
+			);
+			if (!modules) continue;
+			for (const m of modules) {
+				const data = codeGenerationResults.getData(
+					m,
+					chunk.runtime,
+					"share-init"
+				);
+				if (!data) continue;
+				for (const item of data) {
+					const { shareScope, initStage, init } = item;
+					let stages = initCodePerScope.get(shareScope);
+					if (stages === undefined) {
+						initCodePerScope.set(shareScope, (stages = new Map()));
+					}
+					let list = stages.get(initStage || 0);
+					if (list === undefined) {
+						stages.set(initStage || 0, (list = new Set()));
+					}
+					list.add(init);
+				}
+			}
+		}
+		return Template.asString([
+			`${RuntimeGlobals.shareScopeMap} = {};`,
+			"var initPromises = {};",
+			"var initTokens = {};",
+			`${RuntimeGlobals.initializeSharing} = ${runtimeTemplate.basicFunction(
+				"name, initScope",
+				[
+					"if(!initScope) initScope = [];",
+					"// handling circular init calls",
+					"var initToken = initTokens[name];",
+					"if(!initToken) initToken = initTokens[name] = {};",
+					"if(initScope.indexOf(initToken) >= 0) return;",
+					"initScope.push(initToken);",
+					"// only runs once",
+					"if(initPromises[name]) return initPromises[name];",
+					"// creates a new share scope if needed",
+					`if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`,
+					"// runs all init snippets from all modules reachable",
+					`var scope = ${RuntimeGlobals.shareScopeMap}[name];`,
+					`var warn = ${
+						ignoreBrowserWarnings
+							? runtimeTemplate.basicFunction("", "")
+							: runtimeTemplate.basicFunction("msg", [
+									'if (typeof console !== "undefined" && console.warn) console.warn(msg);'
+								])
+					};`,
+					`var uniqueName = ${JSON.stringify(uniqueName || undefined)};`,
+					`var register = ${runtimeTemplate.basicFunction(
+						"name, version, factory, eager",
+						[
+							"var versions = scope[name] = scope[name] || {};",
+							"var activeVersion = versions[version];",
+							"if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };"
+						]
+					)};`,
+					`var initExternal = ${runtimeTemplate.basicFunction("id", [
+						`var handleError = ${runtimeTemplate.expressionFunction(
+							'warn("Initialization of sharing external failed: " + err)',
+							"err"
+						)};`,
+						"try {",
+						Template.indent([
+							`var module = ${RuntimeGlobals.require}(id);`,
+							"if(!module) return;",
+							`var initFn = ${runtimeTemplate.returningFunction(
+								`module && module.init && module.init(${RuntimeGlobals.shareScopeMap}[name], initScope)`,
+								"module"
+							)}`,
+							"if(module.then) return promises.push(module.then(initFn, handleError));",
+							"var initResult = initFn(module);",
+							"if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));"
+						]),
+						"} catch(err) { handleError(err); }"
+					])}`,
+					"var promises = [];",
+					"switch(name) {",
+					...[...initCodePerScope]
+						.sort(([a], [b]) => compareStrings(a, b))
+						.map(([name, stages]) =>
+							Template.indent([
+								`case ${JSON.stringify(name)}: {`,
+								Template.indent(
+									[...stages]
+										.sort(([a], [b]) => a - b)
+										.map(([, initCode]) => Template.asString([...initCode]))
+								),
+								"}",
+								"break;"
+							])
+						),
+					"}",
+					"if(!promises.length) return initPromises[name] = 1;",
+					`return initPromises[name] = Promise.all(promises).then(${runtimeTemplate.returningFunction(
+						"initPromises[name] = 1"
+					)});`
+				]
+			)};`
+		]);
+	}
+}
+
+module.exports = ShareRuntimeModule;
Index: frontend/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,109 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleNotFoundError = require("../errors/ModuleNotFoundError");
+const LazySet = require("../util/LazySet");
+
+/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").FileSystemDependencies} FileSystemDependencies */
+/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
+
+/**
+ * Defines the matched configs item type used by this module.
+ * @template T
+ * @typedef {Map<string, T>} MatchedConfigsItem
+ */
+
+/**
+ * Defines the matched configs type used by this module.
+ * @template T
+ * @typedef {object} MatchedConfigs
+ * @property {MatchedConfigsItem<T>} resolved
+ * @property {MatchedConfigsItem<T>} unresolved
+ * @property {MatchedConfigsItem<T>} prefixed
+ */
+
+/** @type {ResolveOptionsWithDependencyType} */
+const RESOLVE_OPTIONS = { dependencyType: "esm" };
+
+/**
+ * Returns resolved matchers.
+ * @template T
+ * @param {Compilation} compilation the compilation
+ * @param {[string, T][]} configs to be processed configs
+ * @returns {Promise<MatchedConfigs<T>>} resolved matchers
+ */
+module.exports.resolveMatchedConfigs = (compilation, configs) => {
+	/** @type {MatchedConfigsItem<T>} */
+	const resolved = new Map();
+	/** @type {MatchedConfigsItem<T>} */
+	const unresolved = new Map();
+	/** @type {MatchedConfigsItem<T>} */
+	const prefixed = new Map();
+	/** @type {ResolveContext} */
+	const resolveContext = {
+		fileDependencies: new LazySet(),
+		contextDependencies: new LazySet(),
+		missingDependencies: new LazySet()
+	};
+	const resolver = compilation.resolverFactory.get("normal", RESOLVE_OPTIONS);
+	const context = compilation.compiler.context;
+
+	return Promise.all(
+		// eslint-disable-next-line array-callback-return
+		configs.map(([request, config]) => {
+			if (/^\.\.?(?:\/|$)/.test(request)) {
+				// relative request
+				return new Promise((resolve) => {
+					resolver.resolve(
+						{},
+						context,
+						request,
+						resolveContext,
+						(err, result) => {
+							if (err || result === false) {
+								err = err || new Error(`Can't resolve ${request}`);
+								compilation.errors.push(
+									new ModuleNotFoundError(null, err, {
+										name: `shared module ${request}`
+									})
+								);
+								return resolve(null);
+							}
+							resolved.set(/** @type {string} */ (result), config);
+							resolve(null);
+						}
+					);
+				});
+			} else if (/^(?:\/|[a-z]:\\|\\\\)/i.test(request)) {
+				// absolute path
+				resolved.set(request, config);
+			} else if (request.endsWith("/")) {
+				// module request prefix
+				prefixed.set(request, config);
+			} else {
+				// module request
+				unresolved.set(request, config);
+			}
+		})
+	).then(() => {
+		compilation.contextDependencies.addAll(
+			/** @type {FileSystemDependencies} */
+			(resolveContext.contextDependencies)
+		);
+		compilation.fileDependencies.addAll(
+			/** @type {FileSystemDependencies} */
+			(resolveContext.fileDependencies)
+		);
+		compilation.missingDependencies.addAll(
+			/** @type {FileSystemDependencies} */
+			(resolveContext.missingDependencies)
+		);
+		return { resolved, unresolved, prefixed };
+	});
+};
Index: frontend/node_modules/webpack/lib/sharing/utils.js
===================================================================
--- frontend/node_modules/webpack/lib/sharing/utils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/sharing/utils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,429 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { dirname, join, readJson } = require("../util/fs");
+
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../util/fs").JsonObject} JsonObject */
+/** @typedef {import("../util/fs").JsonPrimitive} JsonPrimitive */
+
+// Extreme shorthand only for github. eg: foo/bar
+const RE_URL_GITHUB_EXTREME_SHORT = /^[^/@:.\s][^/@:\s]*\/[^@:\s]*[^/@:\s]#\S+/;
+
+// Short url with specific protocol. eg: github:foo/bar
+const RE_GIT_URL_SHORT = /^(?:github|gitlab|bitbucket|gist):\/?[^/.]+\/?/i;
+
+// Currently supported protocols
+const RE_PROTOCOL =
+	/^(?:(?:git\+)?(?:ssh|https?|file)|git|github|gitlab|bitbucket|gist):$/i;
+
+// Has custom protocol
+const RE_CUSTOM_PROTOCOL = /^(?:(?:git\+)?(?:ssh|https?|file)|git):\/\//i;
+
+// Valid hash format for npm / yarn ...
+const RE_URL_HASH_VERSION = /#(?:semver:)?(.+)/;
+
+// Simple hostname validate
+const RE_HOSTNAME = /^(?:[^/.]+(?:\.[^/]+)+|localhost)$/;
+
+// For hostname with colon. eg: ssh://user@github.com:foo/bar
+const RE_HOSTNAME_WITH_COLON =
+	/([^/@#:.]+(?:\.[^/@#:.]+)+|localhost):([^#/0-9]+)/;
+
+// Reg for url without protocol
+const RE_NO_PROTOCOL = /^[^/@#:.]+(?:\.[^/@#:.]+)+/;
+
+// RegExp for version string
+const VERSION_PATTERN_REGEXP = /^(?:[\d^=v<>~]|[*xX]$)/;
+
+// Specific protocol for short url without normal hostname
+const PROTOCOLS_FOR_SHORT = [
+	"github:",
+	"gitlab:",
+	"bitbucket:",
+	"gist:",
+	"file:"
+];
+
+// Default protocol for git url
+const DEF_GIT_PROTOCOL = "git+ssh://";
+
+// thanks to https://github.com/npm/hosted-git-info/blob/latest/git-host-info.js
+const extractCommithashByDomain = {
+	/**
+	 * Returns hash.
+	 * @param {string} pathname pathname
+	 * @param {string} hash hash
+	 * @returns {string | undefined} hash
+	 */
+	"github.com": (pathname, hash) => {
+		let [, user, project, type, commithash] = pathname.split("/", 5);
+		if (type && type !== "tree") {
+			return;
+		}
+
+		commithash = !type ? hash : `#${commithash}`;
+
+		if (project && project.endsWith(".git")) {
+			project = project.slice(0, -4);
+		}
+
+		if (!user || !project) {
+			return;
+		}
+
+		return commithash;
+	},
+	/**
+	 * Returns hash.
+	 * @param {string} pathname pathname
+	 * @param {string} hash hash
+	 * @returns {string | undefined} hash
+	 */
+	"gitlab.com": (pathname, hash) => {
+		const path = pathname.slice(1);
+		if (path.includes("/-/") || path.includes("/archive.tar.gz")) {
+			return;
+		}
+
+		const segments = path.split("/");
+		let project = /** @type {string} */ (segments.pop());
+		if (project.endsWith(".git")) {
+			project = project.slice(0, -4);
+		}
+
+		const user = segments.join("/");
+		if (!user || !project) {
+			return;
+		}
+
+		return hash;
+	},
+	/**
+	 * Returns hash.
+	 * @param {string} pathname pathname
+	 * @param {string} hash hash
+	 * @returns {string | undefined} hash
+	 */
+	"bitbucket.org": (pathname, hash) => {
+		let [, user, project, aux] = pathname.split("/", 4);
+		if (["get"].includes(aux)) {
+			return;
+		}
+
+		if (project && project.endsWith(".git")) {
+			project = project.slice(0, -4);
+		}
+
+		if (!user || !project) {
+			return;
+		}
+
+		return hash;
+	},
+	/**
+	 * Returns hash.
+	 * @param {string} pathname pathname
+	 * @param {string} hash hash
+	 * @returns {string | undefined} hash
+	 */
+	"gist.github.com": (pathname, hash) => {
+		let [, user, project, aux] = pathname.split("/", 4);
+		if (aux === "raw") {
+			return;
+		}
+
+		if (!project) {
+			if (!user) {
+				return;
+			}
+
+			project = user;
+		}
+
+		if (project.endsWith(".git")) {
+			project = project.slice(0, -4);
+		}
+
+		return hash;
+	}
+};
+
+/**
+ * extract commit hash from parsed url
+ * @param {URL} urlParsed parsed url
+ * @returns {string} commithash
+ */
+function getCommithash(urlParsed) {
+	let { hostname, pathname, hash } = urlParsed;
+	hostname = hostname.replace(/^www\./, "");
+
+	try {
+		hash = decodeURIComponent(hash);
+		// eslint-disable-next-line no-empty
+	} catch (_err) {}
+
+	if (
+		extractCommithashByDomain[
+			/** @type {keyof extractCommithashByDomain} */ (hostname)
+		]
+	) {
+		return (
+			extractCommithashByDomain[
+				/** @type {keyof extractCommithashByDomain} */ (hostname)
+			](pathname, hash) || ""
+		);
+	}
+
+	return hash;
+}
+
+/**
+ * make url right for URL parse
+ * @param {string} gitUrl git url
+ * @returns {string} fixed url
+ */
+function correctUrl(gitUrl) {
+	// like:
+	// proto://hostname.com:user/repo -> proto://hostname.com/user/repo
+	return gitUrl.replace(RE_HOSTNAME_WITH_COLON, "$1/$2");
+}
+
+/**
+ * make url protocol right for URL parse
+ * @param {string} gitUrl git url
+ * @returns {string} fixed url
+ */
+function correctProtocol(gitUrl) {
+	// eg: github:foo/bar#v1.0. Should not add double slash, in case of error parsed `pathname`
+	if (RE_GIT_URL_SHORT.test(gitUrl)) {
+		return gitUrl;
+	}
+
+	// eg: user@github.com:foo/bar
+	if (!RE_CUSTOM_PROTOCOL.test(gitUrl)) {
+		return `${DEF_GIT_PROTOCOL}${gitUrl}`;
+	}
+
+	return gitUrl;
+}
+
+/**
+ * extract git dep version from hash
+ * @param {string} hash hash
+ * @returns {string} git dep version
+ */
+function getVersionFromHash(hash) {
+	const matched = hash.match(RE_URL_HASH_VERSION);
+
+	return (matched && matched[1]) || "";
+}
+
+/**
+ * if string can be decoded
+ * @param {string} str str to be checked
+ * @returns {boolean} if can be decoded
+ */
+function canBeDecoded(str) {
+	try {
+		decodeURIComponent(str);
+	} catch (_err) {
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * get right dep version from git url
+ * @param {string} gitUrl git url
+ * @returns {string} dep version
+ */
+function getGitUrlVersion(gitUrl) {
+	const oriGitUrl = gitUrl;
+	// github extreme shorthand
+	gitUrl = RE_URL_GITHUB_EXTREME_SHORT.test(gitUrl)
+		? `github:${gitUrl}`
+		: correctProtocol(gitUrl);
+
+	gitUrl = correctUrl(gitUrl);
+
+	/** @type {undefined | URL} */
+	let parsed;
+
+	try {
+		parsed = new URL(gitUrl);
+		// eslint-disable-next-line no-empty
+	} catch (_err) {}
+
+	if (!parsed) {
+		return "";
+	}
+
+	const { protocol, hostname, pathname, username, password } = parsed;
+	if (!RE_PROTOCOL.test(protocol)) {
+		return "";
+	}
+
+	// pathname shouldn't be empty or URL malformed
+	if (!pathname || !canBeDecoded(pathname)) {
+		return "";
+	}
+
+	// without protocol, there should have auth info
+	if (RE_NO_PROTOCOL.test(oriGitUrl) && !username && !password) {
+		return "";
+	}
+
+	if (!PROTOCOLS_FOR_SHORT.includes(protocol.toLowerCase())) {
+		if (!RE_HOSTNAME.test(hostname)) {
+			return "";
+		}
+
+		const commithash = getCommithash(parsed);
+		return getVersionFromHash(commithash) || commithash;
+	}
+
+	// for protocol short
+	return getVersionFromHash(gitUrl);
+}
+
+/** @typedef {{ data: JsonObject, path: string }} DescriptionFile */
+
+/**
+ * Gets description file.
+ * @param {InputFileSystem} fs file system
+ * @param {string} directory directory to start looking into
+ * @param {string[]} descriptionFiles possible description filenames
+ * @param {(err?: Error | null, descriptionFile?: DescriptionFile, paths?: string[]) => void} callback callback
+ * @param {(descriptionFile?: DescriptionFile) => boolean} satisfiesDescriptionFileData file data compliance check
+ * @param {Set<string>} checkedFilePaths set of file paths that have been checked
+ */
+const getDescriptionFile = (
+	fs,
+	directory,
+	descriptionFiles,
+	callback,
+	satisfiesDescriptionFileData,
+	checkedFilePaths = new Set()
+) => {
+	let i = 0;
+
+	const satisfiesDescriptionFileDataInternal = {
+		check: satisfiesDescriptionFileData,
+		checkedFilePaths
+	};
+
+	const tryLoadCurrent = () => {
+		if (i >= descriptionFiles.length) {
+			const parentDirectory = dirname(fs, directory);
+			if (!parentDirectory || parentDirectory === directory) {
+				return callback(null, undefined, [
+					...satisfiesDescriptionFileDataInternal.checkedFilePaths
+				]);
+			}
+			return getDescriptionFile(
+				fs,
+				parentDirectory,
+				descriptionFiles,
+				callback,
+				satisfiesDescriptionFileDataInternal.check,
+				satisfiesDescriptionFileDataInternal.checkedFilePaths
+			);
+		}
+		const filePath = join(fs, directory, descriptionFiles[i]);
+		readJson(fs, filePath, (err, data) => {
+			if (err) {
+				if ("code" in err && err.code === "ENOENT") {
+					i++;
+					return tryLoadCurrent();
+				}
+				return callback(err);
+			}
+			if (!data || typeof data !== "object" || Array.isArray(data)) {
+				return callback(
+					new Error(`Description file ${filePath} is not an object`)
+				);
+			}
+			if (
+				typeof satisfiesDescriptionFileDataInternal.check === "function" &&
+				!satisfiesDescriptionFileDataInternal.check({ data, path: filePath })
+			) {
+				i++;
+				satisfiesDescriptionFileDataInternal.checkedFilePaths.add(filePath);
+				return tryLoadCurrent();
+			}
+			callback(null, { data, path: filePath });
+		});
+	};
+	tryLoadCurrent();
+};
+
+module.exports.getDescriptionFile = getDescriptionFile;
+
+/**
+ * Gets required version from description file.
+ * @param {JsonObject} data description file data i.e.: package.json
+ * @param {string} packageName name of the dependency
+ * @returns {string | undefined} normalized version
+ */
+const getRequiredVersionFromDescriptionFile = (data, packageName) => {
+	const dependencyTypes = [
+		"optionalDependencies",
+		"dependencies",
+		"peerDependencies",
+		"devDependencies"
+	];
+
+	for (const dependencyType of dependencyTypes) {
+		const dependency = /** @type {JsonObject} */ (data[dependencyType]);
+		if (
+			dependency &&
+			typeof dependency === "object" &&
+			packageName in dependency
+		) {
+			return normalizeVersion(
+				/** @type {Exclude<JsonPrimitive, null | boolean | number>} */ (
+					dependency[packageName]
+				)
+			);
+		}
+	}
+};
+
+module.exports.getRequiredVersionFromDescriptionFile =
+	getRequiredVersionFromDescriptionFile;
+
+/**
+ * Checks whether this object is required version.
+ * @param {string} str maybe required version
+ * @returns {boolean} true, if it looks like a version
+ */
+function isRequiredVersion(str) {
+	return VERSION_PATTERN_REGEXP.test(str);
+}
+
+module.exports.isRequiredVersion = isRequiredVersion;
+
+/**
+ * Normalizes version.
+ * @see https://docs.npmjs.com/cli/v7/configuring-npm/package-json#urls-as-dependencies
+ * @param {string} versionDesc version to be normalized
+ * @returns {string} normalized version
+ */
+function normalizeVersion(versionDesc) {
+	versionDesc = (versionDesc && versionDesc.trim()) || "";
+
+	if (isRequiredVersion(versionDesc)) {
+		return versionDesc;
+	}
+
+	// add handle for URL Dependencies
+	return getGitUrlVersion(versionDesc.toLowerCase());
+}
+
+module.exports.normalizeVersion = normalizeVersion;
Index: frontend/node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,2846 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const { WEBPACK_MODULE_TYPE_RUNTIME } = require("../ModuleTypeConstants");
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const { LogType } = require("../logging/Logger");
+const AggressiveSplittingPlugin = require("../optimize/AggressiveSplittingPlugin");
+const SizeLimitsPlugin = require("../performance/SizeLimitsPlugin");
+const { countIterable } = require("../util/IterableHelpers");
+const {
+	compareChunksById,
+	compareIds,
+	compareLocations,
+	compareModulesByIdentifier,
+	compareNumbers,
+	compareSelect,
+	concatComparators
+} = require("../util/comparators");
+const formatLocation = require("../util/formatLocation");
+const { makePathsRelative, parseResource } = require("../util/identifier");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").StatsValue} StatsValue */
+/** @typedef {import("./StatsFactory")} StatsFactory */
+/** @typedef {import("./StatsFactory").StatsFactoryContext} StatsFactoryContext */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../Chunk").ChunkName} ChunkName */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../ChunkGroup").OriginRecord} OriginRecord */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").Asset} Asset */
+/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("../Compilation").ExcludeModulesType} ExcludeModulesType */
+/** @typedef {import("../Compilation").KnownNormalizedStatsOptions} KnownNormalizedStatsOptions */
+/** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").NameForCondition} NameForCondition */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../ModuleProfile")} ModuleProfile */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../serialization/AggregateErrorSerializer").AggregateError} AggregateError */
+/** @typedef {import("../serialization/ErrorObjectSerializer").ErrorWithCause} ErrorWithCause */
+/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {import("../util/comparators").Comparator<T>} Comparator<T>
+ */
+
+/**
+ * Defines the group config type used by this module.
+ * @template I, G
+ * @typedef {import("../util/smartGrouping").GroupConfig<I, G>} GroupConfig
+ */
+
+/** @typedef {KnownStatsCompilation & Record<string, EXPECTED_ANY>} StatsCompilation */
+/**
+ * Defines the known stats compilation type used by this module.
+ * @typedef {object} KnownStatsCompilation
+ * @property {EXPECTED_ANY=} env
+ * @property {string=} name
+ * @property {string=} hash
+ * @property {string=} version
+ * @property {number=} time
+ * @property {number=} builtAt
+ * @property {boolean=} needAdditionalPass
+ * @property {string=} publicPath
+ * @property {string=} outputPath
+ * @property {Record<string, string[]>=} assetsByChunkName
+ * @property {StatsAsset[]=} assets
+ * @property {number=} filteredAssets
+ * @property {StatsChunk[]=} chunks
+ * @property {StatsModule[]=} modules
+ * @property {number=} filteredModules
+ * @property {Record<string, StatsChunkGroup>=} entrypoints
+ * @property {Record<string, StatsChunkGroup>=} namedChunkGroups
+ * @property {StatsError[]=} errors
+ * @property {number=} errorsCount
+ * @property {StatsError[]=} warnings
+ * @property {number=} warningsCount
+ * @property {StatsCompilation[]=} children
+ * @property {Record<string, StatsLogging>=} logging
+ * @property {number=} filteredWarningDetailsCount
+ * @property {number=} filteredErrorDetailsCount
+ */
+
+/** @typedef {KnownStatsLogging & Record<string, EXPECTED_ANY>} StatsLogging */
+/**
+ * Defines the known stats logging type used by this module.
+ * @typedef {object} KnownStatsLogging
+ * @property {StatsLoggingEntry[]} entries
+ * @property {number} filteredEntries
+ * @property {boolean} debug
+ */
+
+/** @typedef {KnownStatsLoggingEntry & Record<string, EXPECTED_ANY>} StatsLoggingEntry */
+/**
+ * Defines the known stats logging entry type used by this module.
+ * @typedef {object} KnownStatsLoggingEntry
+ * @property {string} type
+ * @property {string=} message
+ * @property {string[]=} trace
+ * @property {StatsLoggingEntry[]=} children
+ * @property {EXPECTED_ANY[]=} args
+ * @property {number=} time
+ */
+
+/** @typedef {KnownStatsAsset & Record<string, EXPECTED_ANY>} StatsAsset */
+/** @typedef {string[]} ChunkIdHints */
+/**
+ * Defines the known stats asset type used by this module.
+ * @typedef {object} KnownStatsAsset
+ * @property {string} type
+ * @property {string} name
+ * @property {AssetInfo} info
+ * @property {number} size
+ * @property {boolean} emitted
+ * @property {boolean} comparedForEmit
+ * @property {boolean} cached
+ * @property {StatsAsset[]=} related
+ * @property {ChunkId[]=} chunks
+ * @property {ChunkName[]=} chunkNames
+ * @property {ChunkIdHints=} chunkIdHints
+ * @property {ChunkId[]=} auxiliaryChunks
+ * @property {ChunkName[]=} auxiliaryChunkNames
+ * @property {ChunkIdHints=} auxiliaryChunkIdHints
+ * @property {number=} filteredRelated
+ * @property {boolean=} isOverSizeLimit
+ */
+
+/** @typedef {KnownStatsChunkGroup & Record<string, EXPECTED_ANY>} StatsChunkGroup */
+/**
+ * Defines the known stats chunk group type used by this module.
+ * @typedef {object} KnownStatsChunkGroup
+ * @property {ChunkName=} name
+ * @property {ChunkId[]=} chunks
+ * @property {({ name: string, size?: number })[]=} assets
+ * @property {number=} filteredAssets
+ * @property {number=} assetsSize
+ * @property {({ name: string, size?: number })[]=} auxiliaryAssets
+ * @property {number=} filteredAuxiliaryAssets
+ * @property {number=} auxiliaryAssetsSize
+ * @property {Record<string, StatsChunkGroup[]>=} children
+ * @property {Record<string, string[]>=} childAssets
+ * @property {boolean=} isOverSizeLimit
+ */
+
+/** @typedef {Module[]} ModuleIssuerPath */
+/** @typedef {KnownStatsModule & Record<string, EXPECTED_ANY>} StatsModule */
+/**
+ * Defines the known stats module type used by this module.
+ * @typedef {object} KnownStatsModule
+ * @property {string=} type
+ * @property {string=} moduleType
+ * @property {(string | null)=} layer
+ * @property {string=} identifier
+ * @property {string=} name
+ * @property {NameForCondition | null=} nameForCondition
+ * @property {number=} index
+ * @property {number=} preOrderIndex
+ * @property {number=} index2
+ * @property {number=} postOrderIndex
+ * @property {number=} size
+ * @property {Record<string, number>=} sizes
+ * @property {boolean=} cacheable
+ * @property {boolean=} built
+ * @property {boolean=} codeGenerated
+ * @property {boolean=} buildTimeExecuted
+ * @property {boolean=} cached
+ * @property {boolean=} optional
+ * @property {boolean=} orphan
+ * @property {ModuleId=} id
+ * @property {ModuleId | null=} issuerId
+ * @property {ChunkId[]=} chunks
+ * @property {string[]=} assets
+ * @property {boolean=} dependent
+ * @property {(string | null)=} issuer
+ * @property {(string | null)=} issuerName
+ * @property {StatsModuleIssuer[] | null=} issuerPath
+ * @property {boolean=} failed
+ * @property {number=} errors
+ * @property {number=} warnings
+ * @property {StatsProfile=} profile
+ * @property {StatsModuleReason[]=} reasons
+ * @property {boolean | null | ExportInfoName[]=} usedExports
+ * @property {ExportInfoName[] | null=} providedExports
+ * @property {string[]=} optimizationBailout
+ * @property {(number | null)=} depth
+ * @property {StatsModule[]=} modules
+ * @property {number=} filteredModules
+ * @property {ReturnType<Source["source"]>=} source
+ */
+
+/** @typedef {KnownStatsProfile & Record<string, EXPECTED_ANY>} StatsProfile */
+/**
+ * Defines the known stats profile type used by this module.
+ * @typedef {object} KnownStatsProfile
+ * @property {number} total
+ * @property {number} resolving
+ * @property {number} restoring
+ * @property {number} building
+ * @property {number} integration
+ * @property {number} storing
+ * @property {number} additionalResolving
+ * @property {number} additionalIntegration
+ * @property {number} factory
+ * @property {number} dependencies
+ */
+
+/** @typedef {KnownStatsModuleIssuer & Record<string, EXPECTED_ANY>} StatsModuleIssuer */
+/**
+ * Defines the known stats module issuer type used by this module.
+ * @typedef {object} KnownStatsModuleIssuer
+ * @property {string} identifier
+ * @property {string} name
+ * @property {ModuleId=} id
+ * @property {StatsProfile} profile
+ */
+
+/** @typedef {KnownStatsModuleReason & Record<string, EXPECTED_ANY>} StatsModuleReason */
+/**
+ * Defines the known stats module reason type used by this module.
+ * @typedef {object} KnownStatsModuleReason
+ * @property {string | null} moduleIdentifier
+ * @property {string | null} module
+ * @property {string | null} moduleName
+ * @property {string | null} resolvedModuleIdentifier
+ * @property {string | null} resolvedModule
+ * @property {string | null} type
+ * @property {boolean} active
+ * @property {string | null} explanation
+ * @property {string | null} userRequest
+ * @property {(string | null)=} loc
+ * @property {ModuleId | null=} moduleId
+ * @property {ModuleId | null=} resolvedModuleId
+ */
+
+/** @typedef {KnownStatsChunk & Record<string, EXPECTED_ANY>} StatsChunk */
+/**
+ * Defines the known stats chunk type used by this module.
+ * @typedef {object} KnownStatsChunk
+ * @property {boolean} rendered
+ * @property {boolean} initial
+ * @property {boolean} entry
+ * @property {boolean} recorded
+ * @property {string=} reason
+ * @property {number} size
+ * @property {Record<string, number>} sizes
+ * @property {string[]} names
+ * @property {string[]} idHints
+ * @property {string[]=} runtime
+ * @property {string[]} files
+ * @property {string[]} auxiliaryFiles
+ * @property {string} hash
+ * @property {Record<string, ChunkId[]>} childrenByOrder
+ * @property {ChunkId=} id
+ * @property {ChunkId[]=} siblings
+ * @property {ChunkId[]=} parents
+ * @property {ChunkId[]=} children
+ * @property {StatsModule[]=} modules
+ * @property {number=} filteredModules
+ * @property {StatsChunkOrigin[]=} origins
+ */
+
+/** @typedef {KnownStatsChunkOrigin & Record<string, EXPECTED_ANY>} StatsChunkOrigin */
+/**
+ * Defines the known stats chunk origin type used by this module.
+ * @typedef {object} KnownStatsChunkOrigin
+ * @property {string} module
+ * @property {string} moduleIdentifier
+ * @property {string} moduleName
+ * @property {string} loc
+ * @property {string} request
+ * @property {ModuleId=} moduleId
+ */
+
+/** @typedef {KnownStatsModuleTraceItem & Record<string, EXPECTED_ANY>} StatsModuleTraceItem */
+/**
+ * Defines the known stats module trace item type used by this module.
+ * @typedef {object} KnownStatsModuleTraceItem
+ * @property {string=} originIdentifier
+ * @property {string=} originName
+ * @property {string=} moduleIdentifier
+ * @property {string=} moduleName
+ * @property {StatsModuleTraceDependency[]=} dependencies
+ * @property {ModuleId=} originId
+ * @property {ModuleId=} moduleId
+ */
+
+/** @typedef {KnownStatsModuleTraceDependency & Record<string, EXPECTED_ANY>} StatsModuleTraceDependency */
+/**
+ * Defines the known stats module trace dependency type used by this module.
+ * @typedef {object} KnownStatsModuleTraceDependency
+ * @property {string=} loc
+ */
+
+/** @typedef {KnownStatsError & Record<string, EXPECTED_ANY>} StatsError */
+/**
+ * Defines the known stats error type used by this module.
+ * @typedef {object} KnownStatsError
+ * @property {string} message
+ * @property {string=} chunkName
+ * @property {boolean=} chunkEntry
+ * @property {boolean=} chunkInitial
+ * @property {string=} file
+ * @property {string=} moduleIdentifier
+ * @property {string=} moduleName
+ * @property {string=} loc
+ * @property {ChunkId=} chunkId
+ * @property {ModuleId=} moduleId
+ * @property {StatsModuleTraceItem[]=} moduleTrace
+ * @property {string=} details
+ * @property {string=} stack
+ * @property {KnownStatsError=} cause
+ * @property {KnownStatsError[]=} errors
+ * @property {string=} compilerPath
+ */
+
+/** @typedef {Asset & { type: string, related: PreprocessedAsset[] | undefined }} PreprocessedAsset */
+
+/**
+ * Defines the extractors by option type used by this module.
+ * @template T
+ * @template O
+ * @typedef {Record<string, (object: O, data: T, context: StatsFactoryContext, options: NormalizedStatsOptions, factory: StatsFactory) => void>} ExtractorsByOption
+ */
+
+/** @typedef {{ name: string, chunkGroup: ChunkGroup }} ChunkGroupInfoWithName */
+/** @typedef {{ origin: Module, module: Module }} ModuleTrace */
+
+/**
+ * Defines the simple extractors type used by this module.
+ * @typedef {object} SimpleExtractors
+ * @property {ExtractorsByOption<Compilation, StatsCompilation>} compilation
+ * @property {ExtractorsByOption<PreprocessedAsset, StatsAsset>} asset
+ * @property {ExtractorsByOption<PreprocessedAsset, StatsAsset>} asset$visible
+ * @property {ExtractorsByOption<ChunkGroupInfoWithName, StatsChunkGroup>} chunkGroup
+ * @property {ExtractorsByOption<Module, StatsModule>} module
+ * @property {ExtractorsByOption<Module, StatsModule>} module$visible
+ * @property {ExtractorsByOption<Module, StatsModuleIssuer>} moduleIssuer
+ * @property {ExtractorsByOption<ModuleProfile, StatsProfile>} profile
+ * @property {ExtractorsByOption<ModuleGraphConnection, StatsModuleReason>} moduleReason
+ * @property {ExtractorsByOption<Chunk, StatsChunk>} chunk
+ * @property {ExtractorsByOption<OriginRecord, StatsChunkOrigin>} chunkOrigin
+ * @property {ExtractorsByOption<WebpackError, StatsError>} error
+ * @property {ExtractorsByOption<WebpackError, StatsError>} warning
+ * @property {ExtractorsByOption<WebpackError, StatsError>} cause
+ * @property {ExtractorsByOption<ModuleTrace, StatsModuleTraceItem>} moduleTraceItem
+ * @property {ExtractorsByOption<Dependency, StatsModuleTraceDependency>} moduleTraceDependency
+ */
+
+/**
+ * Returns array of values.
+ * @template T
+ * @template I
+ * @param {Iterable<T>} items items to select from
+ * @param {(item: T) => Iterable<I>} selector selector function to select values from item
+ * @returns {I[]} array of values
+ */
+const uniqueArray = (items, selector) => {
+	/** @type {Set<I>} */
+	const set = new Set();
+	for (const item of items) {
+		for (const i of selector(item)) {
+			set.add(i);
+		}
+	}
+	return [...set];
+};
+
+/**
+ * Unique ordered array.
+ * @template T
+ * @template I
+ * @param {Iterable<T>} items items to select from
+ * @param {(item: T) => Iterable<I>} selector selector function to select values from item
+ * @param {Comparator<I>} comparator comparator function
+ * @returns {I[]} array of values
+ */
+const uniqueOrderedArray = (items, selector, comparator) =>
+	uniqueArray(items, selector).sort(comparator);
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @template R
+ * @typedef {{ [P in keyof T]: R }} MappedValues<T, R>
+ */
+
+/**
+ * Returns mapped object.
+ * @template {object} T
+ * @template {object} R
+ * @param {T} obj object to be mapped
+ * @param {(value: T[keyof T], key: keyof T) => R} fn mapping function
+ * @returns {MappedValues<T, R>} mapped object
+ */
+const mapObject = (obj, fn) => {
+	/** @type {MappedValues<T, R>} */
+	const newObj = Object.create(null);
+	for (const key of /** @type {(keyof T)[]} */ (Object.keys(obj))) {
+		newObj[key] = fn(obj[key], key);
+	}
+	return newObj;
+};
+
+/**
+ * Count with children.
+ * @template T
+ * @param {Compilation} compilation the compilation
+ * @param {(compilation: Compilation, name: string) => T[]} getItems get items
+ * @returns {number} total number
+ */
+const countWithChildren = (compilation, getItems) => {
+	let count = getItems(compilation, "").length;
+	for (const child of compilation.children) {
+		count += countWithChildren(child, (c, type) =>
+			getItems(c, `.children[].compilation${type}`)
+		);
+	}
+	return count;
+};
+
+/** @type {ExtractorsByOption<string | ErrorWithCause | AggregateError | WebpackError, StatsError>} */
+const EXTRACT_ERROR = {
+	_: (object, error, context, { requestShortener }) => {
+		// TODO webpack 6 disallow strings in the errors/warnings list
+		if (typeof error === "string") {
+			object.message = error;
+		} else {
+			if (/** @type {WebpackError} */ (error).chunk) {
+				const chunk = /** @type {WebpackError} */ (error).chunk;
+				object.chunkName =
+					/** @type {string | undefined} */
+					(chunk.name);
+				object.chunkEntry = chunk.hasRuntime();
+				object.chunkInitial = chunk.canBeInitial();
+			}
+
+			if (/** @type {WebpackError} */ (error).file) {
+				object.file = /** @type {WebpackError} */ (error).file;
+			}
+
+			if (/** @type {WebpackError} */ (error).module) {
+				object.moduleIdentifier =
+					/** @type {WebpackError} */
+					(error).module.identifier();
+				object.moduleName =
+					/** @type {WebpackError} */
+					(error).module.readableIdentifier(requestShortener);
+			}
+
+			if (/** @type {WebpackError} */ (error).loc) {
+				object.loc = formatLocation(/** @type {WebpackError} */ (error).loc);
+			}
+
+			object.message = error.message;
+		}
+	},
+	ids: (object, error, { compilation: { chunkGraph } }) => {
+		if (typeof error !== "string") {
+			if (/** @type {WebpackError} */ (error).chunk) {
+				object.chunkId = /** @type {ChunkId} */ (
+					/** @type {WebpackError} */
+					(error).chunk.id
+				);
+			}
+
+			if (/** @type {WebpackError} */ (error).module) {
+				object.moduleId =
+					/** @type {ModuleId} */
+					(chunkGraph.getModuleId(/** @type {WebpackError} */ (error).module));
+			}
+		}
+	},
+	moduleTrace: (object, error, context, options, factory) => {
+		if (
+			typeof error !== "string" &&
+			/** @type {WebpackError} */ (error).module
+		) {
+			const {
+				type,
+				compilation: { moduleGraph }
+			} = context;
+			/** @type {Set<Module>} */
+			const visitedModules = new Set();
+			/** @type {ModuleTrace[]} */
+			const moduleTrace = [];
+			let current = /** @type {WebpackError} */ (error).module;
+			while (current) {
+				if (visitedModules.has(current)) break; // circular (technically impossible, but how knows)
+				visitedModules.add(current);
+				const origin = moduleGraph.getIssuer(current);
+				if (!origin) break;
+				moduleTrace.push({ origin, module: current });
+				current = origin;
+			}
+			object.moduleTrace = factory.create(
+				`${type}.moduleTrace`,
+				moduleTrace,
+				context
+			);
+		}
+	},
+	errorDetails: (
+		object,
+		error,
+		{ type, compilation, cachedGetErrors },
+		{ errorDetails }
+	) => {
+		if (
+			typeof error !== "string" &&
+			(errorDetails === true ||
+				(type.endsWith(".error") && cachedGetErrors(compilation).length < 3))
+		) {
+			object.details = /** @type {WebpackError} */ (error).details;
+		}
+	},
+	errorStack: (object, error, _context, { errorStack }) => {
+		if (typeof error !== "string" && errorStack) {
+			object.stack = error.stack;
+		}
+	},
+	errorCause: (object, error, context, options, factory) => {
+		if (
+			typeof error !== "string" &&
+			/** @type {ErrorWithCause} */ (error).cause
+		) {
+			const rawCause = /** @type {ErrorWithCause} */ (error).cause;
+			/** @type {Error} */
+			const cause =
+				typeof rawCause === "string"
+					? /** @type {Error} */ ({ message: rawCause })
+					: /** @type {Error} */ (rawCause);
+			const { type } = context;
+
+			object.cause = factory.create(`${type}.cause`, cause, context);
+		}
+	},
+	errorErrors: (object, error, context, options, factory) => {
+		if (
+			typeof error !== "string" &&
+			/** @type {AggregateError} */
+			(error).errors
+		) {
+			const { type } = context;
+			object.errors = factory.create(
+				`${type}.errors`,
+				/** @type {Error[]} */
+				(/** @type {AggregateError} */ (error).errors),
+				context
+			);
+		}
+	}
+};
+
+/** @typedef {((value: string) => boolean)} FilterItemTypeFn */
+
+/** @type {SimpleExtractors} */
+const SIMPLE_EXTRACTORS = {
+	compilation: {
+		_: (object, compilation, context, options) => {
+			if (!context.makePathsRelative) {
+				context.makePathsRelative = makePathsRelative.bindContextCache(
+					compilation.compiler.context,
+					compilation.compiler.root
+				);
+			}
+			if (!context.cachedGetErrors) {
+				/** @type {WeakMap<Compilation, Error[]>} */
+				const map = new WeakMap();
+				context.cachedGetErrors = (compilation) =>
+					map.get(compilation) ||
+					// eslint-disable-next-line no-sequences
+					((errors) => (map.set(compilation, errors), errors))(
+						compilation.getErrors()
+					);
+			}
+			if (!context.cachedGetWarnings) {
+				/** @type {WeakMap<Compilation, Error[]>} */
+				const map = new WeakMap();
+				context.cachedGetWarnings = (compilation) =>
+					map.get(compilation) ||
+					// eslint-disable-next-line no-sequences
+					((warnings) => (map.set(compilation, warnings), warnings))(
+						compilation.getWarnings()
+					);
+			}
+			if (compilation.name) {
+				object.name = compilation.name;
+			}
+			if (compilation.needAdditionalPass) {
+				object.needAdditionalPass = true;
+			}
+
+			const { logging, loggingDebug, loggingTrace } = options;
+			if (logging || (loggingDebug && loggingDebug.length > 0)) {
+				const util = require("util");
+
+				object.logging = {};
+				/** @type {Set<keyof LogType>} */
+				let acceptedTypes;
+				let collapsedGroups = false;
+				switch (logging) {
+					case "error":
+						acceptedTypes = new Set([LogType.error]);
+						break;
+					case "warn":
+						acceptedTypes = new Set([LogType.error, LogType.warn]);
+						break;
+					case "info":
+						acceptedTypes = new Set([
+							LogType.error,
+							LogType.warn,
+							LogType.info
+						]);
+						break;
+					case "log":
+						acceptedTypes = new Set([
+							LogType.error,
+							LogType.warn,
+							LogType.info,
+							LogType.log,
+							LogType.group,
+							LogType.groupEnd,
+							LogType.groupCollapsed,
+							LogType.clear
+						]);
+						break;
+					case "verbose":
+						acceptedTypes = new Set([
+							LogType.error,
+							LogType.warn,
+							LogType.info,
+							LogType.log,
+							LogType.group,
+							LogType.groupEnd,
+							LogType.groupCollapsed,
+							LogType.profile,
+							LogType.profileEnd,
+							LogType.time,
+							LogType.status,
+							LogType.clear
+						]);
+						collapsedGroups = true;
+						break;
+					default:
+						acceptedTypes = new Set();
+						break;
+				}
+				const cachedMakePathsRelative = makePathsRelative.bindContextCache(
+					options.context,
+					compilation.compiler.root
+				);
+				let depthInCollapsedGroup = 0;
+				for (const [origin, logEntries] of compilation.logging) {
+					const debugMode = loggingDebug.some((fn) => fn(origin));
+					if (logging === false && !debugMode) continue;
+					/** @type {KnownStatsLoggingEntry[]} */
+					const groupStack = [];
+					/** @type {KnownStatsLoggingEntry[]} */
+					const rootList = [];
+					let currentList = rootList;
+					let processedLogEntries = 0;
+					for (const entry of logEntries) {
+						let type = entry.type;
+						if (!debugMode && !acceptedTypes.has(type)) continue;
+
+						// Expand groups in verbose and debug modes
+						if (
+							type === LogType.groupCollapsed &&
+							(debugMode || collapsedGroups)
+						) {
+							type = LogType.group;
+						}
+
+						if (depthInCollapsedGroup === 0) {
+							processedLogEntries++;
+						}
+
+						if (type === LogType.groupEnd) {
+							groupStack.pop();
+							currentList =
+								groupStack.length > 0
+									? /** @type {KnownStatsLoggingEntry[]} */ (
+											groupStack[groupStack.length - 1].children
+										)
+									: rootList;
+							if (depthInCollapsedGroup > 0) depthInCollapsedGroup--;
+							continue;
+						}
+						/** @type {undefined | string} */
+						let message;
+						if (entry.type === LogType.time) {
+							const [label, first, second] =
+								/** @type {[string, number, number]} */
+								(entry.args);
+							message = `${label}: ${first * 1000 + second / 1000000} ms`;
+						} else if (entry.args && entry.args.length > 0) {
+							message = util.format(entry.args[0], ...entry.args.slice(1));
+						}
+						/** @type {KnownStatsLoggingEntry} */
+						const newEntry = {
+							...entry,
+							type,
+							message,
+							trace: loggingTrace ? entry.trace : undefined,
+							children:
+								type === LogType.group || type === LogType.groupCollapsed
+									? []
+									: undefined
+						};
+						currentList.push(newEntry);
+						if (newEntry.children) {
+							groupStack.push(newEntry);
+							currentList = newEntry.children;
+							if (depthInCollapsedGroup > 0) {
+								depthInCollapsedGroup++;
+							} else if (type === LogType.groupCollapsed) {
+								depthInCollapsedGroup = 1;
+							}
+						}
+					}
+					let name = cachedMakePathsRelative(origin).replace(/\|/g, " ");
+					if (name in object.logging) {
+						let i = 1;
+						while (`${name}#${i}` in object.logging) {
+							i++;
+						}
+						name = `${name}#${i}`;
+					}
+					object.logging[name] = {
+						entries: rootList,
+						filteredEntries: logEntries.length - processedLogEntries,
+						debug: debugMode
+					};
+				}
+			}
+		},
+		hash: (object, compilation) => {
+			object.hash = compilation.hash;
+		},
+		version: (object) => {
+			object.version = require("../../package.json").version;
+		},
+		env: (object, compilation, context, { _env }) => {
+			object.env = _env;
+		},
+		timings: (object, compilation) => {
+			object.time =
+				/** @type {number} */ (compilation.endTime) -
+				/** @type {number} */ (compilation.startTime);
+		},
+		builtAt: (object, compilation) => {
+			object.builtAt = /** @type {number} */ (compilation.endTime);
+		},
+		publicPath: (object, compilation) => {
+			object.publicPath = compilation.getPath(
+				compilation.outputOptions.publicPath
+			);
+		},
+		outputPath: (object, compilation) => {
+			object.outputPath = compilation.outputOptions.path;
+		},
+		assets: (object, compilation, context, options, factory) => {
+			const { type } = context;
+			/** @type {Map<string, Chunk[]>} */
+			const compilationFileToChunks = new Map();
+			/** @type {Map<string, Chunk[]>} */
+			const compilationAuxiliaryFileToChunks = new Map();
+			for (const chunk of compilation.chunks) {
+				for (const file of chunk.files) {
+					let array = compilationFileToChunks.get(file);
+					if (array === undefined) {
+						array = [];
+						compilationFileToChunks.set(file, array);
+					}
+					array.push(chunk);
+				}
+				for (const file of chunk.auxiliaryFiles) {
+					let array = compilationAuxiliaryFileToChunks.get(file);
+					if (array === undefined) {
+						array = [];
+						compilationAuxiliaryFileToChunks.set(file, array);
+					}
+					array.push(chunk);
+				}
+			}
+			/** @type {Map<string, PreprocessedAsset>} */
+			const assetMap = new Map();
+			/** @type {Set<PreprocessedAsset>} */
+			const assets = new Set();
+			for (const asset of compilation.getAssets()) {
+				/** @type {PreprocessedAsset} */
+				const item = {
+					...asset,
+					type: "asset",
+					related: undefined
+				};
+				assets.add(item);
+				assetMap.set(asset.name, item);
+			}
+			for (const item of assetMap.values()) {
+				const related = item.info.related;
+				if (!related) continue;
+				for (const type of Object.keys(related)) {
+					const relatedEntry = related[type];
+					const deps = Array.isArray(relatedEntry)
+						? relatedEntry
+						: [relatedEntry];
+					for (const dep of deps) {
+						if (!dep) continue;
+						const depItem = assetMap.get(dep);
+						if (!depItem) continue;
+						assets.delete(depItem);
+						depItem.type = type;
+						item.related = item.related || [];
+						item.related.push(depItem);
+					}
+				}
+			}
+
+			object.assetsByChunkName = {};
+			for (const [file, chunks] of [
+				...compilationFileToChunks,
+				...compilationAuxiliaryFileToChunks
+			]) {
+				for (const chunk of chunks) {
+					const name = chunk.name;
+					if (!name) continue;
+					if (
+						!Object.prototype.hasOwnProperty.call(
+							object.assetsByChunkName,
+							name
+						)
+					) {
+						object.assetsByChunkName[name] = [];
+					}
+					object.assetsByChunkName[name].push(file);
+				}
+			}
+
+			const groupedAssets = factory.create(`${type}.assets`, [...assets], {
+				...context,
+				compilationFileToChunks,
+				compilationAuxiliaryFileToChunks
+			});
+			const limited = spaceLimited(
+				groupedAssets,
+				/** @type {number} */ (options.assetsSpace)
+			);
+			object.assets = limited.children;
+			object.filteredAssets = limited.filteredChildren;
+		},
+		chunks: (object, compilation, context, options, factory) => {
+			const { type } = context;
+			object.chunks = factory.create(
+				`${type}.chunks`,
+				[...compilation.chunks],
+				context
+			);
+		},
+		modules: (object, compilation, context, options, factory) => {
+			const { type } = context;
+			const array = [...compilation.modules];
+			const groupedModules = factory.create(`${type}.modules`, array, context);
+			const limited = spaceLimited(groupedModules, options.modulesSpace);
+			object.modules = limited.children;
+			object.filteredModules = limited.filteredChildren;
+		},
+		entrypoints: (
+			object,
+			compilation,
+			context,
+			{ entrypoints, chunkGroups, chunkGroupAuxiliary, chunkGroupChildren },
+			factory
+		) => {
+			const { type } = context;
+			/** @type {ChunkGroupInfoWithName[]} */
+			const array = Array.from(compilation.entrypoints, ([key, value]) => ({
+				name: key,
+				chunkGroup: value
+			}));
+			if (entrypoints === "auto" && !chunkGroups) {
+				if (array.length > 5) return;
+				if (
+					!chunkGroupChildren &&
+					array.every(({ chunkGroup }) => {
+						if (chunkGroup.chunks.length !== 1) return false;
+						const chunk = chunkGroup.chunks[0];
+						return (
+							chunk.files.size === 1 &&
+							(!chunkGroupAuxiliary || chunk.auxiliaryFiles.size === 0)
+						);
+					})
+				) {
+					return;
+				}
+			}
+			object.entrypoints = factory.create(
+				`${type}.entrypoints`,
+				array,
+				context
+			);
+		},
+		chunkGroups: (object, compilation, context, options, factory) => {
+			const { type } = context;
+			const array = Array.from(
+				compilation.namedChunkGroups,
+				([key, value]) => ({
+					name: key,
+					chunkGroup: value
+				})
+			);
+			object.namedChunkGroups = factory.create(
+				`${type}.namedChunkGroups`,
+				array,
+				context
+			);
+		},
+		errors: (object, compilation, context, options, factory) => {
+			const { type, cachedGetErrors } = context;
+			const rawErrors = cachedGetErrors(compilation);
+			const factorizedErrors = factory.create(
+				`${type}.errors`,
+				cachedGetErrors(compilation),
+				context
+			);
+			let filtered = 0;
+			if (options.errorDetails === "auto" && rawErrors.length >= 3) {
+				filtered = rawErrors
+					.map(
+						(e) =>
+							typeof e !== "string" && /** @type {WebpackError} */ (e).details
+					)
+					.filter(Boolean).length;
+			}
+			if (
+				options.errorDetails === true ||
+				!Number.isFinite(options.errorsSpace)
+			) {
+				object.errors = factorizedErrors;
+				if (filtered) object.filteredErrorDetailsCount = filtered;
+				return;
+			}
+			const [errors, filteredBySpace] = errorsSpaceLimit(
+				factorizedErrors,
+				/** @type {number} */
+				(options.errorsSpace)
+			);
+			object.filteredErrorDetailsCount = filtered + filteredBySpace;
+			object.errors = errors;
+		},
+		errorsCount: (object, compilation, { cachedGetErrors }) => {
+			object.errorsCount = countWithChildren(compilation, (c) =>
+				cachedGetErrors(c)
+			);
+		},
+		warnings: (object, compilation, context, options, factory) => {
+			const { type, cachedGetWarnings } = context;
+			const rawWarnings = factory.create(
+				`${type}.warnings`,
+				cachedGetWarnings(compilation),
+				context
+			);
+			let filtered = 0;
+			if (options.errorDetails === "auto") {
+				filtered = cachedGetWarnings(compilation)
+					.map(
+						(e) =>
+							typeof e !== "string" && /** @type {WebpackError} */ (e).details
+					)
+					.filter(Boolean).length;
+			}
+			if (
+				options.errorDetails === true ||
+				!Number.isFinite(options.warningsSpace)
+			) {
+				object.warnings = rawWarnings;
+				if (filtered) object.filteredWarningDetailsCount = filtered;
+				return;
+			}
+			const [warnings, filteredBySpace] = errorsSpaceLimit(
+				rawWarnings,
+				/** @type {number} */
+				(options.warningsSpace)
+			);
+			object.filteredWarningDetailsCount = filtered + filteredBySpace;
+			object.warnings = warnings;
+		},
+		warningsCount: (
+			object,
+			compilation,
+			context,
+			{ warningsFilter },
+			factory
+		) => {
+			const { type, cachedGetWarnings } = context;
+			object.warningsCount = countWithChildren(compilation, (c, childType) => {
+				if (
+					!warningsFilter &&
+					/** @type {KnownNormalizedStatsOptions["warningsFilter"]} */
+					(warningsFilter).length === 0
+				) {
+					// Type is wrong, because we don't need the real value for counting
+					return /** @type {EXPECTED_ANY[]} */ (cachedGetWarnings(c));
+				}
+				return factory
+					.create(`${type}${childType}.warnings`, cachedGetWarnings(c), context)
+					.filter(
+						/**
+						 * Handles the warnings count callback for this hook.
+						 * @param {StatsError} warning warning
+						 * @returns {boolean} result
+						 */
+						(warning) => {
+							const warningString = Object.keys(warning)
+								.map(
+									(key) =>
+										`${warning[/** @type {keyof KnownStatsError} */ (key)]}`
+								)
+								.join("\n");
+							return !warningsFilter.some((filter) =>
+								filter(warning, warningString)
+							);
+						}
+					);
+			});
+		},
+		children: (object, compilation, context, options, factory) => {
+			const { type } = context;
+			object.children = factory.create(
+				`${type}.children`,
+				compilation.children,
+				context
+			);
+		}
+	},
+	asset: {
+		_: (object, asset, context, options, factory) => {
+			const { compilation } = context;
+			object.type = asset.type;
+			object.name = asset.name;
+			object.size = asset.source.size();
+			object.emitted = compilation.emittedAssets.has(asset.name);
+			object.comparedForEmit = compilation.comparedForEmitAssets.has(
+				asset.name
+			);
+			const cached = !object.emitted && !object.comparedForEmit;
+			object.cached = cached;
+			object.info = asset.info;
+			if (!cached || options.cachedAssets) {
+				Object.assign(
+					object,
+					factory.create(`${context.type}$visible`, asset, context)
+				);
+			}
+		}
+	},
+	asset$visible: {
+		_: (
+			object,
+			asset,
+			{ compilationFileToChunks, compilationAuxiliaryFileToChunks }
+		) => {
+			const chunks = compilationFileToChunks.get(asset.name) || [];
+			const auxiliaryChunks =
+				compilationAuxiliaryFileToChunks.get(asset.name) || [];
+			object.chunkNames = uniqueOrderedArray(
+				chunks,
+				(c) => (c.name ? [c.name] : []),
+				compareIds
+			);
+			object.chunkIdHints = uniqueOrderedArray(
+				chunks,
+				(c) => [...c.idNameHints],
+				compareIds
+			);
+			object.auxiliaryChunkNames = uniqueOrderedArray(
+				auxiliaryChunks,
+				(c) => (c.name ? [c.name] : []),
+				compareIds
+			);
+			object.auxiliaryChunkIdHints = uniqueOrderedArray(
+				auxiliaryChunks,
+				(c) => [...c.idNameHints],
+				compareIds
+			);
+			object.filteredRelated = asset.related ? asset.related.length : undefined;
+		},
+		relatedAssets: (object, asset, context, options, factory) => {
+			const { type } = context;
+			object.related = factory.create(
+				`${type.slice(0, -8)}.related`,
+				asset.related || [],
+				context
+			);
+			object.filteredRelated = asset.related
+				? asset.related.length -
+					/** @type {StatsAsset[]} */ (object.related).length
+				: undefined;
+		},
+		ids: (
+			object,
+			asset,
+			{ compilationFileToChunks, compilationAuxiliaryFileToChunks }
+		) => {
+			const chunks = compilationFileToChunks.get(asset.name) || [];
+			const auxiliaryChunks =
+				compilationAuxiliaryFileToChunks.get(asset.name) || [];
+			object.chunks = uniqueOrderedArray(
+				chunks,
+				(c) => /** @type {ChunkId[]} */ (c.ids),
+				compareIds
+			);
+			object.auxiliaryChunks = uniqueOrderedArray(
+				auxiliaryChunks,
+				(c) => /** @type {ChunkId[]} */ (c.ids),
+				compareIds
+			);
+		},
+		performance: (object, asset) => {
+			object.isOverSizeLimit = SizeLimitsPlugin.isOverSizeLimit(asset.source);
+		}
+	},
+	chunkGroup: {
+		_: (
+			object,
+			{ name, chunkGroup },
+			{ compilation, compilation: { moduleGraph, chunkGraph } },
+			{ ids, chunkGroupAuxiliary, chunkGroupChildren, chunkGroupMaxAssets }
+		) => {
+			const children =
+				chunkGroupChildren &&
+				chunkGroup.getChildrenByOrders(moduleGraph, chunkGraph);
+			/**
+			 * Returns } Asset object.
+			 * @param {string} name Name
+			 * @returns {{ name: string, size: number }} Asset object
+			 */
+			const toAsset = (name) => {
+				const asset = compilation.getAsset(name);
+				return {
+					name,
+					size: /** @type {number} */ (asset ? asset.info.size : -1)
+				};
+			};
+			/** @type {(total: number, asset: { size: number }) => number} */
+			const sizeReducer = (total, { size }) => total + size;
+			const assets = uniqueArray(chunkGroup.chunks, (c) => c.files).map(
+				toAsset
+			);
+			const auxiliaryAssets = uniqueOrderedArray(
+				chunkGroup.chunks,
+				(c) => c.auxiliaryFiles,
+				compareIds
+			).map(toAsset);
+			const assetsSize = assets.reduce(sizeReducer, 0);
+			const auxiliaryAssetsSize = auxiliaryAssets.reduce(sizeReducer, 0);
+			/** @type {KnownStatsChunkGroup} */
+			const statsChunkGroup = {
+				name,
+				chunks: ids
+					? /** @type {ChunkId[]} */ (chunkGroup.chunks.map((c) => c.id))
+					: undefined,
+				assets: assets.length <= chunkGroupMaxAssets ? assets : undefined,
+				filteredAssets:
+					assets.length <= chunkGroupMaxAssets ? 0 : assets.length,
+				assetsSize,
+				auxiliaryAssets:
+					chunkGroupAuxiliary && auxiliaryAssets.length <= chunkGroupMaxAssets
+						? auxiliaryAssets
+						: undefined,
+				filteredAuxiliaryAssets:
+					chunkGroupAuxiliary && auxiliaryAssets.length <= chunkGroupMaxAssets
+						? 0
+						: auxiliaryAssets.length,
+				auxiliaryAssetsSize,
+				children: children
+					? mapObject(children, (groups) =>
+							groups.map((group) => {
+								const assets = uniqueArray(group.chunks, (c) => c.files).map(
+									toAsset
+								);
+								const auxiliaryAssets = uniqueOrderedArray(
+									group.chunks,
+									(c) => c.auxiliaryFiles,
+									compareIds
+								).map(toAsset);
+
+								/** @type {KnownStatsChunkGroup} */
+								const childStatsChunkGroup = {
+									name: group.name,
+									chunks: ids
+										? /** @type {ChunkId[]} */
+											(group.chunks.map((c) => c.id))
+										: undefined,
+									assets:
+										assets.length <= chunkGroupMaxAssets ? assets : undefined,
+									filteredAssets:
+										assets.length <= chunkGroupMaxAssets ? 0 : assets.length,
+									auxiliaryAssets:
+										chunkGroupAuxiliary &&
+										auxiliaryAssets.length <= chunkGroupMaxAssets
+											? auxiliaryAssets
+											: undefined,
+									filteredAuxiliaryAssets:
+										chunkGroupAuxiliary &&
+										auxiliaryAssets.length <= chunkGroupMaxAssets
+											? 0
+											: auxiliaryAssets.length
+								};
+
+								return childStatsChunkGroup;
+							})
+						)
+					: undefined,
+				childAssets: children
+					? mapObject(children, (groups) => {
+							/** @type {Set<string>} */
+							const set = new Set();
+							for (const group of groups) {
+								for (const chunk of group.chunks) {
+									for (const asset of chunk.files) {
+										set.add(asset);
+									}
+								}
+							}
+							return [...set];
+						})
+					: undefined
+			};
+			Object.assign(object, statsChunkGroup);
+		},
+		performance: (object, { chunkGroup }) => {
+			object.isOverSizeLimit = SizeLimitsPlugin.isOverSizeLimit(chunkGroup);
+		}
+	},
+	module: {
+		_: (object, module, context, options, factory) => {
+			const { type } = context;
+			const compilation = /** @type {Compilation} */ (context.compilation);
+			const built = compilation.builtModules.has(module);
+			const codeGenerated = compilation.codeGeneratedModules.has(module);
+			const buildTimeExecuted =
+				compilation.buildTimeExecutedModules.has(module);
+			/** @type {{ [x: string]: number }} */
+			const sizes = {};
+			for (const sourceType of module.getSourceTypes()) {
+				sizes[sourceType] = module.size(sourceType);
+			}
+			/** @type {KnownStatsModule} */
+			const statsModule = {
+				type: "module",
+				moduleType: module.type,
+				layer: module.layer,
+				size: module.size(),
+				sizes,
+				built,
+				codeGenerated,
+				buildTimeExecuted,
+				cached: !built && !codeGenerated
+			};
+			Object.assign(object, statsModule);
+			if (built || codeGenerated || options.cachedModules) {
+				Object.assign(
+					object,
+					factory.create(`${type}$visible`, module, context)
+				);
+			}
+		}
+	},
+	module$visible: {
+		_: (object, module, context, { requestShortener }, factory) => {
+			const { type, rootModules } = context;
+			const compilation = /** @type {Compilation} */ (context.compilation);
+			const { moduleGraph } = compilation;
+			/** @type {ModuleIssuerPath} */
+			const path = [];
+			const issuer = moduleGraph.getIssuer(module);
+			let current = issuer;
+			while (current) {
+				path.push(current);
+				current = moduleGraph.getIssuer(current);
+			}
+			path.reverse();
+			const profile = moduleGraph.getProfile(module);
+			const errors = module.getErrors();
+			const errorsCount = errors !== undefined ? countIterable(errors) : 0;
+			const warnings = module.getWarnings();
+			const warningsCount =
+				warnings !== undefined ? countIterable(warnings) : 0;
+			/** @type {KnownStatsModule} */
+			const statsModule = {
+				identifier: module.identifier(),
+				name: module.readableIdentifier(requestShortener),
+				nameForCondition: module.nameForCondition(),
+				index: /** @type {number} */ (moduleGraph.getPreOrderIndex(module)),
+				preOrderIndex: /** @type {number} */ (
+					moduleGraph.getPreOrderIndex(module)
+				),
+				index2: /** @type {number} */ (moduleGraph.getPostOrderIndex(module)),
+				postOrderIndex: /** @type {number} */ (
+					moduleGraph.getPostOrderIndex(module)
+				),
+				cacheable: /** @type {BuildInfo} */ (module.buildInfo).cacheable,
+				optional: module.isOptional(moduleGraph),
+				orphan:
+					!type.endsWith("module.modules[].module$visible") &&
+					compilation.chunkGraph.getNumberOfModuleChunks(module) === 0,
+				dependent: rootModules ? !rootModules.has(module) : undefined,
+				issuer: issuer && issuer.identifier(),
+				issuerName: issuer && issuer.readableIdentifier(requestShortener),
+				issuerPath:
+					issuer &&
+					/** @type {StatsModuleIssuer[] | undefined} */
+					(factory.create(`${type.slice(0, -8)}.issuerPath`, path, context)),
+				failed: errorsCount > 0,
+				errors: errorsCount,
+				warnings: warningsCount
+			};
+			Object.assign(object, statsModule);
+			if (profile) {
+				object.profile = factory.create(
+					`${type.slice(0, -8)}.profile`,
+					profile,
+					context
+				);
+			}
+		},
+		ids: (object, module, { compilation: { chunkGraph, moduleGraph } }) => {
+			object.id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+			const issuer = moduleGraph.getIssuer(module);
+			object.issuerId = issuer && chunkGraph.getModuleId(issuer);
+			object.chunks =
+				/** @type {ChunkId[]} */
+				(
+					Array.from(
+						chunkGraph.getOrderedModuleChunksIterable(
+							module,
+							compareChunksById
+						),
+						(chunk) => chunk.id
+					)
+				);
+		},
+		moduleAssets: (object, module) => {
+			object.assets = /** @type {BuildInfo} */ (module.buildInfo).assets
+				? Object.keys(/** @type {BuildInfo} */ (module.buildInfo).assets)
+				: [];
+		},
+		reasons: (object, module, context, options, factory) => {
+			const {
+				type,
+				compilation: { moduleGraph }
+			} = context;
+			const groupsReasons = factory.create(
+				`${type.slice(0, -8)}.reasons`,
+				[...moduleGraph.getIncomingConnections(module)],
+				context
+			);
+			const limited = spaceLimited(
+				groupsReasons,
+				/** @type {number} */
+				(options.reasonsSpace)
+			);
+			object.reasons = limited.children;
+			object.filteredReasons = limited.filteredChildren;
+		},
+		usedExports: (
+			object,
+			module,
+			{ runtime, compilation: { moduleGraph } }
+		) => {
+			const usedExports = moduleGraph.getUsedExports(module, runtime);
+			if (usedExports === null) {
+				object.usedExports = null;
+			} else if (typeof usedExports === "boolean") {
+				object.usedExports = usedExports;
+			} else {
+				object.usedExports = [...usedExports];
+			}
+		},
+		providedExports: (object, module, { compilation: { moduleGraph } }) => {
+			const providedExports = moduleGraph.getProvidedExports(module);
+			object.providedExports = Array.isArray(providedExports)
+				? providedExports
+				: null;
+		},
+		optimizationBailout: (
+			object,
+			module,
+			{ compilation: { moduleGraph } },
+			{ requestShortener }
+		) => {
+			object.optimizationBailout = moduleGraph
+				.getOptimizationBailout(module)
+				.map((item) => {
+					if (typeof item === "function") return item(requestShortener);
+					return item;
+				});
+		},
+		depth: (object, module, { compilation: { moduleGraph } }) => {
+			object.depth = moduleGraph.getDepth(module);
+		},
+		nestedModules: (object, module, context, options, factory) => {
+			const { type } = context;
+			const innerModules = /** @type {Module & { modules?: Module[] }} */ (
+				module
+			).modules;
+			if (Array.isArray(innerModules)) {
+				const groupedModules = factory.create(
+					`${type.slice(0, -8)}.modules`,
+					innerModules,
+					context
+				);
+				const limited = spaceLimited(
+					groupedModules,
+					options.nestedModulesSpace
+				);
+				object.modules = limited.children;
+				object.filteredModules = limited.filteredChildren;
+			}
+		},
+		source: (object, module) => {
+			const originalSource = module.originalSource();
+			if (originalSource) {
+				object.source = originalSource.source();
+			}
+		}
+	},
+	profile: {
+		_: (object, profile) => {
+			/** @type {KnownStatsProfile} */
+			const statsProfile = {
+				total:
+					profile.factory +
+					profile.restoring +
+					profile.integration +
+					profile.building +
+					profile.storing,
+				resolving: profile.factory,
+				restoring: profile.restoring,
+				building: profile.building,
+				integration: profile.integration,
+				storing: profile.storing,
+				additionalResolving: profile.additionalFactories,
+				additionalIntegration: profile.additionalIntegration,
+				// TODO remove this in webpack 6
+				factory: profile.factory,
+				// TODO remove this in webpack 6
+				dependencies: profile.additionalFactories
+			};
+			Object.assign(object, statsProfile);
+		}
+	},
+	moduleIssuer: {
+		_: (object, module, context, { requestShortener }, factory) => {
+			const { type } = context;
+			const compilation = /** @type {Compilation} */ (context.compilation);
+			const { moduleGraph } = compilation;
+			const profile = moduleGraph.getProfile(module);
+			/** @type {Partial<KnownStatsModuleIssuer>} */
+			const statsModuleIssuer = {
+				identifier: module.identifier(),
+				name: module.readableIdentifier(requestShortener)
+			};
+			Object.assign(object, statsModuleIssuer);
+			if (profile) {
+				object.profile = factory.create(`${type}.profile`, profile, context);
+			}
+		},
+		ids: (object, module, { compilation: { chunkGraph } }) => {
+			object.id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+		}
+	},
+	moduleReason: {
+		_: (object, reason, { runtime }, { requestShortener }) => {
+			const dep = reason.dependency;
+			const moduleDep =
+				dep && dep instanceof ModuleDependency ? dep : undefined;
+			/** @type {KnownStatsModuleReason} */
+			const statsModuleReason = {
+				moduleIdentifier: reason.originModule
+					? reason.originModule.identifier()
+					: null,
+				module: reason.originModule
+					? reason.originModule.readableIdentifier(requestShortener)
+					: null,
+				moduleName: reason.originModule
+					? reason.originModule.readableIdentifier(requestShortener)
+					: null,
+				resolvedModuleIdentifier: reason.resolvedOriginModule
+					? reason.resolvedOriginModule.identifier()
+					: null,
+				resolvedModule: reason.resolvedOriginModule
+					? reason.resolvedOriginModule.readableIdentifier(requestShortener)
+					: null,
+				type: reason.dependency ? reason.dependency.type : null,
+				active: reason.isActive(runtime),
+				explanation: reason.explanation,
+				userRequest: (moduleDep && moduleDep.userRequest) || null
+			};
+			Object.assign(object, statsModuleReason);
+			if (reason.dependency) {
+				const locInfo = formatLocation(reason.dependency.loc);
+				if (locInfo) {
+					object.loc = locInfo;
+				}
+			}
+		},
+		ids: (object, reason, { compilation: { chunkGraph } }) => {
+			object.moduleId = reason.originModule
+				? chunkGraph.getModuleId(reason.originModule)
+				: null;
+			object.resolvedModuleId = reason.resolvedOriginModule
+				? chunkGraph.getModuleId(reason.resolvedOriginModule)
+				: null;
+		}
+	},
+	chunk: {
+		_: (object, chunk, { makePathsRelative, compilation: { chunkGraph } }) => {
+			const childIdByOrder = chunk.getChildIdsByOrders(chunkGraph);
+
+			/** @type {KnownStatsChunk} */
+			const statsChunk = {
+				rendered: chunk.rendered,
+				initial: chunk.canBeInitial(),
+				entry: chunk.hasRuntime(),
+				recorded: AggressiveSplittingPlugin.wasChunkRecorded(chunk),
+				reason: chunk.chunkReason,
+				size: chunkGraph.getChunkModulesSize(chunk),
+				sizes: chunkGraph.getChunkModulesSizes(chunk),
+				names: chunk.name ? [chunk.name] : [],
+				idHints: [...chunk.idNameHints],
+				runtime:
+					chunk.runtime === undefined
+						? undefined
+						: typeof chunk.runtime === "string"
+							? [makePathsRelative(chunk.runtime)]
+							: Array.from(chunk.runtime.sort(), makePathsRelative),
+				files: [...chunk.files],
+				auxiliaryFiles: [...chunk.auxiliaryFiles].sort(compareIds),
+				hash: /** @type {string} */ (chunk.renderedHash),
+				childrenByOrder: childIdByOrder
+			};
+			Object.assign(object, statsChunk);
+		},
+		ids: (object, chunk) => {
+			object.id = /** @type {ChunkId} */ (chunk.id);
+		},
+		chunkRelations: (object, chunk, _context) => {
+			/** @typedef {Set<ChunkId>} ChunkRelations */
+			/** @type {ChunkRelations} */
+			const parents = new Set();
+			/** @type {ChunkRelations} */
+			const children = new Set();
+			/** @type {ChunkRelations} */
+			const siblings = new Set();
+
+			for (const chunkGroup of chunk.groupsIterable) {
+				for (const parentGroup of chunkGroup.parentsIterable) {
+					for (const chunk of parentGroup.chunks) {
+						parents.add(/** @type {ChunkId} */ (chunk.id));
+					}
+				}
+				for (const childGroup of chunkGroup.childrenIterable) {
+					for (const chunk of childGroup.chunks) {
+						children.add(/** @type {ChunkId} */ (chunk.id));
+					}
+				}
+				for (const sibling of chunkGroup.chunks) {
+					if (sibling !== chunk) {
+						siblings.add(/** @type {ChunkId} */ (sibling.id));
+					}
+				}
+			}
+			object.siblings = [...siblings].sort(compareIds);
+			object.parents = [...parents].sort(compareIds);
+			object.children = [...children].sort(compareIds);
+		},
+		chunkModules: (object, chunk, context, options, factory) => {
+			const {
+				type,
+				compilation: { chunkGraph }
+			} = context;
+			const array = chunkGraph.getChunkModules(chunk);
+			const groupedModules = factory.create(`${type}.modules`, array, {
+				...context,
+				runtime: chunk.runtime,
+				rootModules: new Set(chunkGraph.getChunkRootModules(chunk))
+			});
+			const limited = spaceLimited(groupedModules, options.chunkModulesSpace);
+			object.modules = limited.children;
+			object.filteredModules = limited.filteredChildren;
+		},
+		chunkOrigins: (object, chunk, context, options, factory) => {
+			const {
+				type,
+				compilation: { chunkGraph }
+			} = context;
+			/** @type {Set<string>} */
+			const originsKeySet = new Set();
+			/** @type {OriginRecord[]} */
+			const origins = [];
+			for (const g of chunk.groupsIterable) {
+				origins.push(...g.origins);
+			}
+			const array = origins.filter((origin) => {
+				const key = [
+					origin.module ? chunkGraph.getModuleId(origin.module) : undefined,
+					formatLocation(origin.loc),
+					origin.request
+				].join();
+				if (originsKeySet.has(key)) return false;
+				originsKeySet.add(key);
+				return true;
+			});
+			object.origins = factory.create(`${type}.origins`, array, context);
+		}
+	},
+	chunkOrigin: {
+		_: (object, origin, context, { requestShortener }) => {
+			/** @type {KnownStatsChunkOrigin} */
+			const statsChunkOrigin = {
+				module: origin.module ? origin.module.identifier() : "",
+				moduleIdentifier: origin.module ? origin.module.identifier() : "",
+				moduleName: origin.module
+					? origin.module.readableIdentifier(requestShortener)
+					: "",
+				loc: formatLocation(origin.loc),
+				request: origin.request
+			};
+			Object.assign(object, statsChunkOrigin);
+		},
+		ids: (object, origin, { compilation: { chunkGraph } }) => {
+			object.moduleId = origin.module
+				? /** @type {ModuleId} */ (chunkGraph.getModuleId(origin.module))
+				: undefined;
+		}
+	},
+	error: EXTRACT_ERROR,
+	warning: EXTRACT_ERROR,
+	cause: EXTRACT_ERROR,
+	moduleTraceItem: {
+		_: (object, { origin, module }, context, { requestShortener }, factory) => {
+			const {
+				type,
+				compilation: { moduleGraph }
+			} = context;
+			object.originIdentifier = origin.identifier();
+			object.originName = origin.readableIdentifier(requestShortener);
+			object.moduleIdentifier = module.identifier();
+			object.moduleName = module.readableIdentifier(requestShortener);
+			const dependencies = [...moduleGraph.getIncomingConnections(module)]
+				.filter((c) => c.resolvedOriginModule === origin && c.dependency)
+				.map((c) => c.dependency);
+			object.dependencies = factory.create(
+				`${type}.dependencies`,
+				/** @type {Dependency[]} */
+				([...new Set(dependencies)]),
+				context
+			);
+		},
+		ids: (object, { origin, module }, { compilation: { chunkGraph } }) => {
+			object.originId =
+				/** @type {ModuleId} */
+				(chunkGraph.getModuleId(origin));
+			object.moduleId =
+				/** @type {ModuleId} */
+				(chunkGraph.getModuleId(module));
+		}
+	},
+	moduleTraceDependency: {
+		_: (object, dependency) => {
+			object.loc = formatLocation(dependency.loc);
+		}
+	}
+};
+
+/** @type {Record<string, Record<string, (thing: ModuleGraphConnection, context: StatsFactoryContext, options: NormalizedStatsOptions, idx: number, i: number) => boolean | undefined>>} */
+const FILTER = {
+	"module.reasons": {
+		"!orphanModules": (reason, { compilation: { chunkGraph } }) => {
+			if (
+				reason.originModule &&
+				chunkGraph.getNumberOfModuleChunks(reason.originModule) === 0
+			) {
+				return false;
+			}
+		}
+	}
+};
+
+/** @type {Record<string, Record<string, (thing: KnownStatsError, context: StatsFactoryContext, options: NormalizedStatsOptions, idx: number, i: number) => boolean | undefined>>} */
+const FILTER_RESULTS = {
+	"compilation.warnings": {
+		warningsFilter: util.deprecate(
+			(warning, context, { warningsFilter }) => {
+				const warningString = Object.keys(warning)
+					.map(
+						(key) => `${warning[/** @type {keyof KnownStatsError} */ (key)]}`
+					)
+					.join("\n");
+				return !warningsFilter.some((filter) => filter(warning, warningString));
+			},
+			"config.stats.warningsFilter is deprecated in favor of config.ignoreWarnings",
+			"DEP_WEBPACK_STATS_WARNINGS_FILTER"
+		)
+	}
+};
+
+/** @type {Record<string, (comparators: Comparator<Module>[], context: StatsFactoryContext) => void>} */
+const MODULES_SORTER = {
+	_: (comparators, { compilation: { moduleGraph } }) => {
+		comparators.push(
+			compareSelect((m) => moduleGraph.getDepth(m), compareNumbers),
+			compareSelect((m) => moduleGraph.getPreOrderIndex(m), compareNumbers),
+			compareSelect((m) => m.identifier(), compareIds)
+		);
+	}
+};
+
+/**
+ * @type {{
+ * "compilation.chunks": Record<string, (comparators: Comparator<Chunk>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * "compilation.modules": Record<string, (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * "chunk.rootModules": Record<string, (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * "chunk.modules": Record<string, (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * "module.modules": Record<string, (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * "module.reasons": Record<string, (comparators: Comparator<ModuleGraphConnection>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * "chunk.origins": Record<string, (comparators: Comparator<OriginRecord>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>,
+ * }}
+ */
+const SORTERS = {
+	"compilation.chunks": {
+		_: (comparators) => {
+			comparators.push(compareSelect((c) => c.id, compareIds));
+		}
+	},
+	"compilation.modules": MODULES_SORTER,
+	"chunk.rootModules": MODULES_SORTER,
+	"chunk.modules": MODULES_SORTER,
+	"module.modules": MODULES_SORTER,
+	"module.reasons": {
+		_: (comparators, _context) => {
+			comparators.push(
+				compareSelect((x) => x.originModule, compareModulesByIdentifier)
+			);
+			comparators.push(
+				compareSelect((x) => x.resolvedOriginModule, compareModulesByIdentifier)
+			);
+			comparators.push(
+				compareSelect(
+					(x) => x.dependency,
+					concatComparators(
+						compareSelect(
+							/**
+							 * Handles the  callback for this hook.
+							 * @param {Dependency} x dependency
+							 * @returns {DependencyLocation} location
+							 */
+							(x) => x.loc,
+							compareLocations
+						),
+						compareSelect((x) => x.type, compareIds)
+					)
+				)
+			);
+		}
+	},
+	"chunk.origins": {
+		_: (comparators, { compilation: { chunkGraph } }) => {
+			comparators.push(
+				compareSelect(
+					(origin) =>
+						origin.module ? chunkGraph.getModuleId(origin.module) : undefined,
+					compareIds
+				),
+				compareSelect((origin) => formatLocation(origin.loc), compareIds),
+				compareSelect((origin) => origin.request, compareIds)
+			);
+		}
+	}
+};
+
+/**
+ * Defines the children type used by this module.
+ * @template T
+ * @typedef {T & { children?: Children<T>[] | undefined, filteredChildren?: number }} Children
+ */
+
+/**
+ * Returns item size.
+ * @template T
+ * @param {Children<T>} item item
+ * @returns {number} item size
+ */
+const getItemSize = (item) =>
+	// Each item takes 1 line
+	// + the size of the children
+	// + 1 extra line when it has children and filteredChildren
+	!item.children
+		? 1
+		: item.filteredChildren
+			? 2 + getTotalSize(item.children)
+			: 1 + getTotalSize(item.children);
+
+/**
+ * Returns total size.
+ * @template T
+ * @param {Children<T>[]} children children
+ * @returns {number} total size
+ */
+const getTotalSize = (children) => {
+	let size = 0;
+	for (const child of children) {
+		size += getItemSize(child);
+	}
+	return size;
+};
+
+/**
+ * Returns total items.
+ * @template T
+ * @param {Children<T>[]} children children
+ * @returns {number} total items
+ */
+const getTotalItems = (children) => {
+	let count = 0;
+	for (const child of children) {
+		if (!child.children && !child.filteredChildren) {
+			count++;
+		} else {
+			if (child.children) count += getTotalItems(child.children);
+			if (child.filteredChildren) count += child.filteredChildren;
+		}
+	}
+	return count;
+};
+
+/**
+ * Returns collapsed children.
+ * @template T
+ * @param {Children<T>[]} children children
+ * @returns {Children<T>[]} collapsed children
+ */
+const collapse = (children) => {
+	// After collapse each child must take exactly one line
+	/** @type {Children<T>[]} */
+	const newChildren = [];
+	for (const child of children) {
+		if (child.children) {
+			let filteredChildren = child.filteredChildren || 0;
+			filteredChildren += getTotalItems(child.children);
+			newChildren.push({
+				...child,
+				children: undefined,
+				filteredChildren
+			});
+		} else {
+			newChildren.push(child);
+		}
+	}
+	return newChildren;
+};
+
+/**
+ * Returns result.
+ * @template T
+ * @param {Children<T>[]} itemsAndGroups item and groups
+ * @param {number} max max
+ * @param {boolean=} filteredChildrenLineReserved filtered children line reserved
+ * @returns {Children<T>} result
+ */
+const spaceLimited = (
+	itemsAndGroups,
+	max,
+	filteredChildrenLineReserved = false
+) => {
+	if (max < 1) {
+		return /** @type {Children<T>} */ ({
+			children: undefined,
+			filteredChildren: getTotalItems(itemsAndGroups)
+		});
+	}
+	/** @type {Children<T>[] | undefined} */
+	let children;
+	/** @type {number | undefined} */
+	let filteredChildren;
+	// This are the groups, which take 1+ lines each
+	/** @type {Children<T>[] | undefined} */
+	const groups = [];
+	// The sizes of the groups are stored in groupSizes
+	/** @type {number[]} */
+	const groupSizes = [];
+	// This are the items, which take 1 line each
+	/** @type {Children<T>[]} */
+	const items = [];
+	// The total of group sizes
+	let groupsSize = 0;
+
+	for (const itemOrGroup of itemsAndGroups) {
+		// is item
+		if (!itemOrGroup.children && !itemOrGroup.filteredChildren) {
+			items.push(itemOrGroup);
+		} else {
+			groups.push(itemOrGroup);
+			const size = getItemSize(itemOrGroup);
+			groupSizes.push(size);
+			groupsSize += size;
+		}
+	}
+
+	if (groupsSize + items.length <= max) {
+		// The total size in the current state fits into the max
+		// keep all
+		children = groups.length > 0 ? [...groups, ...items] : items;
+	} else if (groups.length === 0) {
+		// slice items to max
+		// inner space marks that lines for filteredChildren already reserved
+		const limit = max - (filteredChildrenLineReserved ? 0 : 1);
+		filteredChildren = items.length - limit;
+		items.length = limit;
+		children = items;
+	} else {
+		// limit is the size when all groups are collapsed
+		const limit =
+			groups.length +
+			(filteredChildrenLineReserved || items.length === 0 ? 0 : 1);
+		if (limit < max) {
+			// calculate how much we are over the size limit
+			// this allows to approach the limit faster
+			/** @type {number} */
+			let oversize;
+			// If each group would take 1 line the total would be below the maximum
+			// collapse some groups, keep items
+			while (
+				(oversize =
+					groupsSize +
+					items.length +
+					(filteredChildren && !filteredChildrenLineReserved ? 1 : 0) -
+					max) > 0
+			) {
+				// Find the maximum group and process only this one
+				const maxGroupSize = Math.max(...groupSizes);
+				if (maxGroupSize < items.length) {
+					filteredChildren = items.length;
+					items.length = 0;
+					continue;
+				}
+				for (let i = 0; i < groups.length; i++) {
+					if (groupSizes[i] === maxGroupSize) {
+						const group = groups[i];
+						// run this algorithm recursively and limit the size of the children to
+						// current size - oversize / number of groups
+						// So it should always end up being smaller
+						const headerSize = group.filteredChildren ? 2 : 1;
+						const limited = spaceLimited(
+							/** @type {Children<T>[]} */ (group.children),
+							maxGroupSize -
+								// we should use ceil to always feet in max
+								Math.ceil(oversize / groups.length) -
+								// we substitute size of group head
+								headerSize,
+							headerSize === 2
+						);
+						groups[i] = {
+							...group,
+							children: limited.children,
+							filteredChildren: limited.filteredChildren
+								? (group.filteredChildren || 0) + limited.filteredChildren
+								: group.filteredChildren
+						};
+						const newSize = getItemSize(groups[i]);
+						groupsSize -= maxGroupSize - newSize;
+						groupSizes[i] = newSize;
+						break;
+					}
+				}
+			}
+			children = [...groups, ...items];
+		} else if (limit === max) {
+			// If we have only enough space to show one line per group and one line for the filtered items
+			// collapse all groups and items
+			children = collapse(groups);
+			filteredChildren = items.length;
+		} else {
+			// If we have no space
+			// collapse complete group
+			filteredChildren = getTotalItems(itemsAndGroups);
+		}
+	}
+
+	return /** @type {Children<T>} */ ({ children, filteredChildren });
+};
+
+/**
+ * Errors space limit.
+ * @param {StatsError[]} errors errors
+ * @param {number} max max
+ * @returns {[StatsError[], number]} error space limit
+ */
+const errorsSpaceLimit = (errors, max) => {
+	let filtered = 0;
+	// Can not fit into limit
+	// print only messages
+	if (errors.length + 1 >= max) {
+		return [
+			errors.map((error) => {
+				if (typeof error === "string" || !error.details) return error;
+				filtered++;
+				return { ...error, details: "" };
+			}),
+			filtered
+		];
+	}
+	let fullLength = errors.length;
+	let result = errors;
+
+	let i = 0;
+	for (; i < errors.length; i++) {
+		const error = errors[i];
+		if (typeof error !== "string" && error.details) {
+			const splitted = error.details.split("\n");
+			const len = splitted.length;
+			fullLength += len;
+			if (fullLength > max) {
+				result = i > 0 ? errors.slice(0, i) : [];
+				const overLimit = fullLength - max + 1;
+				const error = errors[i++];
+				result.push({
+					...error,
+					details:
+						/** @type {string} */
+						(error.details).split("\n").slice(0, -overLimit).join("\n"),
+					filteredDetails: overLimit
+				});
+				filtered = errors.length - i;
+				for (; i < errors.length; i++) {
+					const error = errors[i];
+					if (typeof error === "string" || !error.details) result.push(error);
+					result.push({ ...error, details: "" });
+				}
+				break;
+			} else if (fullLength === max) {
+				result = errors.slice(0, ++i);
+				filtered = errors.length - i;
+				for (; i < errors.length; i++) {
+					const error = errors[i];
+					if (typeof error === "string" || !error.details) result.push(error);
+					result.push({ ...error, details: "" });
+				}
+				break;
+			}
+		}
+	}
+
+	return [result, filtered];
+};
+
+/**
+ * Returns } asset size.
+ * @template {{ size: number }} T
+ * @param {T[]} children children
+ * @param {T[]} assets assets
+ * @returns {{ size: number }} asset size
+ */
+const assetGroup = (children, assets) => {
+	let size = 0;
+	for (const asset of children) {
+		size += asset.size;
+	}
+	return { size };
+};
+
+/** @typedef {{ size: number, sizes: Record<string, number> }} ModuleGroupBySizeResult */
+
+/**
+ * Returns size and sizes.
+ * @template {ModuleGroupBySizeResult} T
+ * @param {Children<T>[]} children children
+ * @param {KnownStatsModule[]} modules modules
+ * @returns {ModuleGroupBySizeResult} size and sizes
+ */
+const moduleGroup = (children, modules) => {
+	let size = 0;
+	/** @type {Record<string, number>} */
+	const sizes = {};
+	for (const module of children) {
+		size += module.size;
+		for (const key of Object.keys(module.sizes)) {
+			sizes[key] = (sizes[key] || 0) + module.sizes[key];
+		}
+	}
+	return {
+		size,
+		sizes
+	};
+};
+
+/**
+ * Returns } reason group.
+ * @template {{ active: boolean }} T
+ * @param {Children<T>[]} children children
+ * @param {KnownStatsModuleReason[]} reasons reasons
+ * @returns {{ active: boolean }} reason group
+ */
+const reasonGroup = (children, reasons) => {
+	let active = false;
+	for (const reason of children) {
+		active = active || reason.active;
+	}
+	return {
+		active
+	};
+};
+
+const GROUP_EXTENSION_REGEXP = /(\.[^.]+?)(?:\?|(?: \+ \d+ modules?)?$)/;
+const GROUP_PATH_REGEXP = /(.+)[/\\][^/\\]+?(?:\?|(?: \+ \d+ modules?)?$)/;
+
+/** @typedef {{ type: string }} BaseGroup */
+
+/**
+ * Defines the base group with children type used by this module.
+ * @template T
+ * @typedef {BaseGroup & { children: T[], size: number }} BaseGroupWithChildren
+ */
+
+/** @typedef {(name: string, asset: StatsAsset) => boolean} AssetFilterItemFn */
+
+/**
+ * Describes the assets groupers shape.
+ * @typedef {{
+ * _: (groupConfigs: GroupConfig<KnownStatsAsset, BaseGroup & { filteredChildren: number, size: number } | BaseGroupWithChildren<KnownStatsAsset>>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * groupAssetsByInfo: (groupConfigs: GroupConfig<KnownStatsAsset, BaseGroupWithChildren<KnownStatsAsset>>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * groupAssetsByChunk: (groupConfigs: GroupConfig<KnownStatsAsset, BaseGroupWithChildren<KnownStatsAsset>>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * excludeAssets: (groupConfigs: GroupConfig<KnownStatsAsset, BaseGroup & { filteredChildren: number, size: number }>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * }} AssetsGroupers
+ */
+
+/** @type {AssetsGroupers} */
+const ASSETS_GROUPERS = {
+	_: (groupConfigs, context, options) => {
+		/**
+		 * Processes the provided name.
+		 * @param {keyof KnownStatsAsset} name name
+		 * @param {boolean=} exclude need exclude?
+		 */
+		const groupByFlag = (name, exclude) => {
+			groupConfigs.push({
+				getKeys: (asset) => (asset[name] ? ["1"] : undefined),
+				getOptions: () => ({
+					groupChildren: !exclude,
+					force: exclude
+				}),
+				createGroup: (key, children, assets) =>
+					exclude
+						? {
+								type: "assets by status",
+								[name]: Boolean(key),
+								filteredChildren: assets.length,
+								...assetGroup(children, assets)
+							}
+						: {
+								type: "assets by status",
+								[name]: Boolean(key),
+								children,
+								...assetGroup(children, assets)
+							}
+			});
+		};
+		const {
+			groupAssetsByEmitStatus,
+			groupAssetsByPath,
+			groupAssetsByExtension
+		} = options;
+		if (groupAssetsByEmitStatus) {
+			groupByFlag("emitted");
+			groupByFlag("comparedForEmit");
+			groupByFlag("isOverSizeLimit");
+		}
+		if (groupAssetsByEmitStatus || !options.cachedAssets) {
+			groupByFlag("cached", !options.cachedAssets);
+		}
+		if (groupAssetsByPath || groupAssetsByExtension) {
+			groupConfigs.push({
+				getKeys: (asset) => {
+					const extensionMatch =
+						groupAssetsByExtension && GROUP_EXTENSION_REGEXP.exec(asset.name);
+					const extension = extensionMatch ? extensionMatch[1] : "";
+					const pathMatch =
+						groupAssetsByPath && GROUP_PATH_REGEXP.exec(asset.name);
+					const path = pathMatch ? pathMatch[1].split(/[/\\]/) : [];
+					/** @type {string[]} */
+					const keys = [];
+					if (groupAssetsByPath) {
+						keys.push(".");
+						if (extension) {
+							keys.push(
+								path.length
+									? `${path.join("/")}/*${extension}`
+									: `*${extension}`
+							);
+						}
+						while (path.length > 0) {
+							keys.push(`${path.join("/")}/`);
+							path.pop();
+						}
+					} else if (extension) {
+						keys.push(`*${extension}`);
+					}
+					return keys;
+				},
+				createGroup: (key, children, assets) => ({
+					type: groupAssetsByPath ? "assets by path" : "assets by extension",
+					name: key,
+					children,
+					...assetGroup(children, assets)
+				})
+			});
+		}
+	},
+	groupAssetsByInfo: (groupConfigs, _context, _options) => {
+		/**
+		 * Group by asset info flag.
+		 * @param {string} name name
+		 */
+		const groupByAssetInfoFlag = (name) => {
+			groupConfigs.push({
+				getKeys: (asset) =>
+					asset.info && asset.info[name] ? ["1"] : undefined,
+				createGroup: (key, children, assets) => ({
+					type: "assets by info",
+					info: {
+						[name]: Boolean(key)
+					},
+					children,
+					...assetGroup(children, assets)
+				})
+			});
+		};
+		groupByAssetInfoFlag("immutable");
+		groupByAssetInfoFlag("development");
+		groupByAssetInfoFlag("hotModuleReplacement");
+	},
+	groupAssetsByChunk: (groupConfigs, _context, _options) => {
+		/**
+		 * Processes the provided name.
+		 * @param {keyof KnownStatsAsset} name name
+		 */
+		const groupByNames = (name) => {
+			groupConfigs.push({
+				getKeys: (asset) => /** @type {string[]} */ (asset[name]),
+				createGroup: (key, children, assets) => ({
+					type: "assets by chunk",
+					[name]: [key],
+					children,
+					...assetGroup(children, assets)
+				})
+			});
+		};
+		groupByNames("chunkNames");
+		groupByNames("auxiliaryChunkNames");
+		groupByNames("chunkIdHints");
+		groupByNames("auxiliaryChunkIdHints");
+	},
+	excludeAssets: (groupConfigs, context, { excludeAssets }) => {
+		groupConfigs.push({
+			getKeys: (asset) => {
+				const ident = asset.name;
+				const excluded = excludeAssets.some((fn) => fn(ident, asset));
+				if (excluded) return ["excluded"];
+			},
+			getOptions: () => ({
+				groupChildren: false,
+				force: true
+			}),
+			createGroup: (key, children, assets) => ({
+				type: "hidden assets",
+				filteredChildren: assets.length,
+				...assetGroup(children, assets)
+			})
+		});
+	}
+};
+
+/**
+ * Describes the modules groupers shape.
+ * @typedef {{
+ * _: (groupConfigs: GroupConfig<KnownStatsModule, BaseGroup & { filteredChildren?: number, children?: KnownStatsModule[], size: number, sizes: Record<string, number> }>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * excludeModules: (groupConfigs: GroupConfig<KnownStatsModule, BaseGroup & { filteredChildren: number, size: number, sizes: Record<string, number> }>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * }} ModulesGroupers
+ */
+
+/** @typedef {(name: string, module: StatsModule, type: "module" | "chunk" | "root-of-chunk" | "nested") => boolean} ModuleFilterItemTypeFn */
+
+/**
+ * @type {(type: ExcludeModulesType) => ModulesGroupers}
+ */
+const MODULES_GROUPERS = (type) => ({
+	_: (groupConfigs, context, options) => {
+		/**
+		 * Processes the provided name.
+		 * @param {keyof KnownStatsModule} name name
+		 * @param {string} type type
+		 * @param {boolean=} exclude need exclude?
+		 */
+		const groupByFlag = (name, type, exclude) => {
+			groupConfigs.push({
+				getKeys: (module) => (module[name] ? ["1"] : undefined),
+				getOptions: () => ({
+					groupChildren: !exclude,
+					force: exclude
+				}),
+				createGroup: (key, children, modules) => ({
+					type,
+					[name]: Boolean(key),
+					...(exclude ? { filteredChildren: modules.length } : { children }),
+					...moduleGroup(
+						/** @type {(KnownStatsModule & ModuleGroupBySizeResult)[]} */
+						(children),
+						modules
+					)
+				})
+			});
+		};
+		const {
+			groupModulesByCacheStatus,
+			groupModulesByLayer,
+			groupModulesByAttributes,
+			groupModulesByType,
+			groupModulesByPath,
+			groupModulesByExtension
+		} = options;
+		if (groupModulesByAttributes) {
+			groupByFlag("errors", "modules with errors");
+			groupByFlag("warnings", "modules with warnings");
+			groupByFlag("assets", "modules with assets");
+			groupByFlag("optional", "optional modules");
+		}
+		if (groupModulesByCacheStatus) {
+			groupByFlag("cacheable", "cacheable modules");
+			groupByFlag("built", "built modules");
+			groupByFlag("codeGenerated", "code generated modules");
+		}
+		if (groupModulesByCacheStatus || !options.cachedModules) {
+			groupByFlag("cached", "cached modules", !options.cachedModules);
+		}
+		if (groupModulesByAttributes || !options.orphanModules) {
+			groupByFlag("orphan", "orphan modules", !options.orphanModules);
+		}
+		if (groupModulesByAttributes || !options.dependentModules) {
+			groupByFlag("dependent", "dependent modules", !options.dependentModules);
+		}
+		if (groupModulesByType || !options.runtimeModules) {
+			groupConfigs.push({
+				getKeys: (module) => {
+					if (!module.moduleType) return;
+					if (groupModulesByType) {
+						return [module.moduleType.split("/", 1)[0]];
+					} else if (module.moduleType === WEBPACK_MODULE_TYPE_RUNTIME) {
+						return [WEBPACK_MODULE_TYPE_RUNTIME];
+					}
+				},
+				getOptions: (key) => {
+					const exclude =
+						key === WEBPACK_MODULE_TYPE_RUNTIME && !options.runtimeModules;
+					return {
+						groupChildren: !exclude,
+						force: exclude
+					};
+				},
+				createGroup: (key, children, modules) => {
+					const exclude =
+						key === WEBPACK_MODULE_TYPE_RUNTIME && !options.runtimeModules;
+					return {
+						type: `${key} modules`,
+						moduleType: key,
+						...(exclude ? { filteredChildren: modules.length } : { children }),
+						...moduleGroup(
+							/** @type {(KnownStatsModule & ModuleGroupBySizeResult)[]} */
+							(children),
+							modules
+						)
+					};
+				}
+			});
+		}
+		if (groupModulesByLayer) {
+			groupConfigs.push({
+				getKeys: (module) => /** @type {string[]} */ ([module.layer]),
+				createGroup: (key, children, modules) => ({
+					type: "modules by layer",
+					layer: key,
+					children,
+					...moduleGroup(
+						/** @type {(KnownStatsModule & ModuleGroupBySizeResult)[]} */
+						(children),
+						modules
+					)
+				})
+			});
+		}
+		if (groupModulesByPath || groupModulesByExtension) {
+			groupConfigs.push({
+				getKeys: (module) => {
+					if (!module.name) return;
+					const resource = parseResource(
+						/** @type {string} */ (module.name.split("!").pop())
+					).path;
+					const dataUrl = /^data:[^,;]+/.exec(resource);
+					if (dataUrl) return [dataUrl[0]];
+					const extensionMatch =
+						groupModulesByExtension && GROUP_EXTENSION_REGEXP.exec(resource);
+					const extension = extensionMatch ? extensionMatch[1] : "";
+					const pathMatch =
+						groupModulesByPath && GROUP_PATH_REGEXP.exec(resource);
+					const path = pathMatch ? pathMatch[1].split(/[/\\]/) : [];
+					/** @type {string[]} */
+					const keys = [];
+					if (groupModulesByPath) {
+						if (extension) {
+							keys.push(
+								path.length
+									? `${path.join("/")}/*${extension}`
+									: `*${extension}`
+							);
+						}
+						while (path.length > 0) {
+							keys.push(`${path.join("/")}/`);
+							path.pop();
+						}
+					} else if (extension) {
+						keys.push(`*${extension}`);
+					}
+					return keys;
+				},
+				createGroup: (key, children, modules) => {
+					const isDataUrl = key.startsWith("data:");
+					return {
+						type: isDataUrl
+							? "modules by mime type"
+							: groupModulesByPath
+								? "modules by path"
+								: "modules by extension",
+						name: isDataUrl ? key.slice(/* 'data:'.length */ 5) : key,
+						children,
+						...moduleGroup(
+							/** @type {(KnownStatsModule & ModuleGroupBySizeResult)[]} */
+							(children),
+							modules
+						)
+					};
+				}
+			});
+		}
+	},
+	excludeModules: (groupConfigs, context, { excludeModules }) => {
+		groupConfigs.push({
+			getKeys: (module) => {
+				const name = module.name;
+				if (name) {
+					const excluded = excludeModules.some((fn) => fn(name, module, type));
+					if (excluded) return ["1"];
+				}
+			},
+			getOptions: () => ({
+				groupChildren: false,
+				force: true
+			}),
+			createGroup: (key, children, modules) => ({
+				type: "hidden modules",
+				filteredChildren: children.length,
+				...moduleGroup(
+					/** @type {(KnownStatsModule & ModuleGroupBySizeResult)[]} */
+					(children),
+					modules
+				)
+			})
+		});
+	}
+});
+
+/**
+ * Defines the module reasons groupers type used by this module.
+ * @typedef {{ groupReasonsByOrigin: (groupConfigs: GroupConfig<KnownStatsModuleReason, BaseGroup & { module: string, children: KnownStatsModuleReason[], active: boolean }>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void }} ModuleReasonsGroupers
+ */
+
+/** @type {ModuleReasonsGroupers} */
+const MODULE_REASONS_GROUPERS = {
+	groupReasonsByOrigin: (groupConfigs) => {
+		groupConfigs.push({
+			getKeys: (reason) => /** @type {string[]} */ ([reason.module]),
+			createGroup: (key, children, reasons) => ({
+				type: "from origin",
+				module: key,
+				children,
+				...reasonGroup(children, reasons)
+			})
+		});
+	}
+};
+
+/**
+ * @type {{
+ * "compilation.assets": AssetsGroupers,
+ * "asset.related": AssetsGroupers,
+ * "compilation.modules": ModulesGroupers,
+ * "chunk.modules": ModulesGroupers,
+ * "chunk.rootModules": ModulesGroupers,
+ * "module.modules": ModulesGroupers,
+ * "module.reasons": ModuleReasonsGroupers,
+ * }}
+ */
+const RESULT_GROUPERS = {
+	"compilation.assets": ASSETS_GROUPERS,
+	"asset.related": ASSETS_GROUPERS,
+	"compilation.modules": MODULES_GROUPERS("module"),
+	"chunk.modules": MODULES_GROUPERS("chunk"),
+	"chunk.rootModules": MODULES_GROUPERS("root-of-chunk"),
+	"module.modules": MODULES_GROUPERS("nested"),
+	"module.reasons": MODULE_REASONS_GROUPERS
+};
+
+// remove a prefixed "!" that can be specified to reverse sort order
+/**
+ * Normalizes field key.
+ * @param {string} field a field name
+ * @returns {field} normalized field
+ */
+const normalizeFieldKey = (field) => {
+	if (field[0] === "!") {
+		return field.slice(1);
+	}
+	return field;
+};
+
+// if a field is prefixed by a "!" reverse sort order
+/**
+ * Sorts order regular.
+ * @param {string} field a field name
+ * @returns {boolean} result
+ */
+const sortOrderRegular = (field) => {
+	if (field[0] === "!") {
+		return false;
+	}
+	return true;
+};
+
+/**
+ * Returns comparators.
+ * @template T
+ * @param {string | false} field field name
+ * @returns {(a: T, b: T) => 0 | 1 | -1} comparators
+ */
+const sortByField = (field) => {
+	if (!field) {
+		/**
+		 * Returns zero.
+		 * @param {T} a first
+		 * @param {T} b second
+		 * @returns {-1 | 0 | 1} zero
+		 */
+		const noSort = (a, b) => 0;
+		return noSort;
+	}
+
+	const fieldKey = normalizeFieldKey(field);
+
+	let sortFn = compareSelect((m) => m[fieldKey], compareIds);
+
+	// if a field is prefixed with a "!" the sort is reversed!
+	const sortIsRegular = sortOrderRegular(field);
+
+	if (!sortIsRegular) {
+		const oldSortFn = sortFn;
+		sortFn = (a, b) => oldSortFn(b, a);
+	}
+
+	return sortFn;
+};
+
+/**
+ * Describes the asset sorters shape.
+ * @typedef {{
+ * assetsSort: (comparators: Comparator<Asset>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * _: (comparators: Comparator<Asset>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void,
+ * }} AssetSorters
+ */
+
+/** @type {AssetSorters} */
+const ASSET_SORTERS = {
+	assetsSort: (comparators, context, { assetsSort }) => {
+		comparators.push(sortByField(assetsSort));
+	},
+	_: (comparators) => {
+		comparators.push(compareSelect((a) => a.name, compareIds));
+	}
+};
+
+/**
+ * @type {{
+ * "compilation.chunks": { chunksSort: (comparators: Comparator<Chunk>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void },
+ * "compilation.modules": { modulesSort: (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void },
+ * "chunk.modules": { chunkModulesSort: (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void },
+ * "module.modules": { nestedModulesSort: (comparators: Comparator<Module>[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void },
+ * "compilation.assets": AssetSorters,
+ * "asset.related": AssetSorters,
+ * }}
+ */
+const RESULT_SORTERS = {
+	"compilation.chunks": {
+		chunksSort: (comparators, context, { chunksSort }) => {
+			comparators.push(sortByField(chunksSort));
+		}
+	},
+	"compilation.modules": {
+		modulesSort: (comparators, context, { modulesSort }) => {
+			comparators.push(sortByField(modulesSort));
+		}
+	},
+	"chunk.modules": {
+		chunkModulesSort: (comparators, context, { chunkModulesSort }) => {
+			comparators.push(sortByField(chunkModulesSort));
+		}
+	},
+	"module.modules": {
+		nestedModulesSort: (comparators, context, { nestedModulesSort }) => {
+			comparators.push(sortByField(nestedModulesSort));
+		}
+	},
+	"compilation.assets": ASSET_SORTERS,
+	"asset.related": ASSET_SORTERS
+};
+
+/**
+ * Defines the extract function type used by this module.
+ * @template T
+ * @typedef {T extends Record<string, Record<string, infer F>> ? F : never} ExtractFunction
+ */
+
+/**
+ * Processes the provided config.
+ * @template {Record<string, Record<string, EXPECTED_ANY>>} T
+ * @param {T} config the config see above
+ * @param {NormalizedStatsOptions} options stats options
+ * @param {(hookFor: keyof T, fn: ExtractFunction<T>) => void} fn handler function called for every active line in config
+ * @returns {void}
+ */
+const iterateConfig = (config, options, fn) => {
+	for (const hookFor of Object.keys(config)) {
+		const subConfig = config[hookFor];
+		for (const option of Object.keys(subConfig)) {
+			if (option !== "_") {
+				if (option.startsWith("!")) {
+					if (options[option.slice(1)]) continue;
+				} else {
+					const value = options[option];
+					if (
+						value === false ||
+						value === undefined ||
+						(Array.isArray(value) && value.length === 0)
+					) {
+						continue;
+					}
+				}
+			}
+			fn(hookFor, subConfig[option]);
+		}
+	}
+};
+
+/** @type {Record<string, string>} */
+const ITEM_NAMES = {
+	"compilation.children[]": "compilation",
+	"compilation.modules[]": "module",
+	"compilation.entrypoints[]": "chunkGroup",
+	"compilation.namedChunkGroups[]": "chunkGroup",
+	"compilation.errors[]": "error",
+	"compilation.warnings[]": "warning",
+	"error.errors[]": "error",
+	"warning.errors[]": "error",
+	"chunk.modules[]": "module",
+	"chunk.rootModules[]": "module",
+	"chunk.origins[]": "chunkOrigin",
+	"compilation.chunks[]": "chunk",
+	"compilation.assets[]": "asset",
+	"asset.related[]": "asset",
+	"module.issuerPath[]": "moduleIssuer",
+	"module.reasons[]": "moduleReason",
+	"module.modules[]": "module",
+	"module.children[]": "module",
+	"moduleTrace[]": "moduleTraceItem",
+	"moduleTraceItem.dependencies[]": "moduleTraceDependency"
+};
+
+/**
+ * Defines the named object type used by this module.
+ * @template T
+ * @typedef {{ name: T }} NamedObject
+ */
+
+/**
+ * Merges the provided values into a single result.
+ * @template {{ name: string }} T
+ * @param {T[]} items items to be merged
+ * @returns {NamedObject<T>} an object
+ */
+const mergeToObject = (items) => {
+	const obj = Object.create(null);
+	for (const item of items) {
+		obj[item.name] = item;
+	}
+	return obj;
+};
+
+/**
+ * @template {{ name: string }} T
+ * @type {Record<string, (items: T[]) => NamedObject<T>>}
+ */
+const MERGER = {
+	"compilation.entrypoints": mergeToObject,
+	"compilation.namedChunkGroups": mergeToObject
+};
+
+const PLUGIN_NAME = "DefaultStatsFactoryPlugin";
+
+class DefaultStatsFactoryPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.statsFactory.tap(
+				PLUGIN_NAME,
+				/**
+				 * Handles the callback logic for this hook.
+				 * @param {StatsFactory} stats stats factory
+				 * @param {NormalizedStatsOptions} options stats options
+				 */
+				(stats, options) => {
+					iterateConfig(SIMPLE_EXTRACTORS, options, (hookFor, fn) => {
+						stats.hooks.extract
+							.for(hookFor)
+							.tap(PLUGIN_NAME, (obj, data, ctx) =>
+								fn(obj, data, ctx, options, stats)
+							);
+					});
+					iterateConfig(FILTER, options, (hookFor, fn) => {
+						stats.hooks.filter
+							.for(hookFor)
+							.tap(PLUGIN_NAME, (item, ctx, idx, i) =>
+								fn(item, ctx, options, idx, i)
+							);
+					});
+					iterateConfig(FILTER_RESULTS, options, (hookFor, fn) => {
+						stats.hooks.filterResults
+							.for(hookFor)
+							.tap(PLUGIN_NAME, (item, ctx, idx, i) =>
+								fn(item, ctx, options, idx, i)
+							);
+					});
+					iterateConfig(SORTERS, options, (hookFor, fn) => {
+						stats.hooks.sort
+							.for(hookFor)
+							.tap(PLUGIN_NAME, (comparators, ctx) =>
+								fn(comparators, ctx, options)
+							);
+					});
+					iterateConfig(RESULT_SORTERS, options, (hookFor, fn) => {
+						stats.hooks.sortResults
+							.for(hookFor)
+							.tap(PLUGIN_NAME, (comparators, ctx) =>
+								fn(comparators, ctx, options)
+							);
+					});
+					iterateConfig(RESULT_GROUPERS, options, (hookFor, fn) => {
+						stats.hooks.groupResults
+							.for(hookFor)
+							.tap(PLUGIN_NAME, (groupConfigs, ctx) =>
+								fn(groupConfigs, ctx, options)
+							);
+					});
+					for (const key of Object.keys(ITEM_NAMES)) {
+						const itemName = ITEM_NAMES[key];
+						stats.hooks.getItemName.for(key).tap(PLUGIN_NAME, () => itemName);
+					}
+					for (const key of Object.keys(MERGER)) {
+						const merger = MERGER[key];
+						stats.hooks.merge.for(key).tap(PLUGIN_NAME, merger);
+					}
+					if (options.children) {
+						if (Array.isArray(options.children)) {
+							stats.hooks.getItemFactory
+								.for("compilation.children[].compilation")
+								.tap(
+									PLUGIN_NAME,
+									/**
+									 * Handles the callback logic for this hook.
+									 * @param {Compilation} comp compilation
+									 * @param {StatsFactoryContext} options options
+									 * @returns {StatsFactory | undefined} stats factory
+									 */
+									(comp, { _index: idx }) => {
+										const children =
+											/** @type {StatsValue[]} */
+											(options.children);
+										if (idx < children.length) {
+											return compilation.createStatsFactory(
+												compilation.createStatsOptions(children[idx])
+											);
+										}
+									}
+								);
+						} else if (options.children !== true) {
+							const childFactory = compilation.createStatsFactory(
+								compilation.createStatsOptions(options.children)
+							);
+							stats.hooks.getItemFactory
+								.for("compilation.children[].compilation")
+								.tap(PLUGIN_NAME, () => childFactory);
+						}
+					}
+				}
+			);
+		});
+	}
+}
+
+module.exports = DefaultStatsFactoryPlugin;
Index: frontend/node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,427 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RequestShortener = require("../RequestShortener");
+
+/** @typedef {import("../../declarations/WebpackOptions").StatsOptions} StatsOptions */
+/** @typedef {import("../../declarations/WebpackOptions").StatsValue} StatsValue */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
+/** @typedef {import("../Compilation").KnownNormalizedStatsOptions} KnownNormalizedStatsOptions */
+/** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */
+
+/**
+ * Processes the provided normalized stats option.
+ * @param {Partial<NormalizedStatsOptions>} options options
+ * @param {StatsOptions} defaults default options
+ */
+const applyDefaults = (options, defaults) => {
+	for (const _k of Object.keys(defaults)) {
+		const key = /** @type {keyof StatsOptions} */ (_k);
+		if (typeof options[key] === "undefined") {
+			options[/** @type {keyof NormalizedStatsOptions} */ (key)] =
+				defaults[key];
+		}
+	}
+};
+
+/** @typedef {{ [Key in Exclude<StatsValue, boolean | StatsOptions | "normal">]: StatsOptions }} NamedPresets */
+
+/** @type {NamedPresets} */
+const NAMED_PRESETS = {
+	verbose: {
+		hash: true,
+		builtAt: true,
+		relatedAssets: true,
+		entrypoints: true,
+		chunkGroups: true,
+		ids: true,
+		modules: false,
+		chunks: true,
+		chunkRelations: true,
+		chunkModules: true,
+		dependentModules: true,
+		chunkOrigins: true,
+		depth: true,
+		env: true,
+		reasons: true,
+		usedExports: true,
+		providedExports: true,
+		optimizationBailout: true,
+		errorDetails: true,
+		errorStack: true,
+		errorCause: true,
+		errorErrors: true,
+		publicPath: true,
+		logging: "verbose",
+		orphanModules: true,
+		runtimeModules: true,
+		exclude: false,
+		errorsSpace: Infinity,
+		warningsSpace: Infinity,
+		modulesSpace: Infinity,
+		chunkModulesSpace: Infinity,
+		assetsSpace: Infinity,
+		reasonsSpace: Infinity,
+		children: true
+	},
+	detailed: {
+		hash: true,
+		builtAt: true,
+		relatedAssets: true,
+		entrypoints: true,
+		chunkGroups: true,
+		ids: true,
+		chunks: true,
+		chunkRelations: true,
+		chunkModules: false,
+		chunkOrigins: true,
+		depth: true,
+		usedExports: true,
+		providedExports: true,
+		optimizationBailout: true,
+		errorDetails: true,
+		errorCause: true,
+		errorErrors: true,
+		publicPath: true,
+		logging: true,
+		runtimeModules: true,
+		exclude: false,
+		errorsSpace: 1000,
+		warningsSpace: 1000,
+		modulesSpace: 1000,
+		assetsSpace: 1000,
+		reasonsSpace: 1000
+	},
+	minimal: {
+		all: false,
+		version: true,
+		timings: true,
+		modules: true,
+		errorsSpace: 0,
+		warningsSpace: 0,
+		modulesSpace: 0,
+		assets: true,
+		assetsSpace: 0,
+		errors: true,
+		errorsCount: true,
+		warnings: true,
+		warningsCount: true,
+		logging: "warn"
+	},
+	"errors-only": {
+		all: false,
+		errors: true,
+		errorsCount: true,
+		errorsSpace: Infinity,
+		moduleTrace: true,
+		logging: "error"
+	},
+	"errors-warnings": {
+		all: false,
+		errors: true,
+		errorsCount: true,
+		errorsSpace: Infinity,
+		warnings: true,
+		warningsCount: true,
+		warningsSpace: Infinity,
+		logging: "warn"
+	},
+	summary: {
+		all: false,
+		version: true,
+		errorsCount: true,
+		warningsCount: true
+	},
+	none: {
+		all: false
+	}
+};
+
+/**
+ * Returns true when enabled, otherwise false.
+ * @param {Partial<NormalizedStatsOptions>} all stats options
+ * @returns {boolean} true when enabled, otherwise false
+ */
+const NORMAL_ON = ({ all }) => all !== false;
+/**
+ * Returns true when enabled, otherwise false.
+ * @param {Partial<NormalizedStatsOptions>} all stats options
+ * @returns {boolean} true when enabled, otherwise false
+ */
+const NORMAL_OFF = ({ all }) => all === true;
+/**
+ * Returns true when enabled, otherwise false.
+ * @param {Partial<NormalizedStatsOptions>} all stats options
+ * @param {CreateStatsOptionsContext} forToString stats options context
+ * @returns {boolean} true when enabled, otherwise false
+ */
+const ON_FOR_TO_STRING = ({ all }, { forToString }) =>
+	forToString ? all !== false : all === true;
+/**
+ * Returns true when enabled, otherwise false.
+ * @param {Partial<NormalizedStatsOptions>} all stats options
+ * @param {CreateStatsOptionsContext} forToString stats options context
+ * @returns {boolean} true when enabled, otherwise false
+ */
+const OFF_FOR_TO_STRING = ({ all }, { forToString }) =>
+	forToString ? all === true : all !== false;
+/**
+ * Auto for to string.
+ * @param {Partial<NormalizedStatsOptions>} all stats options
+ * @param {CreateStatsOptionsContext} forToString stats options context
+ * @returns {boolean | "auto"} true when enabled, otherwise false
+ */
+const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => {
+	if (all === false) return false;
+	if (all === true) return true;
+	if (forToString) return "auto";
+	return true;
+};
+
+/** @typedef {keyof NormalizedStatsOptions} DefaultsKeys */
+/** @typedef {{ [Key in DefaultsKeys]: (options: Partial<NormalizedStatsOptions>, context: CreateStatsOptionsContext, compilation: Compilation) => NormalizedStatsOptions[Key] | RequestShortener }} Defaults */
+
+/** @type {Defaults} */
+const DEFAULTS = {
+	context: (options, context, compilation) => compilation.compiler.context,
+	requestShortener: (options, context, compilation) =>
+		compilation.compiler.context === options.context
+			? compilation.requestShortener
+			: new RequestShortener(
+					/** @type {string} */
+					(options.context),
+					compilation.compiler.root
+				),
+	performance: NORMAL_ON,
+	hash: OFF_FOR_TO_STRING,
+	env: NORMAL_OFF,
+	version: NORMAL_ON,
+	timings: NORMAL_ON,
+	builtAt: OFF_FOR_TO_STRING,
+	assets: NORMAL_ON,
+	entrypoints: AUTO_FOR_TO_STRING,
+	chunkGroups: OFF_FOR_TO_STRING,
+	chunkGroupAuxiliary: OFF_FOR_TO_STRING,
+	chunkGroupChildren: OFF_FOR_TO_STRING,
+	chunkGroupMaxAssets: (o, { forToString }) => (forToString ? 5 : Infinity),
+	chunks: OFF_FOR_TO_STRING,
+	chunkRelations: OFF_FOR_TO_STRING,
+	chunkModules: ({ all, modules }) => {
+		if (all === false) return false;
+		if (all === true) return true;
+		if (modules) return false;
+		return true;
+	},
+	dependentModules: OFF_FOR_TO_STRING,
+	chunkOrigins: OFF_FOR_TO_STRING,
+	ids: OFF_FOR_TO_STRING,
+	modules: ({ all, chunks, chunkModules }, { forToString }) => {
+		if (all === false) return false;
+		if (all === true) return true;
+		if (forToString && chunks && chunkModules) return false;
+		return true;
+	},
+	nestedModules: OFF_FOR_TO_STRING,
+	groupModulesByType: ON_FOR_TO_STRING,
+	groupModulesByCacheStatus: ON_FOR_TO_STRING,
+	groupModulesByLayer: ON_FOR_TO_STRING,
+	groupModulesByAttributes: ON_FOR_TO_STRING,
+	groupModulesByPath: ON_FOR_TO_STRING,
+	groupModulesByExtension: ON_FOR_TO_STRING,
+	modulesSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
+	chunkModulesSpace: (o, { forToString }) => (forToString ? 10 : Infinity),
+	nestedModulesSpace: (o, { forToString }) => (forToString ? 10 : Infinity),
+	relatedAssets: OFF_FOR_TO_STRING,
+	groupAssetsByEmitStatus: ON_FOR_TO_STRING,
+	groupAssetsByInfo: ON_FOR_TO_STRING,
+	groupAssetsByPath: ON_FOR_TO_STRING,
+	groupAssetsByExtension: ON_FOR_TO_STRING,
+	groupAssetsByChunk: ON_FOR_TO_STRING,
+	assetsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
+	orphanModules: OFF_FOR_TO_STRING,
+	runtimeModules: ({ all, runtime }, { forToString }) =>
+		runtime !== undefined
+			? runtime
+			: forToString
+				? all === true
+				: all !== false,
+	cachedModules: ({ all, cached }, { forToString }) =>
+		cached !== undefined ? cached : forToString ? all === true : all !== false,
+	moduleAssets: OFF_FOR_TO_STRING,
+	depth: OFF_FOR_TO_STRING,
+	cachedAssets: OFF_FOR_TO_STRING,
+	reasons: OFF_FOR_TO_STRING,
+	reasonsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
+	groupReasonsByOrigin: ON_FOR_TO_STRING,
+	usedExports: OFF_FOR_TO_STRING,
+	providedExports: OFF_FOR_TO_STRING,
+	optimizationBailout: OFF_FOR_TO_STRING,
+	children: OFF_FOR_TO_STRING,
+	source: NORMAL_OFF,
+	moduleTrace: NORMAL_ON,
+	errors: NORMAL_ON,
+	errorsCount: NORMAL_ON,
+	errorDetails: AUTO_FOR_TO_STRING,
+	errorStack: OFF_FOR_TO_STRING,
+	errorCause: AUTO_FOR_TO_STRING,
+	errorErrors: AUTO_FOR_TO_STRING,
+	warnings: NORMAL_ON,
+	warningsCount: NORMAL_ON,
+	publicPath: OFF_FOR_TO_STRING,
+	logging: ({ all }, { forToString }) =>
+		forToString && all !== false ? "info" : false,
+	loggingDebug: () => [],
+	loggingTrace: OFF_FOR_TO_STRING,
+	excludeModules: () => [],
+	excludeAssets: () => [],
+	modulesSort: () => "depth",
+	chunkModulesSort: () => "name",
+	nestedModulesSort: () => false,
+	chunksSort: () => false,
+	assetsSort: () => "!size",
+	outputPath: OFF_FOR_TO_STRING,
+	colors: () => false
+};
+
+/**
+ * Defines the normalize function type used by this module.
+ * @template T
+ * @typedef {(value: T, ...args: EXPECTED_ANY[]) => boolean} NormalizeFunction
+ */
+
+/**
+ * Returns normalize fn.
+ * @template {string} T
+ * @param {string | ({ test: (value: T) => boolean }) | NormalizeFunction<T> | boolean} item item to normalize
+ * @returns {NormalizeFunction<T>} normalize fn
+ */
+const normalizeFilter = (item) => {
+	if (typeof item === "string") {
+		const regExp = new RegExp(
+			`[\\\\/]${item.replace(/[-[\]{}()*+?.\\^$|]/g, "\\$&")}([\\\\/]|$|!|\\?)`
+		);
+		return (ident) => regExp.test(/** @type {T} */ (ident));
+	}
+	if (item && typeof item === "object" && typeof item.test === "function") {
+		return (ident) => item.test(ident);
+	}
+	if (typeof item === "boolean") {
+		return () => item;
+	}
+
+	return /** @type {NormalizeFunction<T>} */ (item);
+};
+
+/** @typedef {keyof (KnownNormalizedStatsOptions | StatsOptions)} NormalizerKeys */
+/** @typedef {{ [Key in NormalizerKeys]?: (value: StatsOptions[Key]) => KnownNormalizedStatsOptions[Key] }} Normalizers */
+
+/**
+ * Defines the warning filter fn callback.
+ * @callback WarningFilterFn
+ * @param {StatsError} warning warning
+ * @param {string} warningString warning string
+ * @returns {boolean} result
+ */
+
+/** @type {Normalizers} */
+const NORMALIZER = {
+	excludeModules: (value) => {
+		if (!Array.isArray(value)) {
+			value = value
+				? /** @type {KnownNormalizedStatsOptions["excludeModules"]} */ ([value])
+				: [];
+		}
+		return value.map(normalizeFilter);
+	},
+	excludeAssets: (value) => {
+		if (!Array.isArray(value)) {
+			value = value ? [value] : [];
+		}
+		return value.map(normalizeFilter);
+	},
+	warningsFilter: (value) => {
+		if (!Array.isArray(value)) {
+			value = value ? [value] : [];
+		}
+		return value.map(
+			/**
+			 * Handles the warnings filter callback for this hook.
+			 * @param {StatsOptions["warningsFilter"]} filter a warning filter
+			 * @returns {WarningFilterFn} result
+			 */
+			(filter) => {
+				if (typeof filter === "string") {
+					return (warning, warningString) => warningString.includes(filter);
+				}
+				if (filter instanceof RegExp) {
+					return (warning, warningString) => filter.test(warningString);
+				}
+				if (typeof filter === "function") {
+					return filter;
+				}
+				throw new Error(
+					`Can only filter warnings with Strings or RegExps. (Given: ${filter})`
+				);
+			}
+		);
+	},
+	logging: (value) => {
+		if (value === true) value = "log";
+		return /** @type {KnownNormalizedStatsOptions["logging"]} */ (value);
+	},
+	loggingDebug: (value) => {
+		if (!Array.isArray(value)) {
+			value = value
+				? /** @type {KnownNormalizedStatsOptions["loggingDebug"]} */ ([value])
+				: [];
+		}
+		return value.map(normalizeFilter);
+	}
+};
+
+const PLUGIN_NAME = "DefaultStatsPresetPlugin";
+
+class DefaultStatsPresetPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			for (const key of Object.keys(NAMED_PRESETS)) {
+				const defaults = NAMED_PRESETS[/** @type {keyof NamedPresets} */ (key)];
+				compilation.hooks.statsPreset
+					.for(key)
+					.tap(PLUGIN_NAME, (options, _context) => {
+						applyDefaults(options, defaults);
+					});
+			}
+			compilation.hooks.statsNormalize.tap(PLUGIN_NAME, (options, context) => {
+				for (const key of Object.keys(DEFAULTS)) {
+					if (options[key] === undefined) {
+						options[key] = DEFAULTS[/** @type {DefaultsKeys} */ (key)](
+							options,
+							context,
+							compilation
+						);
+					}
+				}
+				for (const key of Object.keys(NORMALIZER)) {
+					options[key] =
+						/** @type {NonNullable<Normalizers[keyof Normalizers]>} */
+						(NORMALIZER[/** @type {NormalizerKeys} */ (key)])(options[key]);
+				}
+			});
+		});
+	}
+}
+
+module.exports = DefaultStatsPresetPlugin;
Index: frontend/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1896 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../logging/Logger").LogTypeEnum} LogTypeEnum */
+/** @typedef {import("./DefaultStatsFactoryPlugin").ChunkId} ChunkId */
+/** @typedef {import("./DefaultStatsFactoryPlugin").ChunkName} ChunkName */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsAsset} KnownStatsAsset */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunk} KnownStatsChunk */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunkGroup} KnownStatsChunkGroup */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunkOrigin} KnownStatsChunkOrigin */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsCompilation} KnownStatsCompilation */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsError} KnownStatsError */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsLogging} KnownStatsLogging */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsLoggingEntry} KnownStatsLoggingEntry */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModule} KnownStatsModule */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleIssuer} KnownStatsModuleIssuer */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleReason} KnownStatsModuleReason */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleTraceDependency} KnownStatsModuleTraceDependency */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsModuleTraceItem} KnownStatsModuleTraceItem */
+/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsProfile} KnownStatsProfile */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
+/** @typedef {import("./StatsPrinter")} StatsPrinter */
+/** @typedef {import("./StatsPrinter").ColorFunction} ColorFunction */
+/** @typedef {import("./StatsPrinter").KnownStatsPrinterColorFunctions} KnownStatsPrinterColorFunctions */
+/** @typedef {import("./StatsPrinter").KnownStatsPrinterContext} KnownStatsPrinterContext */
+/** @typedef {import("./StatsPrinter").KnownStatsPrinterFormatters} KnownStatsPrinterFormatters */
+/** @typedef {import("./StatsPrinter").StatsPrinterContext} StatsPrinterContext */
+/** @typedef {import("./StatsPrinter").StatsPrinterContextWithExtra} StatsPrinterContextWithExtra */
+
+const DATA_URI_CONTENT_LENGTH = 16;
+const MAX_MODULE_IDENTIFIER_LENGTH = 80;
+
+/**
+ * Returns if n is 1, singular, else plural.
+ * @param {number} n a number
+ * @param {string} singular singular
+ * @param {string} plural plural
+ * @returns {string} if n is 1, singular, else plural
+ */
+const plural = (n, singular, plural) => (n === 1 ? singular : plural);
+
+/**
+ * Returns text.
+ * @param {Record<string, number>} sizes sizes by source type
+ * @param {StatsPrinterContext} options options
+ * @returns {string | undefined} text
+ */
+const printSizes = (sizes, { formatSize = (n) => `${n}` }) => {
+	const keys = Object.keys(sizes);
+	if (keys.length > 1) {
+		return keys.map((key) => `${formatSize(sizes[key])} (${key})`).join(" ");
+	} else if (keys.length === 1) {
+		return formatSize(sizes[keys[0]]);
+	}
+};
+
+/**
+ * Gets resource name.
+ * @param {string | null} resource resource
+ * @returns {string} resource name for display
+ */
+const getResourceName = (resource) => {
+	if (!resource) return "";
+	const dataUrl = /^data:[^,]+,/.exec(resource);
+	if (!dataUrl) return resource;
+
+	const len = dataUrl[0].length + DATA_URI_CONTENT_LENGTH;
+	if (resource.length < len) return resource;
+	return `${resource.slice(
+		0,
+		Math.min(resource.length - /* '..'.length */ 2, len)
+	)}..`;
+};
+
+/**
+ * Returns prefix and module name.
+ * @param {string} name module name
+ * @returns {[string, string]} prefix and module name
+ */
+const getModuleName = (name) => {
+	const [, prefix, resource] =
+		/** @type {[string, string, string]} */
+		(/** @type {unknown} */ (/^(.*!)?([^!]*)$/.exec(name)));
+
+	if (resource.length > MAX_MODULE_IDENTIFIER_LENGTH) {
+		const truncatedResource = `${resource.slice(
+			0,
+			Math.min(
+				resource.length - /* '...(truncated)'.length */ 14,
+				MAX_MODULE_IDENTIFIER_LENGTH
+			)
+		)}...(truncated)`;
+
+		return [prefix, getResourceName(truncatedResource)];
+	}
+
+	return [prefix, getResourceName(resource)];
+};
+
+/**
+ * Returns joined string.
+ * @param {string} str string
+ * @param {(item: string) => string} fn function to apply to each line
+ * @returns {string} joined string
+ */
+const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
+
+/**
+ * Returns number as two digit string, leading 0.
+ * @param {number} n a number
+ * @returns {string} number as two digit string, leading 0
+ */
+const twoDigit = (n) => (n >= 10 ? `${n}` : `0${n}`);
+
+/**
+ * Checks whether this object is valid id.
+ * @param {string | number | null} id an id
+ * @returns {id is string | number} is i
+ */
+const isValidId = (id) => {
+	if (typeof id === "number" || id) {
+		return true;
+	}
+
+	return false;
+};
+
+/**
+ * Returns string representation of list.
+ * @template T
+ * @param {T[] | undefined} list of items
+ * @param {number} count number of items to show
+ * @returns {string} string representation of list
+ */
+const moreCount = (list, count) =>
+	list && list.length > 0 ? `+ ${count}` : `${count}`;
+
+/**
+ * Defines the with required type used by this module.
+ * @template T
+ * @template {keyof T} K
+ * @typedef {{ [P in K]-?: T[P] }} WithRequired
+ */
+
+/**
+ * Defines the define stats printer context type used by this module.
+ * @template {keyof StatsPrinterContext} RequiredStatsPrinterContextKeys
+ * @typedef {StatsPrinterContextWithExtra & WithRequired<StatsPrinterContext, "compilation" | RequiredStatsPrinterContextKeys>} DefineStatsPrinterContext
+ */
+
+/**
+ * Defines the simple printer type used by this module.
+ * @template T
+ * @template {keyof StatsPrinterContext} RequiredStatsPrinterContextKeys
+ * @typedef {(thing: Exclude<T, undefined>, context: DefineStatsPrinterContext<RequiredStatsPrinterContextKeys>, printer: StatsPrinter) => string | undefined} SimplePrinter
+ */
+
+/**
+ * Defines the unpacked type used by this module.
+ * @template T
+ * @typedef {T extends (infer U)[] ? U : T} Unpacked
+ */
+
+/**
+ * Defines the property name type used by this module.
+ * @template {object} O
+ * @template {keyof O} K
+ * @template {string} B
+ * @typedef {K extends string ? `${B}.${K}` : never} PropertyName
+ */
+
+/**
+ * Defines the array property name type used by this module.
+ * @template {object} O
+ * @template {keyof O} K
+ * @template {string} B
+ * @typedef {K extends string ? `${B}.${K}[]` : never} ArrayPropertyName
+ */
+
+/**
+ * Defines the exclamation type used by this module.
+ * @template {object} O
+ * @template {string} K
+ * @template {string} E
+ * @typedef {{ [property in `${K}!`]?: SimplePrinter<O, "compilation" | E> }} Exclamation
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @template {object} O
+ * @template {string} B
+ * @template {string} [R=B]
+ * @typedef {{ [K in keyof O as PropertyName<O, K, B>]?: SimplePrinter<O[K], R> } &
+ * { [K in keyof O as ArrayPropertyName<O, K, B>]?: Exclude<O[K], undefined> extends (infer I)[] ? SimplePrinter<I, R> : never }} Printers
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Printers<KnownStatsCompilation, "compilation"> &
+ * { ["compilation.summary!"]?: SimplePrinter<KnownStatsCompilation, "compilation"> } &
+ * { ["compilation.errorsInChildren!"]?: SimplePrinter<KnownStatsCompilation, "compilation"> } &
+ * { ["compilation.warningsInChildren!"]?: SimplePrinter<KnownStatsCompilation, "compilation"> }} CompilationSimplePrinters
+ */
+
+/**
+ * @type {CompilationSimplePrinters}
+ */
+const COMPILATION_SIMPLE_PRINTERS = {
+	"compilation.summary!": (
+		_,
+		{
+			type,
+			bold,
+			green,
+			red,
+			yellow,
+			formatDateTime,
+			formatTime,
+			compilation: {
+				name,
+				hash,
+				version,
+				time,
+				builtAt,
+				errorsCount,
+				warningsCount
+			}
+		}
+	) => {
+		const root = type === "compilation.summary!";
+		const warningsMessage =
+			/** @type {number} */ (warningsCount) > 0
+				? yellow(
+						`${warningsCount} ${plural(/** @type {number} */ (warningsCount), "warning", "warnings")}`
+					)
+				: "";
+		const errorsMessage =
+			/** @type {number} */ (errorsCount) > 0
+				? red(
+						`${errorsCount} ${plural(/** @type {number} */ (errorsCount), "error", "errors")}`
+					)
+				: "";
+		const timeMessage = root && time ? ` in ${formatTime(time)}` : "";
+		const hashMessage = hash ? ` (${hash})` : "";
+		const builtAtMessage =
+			root && builtAt ? `${formatDateTime(builtAt)}: ` : "";
+		const versionMessage = root && version ? `webpack ${version}` : "";
+		const nameMessage =
+			root && name
+				? bold(name)
+				: name
+					? `Child ${bold(name)}`
+					: root
+						? ""
+						: "Child";
+		const subjectMessage =
+			nameMessage && versionMessage
+				? `${nameMessage} (${versionMessage})`
+				: versionMessage || nameMessage || "webpack";
+		/** @type {string} */
+		let statusMessage;
+		if (errorsMessage && warningsMessage) {
+			statusMessage = `compiled with ${errorsMessage} and ${warningsMessage}`;
+		} else if (errorsMessage) {
+			statusMessage = `compiled with ${errorsMessage}`;
+		} else if (warningsMessage) {
+			statusMessage = `compiled with ${warningsMessage}`;
+		} else if (errorsCount === 0 && warningsCount === 0) {
+			statusMessage = `compiled ${green("successfully")}`;
+		} else {
+			statusMessage = "compiled";
+		}
+		if (
+			builtAtMessage ||
+			versionMessage ||
+			errorsMessage ||
+			warningsMessage ||
+			(errorsCount === 0 && warningsCount === 0) ||
+			timeMessage ||
+			hashMessage
+		) {
+			return `${builtAtMessage}${subjectMessage} ${statusMessage}${timeMessage}${hashMessage}`;
+		}
+	},
+	"compilation.filteredWarningDetailsCount": (count) =>
+		count
+			? `${count} ${plural(
+					count,
+					"warning has",
+					"warnings have"
+				)} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
+			: undefined,
+	"compilation.filteredErrorDetailsCount": (count, { yellow }) =>
+		count
+			? yellow(
+					`${count} ${plural(
+						count,
+						"error has",
+						"errors have"
+					)} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
+				)
+			: undefined,
+	"compilation.env": (env, { bold }) =>
+		env
+			? `Environment (--env): ${bold(JSON.stringify(env, null, 2))}`
+			: undefined,
+	"compilation.publicPath": (publicPath, { bold }) =>
+		`PublicPath: ${bold(publicPath || "(none)")}`,
+	"compilation.entrypoints": (entrypoints, context, printer) =>
+		Array.isArray(entrypoints)
+			? undefined
+			: printer.print(context.type, Object.values(entrypoints), {
+					...context,
+					chunkGroupKind: "Entrypoint"
+				}),
+	"compilation.namedChunkGroups": (namedChunkGroups, context, printer) => {
+		if (!Array.isArray(namedChunkGroups)) {
+			const {
+				compilation: { entrypoints }
+			} = context;
+			let chunkGroups = Object.values(namedChunkGroups);
+			if (entrypoints) {
+				chunkGroups = chunkGroups.filter(
+					(group) =>
+						!Object.prototype.hasOwnProperty.call(
+							entrypoints,
+							/** @type {string} */
+							(group.name)
+						)
+				);
+			}
+			return printer.print(context.type, chunkGroups, {
+				...context,
+				chunkGroupKind: "Chunk Group"
+			});
+		}
+	},
+	"compilation.assetsByChunkName": () => "",
+
+	"compilation.filteredModules": (
+		filteredModules,
+		{ compilation: { modules } }
+	) =>
+		filteredModules > 0
+			? `${moreCount(modules, filteredModules)} ${plural(
+					filteredModules,
+					"module",
+					"modules"
+				)}`
+			: undefined,
+	"compilation.filteredAssets": (
+		filteredAssets,
+		{ compilation: { assets } }
+	) =>
+		filteredAssets > 0
+			? `${moreCount(assets, filteredAssets)} ${plural(
+					filteredAssets,
+					"asset",
+					"assets"
+				)}`
+			: undefined,
+	"compilation.logging": (logging, context, printer) =>
+		Array.isArray(logging)
+			? undefined
+			: printer.print(
+					context.type,
+					Object.entries(logging).map(([name, value]) => ({ ...value, name })),
+					context
+				),
+	"compilation.warningsInChildren!": (_, { yellow, compilation }) => {
+		if (
+			!compilation.children &&
+			/** @type {number} */ (compilation.warningsCount) > 0 &&
+			compilation.warnings
+		) {
+			const childWarnings =
+				/** @type {number} */ (compilation.warningsCount) -
+				compilation.warnings.length;
+			if (childWarnings > 0) {
+				return yellow(
+					`${childWarnings} ${plural(
+						childWarnings,
+						"WARNING",
+						"WARNINGS"
+					)} in child compilations${
+						compilation.children
+							? ""
+							: " (Use 'stats.children: true' resp. '--stats-children' for more details)"
+					}`
+				);
+			}
+		}
+	},
+	"compilation.errorsInChildren!": (_, { red, compilation }) => {
+		if (
+			!compilation.children &&
+			/** @type {number} */ (compilation.errorsCount) > 0 &&
+			compilation.errors
+		) {
+			const childErrors =
+				/** @type {number} */ (compilation.errorsCount) -
+				compilation.errors.length;
+			if (childErrors > 0) {
+				return red(
+					`${childErrors} ${plural(
+						childErrors,
+						"ERROR",
+						"ERRORS"
+					)} in child compilations${
+						compilation.children
+							? ""
+							: " (Use 'stats.children: true' resp. '--stats-children' for more details)"
+					}`
+				);
+			}
+		}
+	}
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Printers<KnownStatsAsset, "asset"> &
+ * Printers<KnownStatsAsset["info"], "asset.info"> &
+ * Exclamation<KnownStatsAsset, "asset.separator", "asset"> &
+ * { ["asset.filteredChildren"]?: SimplePrinter<number, "asset"> } &
+ * { assetChunk?: SimplePrinter<ChunkId, "asset"> } &
+ * { assetChunkName?: SimplePrinter<ChunkName, "asset"> } &
+ * { assetChunkIdHint?: SimplePrinter<string, "asset"> }} AssetSimplePrinters
+ */
+
+/** @type {AssetSimplePrinters} */
+const ASSET_SIMPLE_PRINTERS = {
+	"asset.type": (type) => type,
+	"asset.name": (name, { formatFilename, asset: { isOverSizeLimit } }) =>
+		formatFilename(name, isOverSizeLimit),
+	"asset.size": (size, { asset: { isOverSizeLimit }, yellow, formatSize }) =>
+		isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size),
+	"asset.emitted": (emitted, { green, formatFlag }) =>
+		emitted ? green(formatFlag("emitted")) : undefined,
+	"asset.comparedForEmit": (comparedForEmit, { yellow, formatFlag }) =>
+		comparedForEmit ? yellow(formatFlag("compared for emit")) : undefined,
+	"asset.cached": (cached, { green, formatFlag }) =>
+		cached ? green(formatFlag("cached")) : undefined,
+	"asset.isOverSizeLimit": (isOverSizeLimit, { yellow, formatFlag }) =>
+		isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
+
+	"asset.info.immutable": (immutable, { green, formatFlag }) =>
+		immutable ? green(formatFlag("immutable")) : undefined,
+	"asset.info.javascriptModule": (javascriptModule, { formatFlag }) =>
+		javascriptModule ? formatFlag("javascript module") : undefined,
+	"asset.info.sourceFilename": (sourceFilename, { formatFlag }) =>
+		sourceFilename ? formatFlag(`from: ${sourceFilename}`) : undefined,
+	"asset.info.development": (development, { green, formatFlag }) =>
+		development ? green(formatFlag("dev")) : undefined,
+	"asset.info.hotModuleReplacement": (
+		hotModuleReplacement,
+		{ green, formatFlag }
+	) => (hotModuleReplacement ? green(formatFlag("hmr")) : undefined),
+	"asset.separator!": () => "\n",
+	"asset.filteredRelated": (filteredRelated, { asset: { related } }) =>
+		filteredRelated > 0
+			? `${moreCount(related, filteredRelated)} related ${plural(
+					filteredRelated,
+					"asset",
+					"assets"
+				)}`
+			: undefined,
+	"asset.filteredChildren": (filteredChildren, { asset: { children } }) =>
+		filteredChildren > 0
+			? `${moreCount(children, filteredChildren)} ${plural(
+					filteredChildren,
+					"asset",
+					"assets"
+				)}`
+			: undefined,
+
+	assetChunk: (id, { formatChunkId }) => formatChunkId(id),
+	assetChunkName: (name) => name || undefined,
+	assetChunkIdHint: (name) => name || undefined
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Printers<KnownStatsModule, "module"> &
+ * Exclamation<KnownStatsModule, "module.separator", "module"> &
+ * { ["module.filteredChildren"]?: SimplePrinter<number, "module"> } &
+ * { ["module.filteredReasons"]?: SimplePrinter<number, "module"> }} ModuleSimplePrinters
+ */
+
+/** @type {ModuleSimplePrinters} */
+const MODULE_SIMPLE_PRINTERS = {
+	"module.type": (type) => (type !== "module" ? type : undefined),
+	"module.id": (id, { formatModuleId }) =>
+		isValidId(id) ? formatModuleId(id) : undefined,
+	"module.name": (name, { bold }) => {
+		const [prefix, resource] = getModuleName(name);
+		return `${prefix || ""}${bold(resource || "")}`;
+	},
+	"module.identifier": (_identifier) => undefined,
+	"module.layer": (layer, { formatLayer }) =>
+		layer ? formatLayer(layer) : undefined,
+	"module.sizes": printSizes,
+	"module.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
+	"module.depth": (depth, { formatFlag }) =>
+		depth !== null ? formatFlag(`depth ${depth}`) : undefined,
+	"module.cacheable": (cacheable, { formatFlag, red }) =>
+		cacheable === false ? red(formatFlag("not cacheable")) : undefined,
+	"module.orphan": (orphan, { formatFlag, yellow }) =>
+		orphan ? yellow(formatFlag("orphan")) : undefined,
+	// "module.runtime": (runtime, { formatFlag, yellow }) =>
+	// 	runtime ? yellow(formatFlag("runtime")) : undefined,
+	"module.optional": (optional, { formatFlag, yellow }) =>
+		optional ? yellow(formatFlag("optional")) : undefined,
+	"module.dependent": (dependent, { formatFlag, cyan }) =>
+		dependent ? cyan(formatFlag("dependent")) : undefined,
+	"module.built": (built, { formatFlag, yellow }) =>
+		built ? yellow(formatFlag("built")) : undefined,
+	"module.codeGenerated": (codeGenerated, { formatFlag, yellow }) =>
+		codeGenerated ? yellow(formatFlag("code generated")) : undefined,
+	"module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) =>
+		buildTimeExecuted ? green(formatFlag("build time executed")) : undefined,
+	"module.cached": (cached, { formatFlag, green }) =>
+		cached ? green(formatFlag("cached")) : undefined,
+	"module.assets": (assets, { formatFlag, magenta }) =>
+		assets && assets.length
+			? magenta(
+					formatFlag(
+						`${assets.length} ${plural(assets.length, "asset", "assets")}`
+					)
+				)
+			: undefined,
+	"module.warnings": (warnings, { formatFlag, yellow }) =>
+		warnings
+			? yellow(
+					formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`)
+				)
+			: undefined,
+	"module.errors": (errors, { formatFlag, red }) =>
+		errors
+			? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`))
+			: undefined,
+	"module.providedExports": (providedExports, { formatFlag, cyan }) => {
+		if (Array.isArray(providedExports)) {
+			if (providedExports.length === 0) return cyan(formatFlag("no exports"));
+			return cyan(formatFlag(`exports: ${providedExports.join(", ")}`));
+		}
+	},
+	"module.usedExports": (usedExports, { formatFlag, cyan, module }) => {
+		if (usedExports !== true) {
+			if (usedExports === null) return cyan(formatFlag("used exports unknown"));
+			if (usedExports === false) return cyan(formatFlag("module unused"));
+			if (Array.isArray(usedExports)) {
+				if (usedExports.length === 0) {
+					return cyan(formatFlag("no exports used"));
+				}
+				const providedExportsCount = Array.isArray(module.providedExports)
+					? module.providedExports.length
+					: null;
+				if (
+					providedExportsCount !== null &&
+					providedExportsCount === usedExports.length
+				) {
+					return cyan(formatFlag("all exports used"));
+				}
+
+				return cyan(
+					formatFlag(`only some exports used: ${usedExports.join(", ")}`)
+				);
+			}
+		}
+	},
+	"module.optimizationBailout[]": (optimizationBailout, { yellow }) =>
+		yellow(optimizationBailout),
+	"module.issuerPath": (issuerPath, { module }) =>
+		module.profile ? undefined : "",
+	"module.profile": (_profile) => undefined,
+	"module.filteredModules": (filteredModules, { module: { modules } }) =>
+		filteredModules > 0
+			? `${moreCount(modules, filteredModules)} nested ${plural(
+					filteredModules,
+					"module",
+					"modules"
+				)}`
+			: undefined,
+	"module.filteredReasons": (filteredReasons, { module: { reasons } }) =>
+		filteredReasons > 0
+			? `${moreCount(reasons, filteredReasons)} ${plural(
+					filteredReasons,
+					"reason",
+					"reasons"
+				)}`
+			: undefined,
+	"module.filteredChildren": (filteredChildren, { module: { children } }) =>
+		filteredChildren > 0
+			? `${moreCount(children, filteredChildren)} ${plural(
+					filteredChildren,
+					"module",
+					"modules"
+				)}`
+			: undefined,
+	"module.separator!": () => "\n"
+};
+
+/**
+ * Defines the module issuer printers type used by this module.
+ * @typedef {Printers<KnownStatsModuleIssuer, "moduleIssuer"> & Printers<KnownStatsModuleIssuer["profile"], "moduleIssuer.profile", "moduleIssuer">} ModuleIssuerPrinters
+ */
+
+/** @type {ModuleIssuerPrinters} */
+const MODULE_ISSUER_PRINTERS = {
+	"moduleIssuer.id": (id, { formatModuleId }) => formatModuleId(id),
+	"moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value)
+};
+
+/**
+ * Defines the module reasons printers type used by this module.
+ * @typedef {Printers<KnownStatsModuleReason, "moduleReason"> & { ["moduleReason.filteredChildren"]?: SimplePrinter<number, "moduleReason"> }} ModuleReasonsPrinters
+ */
+
+/** @type {ModuleReasonsPrinters} */
+const MODULE_REASON_PRINTERS = {
+	"moduleReason.type": (type) => type || undefined,
+	"moduleReason.userRequest": (userRequest, { cyan }) =>
+		cyan(getResourceName(userRequest)),
+	"moduleReason.moduleId": (moduleId, { formatModuleId }) =>
+		isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
+	"moduleReason.module": (module, { magenta }) =>
+		module ? magenta(module) : undefined,
+	"moduleReason.loc": (loc) => loc || undefined,
+	"moduleReason.explanation": (explanation, { cyan }) =>
+		explanation ? cyan(explanation) : undefined,
+	"moduleReason.active": (active, { formatFlag }) =>
+		active ? undefined : formatFlag("inactive"),
+	"moduleReason.resolvedModule": (module, { magenta }) =>
+		module ? magenta(module) : undefined,
+	"moduleReason.filteredChildren": (
+		filteredChildren,
+		{ moduleReason: { children } }
+	) =>
+		filteredChildren > 0
+			? `${moreCount(children, filteredChildren)} ${plural(
+					filteredChildren,
+					"reason",
+					"reasons"
+				)}`
+			: undefined
+};
+
+/** @typedef {Printers<KnownStatsProfile, "module.profile", "profile">} ModuleProfilePrinters */
+
+/** @type {ModuleProfilePrinters} */
+const MODULE_PROFILE_PRINTERS = {
+	"module.profile.total": (value, { formatTime }) => formatTime(value),
+	"module.profile.resolving": (value, { formatTime }) =>
+		`resolving: ${formatTime(value)}`,
+	"module.profile.restoring": (value, { formatTime }) =>
+		`restoring: ${formatTime(value)}`,
+	"module.profile.integration": (value, { formatTime }) =>
+		`integration: ${formatTime(value)}`,
+	"module.profile.building": (value, { formatTime }) =>
+		`building: ${formatTime(value)}`,
+	"module.profile.storing": (value, { formatTime }) =>
+		`storing: ${formatTime(value)}`,
+	"module.profile.additionalResolving": (value, { formatTime }) =>
+		value ? `additional resolving: ${formatTime(value)}` : undefined,
+	"module.profile.additionalIntegration": (value, { formatTime }) =>
+		value ? `additional integration: ${formatTime(value)}` : undefined
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Exclamation<KnownStatsChunkGroup, "chunkGroup.kind", "chunkGroupKind"> &
+ * Exclamation<KnownStatsChunkGroup, "chunkGroup.separator", "chunkGroup"> &
+ * Printers<KnownStatsChunkGroup, "chunkGroup"> &
+ * Exclamation<KnownStatsChunkGroup, "chunkGroup.is", "chunkGroup"> &
+ * Printers<Exclude<KnownStatsChunkGroup["assets"], undefined>[number], "chunkGroupAsset" | "chunkGroup"> &
+ * { ['chunkGroupChildGroup.type']?: SimplePrinter<string, "chunkGroupAsset"> } &
+ * { ['chunkGroupChild.assets[]']?: SimplePrinter<string, "chunkGroupAsset"> } &
+ * { ['chunkGroupChild.chunks[]']?: SimplePrinter<ChunkId, "chunkGroupAsset"> } &
+ * { ['chunkGroupChild.name']?: SimplePrinter<ChunkName, "chunkGroupAsset"> }} ChunkGroupPrinters
+ */
+
+/** @type {ChunkGroupPrinters} */
+const CHUNK_GROUP_PRINTERS = {
+	"chunkGroup.kind!": (_, { chunkGroupKind }) => chunkGroupKind,
+	"chunkGroup.separator!": () => "\n",
+	"chunkGroup.name": (name, { bold }) => (name ? bold(name) : undefined),
+	"chunkGroup.isOverSizeLimit": (isOverSizeLimit, { formatFlag, yellow }) =>
+		isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
+	"chunkGroup.assetsSize": (size, { formatSize }) =>
+		size ? formatSize(size) : undefined,
+	"chunkGroup.auxiliaryAssetsSize": (size, { formatSize }) =>
+		size ? `(${formatSize(size)})` : undefined,
+	"chunkGroup.filteredAssets": (n, { chunkGroup: { assets } }) =>
+		n > 0
+			? `${moreCount(assets, n)} ${plural(n, "asset", "assets")}`
+			: undefined,
+	"chunkGroup.filteredAuxiliaryAssets": (
+		n,
+		{ chunkGroup: { auxiliaryAssets } }
+	) =>
+		n > 0
+			? `${moreCount(auxiliaryAssets, n)} auxiliary ${plural(
+					n,
+					"asset",
+					"assets"
+				)}`
+			: undefined,
+	"chunkGroup.is!": () => "=",
+	"chunkGroupAsset.name": (asset, { green }) => green(asset),
+	"chunkGroupAsset.size": (size, { formatSize, chunkGroup }) =>
+		chunkGroup.assets &&
+		(chunkGroup.assets.length > 1 ||
+		(chunkGroup.auxiliaryAssets && chunkGroup.auxiliaryAssets.length > 0)
+			? formatSize(size)
+			: undefined),
+	"chunkGroup.children": (children, context, printer) =>
+		Array.isArray(children)
+			? undefined
+			: printer.print(
+					context.type,
+					Object.keys(children).map((key) => ({
+						type: key,
+						children: children[key]
+					})),
+					context
+				),
+	"chunkGroupChildGroup.type": (type) => `${type}:`,
+	"chunkGroupChild.assets[]": (file, { formatFilename }) =>
+		formatFilename(file),
+	"chunkGroupChild.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
+	"chunkGroupChild.name": (name) => (name ? `(name: ${name})` : undefined)
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Printers<KnownStatsChunk, "chunk"> &
+ * { ["chunk.childrenByOrder[].type"]: SimplePrinter<string, "chunk"> } &
+ * { ["chunk.childrenByOrder[].children[]"]: SimplePrinter<ChunkId, "chunk"> } &
+ * Exclamation<KnownStatsChunk, "chunk.separator", "chunk"> &
+ * Printers<KnownStatsChunkOrigin, "chunkOrigin">} ChunkPrinters
+ */
+
+/** @type {ChunkPrinters} */
+const CHUNK_PRINTERS = {
+	"chunk.id": (id, { formatChunkId }) => formatChunkId(id),
+	"chunk.files[]": (file, { formatFilename }) => formatFilename(file),
+	"chunk.names[]": (name) => name,
+	"chunk.idHints[]": (name) => name,
+	"chunk.runtime[]": (name) => name,
+	"chunk.sizes": (sizes, context) => printSizes(sizes, context),
+	"chunk.parents[]": (parents, context) =>
+		context.formatChunkId(parents, "parent"),
+	"chunk.siblings[]": (siblings, context) =>
+		context.formatChunkId(siblings, "sibling"),
+	"chunk.children[]": (children, context) =>
+		context.formatChunkId(children, "child"),
+	"chunk.childrenByOrder": (childrenByOrder, context, printer) =>
+		Array.isArray(childrenByOrder)
+			? undefined
+			: printer.print(
+					context.type,
+					Object.keys(childrenByOrder).map((key) => ({
+						type: key,
+						children: childrenByOrder[key]
+					})),
+					context
+				),
+	"chunk.childrenByOrder[].type": (type) => `${type}:`,
+	"chunk.childrenByOrder[].children[]": (id, { formatChunkId }) =>
+		isValidId(id) ? formatChunkId(id) : undefined,
+	"chunk.entry": (entry, { formatFlag, yellow }) =>
+		entry ? yellow(formatFlag("entry")) : undefined,
+	"chunk.initial": (initial, { formatFlag, yellow }) =>
+		initial ? yellow(formatFlag("initial")) : undefined,
+	"chunk.rendered": (rendered, { formatFlag, green }) =>
+		rendered ? green(formatFlag("rendered")) : undefined,
+	"chunk.recorded": (recorded, { formatFlag, green }) =>
+		recorded ? green(formatFlag("recorded")) : undefined,
+	"chunk.reason": (reason, { yellow }) => (reason ? yellow(reason) : undefined),
+	"chunk.filteredModules": (filteredModules, { chunk: { modules } }) =>
+		filteredModules > 0
+			? `${moreCount(modules, filteredModules)} chunk ${plural(
+					filteredModules,
+					"module",
+					"modules"
+				)}`
+			: undefined,
+	"chunk.separator!": () => "\n",
+
+	"chunkOrigin.request": (request) => request,
+	"chunkOrigin.moduleId": (moduleId, { formatModuleId }) =>
+		isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
+	"chunkOrigin.moduleName": (moduleName, { bold }) => bold(moduleName),
+	"chunkOrigin.loc": (loc) => loc
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Printers<KnownStatsError, "error"> &
+ * { ["error.filteredDetails"]?: SimplePrinter<number, "error"> } &
+ * Exclamation<KnownStatsError, "error.separator", "error">} ErrorPrinters
+ */
+
+/**
+ * @type {ErrorPrinters}
+ */
+const ERROR_PRINTERS = {
+	"error.compilerPath": (compilerPath, { bold }) =>
+		compilerPath ? bold(`(${compilerPath})`) : undefined,
+	"error.chunkId": (chunkId, { formatChunkId }) =>
+		isValidId(chunkId) ? formatChunkId(chunkId) : undefined,
+	"error.chunkEntry": (chunkEntry, { formatFlag }) =>
+		chunkEntry ? formatFlag("entry") : undefined,
+	"error.chunkInitial": (chunkInitial, { formatFlag }) =>
+		chunkInitial ? formatFlag("initial") : undefined,
+	"error.file": (file, { bold }) => bold(file),
+	"error.moduleName": (moduleName, { bold }) =>
+		moduleName.includes("!")
+			? `${bold(moduleName.replace(/^([\s\S])*!/, ""))} (${moduleName})`
+			: `${bold(moduleName)}`,
+	"error.loc": (loc, { green }) => green(loc),
+	"error.message": (message, { bold, formatError }) =>
+		message.includes("\u001B[") ? message : bold(formatError(message)),
+	"error.details": (details, { formatError }) => formatError(details),
+	"error.filteredDetails": (filteredDetails) =>
+		filteredDetails ? `+ ${filteredDetails} hidden lines` : undefined,
+	"error.stack": (stack) => stack,
+	"error.cause": (cause, context, printer) =>
+		cause
+			? indent(
+					`[cause]: ${
+						/** @type {string} */
+						(printer.print(`${context.type}.error`, cause, context))
+					}`,
+					"  "
+				)
+			: undefined,
+	"error.moduleTrace": (_moduleTrace) => undefined,
+	"error.separator!": () => "\n"
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @typedef {Printers<KnownStatsLoggingEntry, `loggingEntry(${LogTypeEnum}).loggingEntry`> &
+ * { ["loggingEntry(clear).loggingEntry"]?: SimplePrinter<KnownStatsLoggingEntry, "logging"> } &
+ * { ["loggingEntry.trace[]"]?: SimplePrinter<Exclude<KnownStatsLoggingEntry["trace"], undefined>[number], "logging"> } &
+ * { loggingGroup?: SimplePrinter<KnownStatsLogging[], "logging"> } &
+ * Printers<KnownStatsLogging & { name: string }, `loggingGroup`> &
+ * Exclamation<KnownStatsLogging, "loggingGroup.separator", "loggingGroup">} LogEntryPrinters
+ */
+
+/** @type {LogEntryPrinters} */
+const LOG_ENTRY_PRINTERS = {
+	"loggingEntry(error).loggingEntry.message": (message, { red }) =>
+		mapLines(message, (x) => `<e> ${red(x)}`),
+	"loggingEntry(warn).loggingEntry.message": (message, { yellow }) =>
+		mapLines(message, (x) => `<w> ${yellow(x)}`),
+	"loggingEntry(info).loggingEntry.message": (message, { green }) =>
+		mapLines(message, (x) => `<i> ${green(x)}`),
+	"loggingEntry(log).loggingEntry.message": (message, { bold }) =>
+		mapLines(message, (x) => `    ${bold(x)}`),
+	"loggingEntry(debug).loggingEntry.message": (message) =>
+		mapLines(message, (x) => `    ${x}`),
+	"loggingEntry(trace).loggingEntry.message": (message) =>
+		mapLines(message, (x) => `    ${x}`),
+	"loggingEntry(status).loggingEntry.message": (message, { magenta }) =>
+		mapLines(message, (x) => `<s> ${magenta(x)}`),
+	"loggingEntry(profile).loggingEntry.message": (message, { magenta }) =>
+		mapLines(message, (x) => `<p> ${magenta(x)}`),
+	"loggingEntry(profileEnd).loggingEntry.message": (message, { magenta }) =>
+		mapLines(message, (x) => `</p> ${magenta(x)}`),
+	"loggingEntry(time).loggingEntry.message": (message, { magenta }) =>
+		mapLines(message, (x) => `<t> ${magenta(x)}`),
+	"loggingEntry(group).loggingEntry.message": (message, { cyan }) =>
+		mapLines(message, (x) => `<-> ${cyan(x)}`),
+	"loggingEntry(groupCollapsed).loggingEntry.message": (message, { cyan }) =>
+		mapLines(message, (x) => `<+> ${cyan(x)}`),
+	"loggingEntry(clear).loggingEntry": () => "    -------",
+	"loggingEntry(groupCollapsed).loggingEntry.children": () => "",
+	"loggingEntry.trace[]": (trace) =>
+		trace ? mapLines(trace, (x) => `| ${x}`) : undefined,
+
+	loggingGroup: (loggingGroup) =>
+		loggingGroup.entries.length === 0 ? "" : undefined,
+	"loggingGroup.debug": (flag, { red }) => (flag ? red("DEBUG") : undefined),
+	"loggingGroup.name": (name, { bold }) => bold(`LOG from ${name}`),
+	"loggingGroup.separator!": () => "\n",
+	"loggingGroup.filteredEntries": (filteredEntries) =>
+		filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined
+};
+
+/** @typedef {Printers<KnownStatsModuleTraceItem, "moduleTraceItem">} ModuleTraceItemPrinters */
+
+/** @type {ModuleTraceItemPrinters} */
+const MODULE_TRACE_ITEM_PRINTERS = {
+	"moduleTraceItem.originName": (originName) => originName
+};
+
+/** @typedef {Printers<KnownStatsModuleTraceDependency, "moduleTraceDependency">} ModuleTraceDependencyPrinters */
+
+/** @type {ModuleTraceDependencyPrinters} */
+const MODULE_TRACE_DEPENDENCY_PRINTERS = {
+	"moduleTraceDependency.loc": (loc) => loc
+};
+
+/**
+ * @type {Record<string, string | ((item: KnownStatsLoggingEntry) => string)>}
+ */
+const ITEM_NAMES = {
+	"compilation.assets[]": "asset",
+	"compilation.modules[]": "module",
+	"compilation.chunks[]": "chunk",
+	"compilation.entrypoints[]": "chunkGroup",
+	"compilation.namedChunkGroups[]": "chunkGroup",
+	"compilation.errors[]": "error",
+	"compilation.warnings[]": "error",
+	"compilation.logging[]": "loggingGroup",
+	"compilation.children[]": "compilation",
+	"asset.related[]": "asset",
+	"asset.children[]": "asset",
+	"asset.chunks[]": "assetChunk",
+	"asset.auxiliaryChunks[]": "assetChunk",
+	"asset.chunkNames[]": "assetChunkName",
+	"asset.chunkIdHints[]": "assetChunkIdHint",
+	"asset.auxiliaryChunkNames[]": "assetChunkName",
+	"asset.auxiliaryChunkIdHints[]": "assetChunkIdHint",
+	"chunkGroup.assets[]": "chunkGroupAsset",
+	"chunkGroup.auxiliaryAssets[]": "chunkGroupAsset",
+	"chunkGroupChild.assets[]": "chunkGroupAsset",
+	"chunkGroupChild.auxiliaryAssets[]": "chunkGroupAsset",
+	"chunkGroup.children[]": "chunkGroupChildGroup",
+	"chunkGroupChildGroup.children[]": "chunkGroupChild",
+	"module.modules[]": "module",
+	"module.children[]": "module",
+	"module.reasons[]": "moduleReason",
+	"moduleReason.children[]": "moduleReason",
+	"module.issuerPath[]": "moduleIssuer",
+	"chunk.origins[]": "chunkOrigin",
+	"chunk.modules[]": "module",
+	"loggingGroup.entries[]": (logEntry) =>
+		`loggingEntry(${logEntry.type}).loggingEntry`,
+	"loggingEntry.children[]": (logEntry) =>
+		`loggingEntry(${logEntry.type}).loggingEntry`,
+	"error.moduleTrace[]": "moduleTraceItem",
+	"error.errors[]": "error",
+	"moduleTraceItem.dependencies[]": "moduleTraceDependency"
+};
+
+const ERROR_PREFERRED_ORDER = [
+	"compilerPath",
+	"chunkId",
+	"chunkEntry",
+	"chunkInitial",
+	"file",
+	"separator!",
+	"moduleName",
+	"loc",
+	"separator!",
+	"message",
+	"separator!",
+	"details",
+	"separator!",
+	"filteredDetails",
+	"separator!",
+	"stack",
+	"separator!",
+	"cause",
+	"separator!",
+	"missing",
+	"separator!",
+	"moduleTrace"
+];
+
+/** @type {Record<string, string[]>} */
+const PREFERRED_ORDERS = {
+	compilation: [
+		"name",
+		"hash",
+		"version",
+		"time",
+		"builtAt",
+		"env",
+		"publicPath",
+		"assets",
+		"filteredAssets",
+		"entrypoints",
+		"namedChunkGroups",
+		"chunks",
+		"modules",
+		"filteredModules",
+		"children",
+		"logging",
+		"warnings",
+		"warningsInChildren!",
+		"filteredWarningDetailsCount",
+		"errors",
+		"errorsInChildren!",
+		"filteredErrorDetailsCount",
+		"summary!",
+		"needAdditionalPass"
+	],
+	asset: [
+		"type",
+		"name",
+		"size",
+		"chunks",
+		"auxiliaryChunks",
+		"emitted",
+		"comparedForEmit",
+		"cached",
+		"info",
+		"isOverSizeLimit",
+		"chunkNames",
+		"auxiliaryChunkNames",
+		"chunkIdHints",
+		"auxiliaryChunkIdHints",
+		"related",
+		"filteredRelated",
+		"children",
+		"filteredChildren"
+	],
+	"asset.info": [
+		"immutable",
+		"sourceFilename",
+		"javascriptModule",
+		"development",
+		"hotModuleReplacement"
+	],
+	chunkGroup: [
+		"kind!",
+		"name",
+		"isOverSizeLimit",
+		"assetsSize",
+		"auxiliaryAssetsSize",
+		"is!",
+		"assets",
+		"filteredAssets",
+		"auxiliaryAssets",
+		"filteredAuxiliaryAssets",
+		"separator!",
+		"children"
+	],
+	chunkGroupAsset: ["name", "size"],
+	chunkGroupChildGroup: ["type", "children"],
+	chunkGroupChild: ["assets", "chunks", "name"],
+	module: [
+		"type",
+		"name",
+		"identifier",
+		"id",
+		"layer",
+		"sizes",
+		"chunks",
+		"depth",
+		"cacheable",
+		"orphan",
+		"runtime",
+		"optional",
+		"dependent",
+		"built",
+		"codeGenerated",
+		"cached",
+		"assets",
+		"failed",
+		"warnings",
+		"errors",
+		"children",
+		"filteredChildren",
+		"providedExports",
+		"usedExports",
+		"optimizationBailout",
+		"reasons",
+		"filteredReasons",
+		"issuerPath",
+		"profile",
+		"modules",
+		"filteredModules"
+	],
+	moduleReason: [
+		"active",
+		"type",
+		"userRequest",
+		"moduleId",
+		"module",
+		"resolvedModule",
+		"loc",
+		"explanation",
+		"children",
+		"filteredChildren"
+	],
+	"module.profile": [
+		"total",
+		"separator!",
+		"resolving",
+		"restoring",
+		"integration",
+		"building",
+		"storing",
+		"additionalResolving",
+		"additionalIntegration"
+	],
+	chunk: [
+		"id",
+		"runtime",
+		"files",
+		"names",
+		"idHints",
+		"sizes",
+		"parents",
+		"siblings",
+		"children",
+		"childrenByOrder",
+		"entry",
+		"initial",
+		"rendered",
+		"recorded",
+		"reason",
+		"separator!",
+		"origins",
+		"separator!",
+		"modules",
+		"separator!",
+		"filteredModules"
+	],
+	chunkOrigin: ["request", "moduleId", "moduleName", "loc"],
+	error: ERROR_PREFERRED_ORDER,
+	warning: ERROR_PREFERRED_ORDER,
+	"chunk.childrenByOrder[]": ["type", "children"],
+	loggingGroup: [
+		"debug",
+		"name",
+		"separator!",
+		"entries",
+		"separator!",
+		"filteredEntries"
+	],
+	loggingEntry: ["message", "trace", "children"]
+};
+
+/** @typedef {(items: string[]) => string | undefined} SimpleItemsJoiner */
+
+/** @type {SimpleItemsJoiner} */
+const itemsJoinOneLine = (items) => items.filter(Boolean).join(" ");
+/** @type {SimpleItemsJoiner} */
+const itemsJoinOneLineBrackets = (items) =>
+	items.length > 0 ? `(${items.filter(Boolean).join(" ")})` : undefined;
+/** @type {SimpleItemsJoiner} */
+const itemsJoinMoreSpacing = (items) => items.filter(Boolean).join("\n\n");
+/** @type {SimpleItemsJoiner} */
+const itemsJoinComma = (items) => items.filter(Boolean).join(", ");
+/** @type {SimpleItemsJoiner} */
+const itemsJoinCommaBrackets = (items) =>
+	items.length > 0 ? `(${items.filter(Boolean).join(", ")})` : undefined;
+/** @type {(item: string) => SimpleItemsJoiner} */
+const itemsJoinCommaBracketsWithName = (name) => (items) =>
+	items.length > 0
+		? `(${name}: ${items.filter(Boolean).join(", ")})`
+		: undefined;
+
+/** @type {Record<string, SimpleItemsJoiner>} */
+const SIMPLE_ITEMS_JOINER = {
+	"chunk.parents": itemsJoinOneLine,
+	"chunk.siblings": itemsJoinOneLine,
+	"chunk.children": itemsJoinOneLine,
+	"chunk.names": itemsJoinCommaBrackets,
+	"chunk.idHints": itemsJoinCommaBracketsWithName("id hint"),
+	"chunk.runtime": itemsJoinCommaBracketsWithName("runtime"),
+	"chunk.files": itemsJoinComma,
+	"chunk.childrenByOrder": itemsJoinOneLine,
+	"chunk.childrenByOrder[].children": itemsJoinOneLine,
+	"chunkGroup.assets": itemsJoinOneLine,
+	"chunkGroup.auxiliaryAssets": itemsJoinOneLineBrackets,
+	"chunkGroupChildGroup.children": itemsJoinComma,
+	"chunkGroupChild.assets": itemsJoinOneLine,
+	"chunkGroupChild.auxiliaryAssets": itemsJoinOneLineBrackets,
+	"asset.chunks": itemsJoinComma,
+	"asset.auxiliaryChunks": itemsJoinCommaBrackets,
+	"asset.chunkNames": itemsJoinCommaBracketsWithName("name"),
+	"asset.auxiliaryChunkNames": itemsJoinCommaBracketsWithName("auxiliary name"),
+	"asset.chunkIdHints": itemsJoinCommaBracketsWithName("id hint"),
+	"asset.auxiliaryChunkIdHints":
+		itemsJoinCommaBracketsWithName("auxiliary id hint"),
+	"module.chunks": itemsJoinOneLine,
+	"module.issuerPath": (items) =>
+		items
+			.filter(Boolean)
+			.map((item) => `${item} ->`)
+			.join(" "),
+	"compilation.errors": itemsJoinMoreSpacing,
+	"compilation.warnings": itemsJoinMoreSpacing,
+	"compilation.logging": itemsJoinMoreSpacing,
+	"compilation.children": (items) =>
+		indent(/** @type {string} */ (itemsJoinMoreSpacing(items)), "  "),
+	"moduleTraceItem.dependencies": itemsJoinOneLine,
+	"loggingEntry.children": (items) =>
+		indent(items.filter(Boolean).join("\n"), "  ", false)
+};
+
+/**
+ * Returns result.
+ * @param {Item[]} items items
+ * @returns {string} result
+ */
+const joinOneLine = (items) =>
+	items
+		.map((item) => item.content)
+		.filter(Boolean)
+		.join(" ");
+
+/**
+ * Returns result.
+ * @param {Item[]} items items
+ * @returns {string} result
+ */
+const joinInBrackets = (items) => {
+	/** @type {string[]} */
+	const res = [];
+	let mode = 0;
+	for (const item of items) {
+		if (item.element === "separator!") {
+			switch (mode) {
+				case 0:
+				case 1:
+					mode += 2;
+					break;
+				case 4:
+					res.push(")");
+					mode = 3;
+					break;
+			}
+		}
+		if (!item.content) continue;
+		switch (mode) {
+			case 0:
+				mode = 1;
+				break;
+			case 1:
+				res.push(" ");
+				break;
+			case 2:
+				res.push("(");
+				mode = 4;
+				break;
+			case 3:
+				res.push(" (");
+				mode = 4;
+				break;
+			case 4:
+				res.push(", ");
+				break;
+		}
+		res.push(item.content);
+	}
+	if (mode === 4) res.push(")");
+	return res.join("");
+};
+
+/**
+ * Returns result.
+ * @param {string} str a string
+ * @param {string} prefix prefix
+ * @param {boolean=} noPrefixInFirstLine need prefix in the first line?
+ * @returns {string} result
+ */
+const indent = (str, prefix, noPrefixInFirstLine) => {
+	const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`);
+	if (noPrefixInFirstLine) return rem;
+	const ind = str[0] === "\n" ? "" : prefix;
+	return ind + rem;
+};
+
+/**
+ * Join explicit new line.
+ * @param {(false | Item)[]} items items
+ * @param {string} indenter indenter
+ * @returns {string} result
+ */
+const joinExplicitNewLine = (items, indenter) => {
+	let firstInLine = true;
+	let first = true;
+	return items
+		.map((item) => {
+			if (!item || !item.content) return;
+			let content = indent(item.content, first ? "" : indenter, !firstInLine);
+			if (firstInLine) {
+				content = content.replace(/^\n+/, "");
+			}
+			if (!content) return;
+			first = false;
+			const noJoiner = firstInLine || content.startsWith("\n");
+			firstInLine = content.endsWith("\n");
+			return noJoiner ? content : ` ${content}`;
+		})
+		.filter(Boolean)
+		.join("")
+		.trim();
+};
+
+/**
+ * Returns joiner.
+ * @param {boolean} error is an error
+ * @returns {SimpleElementJoiner} joiner
+ */
+const joinError =
+	(error) =>
+	/**
+	 * Handles the callback logic for this hook.
+	 * @param {Item[]} items items
+	 * @param {StatsPrinterContextWithExtra} ctx context
+	 * @returns {string} result
+	 */
+	(items, { red, yellow }) =>
+		`${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine(
+			items,
+			""
+		)}`;
+
+/** @typedef {{ element: string, content: string | undefined }} Item */
+/** @typedef {(items: Item[], context: StatsPrinterContextWithExtra & Required<KnownStatsPrinterContext>) => string} SimpleElementJoiner */
+
+/** @type {Record<string, SimpleElementJoiner>} */
+const SIMPLE_ELEMENT_JOINERS = {
+	compilation: (items) => {
+		/** @type {string[]} */
+		const result = [];
+		let lastNeedMore = false;
+		for (const item of items) {
+			if (!item.content) continue;
+			const needMoreSpace =
+				item.element === "warnings" ||
+				item.element === "filteredWarningDetailsCount" ||
+				item.element === "errors" ||
+				item.element === "filteredErrorDetailsCount" ||
+				item.element === "logging";
+			if (result.length !== 0) {
+				result.push(needMoreSpace || lastNeedMore ? "\n\n" : "\n");
+			}
+			result.push(item.content);
+			lastNeedMore = needMoreSpace;
+		}
+		if (lastNeedMore) result.push("\n");
+		return result.join("");
+	},
+	asset: (items) =>
+		joinExplicitNewLine(
+			items.map((item) => {
+				if (
+					(item.element === "related" || item.element === "children") &&
+					item.content
+				) {
+					return {
+						...item,
+						content: `\n${item.content}\n`
+					};
+				}
+				return item;
+			}),
+			"  "
+		),
+	"asset.info": joinOneLine,
+	module: (items, { module }) => {
+		let hasName = false;
+		return joinExplicitNewLine(
+			items.map((item) => {
+				switch (item.element) {
+					case "id":
+						if (module.id === module.name) {
+							if (hasName) return false;
+							if (item.content) hasName = true;
+						}
+						break;
+					case "name":
+						if (hasName) return false;
+						if (item.content) hasName = true;
+						break;
+					case "providedExports":
+					case "usedExports":
+					case "optimizationBailout":
+					case "reasons":
+					case "issuerPath":
+					case "profile":
+					case "children":
+					case "modules":
+						if (item.content) {
+							return {
+								...item,
+								content: `\n${item.content}\n`
+							};
+						}
+						break;
+				}
+				return item;
+			}),
+			"  "
+		);
+	},
+	chunk: (items) => {
+		let hasEntry = false;
+		return `chunk ${joinExplicitNewLine(
+			items.filter((item) => {
+				switch (item.element) {
+					case "entry":
+						if (item.content) hasEntry = true;
+						break;
+					case "initial":
+						if (hasEntry) return false;
+						break;
+				}
+				return true;
+			}),
+			"  "
+		)}`;
+	},
+	"chunk.childrenByOrder[]": (items) => `(${joinOneLine(items)})`,
+	chunkGroup: (items) => joinExplicitNewLine(items, "  "),
+	chunkGroupAsset: joinOneLine,
+	chunkGroupChildGroup: joinOneLine,
+	chunkGroupChild: joinOneLine,
+	moduleReason: (items, { moduleReason }) => {
+		let hasName = false;
+		return joinExplicitNewLine(
+			items.map((item) => {
+				switch (item.element) {
+					case "moduleId":
+						if (moduleReason.moduleId === moduleReason.module && item.content) {
+							hasName = true;
+						}
+						break;
+					case "module":
+						if (hasName) return false;
+						break;
+					case "resolvedModule":
+						if (moduleReason.module === moduleReason.resolvedModule) {
+							return false;
+						}
+						break;
+					case "children":
+						if (item.content) {
+							return {
+								...item,
+								content: `\n${item.content}\n`
+							};
+						}
+						break;
+				}
+				return item;
+			}),
+			"  "
+		);
+	},
+	"module.profile": joinInBrackets,
+	moduleIssuer: joinOneLine,
+	chunkOrigin: (items) => `> ${joinOneLine(items)}`,
+	"errors[].error": joinError(true),
+	"warnings[].error": joinError(false),
+	error: (items) => joinExplicitNewLine(items, ""),
+	"error.errors[].error": (items) =>
+		indent(`[errors]: ${joinExplicitNewLine(items, "")}`, "  "),
+	loggingGroup: (items) => joinExplicitNewLine(items, "").trimEnd(),
+	moduleTraceItem: (items) => ` @ ${joinOneLine(items)}`,
+	moduleTraceDependency: joinOneLine
+};
+
+/** @type {Record<keyof KnownStatsPrinterColorFunctions, string>} */
+const AVAILABLE_COLORS = {
+	bold: "\u001B[1m",
+	yellow: "\u001B[1m\u001B[33m",
+	red: "\u001B[1m\u001B[31m",
+	green: "\u001B[1m\u001B[32m",
+	cyan: "\u001B[1m\u001B[36m",
+	magenta: "\u001B[1m\u001B[35m"
+};
+
+/**
+ * Defines the tail type used by this module.
+ * @template T
+ * @typedef {T extends [infer Head, ...infer Tail] ? Tail : undefined} Tail
+ */
+
+/**
+ * Defines the tail parameters type used by this module.
+ * @template {(...args: EXPECTED_ANY[]) => EXPECTED_ANY} T
+ * @typedef {T extends (firstArg: EXPECTED_ANY, ...rest: infer R) => EXPECTED_ANY ? R : never} TailParameters
+ */
+
+/** @typedef {{ [Key in keyof KnownStatsPrinterFormatters]: (value: Parameters<NonNullable<KnownStatsPrinterFormatters[Key]>>[0], options: Required<KnownStatsPrinterColorFunctions> & StatsPrinterContextWithExtra, ...args: TailParameters<NonNullable<KnownStatsPrinterFormatters[Key]>>) => string }} AvailableFormats */
+
+/** @type {AvailableFormats} */
+const AVAILABLE_FORMATS = {
+	formatChunkId: (id, { yellow }, direction) => {
+		switch (direction) {
+			case "parent":
+				return `<{${yellow(id)}}>`;
+			case "sibling":
+				return `={${yellow(id)}}=`;
+			case "child":
+				return `>{${yellow(id)}}<`;
+			default:
+				return `{${yellow(id)}}`;
+		}
+	},
+	formatModuleId: (id) => `[${id}]`,
+	formatFilename: (filename, { green, yellow }, oversize) =>
+		(oversize ? yellow : green)(filename),
+	formatFlag: (flag) => `[${flag}]`,
+	formatLayer: (layer) => `(in ${layer})`,
+	formatSize: require("../util/formatSize"),
+	formatDateTime: (dateTime, { bold }) => {
+		const d = new Date(dateTime);
+		const x = twoDigit;
+		const date = `${d.getFullYear()}-${x(d.getMonth() + 1)}-${x(d.getDate())}`;
+		const time = `${x(d.getHours())}:${x(d.getMinutes())}:${x(d.getSeconds())}`;
+		return `${date} ${bold(time)}`;
+	},
+	formatTime: (
+		time,
+		{ timeReference, bold, green, yellow, red },
+		boldQuantity
+	) => {
+		const unit = " ms";
+		if (timeReference && time !== timeReference) {
+			const times = [
+				timeReference / 2,
+				timeReference / 4,
+				timeReference / 8,
+				timeReference / 16
+			];
+			if (time < times[3]) return `${time}${unit}`;
+			else if (time < times[2]) return bold(`${time}${unit}`);
+			else if (time < times[1]) return green(`${time}${unit}`);
+			else if (time < times[0]) return yellow(`${time}${unit}`);
+			return red(`${time}${unit}`);
+		}
+		return `${boldQuantity ? bold(time) : time}${unit}`;
+	},
+	formatError: (message, { green, yellow, red }) => {
+		if (message.includes("\u001B[")) return message;
+		const highlights = [
+			{ regExp: /(Did you mean .+)/g, format: green },
+			{
+				regExp: /(Set 'mode' option to 'development' or 'production')/g,
+				format: green
+			},
+			{ regExp: /(\(module has no exports\))/g, format: red },
+			{ regExp: /\(possible exports: (.+)\)/g, format: green },
+			{ regExp: /(?:^|\n)(.* doesn't exist)/g, format: red },
+			{ regExp: /('\w+' option has not been set)/g, format: red },
+			{
+				regExp: /(Emitted value instead of an instance of Error)/g,
+				format: yellow
+			},
+			{ regExp: /(Used? .+ instead)/gi, format: yellow },
+			{ regExp: /\b(deprecated|must|required)\b/g, format: yellow },
+			{
+				regExp: /\b(BREAKING CHANGE)\b/gi,
+				format: red
+			},
+			{
+				regExp:
+					/\b(error|failed|unexpected|invalid|not found|not supported|not available|not possible|not implemented|doesn't support|conflict|conflicting|not existing|duplicate)\b/gi,
+				format: red
+			}
+		];
+		for (const { regExp, format } of highlights) {
+			message = message.replace(
+				regExp,
+				/**
+				 * Handles the format callback for this hook.
+				 * @param {string} match match
+				 * @param {string} content content
+				 * @returns {string} result
+				 */
+				(match, content) => match.replace(content, format(content))
+			);
+		}
+		return message;
+	}
+};
+
+/** @typedef {(result: string) => string} ResultModifierFn */
+/** @type {Record<string, ResultModifierFn>} */
+const RESULT_MODIFIER = {
+	"module.modules": (result) => indent(result, "| ")
+};
+
+/**
+ * Creates an order from the provided array.
+ * @param {string[]} array array
+ * @param {string[]} preferredOrder preferred order
+ * @returns {string[]} result
+ */
+const createOrder = (array, preferredOrder) => {
+	const originalArray = [...array];
+	/** @type {Set<string>} */
+	const set = new Set(array);
+	/** @type {Set<string>} */
+	const usedSet = new Set();
+	array.length = 0;
+	for (const element of preferredOrder) {
+		if (element.endsWith("!") || set.has(element)) {
+			array.push(element);
+			usedSet.add(element);
+		}
+	}
+	for (const element of originalArray) {
+		if (!usedSet.has(element)) {
+			array.push(element);
+		}
+	}
+	return array;
+};
+
+const PLUGIN_NAME = "DefaultStatsPrinterPlugin";
+
+class DefaultStatsPrinterPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.statsPrinter.tap(PLUGIN_NAME, (stats, options) => {
+				// Put colors into context
+				stats.hooks.print
+					.for("compilation")
+					.tap(PLUGIN_NAME, (compilation, context) => {
+						for (const color of Object.keys(AVAILABLE_COLORS)) {
+							const name =
+								/** @type {keyof KnownStatsPrinterColorFunctions} */
+								(color);
+							/** @type {string | undefined} */
+							let start;
+							if (options.colors) {
+								if (
+									typeof options.colors === "object" &&
+									typeof options.colors[name] === "string"
+								) {
+									start = options.colors[name];
+								} else {
+									start = AVAILABLE_COLORS[name];
+								}
+							}
+							if (start) {
+								/** @type {ColorFunction} */
+								context[color] = (str) =>
+									`${start}${
+										typeof str === "string"
+											? str.replace(
+													// eslint-disable-next-line no-control-regex
+													/((\u001B\[39m|\u001B\[22m|\u001B\[0m)+)/g,
+													`$1${start}`
+												)
+											: str
+									}\u001B[39m\u001B[22m`;
+							} else {
+								/**
+								 * Returns str string.
+								 * @param {string} str string
+								 * @returns {string} str string
+								 */
+								context[color] = (str) => str;
+							}
+						}
+						for (const format of /** @type {(keyof KnownStatsPrinterFormatters)[]} */ (
+							Object.keys(AVAILABLE_FORMATS)
+						)) {
+							context[format] =
+								/** @type {(content: Parameters<NonNullable<KnownStatsPrinterFormatters[keyof KnownStatsPrinterFormatters]>>[0], ...args: Tail<Parameters<NonNullable<KnownStatsPrinterFormatters[keyof KnownStatsPrinterFormatters]>>>) => string} */
+								(content, ...args) =>
+									/** @type {EXPECTED_ANY} */
+									(AVAILABLE_FORMATS[format])(
+										content,
+										/** @type {StatsPrinterContext & Required<KnownStatsPrinterColorFunctions>} */
+										(context),
+										...args
+									);
+						}
+						context.timeReference = compilation.time;
+					});
+
+				for (const key of /** @type {(keyof CompilationSimplePrinters)[]} */ (
+					Object.keys(COMPILATION_SIMPLE_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(COMPILATION_SIMPLE_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"compilation">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof AssetSimplePrinters)[]} */ (
+					Object.keys(ASSET_SIMPLE_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {NonNullable<AssetSimplePrinters[keyof AssetSimplePrinters]>} */
+						(ASSET_SIMPLE_PRINTERS[key])(
+							obj,
+							/** @type {DefineStatsPrinterContext<"asset" | "asset.info">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ModuleSimplePrinters)[]} */ (
+					Object.keys(MODULE_SIMPLE_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(MODULE_SIMPLE_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"module">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ModuleIssuerPrinters)[]} */ (
+					Object.keys(MODULE_ISSUER_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {NonNullable<ModuleIssuerPrinters[keyof ModuleIssuerPrinters]>} */
+						(MODULE_ISSUER_PRINTERS[key])(
+							obj,
+							/** @type {DefineStatsPrinterContext<"moduleIssuer">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ModuleReasonsPrinters)[]} */ (
+					Object.keys(MODULE_REASON_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(MODULE_REASON_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"moduleReason">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ModuleProfilePrinters)[]} */ (
+					Object.keys(MODULE_PROFILE_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {NonNullable<ModuleProfilePrinters[keyof ModuleProfilePrinters]>} */
+						(MODULE_PROFILE_PRINTERS[key])(
+							obj,
+							/** @type {DefineStatsPrinterContext<"profile">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ChunkGroupPrinters)[]} */ (
+					Object.keys(CHUNK_GROUP_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(CHUNK_GROUP_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"chunkGroupKind" | "chunkGroup">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ChunkPrinters)[]} */ (
+					Object.keys(CHUNK_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(CHUNK_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"chunk">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ErrorPrinters)[]} */ (
+					Object.keys(ERROR_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(ERROR_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"error">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof LogEntryPrinters)[]} */ (
+					Object.keys(LOG_ENTRY_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {EXPECTED_ANY} */
+						(LOG_ENTRY_PRINTERS)[key](
+							obj,
+							/** @type {DefineStatsPrinterContext<"logging">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ModuleTraceDependencyPrinters)[]} */ (
+					Object.keys(MODULE_TRACE_DEPENDENCY_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {NonNullable<ModuleTraceDependencyPrinters[keyof ModuleTraceDependencyPrinters]>} */
+						(MODULE_TRACE_DEPENDENCY_PRINTERS[key])(
+							obj,
+							/** @type {DefineStatsPrinterContext<"moduleTraceDependency">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of /** @type {(keyof ModuleTraceItemPrinters)[]} */ (
+					Object.keys(MODULE_TRACE_ITEM_PRINTERS)
+				)) {
+					stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
+						/** @type {NonNullable<ModuleTraceItemPrinters[keyof ModuleTraceItemPrinters]>} */
+						(MODULE_TRACE_ITEM_PRINTERS[key])(
+							obj,
+							/** @type {DefineStatsPrinterContext<"moduleTraceItem">} */
+							(ctx),
+							stats
+						)
+					);
+				}
+
+				for (const key of Object.keys(PREFERRED_ORDERS)) {
+					const preferredOrder = PREFERRED_ORDERS[key];
+					stats.hooks.sortElements
+						.for(key)
+						.tap(PLUGIN_NAME, (elements, _context) => {
+							createOrder(elements, preferredOrder);
+						});
+				}
+
+				for (const key of Object.keys(ITEM_NAMES)) {
+					const itemName = ITEM_NAMES[key];
+					stats.hooks.getItemName
+						.for(key)
+						.tap(
+							PLUGIN_NAME,
+							typeof itemName === "string" ? () => itemName : itemName
+						);
+				}
+
+				for (const key of Object.keys(SIMPLE_ITEMS_JOINER)) {
+					const joiner = SIMPLE_ITEMS_JOINER[key];
+					stats.hooks.printItems.for(key).tap(PLUGIN_NAME, joiner);
+				}
+
+				for (const key of Object.keys(SIMPLE_ELEMENT_JOINERS)) {
+					const joiner =
+						/** @type {(items: Item[], context: StatsPrinterContext) => string} */
+						(SIMPLE_ELEMENT_JOINERS[key]);
+					stats.hooks.printElements.for(key).tap(PLUGIN_NAME, joiner);
+				}
+
+				for (const key of Object.keys(RESULT_MODIFIER)) {
+					const modifier = RESULT_MODIFIER[key];
+					stats.hooks.result.for(key).tap(PLUGIN_NAME, modifier);
+				}
+			});
+		});
+	}
+}
+
+module.exports = DefaultStatsPrinterPlugin;
Index: frontend/node_modules/webpack/lib/stats/StatsFactory.js
===================================================================
--- frontend/node_modules/webpack/lib/stats/StatsFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/stats/StatsFactory.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,418 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { HookMap, SyncBailHook, SyncWaterfallHook } = require("tapable");
+const { concatComparators, keepOriginalOrder } = require("../util/comparators");
+const smartGrouping = require("../util/smartGrouping");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGroup").OriginRecord} OriginRecord */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").Asset} Asset */
+/** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph").ModuleProfile} ModuleProfile */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../util/comparators").Comparator<EXPECTED_ANY>} Comparator */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/**
+ * Defines the group config type used by this module.
+ * @template T, R
+ * @typedef {import("../util/smartGrouping").GroupConfig<T, R>} GroupConfig
+ */
+/** @typedef {import("./DefaultStatsFactoryPlugin").ChunkGroupInfoWithName} ChunkGroupInfoWithName */
+/** @typedef {import("./DefaultStatsFactoryPlugin").ModuleIssuerPath} ModuleIssuerPath */
+/** @typedef {import("./DefaultStatsFactoryPlugin").ModuleTrace} ModuleTrace */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunk} StatsChunk */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunkGroup} StatsChunkGroup */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunkOrigin} StatsChunkOrigin */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModule} StatsModule */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleIssuer} StatsModuleIssuer */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceDependency} StatsModuleTraceDependency */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceItem} StatsModuleTraceItem */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsProfile} StatsProfile */
+
+/**
+ * Defines the known stats factory context type used by this module.
+ * @typedef {object} KnownStatsFactoryContext
+ * @property {string} type
+ * @property {Compilation} compilation
+ * @property {(path: string) => string} makePathsRelative
+ * @property {Set<Module>} rootModules
+ * @property {Map<string, Chunk[]>} compilationFileToChunks
+ * @property {Map<string, Chunk[]>} compilationAuxiliaryFileToChunks
+ * @property {RuntimeSpec} runtime
+ * @property {(compilation: Compilation) => Error[]} cachedGetErrors
+ * @property {(compilation: Compilation) => Error[]} cachedGetWarnings
+ */
+
+/** @typedef {KnownStatsFactoryContext & Record<string, EXPECTED_ANY>} StatsFactoryContext */
+
+// StatsLogging StatsLoggingEntry
+
+/**
+ * Defines the stats object type used by this module.
+ * @template T
+ * @template F
+ * @typedef {T extends Compilation ? StatsCompilation : T extends ChunkGroupInfoWithName ? StatsChunkGroup : T extends Chunk ? StatsChunk : T extends OriginRecord ? StatsChunkOrigin : T extends Module ? StatsModule : T extends ModuleGraphConnection ? StatsModuleReason : T extends Asset ? StatsAsset : T extends ModuleTrace ? StatsModuleTraceItem : T extends Dependency ? StatsModuleTraceDependency : T extends Error ? StatsError : T extends ModuleProfile ? StatsProfile : F} StatsObject
+ */
+
+/**
+ * Defines the created object type used by this module.
+ * @template T
+ * @template F
+ * @typedef {T extends ChunkGroupInfoWithName[] ? Record<string, StatsObject<ChunkGroupInfoWithName, F>> : T extends (infer V)[] ? StatsObject<V, F>[] : StatsObject<T, F>} CreatedObject
+ */
+
+/** @typedef {EXPECTED_ANY} ObjectForExtract */
+/** @typedef {EXPECTED_ANY} FactoryData */
+/** @typedef {EXPECTED_ANY} FactoryDataItem */
+/** @typedef {EXPECTED_ANY} Result */
+
+/**
+ * Defines the stats factory hooks type used by this module.
+ * @typedef {object} StatsFactoryHooks
+ * @property {HookMap<SyncBailHook<[ObjectForExtract, FactoryData, StatsFactoryContext], void>>} extract
+ * @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | void>>} filter
+ * @property {HookMap<SyncBailHook<[Comparator[], StatsFactoryContext], void>>} sort
+ * @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | void>>} filterSorted
+ * @property {HookMap<SyncBailHook<[GroupConfig<EXPECTED_ANY, EXPECTED_ANY>[], StatsFactoryContext], void>>} groupResults
+ * @property {HookMap<SyncBailHook<[Comparator[], StatsFactoryContext], void>>} sortResults
+ * @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | void>>} filterResults
+ * @property {HookMap<SyncBailHook<[FactoryDataItem[], StatsFactoryContext], Result | void>>} merge
+ * @property {HookMap<SyncBailHook<[Result, StatsFactoryContext], Result>>} result
+ * @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext], string | void>>} getItemName
+ * @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext], StatsFactory | void>>} getItemFactory
+ */
+
+/**
+ * Represents the stats factory runtime component.
+ * @template T
+ * @typedef {Map<string, T[]>} Caches
+ */
+
+class StatsFactory {
+	constructor() {
+		/** @type {StatsFactoryHooks} */
+		this.hooks = Object.freeze({
+			extract: new HookMap(
+				() => new SyncBailHook(["object", "data", "context"])
+			),
+			filter: new HookMap(
+				() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
+			),
+			sort: new HookMap(() => new SyncBailHook(["comparators", "context"])),
+			filterSorted: new HookMap(
+				() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
+			),
+			groupResults: new HookMap(
+				() => new SyncBailHook(["groupConfigs", "context"])
+			),
+			sortResults: new HookMap(
+				() => new SyncBailHook(["comparators", "context"])
+			),
+			filterResults: new HookMap(
+				() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
+			),
+			merge: new HookMap(() => new SyncBailHook(["items", "context"])),
+			result: new HookMap(() => new SyncWaterfallHook(["result", "context"])),
+			getItemName: new HookMap(() => new SyncBailHook(["item", "context"])),
+			getItemFactory: new HookMap(() => new SyncBailHook(["item", "context"]))
+		});
+		const hooks = this.hooks;
+		this._caches =
+			/** @type {{ [Key in keyof StatsFactoryHooks]: Map<string, SyncBailHook<EXPECTED_ANY, EXPECTED_ANY>[]> }} */ ({});
+		for (const key of Object.keys(hooks)) {
+			this._caches[/** @type {keyof StatsFactoryHooks} */ (key)] = new Map();
+		}
+		this._inCreate = false;
+	}
+
+	/**
+	 * Get all level hooks.
+	 * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM
+	 * @template {HM extends HookMap<infer H> ? H : never} H
+	 * @param {HM} hookMap hook map
+	 * @param {Caches<H>} cache cache
+	 * @param {string} type type
+	 * @returns {H[]} hooks
+	 * @private
+	 */
+	_getAllLevelHooks(hookMap, cache, type) {
+		const cacheEntry = cache.get(type);
+		if (cacheEntry !== undefined) {
+			return cacheEntry;
+		}
+		const hooks = /** @type {H[]} */ ([]);
+		const typeParts = type.split(".");
+		for (let i = 0; i < typeParts.length; i++) {
+			const hook = /** @type {H} */ (hookMap.get(typeParts.slice(i).join(".")));
+			if (hook) {
+				hooks.push(hook);
+			}
+		}
+		cache.set(type, hooks);
+		return hooks;
+	}
+
+	/**
+	 * Returns hook.
+	 * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM
+	 * @template {HM extends HookMap<infer H> ? H : never} H
+	 * @template {H extends import("tapable").Hook<EXPECTED_ANY, infer R> ? R : never} R
+	 * @param {HM} hookMap hook map
+	 * @param {Caches<H>} cache cache
+	 * @param {string} type type
+	 * @param {(hook: H) => R | void} fn fn
+	 * @returns {R | void} hook
+	 * @private
+	 */
+	_forEachLevel(hookMap, cache, type, fn) {
+		for (const hook of this._getAllLevelHooks(hookMap, cache, type)) {
+			const result = fn(/** @type {H} */ (hook));
+			if (result !== undefined) return result;
+		}
+	}
+
+	/**
+	 * For each level waterfall.
+	 * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM
+	 * @template {HM extends HookMap<infer H> ? H : never} H
+	 * @param {HM} hookMap hook map
+	 * @param {Caches<H>} cache cache
+	 * @param {string} type type
+	 * @param {FactoryData} data data
+	 * @param {(hook: H, factoryData: FactoryData) => FactoryData} fn fn
+	 * @returns {FactoryData} data
+	 * @private
+	 */
+	_forEachLevelWaterfall(hookMap, cache, type, data, fn) {
+		for (const hook of this._getAllLevelHooks(hookMap, cache, type)) {
+			data = fn(/** @type {H} */ (hook), data);
+		}
+		return data;
+	}
+
+	/**
+	 * For each level filter.
+	 * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} T
+	 * @template {T extends HookMap<infer H> ? H : never} H
+	 * @template {H extends import("tapable").Hook<EXPECTED_ANY, infer R> ? R : never} R
+	 * @param {T} hookMap hook map
+	 * @param {Caches<H>} cache cache
+	 * @param {string} type type
+	 * @param {FactoryData[]} items items
+	 * @param {(hook: H, item: R, idx: number, i: number) => R | undefined} fn fn
+	 * @param {boolean} forceClone force clone
+	 * @returns {R[]} result for each level
+	 * @private
+	 */
+	_forEachLevelFilter(hookMap, cache, type, items, fn, forceClone) {
+		const hooks = this._getAllLevelHooks(hookMap, cache, type);
+		if (hooks.length === 0) return forceClone ? [...items] : items;
+		let i = 0;
+		return items.filter((item, idx) => {
+			for (const hook of hooks) {
+				const r = fn(/** @type {H} */ (hook), item, idx, i);
+				if (r !== undefined) {
+					if (r) i++;
+					return r;
+				}
+			}
+			i++;
+			return true;
+		});
+	}
+
+	/**
+	 * Returns created object.
+	 * @template FactoryData
+	 * @template FallbackCreatedObject
+	 * @param {string} type type
+	 * @param {FactoryData} data factory data
+	 * @param {Omit<StatsFactoryContext, "type">} baseContext context used as base
+	 * @returns {CreatedObject<FactoryData, FallbackCreatedObject>} created object
+	 */
+	create(type, data, baseContext) {
+		if (this._inCreate) {
+			return this._create(type, data, baseContext);
+		}
+		try {
+			this._inCreate = true;
+			return this._create(type, data, baseContext);
+		} finally {
+			for (const key of Object.keys(this._caches)) {
+				this._caches[/** @type {keyof StatsFactoryHooks} */ (key)].clear();
+			}
+			this._inCreate = false;
+		}
+	}
+
+	/**
+	 * Returns created object.
+	 * @private
+	 * @template FactoryData
+	 * @template FallbackCreatedObject
+	 * @param {string} type type
+	 * @param {FactoryData} data factory data
+	 * @param {Omit<StatsFactoryContext, "type">} baseContext context used as base
+	 * @returns {CreatedObject<FactoryData, FallbackCreatedObject>} created object
+	 */
+	_create(type, data, baseContext) {
+		const context = /** @type {StatsFactoryContext} */ ({
+			...baseContext,
+			type,
+			[type]: data
+		});
+		if (Array.isArray(data)) {
+			// run filter on unsorted items
+			const items = this._forEachLevelFilter(
+				this.hooks.filter,
+				this._caches.filter,
+				type,
+				data,
+				(h, r, idx, i) => h.call(r, context, idx, i),
+				true
+			);
+
+			// sort items
+			/** @type {Comparator[]} */
+			const comparators = [];
+			this._forEachLevel(this.hooks.sort, this._caches.sort, type, (h) =>
+				h.call(comparators, context)
+			);
+			if (comparators.length > 0) {
+				items.sort(
+					// @ts-expect-error number of arguments is correct
+					concatComparators(...comparators, keepOriginalOrder(items))
+				);
+			}
+
+			// run filter on sorted items
+			const items2 = this._forEachLevelFilter(
+				this.hooks.filterSorted,
+				this._caches.filterSorted,
+				type,
+				items,
+				(h, r, idx, i) => h.call(r, context, idx, i),
+				false
+			);
+
+			// for each item
+			let resultItems = items2.map((item, i) => {
+				/** @type {StatsFactoryContext} */
+				const itemContext = {
+					...context,
+					_index: i
+				};
+
+				// run getItemName
+				const itemName = this._forEachLevel(
+					this.hooks.getItemName,
+					this._caches.getItemName,
+					`${type}[]`,
+					(h) => h.call(item, itemContext)
+				);
+				if (itemName) itemContext[itemName] = item;
+				const innerType = itemName ? `${type}[].${itemName}` : `${type}[]`;
+
+				// run getItemFactory
+				const itemFactory =
+					this._forEachLevel(
+						this.hooks.getItemFactory,
+						this._caches.getItemFactory,
+						innerType,
+						(h) => h.call(item, itemContext)
+					) || this;
+
+				// run item factory
+				return itemFactory.create(innerType, item, itemContext);
+			});
+
+			// sort result items
+			/** @type {Comparator[]} */
+			const comparators2 = [];
+			this._forEachLevel(
+				this.hooks.sortResults,
+				this._caches.sortResults,
+				type,
+				(h) => h.call(comparators2, context)
+			);
+			if (comparators2.length > 0) {
+				resultItems.sort(
+					// @ts-expect-error number of arguments is correct
+					concatComparators(...comparators2, keepOriginalOrder(resultItems))
+				);
+			}
+
+			// group result items
+			/** @type {GroupConfig<EXPECTED_ANY, EXPECTED_ANY>[]} */
+			const groupConfigs = [];
+			this._forEachLevel(
+				this.hooks.groupResults,
+				this._caches.groupResults,
+				type,
+				(h) => h.call(groupConfigs, context)
+			);
+			if (groupConfigs.length > 0) {
+				resultItems = smartGrouping(resultItems, groupConfigs);
+			}
+
+			// run filter on sorted result items
+			const finalResultItems = this._forEachLevelFilter(
+				this.hooks.filterResults,
+				this._caches.filterResults,
+				type,
+				resultItems,
+				(h, r, idx, i) => h.call(r, context, idx, i),
+				false
+			);
+
+			// run merge on mapped items
+			let result = this._forEachLevel(
+				this.hooks.merge,
+				this._caches.merge,
+				type,
+				(h) => h.call(finalResultItems, context)
+			);
+			if (result === undefined) result = finalResultItems;
+
+			// run result on merged items
+			return this._forEachLevelWaterfall(
+				this.hooks.result,
+				this._caches.result,
+				type,
+				result,
+				(h, r) => h.call(r, context)
+			);
+		}
+		/** @type {ObjectForExtract} */
+		const object = {};
+
+		// run extract on value
+		this._forEachLevel(this.hooks.extract, this._caches.extract, type, (h) =>
+			h.call(object, data, context)
+		);
+
+		// run result on extracted object
+		return this._forEachLevelWaterfall(
+			this.hooks.result,
+			this._caches.result,
+			type,
+			object,
+			(h, r) => h.call(r, context)
+		);
+	}
+}
+
+module.exports = StatsFactory;
Index: frontend/node_modules/webpack/lib/stats/StatsPrinter.js
===================================================================
--- frontend/node_modules/webpack/lib/stats/StatsPrinter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/stats/StatsPrinter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,307 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { HookMap, SyncBailHook, SyncWaterfallHook } = require("tapable");
+
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunk} StatsChunk */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunkGroup} StatsChunkGroup */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsLogging} StatsLogging */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModule} StatsModule */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleIssuer} StatsModuleIssuer */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceDependency} StatsModuleTraceDependency */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceItem} StatsModuleTraceItem */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsProfile} StatsProfile */
+
+/**
+ * Defines the printed element type used by this module.
+ * @typedef {object} PrintedElement
+ * @property {string} element
+ * @property {string | undefined} content
+ */
+
+/**
+ * Defines the known stats printer context type used by this module.
+ * @typedef {object} KnownStatsPrinterContext
+ * @property {string=} type
+ * @property {StatsCompilation=} compilation
+ * @property {StatsChunkGroup=} chunkGroup
+ * @property {string=} chunkGroupKind
+ * @property {StatsAsset=} asset
+ * @property {StatsModule=} module
+ * @property {StatsChunk=} chunk
+ * @property {StatsModuleReason=} moduleReason
+ * @property {StatsModuleIssuer=} moduleIssuer
+ * @property {StatsError=} error
+ * @property {StatsProfile=} profile
+ * @property {StatsLogging=} logging
+ * @property {StatsModuleTraceItem=} moduleTraceItem
+ * @property {StatsModuleTraceDependency=} moduleTraceDependency
+ */
+
+/** @typedef {(value: string | number) => string} ColorFunction */
+
+/**
+ * Defines the known stats printer color functions type used by this module.
+ * @typedef {object} KnownStatsPrinterColorFunctions
+ * @property {ColorFunction=} bold
+ * @property {ColorFunction=} yellow
+ * @property {ColorFunction=} red
+ * @property {ColorFunction=} green
+ * @property {ColorFunction=} magenta
+ * @property {ColorFunction=} cyan
+ */
+
+/**
+ * Defines the known stats printer formatters type used by this module.
+ * @typedef {object} KnownStatsPrinterFormatters
+ * @property {(file: string, oversize?: boolean) => string=} formatFilename
+ * @property {(id: string | number) => string=} formatModuleId
+ * @property {(id: string | number, direction?: "parent" | "child" | "sibling") => string=} formatChunkId
+ * @property {(size: number) => string=} formatSize
+ * @property {(size: string) => string=} formatLayer
+ * @property {(dateTime: number) => string=} formatDateTime
+ * @property {(flag: string) => string=} formatFlag
+ * @property {(time: number, boldQuantity?: boolean) => string=} formatTime
+ * @property {(message: string) => string=} formatError
+ */
+
+/** @typedef {KnownStatsPrinterColorFunctions & KnownStatsPrinterFormatters & KnownStatsPrinterContext & Record<string, EXPECTED_ANY>} StatsPrinterContext */
+/** @typedef {StatsPrinterContext & Required<KnownStatsPrinterColorFunctions> & Required<KnownStatsPrinterFormatters> & { type: string }} StatsPrinterContextWithExtra */
+/** @typedef {EXPECTED_ANY} PrintObject */
+
+/**
+ * Represents the stats printer runtime component.
+ * @typedef {object} StatsPrintHooks
+ * @property {HookMap<SyncBailHook<[string[], StatsPrinterContext], void>>} sortElements
+ * @property {HookMap<SyncBailHook<[PrintedElement[], StatsPrinterContext], string | undefined | void>>} printElements
+ * @property {HookMap<SyncBailHook<[PrintObject[], StatsPrinterContext], boolean | void>>} sortItems
+ * @property {HookMap<SyncBailHook<[PrintObject, StatsPrinterContext], string | void>>} getItemName
+ * @property {HookMap<SyncBailHook<[string[], StatsPrinterContext], string | undefined>>} printItems
+ * @property {HookMap<SyncBailHook<[PrintObject, StatsPrinterContext], string | undefined | void>>} print
+ * @property {HookMap<SyncWaterfallHook<[string, StatsPrinterContext]>>} result
+ */
+
+class StatsPrinter {
+	constructor() {
+		/** @type {StatsPrintHooks} */
+		this.hooks = Object.freeze({
+			sortElements: new HookMap(
+				() => new SyncBailHook(["elements", "context"])
+			),
+			printElements: new HookMap(
+				() => new SyncBailHook(["printedElements", "context"])
+			),
+			sortItems: new HookMap(() => new SyncBailHook(["items", "context"])),
+			getItemName: new HookMap(() => new SyncBailHook(["item", "context"])),
+			printItems: new HookMap(
+				() => new SyncBailHook(["printedItems", "context"])
+			),
+			print: new HookMap(() => new SyncBailHook(["object", "context"])),
+			result: new HookMap(() => new SyncWaterfallHook(["result", "context"]))
+		});
+		/** @type {Map<StatsPrintHooks[keyof StatsPrintHooks], Map<string, import("tapable").Hook<EXPECTED_ANY, EXPECTED_ANY>[]>>} */
+		this._levelHookCache = new Map();
+		this._inPrint = false;
+	}
+
+	/**
+	 * get all level hooks
+	 * @private
+	 * @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
+	 * @template {HM extends HookMap<infer H> ? H : never} H
+	 * @param {HM} hookMap hook map
+	 * @param {string} type type
+	 * @returns {H[]} hooks
+	 */
+	_getAllLevelHooks(hookMap, type) {
+		let cache = this._levelHookCache.get(hookMap);
+		if (cache === undefined) {
+			cache = new Map();
+			this._levelHookCache.set(hookMap, cache);
+		}
+		const cacheEntry = cache.get(type);
+		if (cacheEntry !== undefined) {
+			return /** @type {H[]} */ (cacheEntry);
+		}
+		/** @type {H[]} */
+		const hooks = [];
+		const typeParts = type.split(".");
+		for (let i = 0; i < typeParts.length; i++) {
+			const hook = /** @type {H} */ (hookMap.get(typeParts.slice(i).join(".")));
+			if (hook) {
+				hooks.push(hook);
+			}
+		}
+		cache.set(type, hooks);
+		return hooks;
+	}
+
+	/**
+	 * Run `fn` for each level
+	 * @private
+	 * @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
+	 * @template {HM extends HookMap<infer H> ? H : never} H
+	 * @template {H extends import("tapable").Hook<EXPECTED_ANY, infer R> ? R : never} R
+	 * @param {HM} hookMap hook map
+	 * @param {string} type type
+	 * @param {(hooK: H) => R | undefined | void} fn fn
+	 * @returns {R | undefined} hook
+	 */
+	_forEachLevel(hookMap, type, fn) {
+		for (const hook of this._getAllLevelHooks(hookMap, type)) {
+			const result = fn(/** @type {H} */ (hook));
+			if (result !== undefined) return /** @type {R} */ (result);
+		}
+	}
+
+	/**
+	 * Run `fn` for each level
+	 * @private
+	 * @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
+	 * @template {HM extends HookMap<infer H> ? H : never} H
+	 * @param {HM} hookMap hook map
+	 * @param {string} type type
+	 * @param {string} data data
+	 * @param {(hook: H, data: string) => string} fn fn
+	 * @returns {string | undefined} result of `fn`
+	 */
+	_forEachLevelWaterfall(hookMap, type, data, fn) {
+		for (const hook of this._getAllLevelHooks(hookMap, type)) {
+			data = fn(/** @type {H} */ (hook), data);
+		}
+		return data;
+	}
+
+	/**
+	 * Returns printed result.
+	 * @param {string} type The type
+	 * @param {PrintObject} object Object to print
+	 * @param {StatsPrinterContext=} baseContext The base context
+	 * @returns {string | undefined} printed result
+	 */
+	print(type, object, baseContext) {
+		if (this._inPrint) {
+			return this._print(type, object, baseContext);
+		}
+		try {
+			this._inPrint = true;
+			return this._print(type, object, baseContext);
+		} finally {
+			this._levelHookCache.clear();
+			this._inPrint = false;
+		}
+	}
+
+	/**
+	 * Returns printed result.
+	 * @private
+	 * @param {string} type type
+	 * @param {PrintObject} object object
+	 * @param {StatsPrinterContext=} baseContext context
+	 * @returns {string | undefined} printed result
+	 */
+	_print(type, object, baseContext) {
+		/** @type {StatsPrinterContext} */
+		const context = {
+			...baseContext,
+			type,
+			[type]: object
+		};
+
+		/** @type {string | undefined} */
+		let printResult = this._forEachLevel(this.hooks.print, type, (hook) =>
+			hook.call(object, context)
+		);
+		if (printResult === undefined) {
+			if (Array.isArray(object)) {
+				const sortedItems = [...object];
+				this._forEachLevel(this.hooks.sortItems, type, (h) =>
+					h.call(
+						sortedItems,
+						/** @type {StatsPrinterContextWithExtra} */
+						(context)
+					)
+				);
+				const printedItems = sortedItems.map((item, i) => {
+					const itemContext =
+						/** @type {StatsPrinterContextWithExtra} */
+						({
+							...context,
+							_index: i
+						});
+					const itemName = this._forEachLevel(
+						this.hooks.getItemName,
+						`${type}[]`,
+						(h) => h.call(item, itemContext)
+					);
+					if (itemName) itemContext[itemName] = item;
+					return this.print(
+						itemName ? `${type}[].${itemName}` : `${type}[]`,
+						item,
+						itemContext
+					);
+				});
+				printResult = this._forEachLevel(this.hooks.printItems, type, (h) =>
+					h.call(
+						/** @type {string[]} */ (printedItems),
+						/** @type {StatsPrinterContextWithExtra} */
+						(context)
+					)
+				);
+				if (printResult === undefined) {
+					const result = printedItems.filter(Boolean);
+					if (result.length > 0) printResult = result.join("\n");
+				}
+			} else if (object !== null && typeof object === "object") {
+				const elements = Object.keys(object).filter(
+					(key) => object[key] !== undefined
+				);
+				this._forEachLevel(this.hooks.sortElements, type, (h) =>
+					h.call(
+						elements,
+						/** @type {StatsPrinterContextWithExtra} */
+						(context)
+					)
+				);
+				const printedElements = elements.map((element) => {
+					const content = this.print(`${type}.${element}`, object[element], {
+						...context,
+						_parent: object,
+						_element: element,
+						[element]: object[element]
+					});
+					return { element, content };
+				});
+				printResult = this._forEachLevel(this.hooks.printElements, type, (h) =>
+					h.call(
+						printedElements,
+						/** @type {StatsPrinterContextWithExtra} */
+						(context)
+					)
+				);
+				if (printResult === undefined) {
+					const result = printedElements.map((e) => e.content).filter(Boolean);
+					if (result.length > 0) printResult = result.join("\n");
+				}
+			}
+		}
+
+		return this._forEachLevelWaterfall(
+			this.hooks.result,
+			type,
+			/** @type {string} */
+			(printResult),
+			(h, r) => h.call(r, /** @type {StatsPrinterContextWithExtra} */ (context))
+		);
+	}
+}
+
+module.exports = StatsPrinter;
Index: frontend/node_modules/webpack/lib/typescript/TypeScriptPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/typescript/TypeScriptPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/typescript/TypeScriptPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,210 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const mod = require("module");
+const {
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+} = require("../ModuleTypeConstants");
+const NormalModule = require("../NormalModule");
+const ModuleBuildError = require("../errors/ModuleBuildError");
+const memoize = require("../util/memoize");
+const removeBOM = require("../util/removeBOM");
+
+/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../NormalModule")} NormalModuleType */
+/** @typedef {import("../NormalModule").Result} Result */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+
+const getSourceMapSource = memoize(
+	() => require("webpack-sources").SourceMapSource
+);
+
+const PLUGIN_NAME = "TypeScriptPlugin";
+
+/** @type {Set<string>} */
+const JS_MODULE_TYPES = new Set([
+	JAVASCRIPT_MODULE_TYPE_AUTO,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
+	JAVASCRIPT_MODULE_TYPE_ESM
+]);
+
+const TS_RESOURCE_RE = /\.(?:[mc]?tsx?)$/i;
+const TSX_RESOURCE_RE = /\.[mc]?tsx$/i;
+const TS_DATA_URI_RE = /^data:(?:text|application)\/typescript/i;
+
+const TSX_NOT_SUPPORTED =
+	"experiments.typescript does not support .tsx/JSX. " +
+	"Use a TSX-capable loader (e.g. swc-loader, esbuild-loader, ts-loader) for .tsx files.";
+
+const NODE_API_MISSING =
+	"experiments.typescript requires Node.js >= 22.6. " +
+	"`module.stripTypeScriptTypes` is not available on this Node.js version.";
+
+/**
+ * Whether the resource (path or `data:` URI) should go through the TypeScript
+ * transform. Returns true for `.ts`, `.cts`, `.mts`, and the JSX-flavoured
+ * variants (so the `.tsx` branch can throw a friendly error), as well as the
+ * `text/typescript` / `application/typescript` data URIs.
+ * @param {string} resource module resource (without query string)
+ * @returns {boolean} true if the resource should be transformed
+ */
+const isTypeScriptResource = (resource) =>
+	TS_RESOURCE_RE.test(resource) || TS_DATA_URI_RE.test(resource);
+
+/**
+ * Build a line-granularity identity source map for a strip-types output.
+ * `mode: "strip"` replaces type annotations with whitespace, so the stripped
+ * output preserves the original line layout — an identity mapping is correct.
+ * Node's API does not emit a source map in strip mode (`sourceMap: true` is
+ * rejected on Node 22+ and Node 26+), so we construct one by hand.
+ * @param {string} resource module resource path
+ * @param {string} originalSource pre-strip source content
+ * @returns {RawSourceMap} identity source map
+ */
+const createIdentitySourceMap = (resource, originalSource) => {
+	const lineCount = (originalSource.match(/\n/g) || []).length + 1;
+	// Mappings: each line emits a single segment at column 0 mapping to
+	// column 0 of the same line in the source. `AAAA` for line 1, `;AACA`
+	// for each subsequent line (cumulative source-line delta of +1 per line).
+	const mappings = `AAAA${";AACA".repeat(lineCount - 1)}`;
+
+	return {
+		version: 3,
+		file: resource,
+		sources: [resource],
+		sourcesContent: [originalSource],
+		names: [],
+		mappings
+	};
+};
+
+/**
+ * Compose the strip-types source map with an upstream loader source map so the
+ * final map points back to the loader's original input (e.g. a `.vue` /
+ * `.svelte` / custom loader that emits TS code).
+ * @param {string} resource module resource
+ * @param {string} strippedSource post-strip JS
+ * @param {RawSourceMap} stripMap identity map for the strip step
+ * @param {string} preStripSource pre-strip TS (loader output)
+ * @param {string | RawSourceMap} loaderSourceMap upstream loader source map
+ * @returns {RawSourceMap} composed map
+ */
+const composeWithLoaderSourceMap = (
+	resource,
+	strippedSource,
+	stripMap,
+	preStripSource,
+	loaderSourceMap
+) => {
+	const SourceMapSource = getSourceMapSource();
+	const composed = new SourceMapSource(
+		strippedSource,
+		resource,
+		stripMap,
+		preStripSource,
+		loaderSourceMap,
+		true
+	);
+	return /** @type {RawSourceMap} */ (composed.sourceAndMap().map) || stripMap;
+};
+
+/**
+ * Run `module.stripTypeScriptTypes` on the input, wrapping any thrown
+ * `TypeScript ...` errors as `ModuleBuildError` so they surface as
+ * per-module build errors instead of uncaught exceptions.
+ * @param {string} input pre-strip TS source (BOM-free string)
+ * @returns {string} stripped JS
+ */
+const stripTypes = (input) => {
+	try {
+		// Pass only `mode`. `sourceUrl` would emit a `//# sourceURL=…` pragma
+		// into the output (V8 debugger hint), and `sourceMap: true` is
+		// rejected in strip mode — we build the source map by hand instead.
+		// eslint-disable-next-line n/no-unsupported-features/node-builtins
+		return mod.stripTypeScriptTypes(input, { mode: "strip" });
+	} catch (err) {
+		throw new ModuleBuildError(/** @type {Error} */ (err));
+	}
+};
+
+/**
+ * Coerce a Buffer-or-string source to a UTF-8 string, dropping any BOM.
+ * @param {string | Buffer} source raw source from the loader pipeline
+ * @returns {string} UTF-8 string without BOM
+ */
+const toBomFreeString = (source) => {
+	const text = Buffer.isBuffer(source) ? source.toString("utf8") : source;
+	const stripped = removeBOM(text);
+	return typeof stripped === "string" ? stripped : stripped.toString("utf8");
+};
+
+class TypeScriptPlugin {
+	/**
+	 * @param {Compiler} compiler webpack compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			NormalModule.getCompilationHooks(compilation).processResult.tap(
+				PLUGIN_NAME,
+				(result, module) => this._processResult(result, module)
+			);
+		});
+	}
+
+	/**
+	 * processResult tap body. Returns the input untouched unless this is a
+	 * TypeScript module that needs to be transformed.
+	 * @param {Result} result loader result tuple
+	 * @param {NormalModuleType} module the normal module
+	 * @returns {Result} possibly transformed result
+	 */
+	_processResult(result, module) {
+		if (!JS_MODULE_TYPES.has(module.type)) return result;
+
+		const parser = /** @type {JavascriptParser} */ (module.parser);
+		if (!parser.options.typescript) return result;
+
+		const resource = module.nameForCondition();
+		if (!resource || !isTypeScriptResource(resource)) return result;
+
+		if (TSX_RESOURCE_RE.test(resource)) {
+			throw new ModuleBuildError(new Error(TSX_NOT_SUPPORTED));
+		}
+
+		if (!("stripTypeScriptTypes" in mod)) {
+			throw new ModuleBuildError(new Error(NODE_API_MISSING));
+		}
+
+		const [rawSource, loaderSourceMap, ...rest] = result;
+		const preStripSource = toBomFreeString(rawSource);
+		const strippedSource = stripTypes(preStripSource);
+
+		const needSourceMap = module.useSourceMap || module.useSimpleSourceMap;
+		const stripMap = needSourceMap
+			? createIdentitySourceMap(module.resource, preStripSource)
+			: undefined;
+
+		const outputSourceMap =
+			stripMap && loaderSourceMap
+				? composeWithLoaderSourceMap(
+						module.resource,
+						strippedSource,
+						stripMap,
+						preStripSource,
+						loaderSourceMap
+					)
+				: stripMap || loaderSourceMap;
+
+		return [strippedSource, outputSourceMap, ...rest];
+	}
+}
+
+module.exports = TypeScriptPlugin;
Index: frontend/node_modules/webpack/lib/url/URLParserPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/url/URLParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/url/URLParserPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,272 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Haijie Xie @hai-x
+*/
+
+"use strict";
+
+const { pathToFileURL } = require("url");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const ConstDependency = require("../dependencies/ConstDependency");
+const ContextDependencyHelpers = require("../dependencies/ContextDependencyHelpers");
+const URLContextDependency = require("../dependencies/URLContextDependency");
+const URLDependency = require("../dependencies/URLDependency");
+const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
+const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
+const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
+const { approve } = require("../javascript/JavascriptParserHelpers");
+const InnerGraph = require("../optimize/InnerGraph");
+
+/** @typedef {import("estree").MemberExpression} MemberExpression */
+/** @typedef {import("estree").NewExpression} NewExpressionNode */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+const PLUGIN_NAME = "URLParserPlugin";
+
+/**
+ * Returns file url.
+ * @param {NormalModule} module module
+ * @returns {URL} file url
+ */
+const getUrl = (module) => pathToFileURL(module.resource);
+
+/**
+ * Checks whether this object is meta url.
+ * @param {JavascriptParser} parser parser parser
+ * @param {MemberExpression} arg arg
+ * @returns {boolean} true when it is `meta.url`, otherwise false
+ */
+const isMetaUrl = (parser, arg) => {
+	const chain = parser.extractMemberExpressionChain(arg);
+
+	if (
+		chain.members.length !== 1 ||
+		chain.object.type !== "MetaProperty" ||
+		chain.object.meta.name !== "import" ||
+		chain.object.property.name !== "meta" ||
+		chain.members[0] !== "url"
+	) {
+		return false;
+	}
+
+	return true;
+};
+
+/** @type {WeakMap<NewExpressionNode, BasicEvaluatedExpression | undefined>} */
+const getEvaluatedExprCache = new WeakMap();
+
+/**
+ * Gets evaluated expr.
+ * @param {NewExpressionNode} expr expression
+ * @param {JavascriptParser} parser parser parser
+ * @returns {BasicEvaluatedExpression | undefined} basic evaluated expression
+ */
+const getEvaluatedExpr = (expr, parser) => {
+	let result = getEvaluatedExprCache.get(expr);
+	if (result !== undefined) return result;
+
+	/**
+	 * Returns basic evaluated expression.
+	 * @returns {BasicEvaluatedExpression | undefined} basic evaluated expression
+	 */
+	const evaluate = () => {
+		if (expr.arguments.length !== 2) return;
+
+		const [arg1, arg2] = expr.arguments;
+
+		if (arg2.type !== "MemberExpression" || arg1.type === "SpreadElement") {
+			return;
+		}
+		if (!isMetaUrl(parser, arg2)) return;
+
+		return parser.evaluateExpression(arg1);
+	};
+
+	result = evaluate();
+	getEvaluatedExprCache.set(expr, result);
+
+	return result;
+};
+
+class URLParserPlugin {
+	/**
+	 * Creates an instance of URLParserPlugin.
+	 * @param {JavascriptParserOptions} options options
+	 */
+	constructor(options) {
+		/** @type {JavascriptParserOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {JavascriptParser} parser the parser
+	 * @returns {void}
+	 */
+	apply(parser) {
+		const relative = this.options.url === "relative";
+
+		parser.hooks.canRename.for("URL").tap(PLUGIN_NAME, approve);
+		parser.hooks.evaluateNewExpression.for("URL").tap(PLUGIN_NAME, (expr) => {
+			const evaluatedExpr = getEvaluatedExpr(expr, parser);
+			const request = evaluatedExpr && evaluatedExpr.asString();
+
+			if (!request) return;
+			const url = new URL(request, getUrl(parser.state.module));
+
+			return new BasicEvaluatedExpression()
+				.setString(url.toString())
+				.setRange(/** @type {Range} */ (expr.range));
+		});
+		parser.hooks.new.for("URL").tap(PLUGIN_NAME, (_expr) => {
+			const expr = /** @type {NewExpressionNode} */ (_expr);
+			const { options: importOptions, errors: commentErrors } =
+				parser.parseCommentOptions(/** @type {Range} */ (expr.range));
+
+			if (commentErrors) {
+				for (const e of commentErrors) {
+					const { comment } = e;
+					parser.state.module.addWarning(
+						new CommentCompilationWarning(
+							`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
+							/** @type {DependencyLocation} */ (comment.loc)
+						)
+					);
+				}
+			}
+
+			if (importOptions && importOptions.webpackIgnore !== undefined) {
+				if (typeof importOptions.webpackIgnore !== "boolean") {
+					parser.state.module.addWarning(
+						new UnsupportedFeatureWarning(
+							`\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`,
+							/** @type {DependencyLocation} */ (expr.loc)
+						)
+					);
+					return;
+				} else if (importOptions.webpackIgnore) {
+					if (expr.arguments.length !== 2) return;
+
+					const [, arg2] = expr.arguments;
+
+					if (arg2.type !== "MemberExpression" || !isMetaUrl(parser, arg2)) {
+						return;
+					}
+
+					const dep = new ConstDependency(
+						RuntimeGlobals.baseURI,
+						/** @type {Range} */ (arg2.range),
+						[RuntimeGlobals.baseURI]
+					);
+					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+					parser.state.module.addPresentationalDependency(dep);
+
+					return true;
+				}
+			}
+
+			const evaluatedExpr = getEvaluatedExpr(expr, parser);
+			if (!evaluatedExpr) return;
+
+			/** @type {string | undefined} */
+			let request;
+
+			// static URL
+			if ((request = evaluatedExpr.asString())) {
+				const [arg1, arg2] = expr.arguments;
+				const dep = new URLDependency(
+					request,
+					[
+						/** @type {Range} */ (arg1.range)[0],
+						/** @type {Range} */ (arg2.range)[1]
+					],
+					/** @type {Range} */ (expr.range),
+					relative
+				);
+				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+				parser.state.current.addDependency(dep);
+				InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
+				return true;
+			}
+
+			if (this.options.dynamicUrl === false) return;
+
+			// context URL
+			/** @type {undefined | RegExp} */
+			let include;
+			/** @type {undefined | RegExp} */
+			let exclude;
+
+			if (importOptions) {
+				if (importOptions.webpackInclude !== undefined) {
+					if (
+						!importOptions.webpackInclude ||
+						!(importOptions.webpackInclude instanceof RegExp)
+					) {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackInclude\` expected a regular expression, but received: ${importOptions.webpackInclude}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else {
+						include = importOptions.webpackInclude;
+					}
+				}
+				if (importOptions.webpackExclude !== undefined) {
+					if (
+						!importOptions.webpackExclude ||
+						!(importOptions.webpackExclude instanceof RegExp)
+					) {
+						parser.state.module.addWarning(
+							new UnsupportedFeatureWarning(
+								`\`webpackExclude\` expected a regular expression, but received: ${importOptions.webpackExclude}.`,
+								/** @type {DependencyLocation} */ (expr.loc)
+							)
+						);
+					} else {
+						exclude = importOptions.webpackExclude;
+					}
+				}
+			}
+			const dep = ContextDependencyHelpers.create(
+				URLContextDependency,
+				/** @type {Range} */ (expr.range),
+				evaluatedExpr,
+				expr,
+				this.options,
+				{
+					include,
+					exclude,
+					mode: "sync",
+					typePrefix: "new URL with import.meta.url",
+					category: "url"
+				},
+				parser
+			);
+			if (!dep) return;
+			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
+			dep.optional = Boolean(parser.scope.inTry);
+			parser.state.current.addDependency(dep);
+			return true;
+		});
+		parser.hooks.isPure.for("NewExpression").tap(PLUGIN_NAME, (_expr) => {
+			const expr = /** @type {NewExpressionNode} */ (_expr);
+			const { callee } = expr;
+			if (callee.type !== "Identifier") return;
+			const calleeInfo = parser.getFreeInfoFromVariable(callee.name);
+			if (!calleeInfo || calleeInfo.name !== "URL") return;
+
+			const evaluatedExpr = getEvaluatedExpr(expr, parser);
+			const request = evaluatedExpr && evaluatedExpr.asString();
+
+			if (request) return true;
+		});
+	}
+}
+
+module.exports = URLParserPlugin;
Index: frontend/node_modules/webpack/lib/util/AppendOnlyStackedSet.js
===================================================================
--- frontend/node_modules/webpack/lib/util/AppendOnlyStackedSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/AppendOnlyStackedSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,93 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+/**
+ * Tracks values across a stack of nested sets where child scopes can add new
+ * values without mutating the sets created by their parents.
+ * @template T
+ */
+class AppendOnlyStackedSet {
+	/**
+	 * Seeds the stacked set with an optional chain of previously created scope
+	 * layers.
+	 * @param {Set<T>[]} sets an optional array of sets
+	 */
+	constructor(sets = []) {
+		/** @type {Set<T>[]} */
+		this._sets = sets;
+		/** @type {Set<T> | undefined} */
+		this._current = undefined;
+	}
+
+	/**
+	 * Adds a value to the current scope layer, creating that layer lazily when
+	 * the first write occurs.
+	 * @param {T} el element
+	 */
+	add(el) {
+		if (!this._current) {
+			this._current = new Set();
+			this._sets.push(this._current);
+		}
+		this._current.add(el);
+	}
+
+	/**
+	 * Checks whether a value is present in any scope layer currently visible to
+	 * this stacked set.
+	 * @param {T} el element
+	 * @returns {boolean} result
+	 */
+	has(el) {
+		for (const set of this._sets) {
+			if (set.has(el)) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Removes every scope layer and any values accumulated in them.
+	 */
+	clear() {
+		this._sets = [];
+		if (this._current) {
+			this._current = undefined;
+		}
+	}
+
+	/**
+	 * Creates a child stacked set that shares the existing scope history while
+	 * allowing subsequent additions to be recorded in its own new layer.
+	 * @returns {AppendOnlyStackedSet<T>} child
+	 */
+	createChild() {
+		return new AppendOnlyStackedSet(this._sets.length ? [...this._sets] : []);
+	}
+
+	/**
+	 * Iterates over the stacked sets from newest to oldest so consumers can
+	 * inspect recently added values first.
+	 * @returns {Iterator<T>} iterable iterator
+	 */
+	[Symbol.iterator]() {
+		const iterators = this._sets.map((map) => map[Symbol.iterator]());
+		let current = iterators.pop();
+		return {
+			next() {
+				if (!current) return { done: true, value: undefined };
+				let result = current.next();
+				while (result.done && iterators.length > 0) {
+					current = /** @type {SetIterator<T>} */ (iterators.pop());
+					result = current.next();
+				}
+				return result;
+			}
+		};
+	}
+}
+
+module.exports = AppendOnlyStackedSet;
Index: frontend/node_modules/webpack/lib/util/ArrayHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/util/ArrayHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/ArrayHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Compare two arrays or strings by performing strict equality check for each value.
+ * @template T
+ * @param {ArrayLike<T>} a Array of values to be compared
+ * @param {ArrayLike<T>} b Array of values to be compared
+ * @returns {boolean} returns true if all the elements of passed arrays are strictly equal.
+ */
+module.exports.equals = (a, b) => {
+	if (a.length !== b.length) return false;
+	for (let i = 0; i < a.length; i++) {
+		if (a[i] !== b[i]) return false;
+	}
+	return true;
+};
+
+/**
+ * Partition an array by calling a predicate function on each value.
+ * @template T
+ * @param {T[]} arr Array of values to be partitioned
+ * @param {(value: T) => boolean} fn Partition function which partitions based on truthiness of result.
+ * @returns {[T[], T[]]} returns the values of `arr` partitioned into two new arrays based on fn predicate.
+ */
+module.exports.groupBy = (
+	// eslint-disable-next-line default-param-last
+	arr = [],
+	fn
+) =>
+	arr.reduce(
+		/**
+		 * Handles the callback logic for this hook.
+		 * @param {[T[], T[]]} groups An accumulator storing already partitioned values returned from previous call.
+		 * @param {T} value The value of the current element
+		 * @returns {[T[], T[]]} returns an array of partitioned groups accumulator resulting from calling a predicate on the current value.
+		 */
+		(groups, value) => {
+			groups[fn(value) ? 0 : 1].push(value);
+			return groups;
+		},
+		[[], []]
+	);
Index: frontend/node_modules/webpack/lib/util/ArrayQueue.js
===================================================================
--- frontend/node_modules/webpack/lib/util/ArrayQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/ArrayQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,109 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * FIFO queue backed by arrays with a reversed dequeue buffer to avoid the cost
+ * of repeated `Array#shift` operations.
+ * @template T
+ */
+class ArrayQueue {
+	/**
+	 * Seeds the queue with an optional iterable of items in dequeue order.
+	 * @param {Iterable<T>=} items The initial elements.
+	 */
+	constructor(items) {
+		/**
+		 * @private
+		 * @type {T[]}
+		 */
+		this._list = items ? [...items] : [];
+		/**
+		 * @private
+		 * @type {T[]}
+		 */
+		this._listReversed = [];
+	}
+
+	/**
+	 * Returns the current number of items waiting in either internal buffer.
+	 * @returns {number} The number of elements in this queue.
+	 */
+	get length() {
+		return this._list.length + this._listReversed.length;
+	}
+
+	/**
+	 * Removes all pending items from both internal buffers.
+	 */
+	clear() {
+		this._list.length = 0;
+		this._listReversed.length = 0;
+	}
+
+	/**
+	 * Appends an item to the tail of the queue.
+	 * @param {T} item The element to add.
+	 * @returns {void}
+	 */
+	enqueue(item) {
+		this._list.push(item);
+	}
+
+	/**
+	 * Removes and returns the next item in FIFO order, switching to a reversed
+	 * buffer when that is cheaper than shifting from the front of the array.
+	 * @returns {T | undefined} The head of the queue of `undefined` if this queue is empty.
+	 */
+	dequeue() {
+		if (this._listReversed.length === 0) {
+			if (this._list.length === 0) return;
+			if (this._list.length === 1) return this._list.pop();
+			if (this._list.length < 16) return this._list.shift();
+			const temp = this._listReversed;
+			this._listReversed = this._list;
+			this._listReversed.reverse();
+			this._list = temp;
+		}
+		return this._listReversed.pop();
+	}
+
+	/**
+	 * Removes the first matching item from whichever internal buffer currently
+	 * contains it.
+	 * @param {T} item the item
+	 * @returns {void}
+	 */
+	delete(item) {
+		const i = this._list.indexOf(item);
+		if (i >= 0) {
+			this._list.splice(i, 1);
+		} else {
+			const i = this._listReversed.indexOf(item);
+			if (i >= 0) this._listReversed.splice(i, 1);
+		}
+	}
+
+	[Symbol.iterator]() {
+		return {
+			next: () => {
+				const item = this.dequeue();
+				if (item) {
+					return {
+						done: false,
+						value: item
+					};
+				}
+				return {
+					done: true,
+					value: undefined
+				};
+			}
+		};
+	}
+}
+
+module.exports = ArrayQueue;
Index: frontend/node_modules/webpack/lib/util/AsyncQueue.js
===================================================================
--- frontend/node_modules/webpack/lib/util/AsyncQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/AsyncQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,431 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { AsyncSeriesHook, SyncHook } = require("tapable");
+const { makeWebpackError } = require("../errors/HookWebpackError");
+const WebpackError = require("../errors/WebpackError");
+const ArrayQueue = require("./ArrayQueue");
+
+const QUEUED_STATE = 0;
+const PROCESSING_STATE = 1;
+const DONE_STATE = 2;
+
+let inHandleResult = 0;
+
+/**
+ * Defines the callback callback.
+ * @template T
+ * @callback Callback
+ * @param {(WebpackError | null)=} err
+ * @param {(T | null)=} result
+ * @returns {void}
+ */
+
+/**
+ * Represents AsyncQueueEntry.
+ * @template T
+ * @template K
+ * @template R
+ */
+class AsyncQueueEntry {
+	/**
+	 * Creates an instance of AsyncQueueEntry.
+	 * @param {T} item the item
+	 * @param {Callback<R>} callback the callback
+	 */
+	constructor(item, callback) {
+		this.item = item;
+		/** @type {typeof QUEUED_STATE | typeof PROCESSING_STATE | typeof DONE_STATE} */
+		this.state = QUEUED_STATE;
+		/** @type {Callback<R> | undefined} */
+		this.callback = callback;
+		/** @type {Callback<R>[] | undefined} */
+		this.callbacks = undefined;
+		/** @type {R | null | undefined} */
+		this.result = undefined;
+		/** @type {WebpackError | null | undefined} */
+		this.error = undefined;
+	}
+}
+
+/**
+ * Defines the get key type used by this module.
+ * @template T, K
+ * @typedef {(item: T) => K} getKey
+ */
+
+/**
+ * Defines the processor type used by this module.
+ * @template T, R
+ * @typedef {(item: T, callback: Callback<R>) => void} Processor
+ */
+
+/**
+ * Represents AsyncQueue.
+ * @template T
+ * @template K
+ * @template R
+ */
+class AsyncQueue {
+	/**
+	 * Creates an instance of AsyncQueue.
+	 * @param {object} options options object
+	 * @param {string=} options.name name of the queue
+	 * @param {number=} options.parallelism how many items should be processed at once
+	 * @param {string=} options.context context of execution
+	 * @param {AsyncQueue<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>=} options.parent parent queue, which will have priority over this queue and with shared parallelism
+	 * @param {getKey<T, K>=} options.getKey extract key from item
+	 * @param {Processor<T, R>} options.processor async function to process items
+	 */
+	constructor({ name, context, parallelism, parent, processor, getKey }) {
+		this._name = name;
+		this._context = context || "normal";
+		this._parallelism = parallelism || 1;
+		this._processor = processor;
+		this._getKey =
+			getKey ||
+			/** @type {getKey<T, K>} */ ((item) => /** @type {T & K} */ (item));
+		/** @type {Map<K, AsyncQueueEntry<T, K, R>>} */
+		this._entries = new Map();
+		/** @type {ArrayQueue<AsyncQueueEntry<T, K, R>>} */
+		this._queued = new ArrayQueue();
+		/** @type {AsyncQueue<T, K, R>[] | undefined} */
+		this._children = undefined;
+		this._activeTasks = 0;
+		this._willEnsureProcessing = false;
+		this._needProcessing = false;
+		this._stopped = false;
+		/** @type {AsyncQueue<T, K, R>} */
+		this._root = parent ? parent._root : this;
+		if (parent) {
+			if (this._root._children === undefined) {
+				this._root._children = [this];
+			} else {
+				this._root._children.push(this);
+			}
+		}
+
+		this.hooks = {
+			/** @type {AsyncSeriesHook<[T]>} */
+			beforeAdd: new AsyncSeriesHook(["item"]),
+			/** @type {SyncHook<[T]>} */
+			added: new SyncHook(["item"]),
+			/** @type {AsyncSeriesHook<[T]>} */
+			beforeStart: new AsyncSeriesHook(["item"]),
+			/** @type {SyncHook<[T]>} */
+			started: new SyncHook(["item"]),
+			/** @type {SyncHook<[T, WebpackError | null | undefined, R | null | undefined]>} */
+			result: new SyncHook(["item", "error", "result"])
+		};
+
+		this._ensureProcessing = this._ensureProcessing.bind(this);
+	}
+
+	/**
+	 * Returns context of execution.
+	 * @returns {string} context of execution
+	 */
+	getContext() {
+		return this._context;
+	}
+
+	/**
+	 * Updates context using the provided value.
+	 * @param {string} value context of execution
+	 */
+	setContext(value) {
+		this._context = value;
+	}
+
+	/**
+	 * Processes the provided item.
+	 * @param {T} item an item
+	 * @param {Callback<R>} callback callback function
+	 * @returns {void}
+	 */
+	add(item, callback) {
+		if (this._stopped) return callback(new WebpackError("Queue was stopped"));
+		this.hooks.beforeAdd.callAsync(item, (err) => {
+			if (err) {
+				callback(
+					makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeAdd`)
+				);
+				return;
+			}
+			const key = this._getKey(item);
+			const entry = this._entries.get(key);
+			if (entry !== undefined) {
+				if (entry.state === DONE_STATE) {
+					if (inHandleResult++ > 3) {
+						process.nextTick(() => callback(entry.error, entry.result));
+					} else {
+						callback(entry.error, entry.result);
+					}
+					inHandleResult--;
+				} else if (entry.callbacks === undefined) {
+					entry.callbacks = [callback];
+				} else {
+					entry.callbacks.push(callback);
+				}
+				return;
+			}
+			const newEntry = new AsyncQueueEntry(item, callback);
+			if (this._stopped) {
+				this.hooks.added.call(item);
+				this._root._activeTasks++;
+				process.nextTick(() =>
+					this._handleResult(newEntry, new WebpackError("Queue was stopped"))
+				);
+			} else {
+				this._entries.set(key, newEntry);
+				this._queued.enqueue(newEntry);
+				const root = this._root;
+				root._needProcessing = true;
+				if (root._willEnsureProcessing === false) {
+					root._willEnsureProcessing = true;
+					setImmediate(root._ensureProcessing);
+				}
+				this.hooks.added.call(item);
+			}
+		});
+	}
+
+	/**
+	 * Processes the provided item.
+	 * @param {T} item an item
+	 * @returns {void}
+	 */
+	invalidate(item) {
+		const key = this._getKey(item);
+		const entry =
+			/** @type {AsyncQueueEntry<T, K, R>} */
+			(this._entries.get(key));
+		this._entries.delete(key);
+		if (entry.state === QUEUED_STATE) {
+			this._queued.delete(entry);
+		}
+	}
+
+	/**
+	 * Waits for an already started item
+	 * @param {T} item an item
+	 * @param {Callback<R>} callback callback function
+	 * @returns {void}
+	 */
+	waitFor(item, callback) {
+		const key = this._getKey(item);
+		const entry = this._entries.get(key);
+		if (entry === undefined) {
+			return callback(
+				new WebpackError(
+					"waitFor can only be called for an already started item"
+				)
+			);
+		}
+		if (entry.state === DONE_STATE) {
+			process.nextTick(() => callback(entry.error, entry.result));
+		} else if (entry.callbacks === undefined) {
+			entry.callbacks = [callback];
+		} else {
+			entry.callbacks.push(callback);
+		}
+	}
+
+	/**
+	 * Describes how this stop operation behaves.
+	 * @returns {void}
+	 */
+	stop() {
+		this._stopped = true;
+		const queue = this._queued;
+		this._queued = new ArrayQueue();
+		const root = this._root;
+		for (const entry of queue) {
+			this._entries.delete(
+				this._getKey(/** @type {AsyncQueueEntry<T, K, R>} */ (entry).item)
+			);
+			root._activeTasks++;
+			this._handleResult(
+				/** @type {AsyncQueueEntry<T, K, R>} */ (entry),
+				new WebpackError("Queue was stopped")
+			);
+		}
+	}
+
+	/**
+	 * Increase parallelism.
+	 * @returns {void}
+	 */
+	increaseParallelism() {
+		const root = this._root;
+		root._parallelism++;
+		/* istanbul ignore next */
+		if (root._willEnsureProcessing === false && root._needProcessing) {
+			root._willEnsureProcessing = true;
+			setImmediate(root._ensureProcessing);
+		}
+	}
+
+	/**
+	 * Decrease parallelism.
+	 * @returns {void}
+	 */
+	decreaseParallelism() {
+		const root = this._root;
+		root._parallelism--;
+	}
+
+	/**
+	 * Checks whether this async queue is processing.
+	 * @param {T} item an item
+	 * @returns {boolean} true, if the item is currently being processed
+	 */
+	isProcessing(item) {
+		const key = this._getKey(item);
+		const entry = this._entries.get(key);
+		return entry !== undefined && entry.state === PROCESSING_STATE;
+	}
+
+	/**
+	 * Checks whether this async queue is queued.
+	 * @param {T} item an item
+	 * @returns {boolean} true, if the item is currently queued
+	 */
+	isQueued(item) {
+		const key = this._getKey(item);
+		const entry = this._entries.get(key);
+		return entry !== undefined && entry.state === QUEUED_STATE;
+	}
+
+	/**
+	 * Checks whether this async queue is done.
+	 * @param {T} item an item
+	 * @returns {boolean} true, if the item is currently queued
+	 */
+	isDone(item) {
+		const key = this._getKey(item);
+		const entry = this._entries.get(key);
+		return entry !== undefined && entry.state === DONE_STATE;
+	}
+
+	/**
+	 * Describes how this ensure processing operation behaves.
+	 * @returns {void}
+	 */
+	_ensureProcessing() {
+		while (this._activeTasks < this._parallelism) {
+			const entry = this._queued.dequeue();
+			if (entry === undefined) break;
+			this._activeTasks++;
+			entry.state = PROCESSING_STATE;
+			this._startProcessing(entry);
+		}
+		this._willEnsureProcessing = false;
+		if (this._queued.length > 0) return;
+		if (this._children !== undefined) {
+			for (const child of this._children) {
+				while (this._activeTasks < this._parallelism) {
+					const entry = child._queued.dequeue();
+					if (entry === undefined) break;
+					this._activeTasks++;
+					entry.state = PROCESSING_STATE;
+					child._startProcessing(entry);
+				}
+				if (child._queued.length > 0) return;
+			}
+		}
+		if (!this._willEnsureProcessing) this._needProcessing = false;
+	}
+
+	/**
+	 * Processes the provided entry.
+	 * @param {AsyncQueueEntry<T, K, R>} entry the entry
+	 * @returns {void}
+	 */
+	_startProcessing(entry) {
+		this.hooks.beforeStart.callAsync(entry.item, (err) => {
+			if (err) {
+				this._handleResult(
+					entry,
+					makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeStart`)
+				);
+				return;
+			}
+			let inCallback = false;
+			try {
+				this._processor(entry.item, (e, r) => {
+					inCallback = true;
+					this._handleResult(entry, e, r);
+				});
+			} catch (err) {
+				if (inCallback) throw err;
+				this._handleResult(entry, /** @type {WebpackError} */ (err), null);
+			}
+			this.hooks.started.call(entry.item);
+		});
+	}
+
+	/**
+	 * Processes the provided entry.
+	 * @param {AsyncQueueEntry<T, K, R>} entry the entry
+	 * @param {(WebpackError | null)=} err error, if any
+	 * @param {(R | null)=} result result, if any
+	 * @returns {void}
+	 */
+	_handleResult(entry, err, result) {
+		this.hooks.result.callAsync(entry.item, err, result, (hookError) => {
+			const error = hookError
+				? makeWebpackError(hookError, `AsyncQueue(${this._name}).hooks.result`)
+				: err;
+
+			const callback = /** @type {Callback<R>} */ (entry.callback);
+			const callbacks = entry.callbacks;
+			entry.state = DONE_STATE;
+			entry.callback = undefined;
+			entry.callbacks = undefined;
+			entry.result = result;
+			entry.error = error;
+
+			const root = this._root;
+			root._activeTasks--;
+			if (root._willEnsureProcessing === false && root._needProcessing) {
+				root._willEnsureProcessing = true;
+				setImmediate(root._ensureProcessing);
+			}
+
+			if (inHandleResult++ > 3) {
+				process.nextTick(() => {
+					callback(error, result);
+					if (callbacks !== undefined) {
+						for (const callback of callbacks) {
+							callback(error, result);
+						}
+					}
+				});
+			} else {
+				callback(error, result);
+				if (callbacks !== undefined) {
+					for (const callback of callbacks) {
+						callback(error, result);
+					}
+				}
+			}
+			inHandleResult--;
+		});
+	}
+
+	clear() {
+		this._entries.clear();
+		this._queued.clear();
+		this._activeTasks = 0;
+		this._willEnsureProcessing = false;
+		this._needProcessing = false;
+		this._stopped = false;
+	}
+}
+
+module.exports = AsyncQueue;
Index: frontend/node_modules/webpack/lib/util/Hash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/Hash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/Hash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,68 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").HashDigest} Encoding */
+/** @typedef {string | typeof Hash} HashFunction */
+
+class Hash {
+	/* istanbul ignore next */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @abstract
+	 * @overload
+	 * @param {string | Buffer} data data
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @abstract
+	 * @overload
+	 * @param {string} data data
+	 * @param {Encoding} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @abstract
+	 * @param {string | Buffer} data data
+	 * @param {Encoding=} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	update(data, inputEncoding) {
+		const AbstractMethodError = require("../errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+
+	/* istanbul ignore next */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @abstract
+	 * @overload
+	 * @returns {Buffer} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @abstract
+	 * @overload
+	 * @param {Encoding} encoding encoding of the return value
+	 * @returns {string} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @abstract
+	 * @param {Encoding=} encoding encoding of the return value
+	 * @returns {string | Buffer} digest
+	 */
+	digest(encoding) {
+		const AbstractMethodError = require("../errors/AbstractMethodError");
+
+		throw new AbstractMethodError();
+	}
+}
+
+module.exports = Hash;
Index: frontend/node_modules/webpack/lib/util/IterableHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/util/IterableHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/IterableHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,49 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Returns last item.
+ * @template T
+ * @param {Iterable<T>} set a set
+ * @returns {T | undefined} last item
+ */
+const last = (set) => {
+	/** @type {T | undefined} */
+	let last;
+	for (const item of set) last = item;
+	return last;
+};
+
+/**
+ * Returns true, if some items match the filter predicate.
+ * @template T
+ * @param {Iterable<T>} iterable iterable
+ * @param {(value: T) => boolean | null | undefined} filter predicate
+ * @returns {boolean} true, if some items match the filter predicate
+ */
+const someInIterable = (iterable, filter) => {
+	for (const item of iterable) {
+		if (filter(item)) return true;
+	}
+	return false;
+};
+
+/**
+ * Returns count of items.
+ * @template T
+ * @param {Iterable<T>} iterable an iterable
+ * @returns {number} count of items
+ */
+const countIterable = (iterable) => {
+	let i = 0;
+	for (const _ of iterable) i++;
+	return i;
+};
+
+module.exports.countIterable = countIterable;
+module.exports.last = last;
+module.exports.someInIterable = someInIterable;
Index: frontend/node_modules/webpack/lib/util/LazyBucketSortedSet.js
===================================================================
--- frontend/node_modules/webpack/lib/util/LazyBucketSortedSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/LazyBucketSortedSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,293 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { first } = require("./SetHelpers");
+const SortableSet = require("./SortableSet");
+
+/**
+ * Callback that extracts the grouping key for an item at one bucket layer.
+ * @template T
+ * @template K
+ * @typedef {(item: T) => K} GetKey
+ */
+
+/**
+ * Comparison function used to order keys or leaf items.
+ * @template T
+ * @typedef {(a: T, n: T) => number} Comparator
+ */
+
+/**
+ * Internal bucket entry, either another nested bucket set or a sorted leaf set.
+ * @template T
+ * @template K
+ * @typedef {LazyBucketSortedSet<T, K> | SortableSet<T>} Entry
+ */
+
+/**
+ * Constructor argument accepted for nested bucket layers or the final leaf
+ * comparator.
+ * @template T
+ * @template K
+ * @typedef {GetKey<T, K> | Comparator<K> | Comparator<T>} Arg
+ */
+
+/**
+ * Multi layer bucket sorted set:
+ * Supports adding non-existing items (DO NOT ADD ITEM TWICE),
+ * Supports removing exiting items (DO NOT REMOVE ITEM NOT IN SET),
+ * Supports popping the first items according to defined order,
+ * Supports iterating all items without order,
+ * Supports updating an item in an efficient way,
+ * Supports size property, which is the number of items,
+ * Items are lazy partially sorted when needed
+ * @template T
+ * @template K
+ */
+class LazyBucketSortedSet {
+	/**
+	 * Creates a lazily sorted, potentially multi-level bucket structure whose
+	 * order is only fully resolved when items are popped.
+	 * @param {GetKey<T, K>} getKey function to get key from item
+	 * @param {Comparator<K>=} comparator comparator to sort keys
+	 * @param {...Arg<T, K>} args more pairs of getKey and comparator plus optional final comparator for the last layer
+	 */
+	constructor(getKey, comparator, ...args) {
+		this._getKey = getKey;
+		this._innerArgs = args;
+		this._leaf = args.length <= 1;
+		this._keys = new SortableSet(undefined, comparator);
+		/** @type {Map<K, Entry<T, K>>} */
+		this._map = new Map();
+		/** @type {Set<T>} */
+		this._unsortedItems = new Set();
+		this.size = 0;
+	}
+
+	/**
+	 * Adds an item to the unsorted staging area so sorting can be deferred until
+	 * an ordered pop is requested.
+	 * @param {T} item an item
+	 * @returns {void}
+	 */
+	add(item) {
+		this.size++;
+		this._unsortedItems.add(item);
+	}
+
+	/**
+	 * Inserts an item into the correct nested bucket, creating intermediate
+	 * bucket structures on demand.
+	 * @param {K} key key of item
+	 * @param {T} item the item
+	 * @returns {void}
+	 */
+	_addInternal(key, item) {
+		let entry = this._map.get(key);
+		if (entry === undefined) {
+			entry = this._leaf
+				? new SortableSet(
+						undefined,
+						/** @type {Comparator<T>} */
+						(this._innerArgs[0])
+					)
+				: new LazyBucketSortedSet(
+						.../** @type {[GetKey<T, K>, Comparator<K>]} */
+						(this._innerArgs)
+					);
+			this._keys.add(key);
+			this._map.set(key, entry);
+		}
+		entry.add(item);
+	}
+
+	/**
+	 * Removes an item from either the unsorted staging area or its resolved
+	 * bucket and prunes empty buckets as needed.
+	 * @param {T} item an item
+	 * @returns {void}
+	 */
+	delete(item) {
+		this.size--;
+		if (this._unsortedItems.has(item)) {
+			this._unsortedItems.delete(item);
+			return;
+		}
+		const key = this._getKey(item);
+		const entry = /** @type {Entry<T, K>} */ (this._map.get(key));
+		entry.delete(item);
+		if (entry.size === 0) {
+			this._deleteKey(key);
+		}
+	}
+
+	/**
+	 * Removes an empty bucket key and its corresponding nested entry.
+	 * @param {K} key key to be removed
+	 * @returns {void}
+	 */
+	_deleteKey(key) {
+		this._keys.delete(key);
+		this._map.delete(key);
+	}
+
+	/**
+	 * Removes and returns the smallest item according to the configured bucket
+	 * order, sorting only the portions of the structure that are needed.
+	 * @returns {T | undefined} an item
+	 */
+	popFirst() {
+		if (this.size === 0) return;
+		this.size--;
+		if (this._unsortedItems.size > 0) {
+			for (const item of this._unsortedItems) {
+				const key = this._getKey(item);
+				this._addInternal(key, item);
+			}
+			this._unsortedItems.clear();
+		}
+		this._keys.sort();
+		const key = /** @type {K} */ (first(this._keys));
+		const entry = this._map.get(key);
+		if (this._leaf) {
+			const leafEntry = /** @type {SortableSet<T>} */ (entry);
+			leafEntry.sort();
+			const item = /** @type {T} */ (first(leafEntry));
+			leafEntry.delete(item);
+			if (leafEntry.size === 0) {
+				this._deleteKey(key);
+			}
+			return item;
+		}
+		const nodeEntry =
+			/** @type {LazyBucketSortedSet<T, K>} */
+			(entry);
+		const item = nodeEntry.popFirst();
+		if (nodeEntry.size === 0) {
+			this._deleteKey(key);
+		}
+		return item;
+	}
+
+	/**
+	 * Begins an in-place update for an item and returns a completion callback
+	 * that can either reinsert it under a new key or remove it entirely.
+	 * @param {T} item to be updated item
+	 * @returns {(remove?: true) => void} finish update
+	 */
+	startUpdate(item) {
+		if (this._unsortedItems.has(item)) {
+			return (remove) => {
+				if (remove) {
+					this._unsortedItems.delete(item);
+					this.size--;
+				}
+			};
+		}
+		const key = this._getKey(item);
+		if (this._leaf) {
+			const oldEntry = /** @type {SortableSet<T>} */ (this._map.get(key));
+			return (remove) => {
+				if (remove) {
+					this.size--;
+					oldEntry.delete(item);
+					if (oldEntry.size === 0) {
+						this._deleteKey(key);
+					}
+					return;
+				}
+				const newKey = this._getKey(item);
+				if (key === newKey) {
+					// This flags the sortable set as unordered
+					oldEntry.add(item);
+				} else {
+					oldEntry.delete(item);
+					if (oldEntry.size === 0) {
+						this._deleteKey(key);
+					}
+					this._addInternal(newKey, item);
+				}
+			};
+		}
+		const oldEntry =
+			/** @type {LazyBucketSortedSet<T, K>} */
+			(this._map.get(key));
+		const finishUpdate = oldEntry.startUpdate(item);
+		return (remove) => {
+			if (remove) {
+				this.size--;
+				finishUpdate(true);
+				if (oldEntry.size === 0) {
+					this._deleteKey(key);
+				}
+				return;
+			}
+			const newKey = this._getKey(item);
+			if (key === newKey) {
+				finishUpdate();
+			} else {
+				finishUpdate(true);
+				if (oldEntry.size === 0) {
+					this._deleteKey(key);
+				}
+				this._addInternal(newKey, item);
+			}
+		};
+	}
+
+	/**
+	 * Appends iterators for every stored bucket and leaf to support unordered
+	 * traversal across the entire structure.
+	 * @param {Iterator<T>[]} iterators list of iterators to append to
+	 * @returns {void}
+	 */
+	_appendIterators(iterators) {
+		if (this._unsortedItems.size > 0) {
+			iterators.push(this._unsortedItems[Symbol.iterator]());
+		}
+		for (const key of this._keys) {
+			const entry = this._map.get(key);
+			if (this._leaf) {
+				const leafEntry = /** @type {SortableSet<T>} */ (entry);
+				const iterator = leafEntry[Symbol.iterator]();
+				iterators.push(iterator);
+			} else {
+				const nodeEntry =
+					/** @type {LazyBucketSortedSet<T, K>} */
+					(entry);
+				nodeEntry._appendIterators(iterators);
+			}
+		}
+	}
+
+	/**
+	 * Iterates over all stored items without imposing bucket sort order.
+	 * @returns {Iterator<T>} the iterator
+	 */
+	[Symbol.iterator]() {
+		/** @type {Iterator<T>[]} */
+		const iterators = [];
+		this._appendIterators(iterators);
+		iterators.reverse();
+		let currentIterator =
+			/** @type {Iterator<T>} */
+			(iterators.pop());
+		return {
+			next: () => {
+				const res = currentIterator.next();
+				if (res.done) {
+					if (iterators.length === 0) return res;
+					currentIterator = /** @type {Iterator<T>} */ (iterators.pop());
+					return currentIterator.next();
+				}
+				return res;
+			}
+		};
+	}
+}
+
+module.exports = LazyBucketSortedSet;
Index: frontend/node_modules/webpack/lib/util/LazySet.js
===================================================================
--- frontend/node_modules/webpack/lib/util/LazySet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/LazySet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,275 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const makeSerializable = require("./makeSerializable");
+
+/**
+ * Merges every queued iterable directly into the concrete backing set.
+ * @template T
+ * @param {Set<T>} targetSet set where items should be added
+ * @param {Set<Iterable<T>>} toMerge iterables to be merged
+ * @returns {void}
+ */
+const merge = (targetSet, toMerge) => {
+	for (const set of toMerge) {
+		for (const item of set) {
+			targetSet.add(item);
+		}
+	}
+};
+
+/**
+ * Flattens nested `LazySet` instances into a single collection of iterables
+ * that can later be merged into the backing set.
+ * @template T
+ * @param {Set<Iterable<T>>} targetSet set where iterables should be added
+ * @param {LazySet<T>[]} toDeepMerge lazy sets to be flattened
+ * @returns {void}
+ */
+const flatten = (targetSet, toDeepMerge) => {
+	for (const set of toDeepMerge) {
+		if (set._set.size > 0) targetSet.add(set._set);
+		if (set._needMerge) {
+			for (const mergedSet of set._toMerge) {
+				targetSet.add(mergedSet);
+			}
+			flatten(targetSet, set._toDeepMerge);
+		}
+	}
+};
+
+/**
+ * Defines the set iterator type used by this module.
+ * @template T
+ * @typedef {import("typescript-iterable").SetIterator<T>} SetIterator
+ */
+
+/**
+ * Like Set but with an addAll method to eventually add items from another iterable.
+ * Access methods make sure that all delayed operations are executed.
+ * Iteration methods deopts to normal Set performance until clear is called again (because of the chance of modifications during iteration).
+ * @template T
+ */
+class LazySet {
+	/**
+	 * Seeds the set with an optional iterable while preparing internal queues for
+	 * deferred merges.
+	 * @param {Iterable<T>=} iterable init iterable
+	 */
+	constructor(iterable) {
+		/** @type {Set<T>} */
+		this._set = new Set(iterable);
+		/** @type {Set<Iterable<T>>} */
+		this._toMerge = new Set();
+		/** @type {LazySet<T>[]} */
+		this._toDeepMerge = [];
+		this._needMerge = false;
+		this._deopt = false;
+	}
+
+	/**
+	 * Flattens any nested lazy sets that were queued for merging.
+	 */
+	_flatten() {
+		flatten(this._toMerge, this._toDeepMerge);
+		this._toDeepMerge.length = 0;
+	}
+
+	/**
+	 * Materializes all deferred additions into the backing set.
+	 */
+	_merge() {
+		this._flatten();
+		merge(this._set, this._toMerge);
+		this._toMerge.clear();
+		this._needMerge = false;
+	}
+
+	/**
+	 * Reports whether the set is empty without forcing a full merge.
+	 * @returns {boolean} true when no items have been stored or queued
+	 */
+	_isEmpty() {
+		return (
+			this._set.size === 0 &&
+			this._toMerge.size === 0 &&
+			this._toDeepMerge.length === 0
+		);
+	}
+
+	/**
+	 * Returns the number of items after applying any deferred merges.
+	 * @returns {number} number of items in the set
+	 */
+	get size() {
+		if (this._needMerge) this._merge();
+		return this._set.size;
+	}
+
+	/**
+	 * Adds a single item immediately to the concrete backing set.
+	 * @param {T} item an item
+	 * @returns {LazySet<T>} itself
+	 */
+	add(item) {
+		this._set.add(item);
+		return this;
+	}
+
+	/**
+	 * Queues another iterable or lazy set for later merging so large bulk adds
+	 * can stay cheap until the set is read.
+	 * @param {Iterable<T> | LazySet<T>} iterable a immutable iterable or another immutable LazySet which will eventually be merged into the Set
+	 * @returns {LazySet<T>} itself
+	 */
+	addAll(iterable) {
+		if (this._deopt) {
+			const _set = this._set;
+			for (const item of iterable) {
+				_set.add(item);
+			}
+		} else {
+			if (iterable instanceof LazySet) {
+				if (iterable._isEmpty()) return this;
+				this._toDeepMerge.push(iterable);
+				this._needMerge = true;
+				if (this._toDeepMerge.length > 100000) {
+					this._flatten();
+				}
+			} else {
+				this._toMerge.add(iterable);
+				this._needMerge = true;
+			}
+			if (this._toMerge.size > 100000) this._merge();
+		}
+		return this;
+	}
+
+	/**
+	 * Removes all items and clears every deferred merge queue.
+	 */
+	clear() {
+		this._set.clear();
+		this._toMerge.clear();
+		this._toDeepMerge.length = 0;
+		this._needMerge = false;
+		this._deopt = false;
+	}
+
+	/**
+	 * Deletes an item after first materializing any deferred additions that may
+	 * contain it.
+	 * @param {T} value an item
+	 * @returns {boolean} true, if the value was in the Set before
+	 */
+	delete(value) {
+		if (this._needMerge) this._merge();
+		return this._set.delete(value);
+	}
+
+	/**
+	 * Returns the set's entry iterator and permanently switches future
+	 * operations to eager merge mode to preserve iterator correctness.
+	 * @returns {SetIterator<[T, T]>} entries
+	 */
+	entries() {
+		this._deopt = true;
+		if (this._needMerge) this._merge();
+		return this._set.entries();
+	}
+
+	/**
+	 * Iterates over every item after forcing pending merges and switching to
+	 * eager mode for correctness during iteration.
+	 * @template K
+	 * @param {(value: T, value2: T, set: Set<T>) => void} callbackFn function called for each entry
+	 * @param {K} thisArg this argument for the callbackFn
+	 * @returns {void}
+	 */
+	forEach(callbackFn, thisArg) {
+		this._deopt = true;
+		if (this._needMerge) this._merge();
+		// eslint-disable-next-line unicorn/no-array-for-each, unicorn/no-array-method-this-argument
+		this._set.forEach(callbackFn, thisArg);
+	}
+
+	/**
+	 * Checks whether an item is present after applying any deferred merges.
+	 * @param {T} item an item
+	 * @returns {boolean} true, when the item is in the Set
+	 */
+	has(item) {
+		if (this._needMerge) this._merge();
+		return this._set.has(item);
+	}
+
+	/**
+	 * Returns the key iterator, eagerly materializing pending merges first.
+	 * @returns {SetIterator<T>} keys
+	 */
+	keys() {
+		this._deopt = true;
+		if (this._needMerge) this._merge();
+		return this._set.keys();
+	}
+
+	/**
+	 * Returns the value iterator, eagerly materializing pending merges first.
+	 * @returns {SetIterator<T>} values
+	 */
+	values() {
+		this._deopt = true;
+		if (this._needMerge) this._merge();
+		return this._set.values();
+	}
+
+	/**
+	 * Returns the default iterator over values after forcing pending merges.
+	 * @returns {SetIterator<T>} iterable iterator
+	 */
+	[Symbol.iterator]() {
+		this._deopt = true;
+		if (this._needMerge) this._merge();
+		return this._set[Symbol.iterator]();
+	}
+
+	/* istanbul ignore next */
+	get [Symbol.toStringTag]() {
+		return "LazySet";
+	}
+
+	/**
+	 * Serializes the fully materialized set contents into webpack's object
+	 * serialization stream.
+	 * @param {import("../serialization/ObjectMiddleware").ObjectSerializerContext} context context
+	 */
+	serialize({ write }) {
+		if (this._needMerge) this._merge();
+		write(this._set.size);
+		for (const item of this._set) write(item);
+	}
+
+	/**
+	 * Restores a `LazySet` from serialized item data.
+	 * @template T
+	 * @param {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} context context
+	 * @returns {LazySet<T>} lazy set
+	 */
+	static deserialize({ read }) {
+		const count = read();
+		/** @type {T[]} */
+		const items = [];
+		for (let i = 0; i < count; i++) {
+			items.push(read());
+		}
+		return new LazySet(items);
+	}
+}
+
+makeSerializable(LazySet, "webpack/lib/util/LazySet");
+
+module.exports = LazySet;
Index: frontend/node_modules/webpack/lib/util/LocConverter.js
===================================================================
--- frontend/node_modules/webpack/lib/util/LocConverter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/LocConverter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,53 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+class LocConverter {
+	/**
+	 * Creates an instance of LocConverter.
+	 * @param {string} input input
+	 */
+	constructor(input) {
+		this._input = input;
+		this.line = 1;
+		this.column = 0;
+		this.pos = 0;
+	}
+
+	/**
+	 * Returns location converter.
+	 * @param {number} pos position
+	 * @returns {LocConverter} location converter
+	 */
+	get(pos) {
+		if (this.pos !== pos) {
+			if (this.pos < pos) {
+				const str = this._input.slice(this.pos, pos);
+				let i = str.lastIndexOf("\n");
+				if (i === -1) {
+					this.column += str.length;
+				} else {
+					this.column = str.length - i - 1;
+					this.line++;
+					while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1) {
+						this.line++;
+					}
+				}
+			} else {
+				let i = this._input.lastIndexOf("\n", this.pos);
+				while (i >= pos) {
+					this.line--;
+					i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1;
+				}
+				this.column = i === -1 ? pos : pos - i - 1;
+			}
+			this.pos = pos;
+		}
+		return this;
+	}
+}
+
+module.exports = LocConverter;
Index: frontend/node_modules/webpack/lib/util/MapHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/util/MapHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/MapHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * getOrInsert is a helper function for maps that allows you to get a value
+ * from a map if it exists, or insert a new value if it doesn't. If it value doesn't
+ * exist, it will be computed by the provided function.
+ * @template K
+ * @template V
+ * @param {Map<K, V>} map The map object to check
+ * @param {K} key The key to check
+ * @param {() => V} computer function which will compute the value if it doesn't exist
+ * @returns {V} The value from the map, or the computed value
+ * @example
+ * ```js
+ * const map = new Map();
+ * const value = getOrInsert(map, "key", () => "value");
+ * console.log(value); // "value"
+ * ```
+ */
+module.exports.getOrInsert = (map, key, computer) => {
+	// Grab key from map
+	const value = map.get(key);
+	// If the value already exists, return it
+	if (value !== undefined) return value;
+	// Otherwise compute the value, set it in the map, and return it
+	const newValue = computer();
+	map.set(key, newValue);
+	return newValue;
+};
Index: frontend/node_modules/webpack/lib/util/ParallelismFactorCalculator.js
===================================================================
--- frontend/node_modules/webpack/lib/util/ParallelismFactorCalculator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/ParallelismFactorCalculator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,71 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const binarySearchBounds = require("./binarySearchBounds");
+
+/** @typedef {(value: number) => void} Callback */
+
+class ParallelismFactorCalculator {
+	constructor() {
+		/** @type {number[]} */
+		this._rangePoints = [];
+		/** @type {Callback[]} */
+		this._rangeCallbacks = [];
+	}
+
+	/**
+	 * Processes the provided start.
+	 * @param {number} start range start
+	 * @param {number} end range end
+	 * @param {Callback} callback callback
+	 * @returns {void}
+	 */
+	range(start, end, callback) {
+		if (start === end) return callback(1);
+		this._rangePoints.push(start);
+		this._rangePoints.push(end);
+		this._rangeCallbacks.push(callback);
+	}
+
+	calculate() {
+		const segments = [...new Set(this._rangePoints)].sort((a, b) =>
+			a < b ? -1 : 1
+		);
+		const parallelism = segments.map(() => 0);
+		/** @type {number[]} */
+		const rangeStartIndices = [];
+		for (let i = 0; i < this._rangePoints.length; i += 2) {
+			const start = this._rangePoints[i];
+			const end = this._rangePoints[i + 1];
+			let idx = binarySearchBounds.eq(segments, start);
+			rangeStartIndices.push(idx);
+			do {
+				parallelism[idx]++;
+				idx++;
+			} while (segments[idx] < end);
+		}
+		for (let i = 0; i < this._rangeCallbacks.length; i++) {
+			const start = this._rangePoints[i * 2];
+			const end = this._rangePoints[i * 2 + 1];
+			let idx = rangeStartIndices[i];
+			let sum = 0;
+			let totalDuration = 0;
+			let current = start;
+			do {
+				const p = parallelism[idx];
+				idx++;
+				const duration = segments[idx] - current;
+				totalDuration += duration;
+				current = segments[idx];
+				sum += p * duration;
+			} while (current < end);
+			this._rangeCallbacks[i](sum / totalDuration);
+		}
+	}
+}
+
+module.exports = ParallelismFactorCalculator;
Index: frontend/node_modules/webpack/lib/util/Queue.js
===================================================================
--- frontend/node_modules/webpack/lib/util/Queue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/Queue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,55 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * FIFO queue that keeps items unique by storing them in insertion order inside
+ * a `Set`.
+ * @template T
+ */
+class Queue {
+	/**
+	 * Seeds the queue with an optional iterable of initial unique items.
+	 * @param {Iterable<T>=} items The initial elements.
+	 */
+	constructor(items) {
+		/**
+		 * @private
+		 * @type {Set<T>}
+		 */
+		this._set = new Set(items);
+	}
+
+	/**
+	 * Returns the number of unique items currently waiting in the queue.
+	 * @returns {number} The number of elements in this queue.
+	 */
+	get length() {
+		return this._set.size;
+	}
+
+	/**
+	 * Enqueues an item, moving nothing if that value is already present.
+	 * @param {T} item The element to add.
+	 * @returns {void}
+	 */
+	enqueue(item) {
+		this._set.add(item);
+	}
+
+	/**
+	 * Removes and returns the oldest enqueued item.
+	 * @returns {T | undefined} The head of the queue of `undefined` if this queue is empty.
+	 */
+	dequeue() {
+		const result = this._set[Symbol.iterator]().next();
+		if (result.done) return;
+		this._set.delete(result.value);
+		return result.value;
+	}
+}
+
+module.exports = Queue;
Index: frontend/node_modules/webpack/lib/util/Semaphore.js
===================================================================
--- frontend/node_modules/webpack/lib/util/Semaphore.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/Semaphore.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,64 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Simple counting semaphore used to limit how many asynchronous tasks may run
+ * concurrently.
+ */
+class Semaphore {
+	/**
+	 * Initializes the semaphore with the number of permits that may be held at
+	 * the same time.
+	 * @param {number} available the amount available number of "tasks"
+	 * in the Semaphore
+	 */
+	constructor(available) {
+		this.available = available;
+		/** @type {(() => void)[]} */
+		this.waiters = [];
+		/** @private */
+		this._continue = this._continue.bind(this);
+	}
+
+	/**
+	 * Acquires a permit for the callback immediately when one is available or
+	 * queues the callback until another task releases its permit.
+	 * @param {() => void} callback function block to capture and run
+	 * @returns {void}
+	 */
+	acquire(callback) {
+		if (this.available > 0) {
+			this.available--;
+			callback();
+		} else {
+			this.waiters.push(callback);
+		}
+	}
+
+	/**
+	 * Releases a permit and schedules the next waiting callback, if any.
+	 */
+	release() {
+		this.available++;
+		if (this.waiters.length > 0) {
+			process.nextTick(this._continue);
+		}
+	}
+
+	/**
+	 * Drains the next waiting callback after a permit becomes available.
+	 */
+	_continue() {
+		if (this.available > 0 && this.waiters.length > 0) {
+			this.available--;
+			const callback = /** @type {(() => void)} */ (this.waiters.pop());
+			callback();
+		}
+	}
+}
+
+module.exports = Semaphore;
Index: frontend/node_modules/webpack/lib/util/SetHelpers.js
===================================================================
--- frontend/node_modules/webpack/lib/util/SetHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/SetHelpers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,97 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * intersect creates Set containing the intersection of elements between all sets
+ * @template T
+ * @param {Set<T>[]} sets an array of sets being checked for shared elements
+ * @returns {Set<T>} returns a new Set containing the intersecting items
+ */
+const intersect = (sets) => {
+	if (sets.length === 0) return new Set();
+	if (sets.length === 1) return new Set(sets[0]);
+	let minSize = Infinity;
+	let minIndex = -1;
+	for (let i = 0; i < sets.length; i++) {
+		const size = sets[i].size;
+		if (size < minSize) {
+			minIndex = i;
+			minSize = size;
+		}
+	}
+	const current = new Set(sets[minIndex]);
+	for (let i = 0; i < sets.length; i++) {
+		if (i === minIndex) continue;
+		const set = sets[i];
+		for (const item of current) {
+			if (!set.has(item)) {
+				current.delete(item);
+			}
+		}
+	}
+	return current;
+};
+
+/**
+ * Checks if a set is the subset of another set
+ * @template T
+ * @param {Set<T>} bigSet a Set which contains the original elements to compare against
+ * @param {Set<T>} smallSet the set whose elements might be contained inside of bigSet
+ * @returns {boolean} returns true if smallSet contains all elements inside of the bigSet
+ */
+const isSubset = (bigSet, smallSet) => {
+	if (bigSet.size < smallSet.size) return false;
+	for (const item of smallSet) {
+		if (!bigSet.has(item)) return false;
+	}
+	return true;
+};
+
+/**
+ * Returns found item.
+ * @template T
+ * @param {Set<T>} set a set
+ * @param {(set: T) => boolean} fn selector function
+ * @returns {T | undefined} found item
+ */
+const find = (set, fn) => {
+	for (const item of set) {
+		if (fn(item)) return item;
+	}
+};
+
+/**
+ * Returns first item.
+ * @template T
+ * @param {Set<T> | ReadonlySet<T>} set a set
+ * @returns {T | undefined} first item
+ */
+const first = (set) => {
+	const entry = set.values().next();
+	return entry.done ? undefined : entry.value;
+};
+
+/**
+ * Returns combined set, may be identical to a or b.
+ * @template T
+ * @param {Set<T>} a first
+ * @param {Set<T>} b second
+ * @returns {Set<T>} combined set, may be identical to a or b
+ */
+const combine = (a, b) => {
+	if (b.size === 0) return a;
+	if (a.size === 0) return b;
+	const set = new Set(a);
+	for (const item of b) set.add(item);
+	return set;
+};
+
+module.exports.combine = combine;
+module.exports.find = find;
+module.exports.first = first;
+module.exports.intersect = intersect;
+module.exports.isSubset = isSubset;
Index: frontend/node_modules/webpack/lib/util/SortableSet.js
===================================================================
--- frontend/node_modules/webpack/lib/util/SortableSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/SortableSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,182 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const NONE = Symbol("not sorted");
+
+/**
+ * A subset of Set that offers sorting functionality
+ * @template T item type in set
+ * @extends {Set<T>}
+ */
+class SortableSet extends Set {
+	/**
+	 * Create a new sortable set
+	 * @template T
+	 * @typedef {(a: T, b: T) => number} SortFunction
+	 * @param {Iterable<T>=} initialIterable The initial iterable value
+	 * @param {SortFunction<T>=} defaultSort Default sorting function
+	 */
+	constructor(initialIterable, defaultSort) {
+		super(initialIterable);
+		/**
+		 * @private
+		 * @type {undefined | SortFunction<T>}
+		 */
+		this._sortFn = defaultSort;
+		/**
+		 * @private
+		 * @type {typeof NONE | undefined | ((a: T, b: T) => number)}}
+		 */
+		this._lastActiveSortFn = NONE;
+		/**
+		 * @private
+		 * @template R
+		 * @type {Map<(set: SortableSet<T>) => EXPECTED_ANY, EXPECTED_ANY> | undefined}
+		 */
+		this._cache = undefined;
+		/**
+		 * @private
+		 * @template R
+		 * @type {Map<(set: SortableSet<T>) => EXPECTED_ANY, EXPECTED_ANY> | undefined}
+		 */
+		this._cacheOrderIndependent = undefined;
+	}
+
+	/**
+	 * Returns itself.
+	 * @param {T} value value to add to set
+	 * @returns {this} returns itself
+	 */
+	add(value) {
+		this._lastActiveSortFn = NONE;
+		this._invalidateCache();
+		this._invalidateOrderedCache();
+		super.add(value);
+		return this;
+	}
+
+	/**
+	 * Returns true if value existed in set, false otherwise.
+	 * @param {T} value value to delete
+	 * @returns {boolean} true if value existed in set, false otherwise
+	 */
+	delete(value) {
+		this._invalidateCache();
+		this._invalidateOrderedCache();
+		return super.delete(value);
+	}
+
+	/**
+	 * Describes how this clear operation behaves.
+	 * @returns {void}
+	 */
+	clear() {
+		this._invalidateCache();
+		this._invalidateOrderedCache();
+		return super.clear();
+	}
+
+	/**
+	 * Sort with a comparer function
+	 * @param {SortFunction<T> | undefined} sortFn Sorting comparer function
+	 * @returns {void}
+	 */
+	sortWith(sortFn) {
+		if (this.size <= 1 || sortFn === this._lastActiveSortFn) {
+			// already sorted - nothing to do
+			return;
+		}
+
+		/** @type {T[]} */
+		const sortedArray = [...this].sort(sortFn);
+		super.clear();
+		for (let i = 0; i < sortedArray.length; i += 1) {
+			super.add(sortedArray[i]);
+		}
+		this._lastActiveSortFn = sortFn;
+		this._invalidateCache();
+	}
+
+	sort() {
+		this.sortWith(this._sortFn);
+		return this;
+	}
+
+	/**
+	 * Get data from cache
+	 * @template R
+	 * @param {(set: SortableSet<T>) => R} fn function to calculate value
+	 * @returns {R} returns result of fn(this), cached until set changes
+	 */
+	getFromCache(fn) {
+		if (this._cache === undefined) {
+			this._cache = new Map();
+		} else {
+			const result = this._cache.get(fn);
+			const data = /** @type {R} */ (result);
+			if (data !== undefined) {
+				return data;
+			}
+		}
+		const newData = fn(this);
+		this._cache.set(fn, newData);
+		return newData;
+	}
+
+	/**
+	 * Get data from cache (ignoring sorting)
+	 * @template R
+	 * @param {(set: SortableSet<T>) => R} fn function to calculate value
+	 * @returns {R} returns result of fn(this), cached until set changes
+	 */
+	getFromUnorderedCache(fn) {
+		if (this._cacheOrderIndependent === undefined) {
+			this._cacheOrderIndependent = new Map();
+		} else {
+			const result = this._cacheOrderIndependent.get(fn);
+			const data = /** @type {R} */ (result);
+			if (data !== undefined) {
+				return data;
+			}
+		}
+		const newData = fn(this);
+		this._cacheOrderIndependent.set(fn, newData);
+		return newData;
+	}
+
+	/**
+	 * Invalidates the cached state associated with this value.
+	 * @private
+	 * @returns {void}
+	 */
+	_invalidateCache() {
+		if (this._cache !== undefined) {
+			this._cache.clear();
+		}
+	}
+
+	/**
+	 * Invalidate ordered cache.
+	 * @private
+	 * @returns {void}
+	 */
+	_invalidateOrderedCache() {
+		if (this._cacheOrderIndependent !== undefined) {
+			this._cacheOrderIndependent.clear();
+		}
+	}
+
+	/**
+	 * Returns the raw array.
+	 * @returns {T[]} the raw array
+	 */
+	toJSON() {
+		return [...this];
+	}
+}
+
+module.exports = SortableSet;
Index: frontend/node_modules/webpack/lib/util/StackedCacheMap.js
===================================================================
--- frontend/node_modules/webpack/lib/util/StackedCacheMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/StackedCacheMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,157 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * The StackedCacheMap is a data structure designed as an alternative to a Map
+ * in situations where you need to handle multiple item additions and
+ * frequently access the largest map.
+ *
+ * It is particularly optimized for efficiently adding multiple items
+ * at once, which can be achieved using the `addAll` method.
+ *
+ * It has a fallback Map that is used when the map to be added is mutable.
+ *
+ * Note: `delete` and `has` are not supported for performance reasons.
+ * @example
+ * ```js
+ * const map = new StackedCacheMap();
+ * map.addAll(new Map([["a", 1], ["b", 2]]), true);
+ * map.addAll(new Map([["c", 3], ["d", 4]]), true);
+ * map.get("a"); // 1
+ * map.get("d"); // 4
+ * for (const [key, value] of map) {
+ * 		console.log(key, value);
+ * }
+ * ```
+ * @template K
+ * @template V
+ */
+class StackedCacheMap {
+	/**
+	 * Initializes the mutable fallback map and the stack of immutable cache
+	 * layers.
+	 */
+	constructor() {
+		/** @type {Map<K, V>} */
+		this.map = new Map();
+		/** @type {ReadonlyMap<K, V>[]} */
+		this.stack = [];
+	}
+
+	/**
+	 * Adds another cache layer. Immutable maps are retained by reference and
+	 * reordered so larger layers are checked first, while mutable maps are
+	 * copied into the fallback map.
+	 * @param {ReadonlyMap<K, V>} map map to add
+	 * @param {boolean=} immutable if 'map' is immutable and StackedCacheMap can keep referencing it
+	 */
+	addAll(map, immutable) {
+		if (immutable) {
+			this.stack.push(map);
+
+			// largest map should go first
+			for (let i = this.stack.length - 1; i > 0; i--) {
+				const beforeLast = this.stack[i - 1];
+				if (beforeLast.size >= map.size) break;
+				this.stack[i] = beforeLast;
+				this.stack[i - 1] = map;
+			}
+		} else {
+			for (const [key, value] of map) {
+				this.map.set(key, value);
+			}
+		}
+	}
+
+	/**
+	 * Stores or overrides a value in the mutable fallback map.
+	 * @param {K} item the key of the element to add
+	 * @param {V} value the value of the element to add
+	 * @returns {void}
+	 */
+	set(item, value) {
+		this.map.set(item, value);
+	}
+
+	/**
+	 * Rejects deletions because this data structure is optimized for append-only
+	 * cache layers.
+	 * @param {K} item the item to delete
+	 * @returns {void}
+	 */
+	delete(item) {
+		throw new Error("Items can't be deleted from a StackedCacheMap");
+	}
+
+	/**
+	 * Rejects `has` checks because they would force the same layered lookup work
+	 * as `get` without returning the cached value.
+	 * @param {K} item the item to test
+	 * @returns {boolean} true if the item exists in this set
+	 */
+	has(item) {
+		throw new Error(
+			"Checking StackedCacheMap.has before reading is inefficient, use StackedCacheMap.get and check for undefined"
+		);
+	}
+
+	/**
+	 * Looks up a key by scanning immutable cache layers first and then the
+	 * mutable fallback map.
+	 * @param {K} item the key of the element to return
+	 * @returns {V | undefined} the value of the element
+	 */
+	get(item) {
+		for (const map of this.stack) {
+			const value = map.get(item);
+			if (value !== undefined) return value;
+		}
+		return this.map.get(item);
+	}
+
+	/**
+	 * Removes every cache layer and clears the mutable fallback map.
+	 */
+	clear() {
+		this.stack.length = 0;
+		this.map.clear();
+	}
+
+	/**
+	 * Returns the total number of entries across the fallback map and all stacked
+	 * cache layers.
+	 * @returns {number} size of the map
+	 */
+	get size() {
+		let size = this.map.size;
+		for (const map of this.stack) {
+			size += map.size;
+		}
+		return size;
+	}
+
+	/**
+	 * Iterates over the fallback map first and then each stacked cache layer.
+	 * @returns {Iterator<[K, V]>} iterator
+	 */
+	[Symbol.iterator]() {
+		const iterators = this.stack.map((map) => map[Symbol.iterator]());
+		let current = this.map[Symbol.iterator]();
+		return {
+			next() {
+				let result = current.next();
+				while (result.done && iterators.length > 0) {
+					current = /** @type {MapIterator<[K, V]>} */ (iterators.pop());
+					result = current.next();
+				}
+				return result;
+			}
+		};
+	}
+}
+
+module.exports = StackedCacheMap;
Index: frontend/node_modules/webpack/lib/util/StackedMap.js
===================================================================
--- frontend/node_modules/webpack/lib/util/StackedMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/StackedMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,209 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const TOMBSTONE = Symbol("tombstone");
+const UNDEFINED_MARKER = Symbol("undefined");
+
+/**
+ * Public cell value exposed by `StackedMap`, where `undefined` is preserved as
+ * a valid stored result.
+ * @template T
+ * @typedef {T | undefined} Cell<T>
+ */
+
+/**
+ * Internal cell value used to distinguish deleted entries and explicit
+ * `undefined` assignments while traversing stacked scopes.
+ * @template T
+ * @typedef {T | typeof TOMBSTONE | typeof UNDEFINED_MARKER} InternalCell<T>
+ */
+
+/**
+ * Converts an internal key/value pair into the external representation returned
+ * by iteration helpers.
+ * @template K
+ * @template V
+ * @param {[K, InternalCell<V>]} pair the internal cell
+ * @returns {[K, Cell<V>]} its “safe” representation
+ */
+const extractPair = (pair) => {
+	const key = pair[0];
+	const val = pair[1];
+	if (val === UNDEFINED_MARKER || val === TOMBSTONE) {
+		return [key, undefined];
+	}
+	return /** @type {[K, Cell<V>]} */ (pair);
+};
+
+/**
+ * Layered map that supports child scopes while memoizing lookups from parent
+ * scopes into the current layer.
+ * @template K
+ * @template V
+ */
+class StackedMap {
+	/**
+	 * Creates a new map layer on top of an optional parent stack.
+	 * @param {Map<K, InternalCell<V>>[]=} parentStack an optional parent
+	 */
+	constructor(parentStack) {
+		/** @type {Map<K, InternalCell<V>>} */
+		this.map = new Map();
+		/** @type {Map<K, InternalCell<V>>[]} */
+		this.stack = parentStack === undefined ? [] : [...parentStack];
+		this.stack.push(this.map);
+	}
+
+	/**
+	 * Stores a value in the current layer, preserving explicit `undefined`
+	 * values with an internal marker.
+	 * @param {K} item the key of the element to add
+	 * @param {V} value the value of the element to add
+	 * @returns {void}
+	 */
+	set(item, value) {
+		this.map.set(item, value === undefined ? UNDEFINED_MARKER : value);
+	}
+
+	/**
+	 * Deletes a key from the current view, either by removing it outright in the
+	 * root layer or by recording a tombstone in child layers.
+	 * @param {K} item the item to delete
+	 * @returns {void}
+	 */
+	delete(item) {
+		if (this.stack.length > 1) {
+			this.map.set(item, TOMBSTONE);
+		} else {
+			this.map.delete(item);
+		}
+	}
+
+	/**
+	 * Checks whether a key exists in the current scope chain, caching any parent
+	 * lookup result in the current layer.
+	 * @param {K} item the item to test
+	 * @returns {boolean} true if the item exists in this set
+	 */
+	has(item) {
+		const topValue = this.map.get(item);
+		if (topValue !== undefined) {
+			return topValue !== TOMBSTONE;
+		}
+		if (this.stack.length > 1) {
+			for (let i = this.stack.length - 2; i >= 0; i--) {
+				const value = this.stack[i].get(item);
+				if (value !== undefined) {
+					this.map.set(item, value);
+					return value !== TOMBSTONE;
+				}
+			}
+			this.map.set(item, TOMBSTONE);
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the visible value for a key, caching parent hits and misses in the
+	 * current layer.
+	 * @param {K} item the key of the element to return
+	 * @returns {Cell<V>} the value of the element
+	 */
+	get(item) {
+		const topValue = this.map.get(item);
+		if (topValue !== undefined) {
+			return topValue === TOMBSTONE || topValue === UNDEFINED_MARKER
+				? undefined
+				: topValue;
+		}
+		if (this.stack.length > 1) {
+			for (let i = this.stack.length - 2; i >= 0; i--) {
+				const value = this.stack[i].get(item);
+				if (value !== undefined) {
+					this.map.set(item, value);
+					return value === TOMBSTONE || value === UNDEFINED_MARKER
+						? undefined
+						: value;
+				}
+			}
+			this.map.set(item, TOMBSTONE);
+		}
+	}
+
+	/**
+	 * Collapses the stacked layers into a single concrete map.
+	 */
+	_compress() {
+		if (this.stack.length === 1) return;
+		this.map = new Map();
+		for (const data of this.stack) {
+			for (const pair of data) {
+				if (pair[1] === TOMBSTONE) {
+					this.map.delete(pair[0]);
+				} else {
+					this.map.set(pair[0], pair[1]);
+				}
+			}
+		}
+		this.stack = [this.map];
+	}
+
+	/**
+	 * Returns the visible keys as an array after collapsing the stack.
+	 * @returns {K[]} array of keys
+	 */
+	asArray() {
+		this._compress();
+		return [...this.map.keys()];
+	}
+
+	/**
+	 * Returns the visible keys as a `Set` after collapsing the stack.
+	 * @returns {Set<K>} set of keys
+	 */
+	asSet() {
+		this._compress();
+		return new Set(this.map.keys());
+	}
+
+	/**
+	 * Returns visible key/value pairs using the external representation.
+	 * @returns {[K, Cell<V>][]} array of key/value pairs
+	 */
+	asPairArray() {
+		this._compress();
+		return Array.from(this.map.entries(), extractPair);
+	}
+
+	/**
+	 * Returns the visible contents as a plain `Map`.
+	 * @returns {Map<K, Cell<V>>} materialized map
+	 */
+	asMap() {
+		return new Map(this.asPairArray());
+	}
+
+	/**
+	 * Returns the number of visible keys after collapsing the stack.
+	 * @returns {number} number of keys
+	 */
+	get size() {
+		this._compress();
+		return this.map.size;
+	}
+
+	/**
+	 * Creates a child `StackedMap` that sees the current layers as its parent
+	 * scope.
+	 * @returns {StackedMap<K, V>} child map
+	 */
+	createChild() {
+		return new StackedMap(this.stack);
+	}
+}
+
+module.exports = StackedMap;
Index: frontend/node_modules/webpack/lib/util/StringXor.js
===================================================================
--- frontend/node_modules/webpack/lib/util/StringXor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/StringXor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,103 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../util/Hash")} Hash */
+
+/**
+ * StringXor class provides methods for performing
+ * [XOR operations](https://en.wikipedia.org/wiki/Exclusive_or) on strings. In this context
+ * we operating on the character codes of two strings, which are represented as
+ * [Buffer](https://nodejs.org/api/buffer.html) objects.
+ *
+ * We use [StringXor in webpack](https://github.com/webpack/webpack/commit/41a8e2ea483a544c4ccd3e6217bdfb80daffca39)
+ * to create a hash of the current state of the compilation. By XOR'ing the Module hashes, it
+ * doesn't matter if the Module hashes are sorted or not. This is useful because it allows us to avoid sorting the
+ * Module hashes.
+ * @example
+ * ```js
+ * const xor = new StringXor();
+ * xor.add('hello');
+ * xor.add('world');
+ * console.log(xor.toString());
+ * ```
+ * @example
+ * ```js
+ * const xor = new StringXor();
+ * xor.add('foo');
+ * xor.add('bar');
+ * const hash = createHash('sha256');
+ * hash.update(xor.toString());
+ * console.log(hash.digest('hex'));
+ * ```
+ */
+class StringXor {
+	constructor() {
+		/** @type {Buffer | undefined} */
+		this._value = undefined;
+	}
+
+	/**
+	 * Processes the provided str.
+	 * @param {string} str string
+	 * @returns {void}
+	 */
+	add(str) {
+		const len = str.length;
+		const value = this._value;
+		if (value === undefined) {
+			/**
+			 * We are choosing to use Buffer.allocUnsafe() because it is often faster than Buffer.alloc() because
+			 * it allocates a new buffer of the specified size without initializing the memory.
+			 */
+			const newValue = (this._value = Buffer.allocUnsafe(len));
+			for (let i = 0; i < len; i++) {
+				newValue[i] = str.charCodeAt(i);
+			}
+			return;
+		}
+		const valueLen = value.length;
+		if (valueLen < len) {
+			const newValue = (this._value = Buffer.allocUnsafe(len));
+			/** @type {number} */
+			let i;
+			for (i = 0; i < valueLen; i++) {
+				newValue[i] = value[i] ^ str.charCodeAt(i);
+			}
+			for (; i < len; i++) {
+				newValue[i] = str.charCodeAt(i);
+			}
+		} else {
+			for (let i = 0; i < len; i++) {
+				// eslint-disable-next-line operator-assignment
+				value[i] = value[i] ^ str.charCodeAt(i);
+			}
+		}
+	}
+
+	/**
+	 * Returns a string that represents the current state of the StringXor object. We chose to use "latin1" encoding
+	 * here because "latin1" encoding is a single-byte encoding that can represent all characters in the
+	 * [ISO-8859-1 character set](https://en.wikipedia.org/wiki/ISO/IEC_8859-1). This is useful when working
+	 * with binary data that needs to be represented as a string.
+	 * @returns {string} Returns a string that represents the current state of the StringXor object.
+	 */
+	toString() {
+		const value = this._value;
+		return value === undefined ? "" : value.toString("latin1");
+	}
+
+	/**
+	 * Updates the hash with the current state of the StringXor object.
+	 * @param {Hash} hash Hash instance
+	 */
+	updateHash(hash) {
+		const value = this._value;
+		if (value !== undefined) hash.update(value);
+	}
+}
+
+module.exports = StringXor;
Index: frontend/node_modules/webpack/lib/util/TupleQueue.js
===================================================================
--- frontend/node_modules/webpack/lib/util/TupleQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/TupleQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,74 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const TupleSet = require("./TupleSet");
+
+/**
+ * FIFO queue for tuples that preserves uniqueness by delegating membership
+ * tracking to `TupleSet`.
+ * @template T
+ * @template V
+ */
+class TupleQueue {
+	/**
+	 * Seeds the queue with an optional iterable of tuples to visit.
+	 * @param {Iterable<[T, V, ...EXPECTED_ANY]>=} items The initial elements.
+	 */
+	constructor(items) {
+		/**
+		 * @private
+		 * @type {TupleSet<T, V>}
+		 */
+		this._set = new TupleSet(items);
+		/**
+		 * @private
+		 * @type {Iterator<[T, V, ...EXPECTED_ANY]>}
+		 */
+		this._iterator = this._set[Symbol.iterator]();
+	}
+
+	/**
+	 * Returns the number of distinct tuples currently queued.
+	 * @returns {number} The number of elements in this queue.
+	 */
+	get length() {
+		return this._set.size;
+	}
+
+	/**
+	 * Enqueues a tuple if it is not already present in the underlying set.
+	 * @param {[T, V, ...EXPECTED_ANY]} item The element to add.
+	 * @returns {void}
+	 */
+	enqueue(...item) {
+		this._set.add(...item);
+	}
+
+	/**
+	 * Removes and returns the next queued tuple, rebuilding the iterator when
+	 * the underlying tuple set has changed since the last full pass.
+	 * @returns {[T, V, ...EXPECTED_ANY] | undefined} The head of the queue of `undefined` if this queue is empty.
+	 */
+	dequeue() {
+		const result = this._iterator.next();
+		if (result.done) {
+			if (this._set.size > 0) {
+				this._iterator = this._set[Symbol.iterator]();
+				const value =
+					/** @type {[T, V, ...EXPECTED_ANY]} */
+					(this._iterator.next().value);
+				this._set.delete(...value);
+				return value;
+			}
+			return;
+		}
+		this._set.delete(.../** @type {[T, V, ...EXPECTED_ANY]} */ (result.value));
+		return result.value;
+	}
+}
+
+module.exports = TupleQueue;
Index: frontend/node_modules/webpack/lib/util/TupleSet.js
===================================================================
--- frontend/node_modules/webpack/lib/util/TupleSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/TupleSet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,198 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Nested map structure used to index tuple prefixes until the final tuple
+ * element can be stored in a `Set`.
+ * @template K
+ * @template V
+ * @typedef {Map<K, InnerMap<K, V> | Set<V>>} InnerMap
+ */
+
+/**
+ * Stores tuples of arbitrary length while preserving efficient prefix lookups
+ * through a tree of maps that ends in a set of final values.
+ * @template T
+ * @template V
+ */
+class TupleSet {
+	/**
+	 * Seeds the tuple set with an optional iterable of tuples.
+	 * @param {Iterable<[T, V, ...EXPECTED_ANY]>=} init init
+	 */
+	constructor(init) {
+		/** @type {InnerMap<T, V>} */
+		this._map = new Map();
+		this.size = 0;
+		if (init) {
+			for (const tuple of init) {
+				this.add(...tuple);
+			}
+		}
+	}
+
+	/**
+	 * Adds a tuple to the set, creating any missing prefix maps along the way.
+	 * @param {[T, V, ...EXPECTED_ANY]} args tuple
+	 * @returns {void}
+	 */
+	add(...args) {
+		let map = this._map;
+		for (let i = 0; i < args.length - 2; i++) {
+			const arg = args[i];
+			const innerMap = map.get(arg);
+			if (innerMap === undefined) {
+				map.set(arg, (map = new Map()));
+			} else {
+				map = /** @type {InnerMap<T, V>} */ (innerMap);
+			}
+		}
+
+		const beforeLast = args[args.length - 2];
+		let set = /** @type {Set<V>} */ (map.get(beforeLast));
+		if (set === undefined) {
+			map.set(beforeLast, (set = new Set()));
+		}
+
+		const last = args[args.length - 1];
+		this.size -= set.size;
+		set.add(last);
+		this.size += set.size;
+	}
+
+	/**
+	 * Checks whether the exact tuple is already present in the set.
+	 * @param {[T, V, ...EXPECTED_ANY]} args tuple
+	 * @returns {boolean} true, if the tuple is in the Set
+	 */
+	has(...args) {
+		let map = this._map;
+		for (let i = 0; i < args.length - 2; i++) {
+			const arg = args[i];
+			map = /** @type {InnerMap<T, V>} */ (map.get(arg));
+			if (map === undefined) {
+				return false;
+			}
+		}
+
+		const beforeLast = args[args.length - 2];
+		const set = map.get(beforeLast);
+		if (set === undefined) {
+			return false;
+		}
+
+		const last = args[args.length - 1];
+		return set.has(last);
+	}
+
+	/**
+	 * Removes a tuple from the set when it is present.
+	 * @param {[T, V, ...EXPECTED_ANY]} args tuple
+	 * @returns {void}
+	 */
+	delete(...args) {
+		let map = this._map;
+		for (let i = 0; i < args.length - 2; i++) {
+			const arg = args[i];
+			map = /** @type {InnerMap<T, V>} */ (map.get(arg));
+			if (map === undefined) {
+				return;
+			}
+		}
+
+		const beforeLast = args[args.length - 2];
+		const set = map.get(beforeLast);
+		if (set === undefined) {
+			return;
+		}
+
+		const last = args[args.length - 1];
+		this.size -= set.size;
+		set.delete(last);
+		this.size += set.size;
+	}
+
+	/**
+	 * Iterates over every stored tuple by walking the nested map structure and
+	 * yielding each complete prefix plus its terminal set value.
+	 * @returns {Iterator<[T, V, ...EXPECTED_ANY]>} iterator
+	 */
+	[Symbol.iterator]() {
+		/**
+		 * Iterator type used while traversing nested tuple-prefix maps.
+		 * @template T, V
+		 * @typedef {MapIterator<[T, InnerMap<T, V> | Set<V>]>} IteratorStack
+		 */
+
+		// This is difficult to type because we can have a map inside a map inside a map, etc. where the end is a set (each key is an argument)
+		// But in basic use we only have 2 arguments in our methods, so we have `Map<K, Set<V>>`
+		/** @type {IteratorStack<T, V>[]} */
+		const iteratorStack = [];
+		/** @type {[T?, V?, ...EXPECTED_ANY]} */
+		const tuple = [];
+		/** @type {SetIterator<V> | undefined} */
+		let currentSetIterator;
+
+		/**
+		 * Advances through nested maps until a terminal value set is reached or
+		 * every remaining branch has been exhausted.
+		 * @param {IteratorStack<T, V>} it iterator
+		 * @returns {boolean} result
+		 */
+		const next = (it) => {
+			const result = it.next();
+			if (result.done) {
+				if (iteratorStack.length === 0) return false;
+				tuple.pop();
+				return next(
+					/** @type {IteratorStack<T, V>} */
+					(iteratorStack.pop())
+				);
+			}
+			const [key, value] = result.value;
+			iteratorStack.push(it);
+			tuple.push(key);
+			if (value instanceof Set) {
+				currentSetIterator = value[Symbol.iterator]();
+				return true;
+			}
+			return next(value[Symbol.iterator]());
+		};
+
+		next(this._map[Symbol.iterator]());
+
+		return {
+			next() {
+				while (currentSetIterator) {
+					const result = currentSetIterator.next();
+					if (result.done) {
+						tuple.pop();
+						if (
+							!next(
+								/** @type {IteratorStack<T, V>} */
+								(iteratorStack.pop())
+							)
+						) {
+							currentSetIterator = undefined;
+						}
+					} else {
+						return {
+							done: false,
+							value:
+								/* eslint-disable unicorn/prefer-spread */
+								/** @type {[T, V, ...EXPECTED_ANY]} */
+								(tuple.concat(result.value))
+						};
+					}
+				}
+				return { done: true, value: undefined };
+			}
+		};
+	}
+}
+
+module.exports = TupleSet;
Index: frontend/node_modules/webpack/lib/util/URLAbsoluteSpecifier.js
===================================================================
--- frontend/node_modules/webpack/lib/util/URLAbsoluteSpecifier.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/URLAbsoluteSpecifier.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,87 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+/** @typedef {(error: Error | null, result?: Buffer) => void} ErrorFirstCallback */
+
+const backSlashCharCode = "\\".charCodeAt(0);
+const slashCharCode = "/".charCodeAt(0);
+const aLowerCaseCharCode = "a".charCodeAt(0);
+const zLowerCaseCharCode = "z".charCodeAt(0);
+const aUpperCaseCharCode = "A".charCodeAt(0);
+const zUpperCaseCharCode = "Z".charCodeAt(0);
+const _0CharCode = "0".charCodeAt(0);
+const _9CharCode = "9".charCodeAt(0);
+const plusCharCode = "+".charCodeAt(0);
+const hyphenCharCode = "-".charCodeAt(0);
+const colonCharCode = ":".charCodeAt(0);
+const hashCharCode = "#".charCodeAt(0);
+const queryCharCode = "?".charCodeAt(0);
+/**
+ * Get scheme if specifier is an absolute URL specifier
+ * e.g. Absolute specifiers like 'file:///user/webpack/index.js'
+ * https://tools.ietf.org/html/rfc3986#section-3.1
+ * @param {string} specifier specifier
+ * @returns {string | undefined} scheme if absolute URL specifier provided
+ */
+function getScheme(specifier) {
+	const start = specifier.charCodeAt(0);
+
+	// First char maybe only a letter
+	if (
+		(start < aLowerCaseCharCode || start > zLowerCaseCharCode) &&
+		(start < aUpperCaseCharCode || start > zUpperCaseCharCode)
+	) {
+		return;
+	}
+
+	let i = 1;
+	let ch = specifier.charCodeAt(i);
+
+	while (
+		(ch >= aLowerCaseCharCode && ch <= zLowerCaseCharCode) ||
+		(ch >= aUpperCaseCharCode && ch <= zUpperCaseCharCode) ||
+		(ch >= _0CharCode && ch <= _9CharCode) ||
+		ch === plusCharCode ||
+		ch === hyphenCharCode
+	) {
+		if (++i === specifier.length) return;
+		ch = specifier.charCodeAt(i);
+	}
+
+	// Scheme must end with colon
+	if (ch !== colonCharCode) return;
+
+	// Check for Windows absolute path
+	// https://url.spec.whatwg.org/#url-miscellaneous
+	if (i === 1) {
+		const nextChar = i + 1 < specifier.length ? specifier.charCodeAt(i + 1) : 0;
+		if (
+			nextChar === 0 ||
+			nextChar === backSlashCharCode ||
+			nextChar === slashCharCode ||
+			nextChar === hashCharCode ||
+			nextChar === queryCharCode
+		) {
+			return;
+		}
+	}
+
+	return specifier.slice(0, i).toLowerCase();
+}
+
+/**
+ * Returns protocol if absolute URL specifier provided.
+ * @param {string} specifier specifier
+ * @returns {string | null | undefined} protocol if absolute URL specifier provided
+ */
+function getProtocol(specifier) {
+	const scheme = getScheme(specifier);
+	return scheme === undefined ? undefined : `${scheme}:`;
+}
+
+module.exports.getProtocol = getProtocol;
+module.exports.getScheme = getScheme;
Index: frontend/node_modules/webpack/lib/util/WeakTupleMap.js
===================================================================
--- frontend/node_modules/webpack/lib/util/WeakTupleMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/WeakTupleMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,260 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Strong-key child map used for tuple elements that cannot be stored in a
+ * `WeakMap`.
+ * @template {EXPECTED_ANY[]} T
+ * @template V
+ * @typedef {Map<EXPECTED_ANY, WeakTupleMap<T, V>>} M
+ */
+
+/**
+ * Weak-key child map used for tuple elements that are objects and can be held
+ * without preventing garbage collection.
+ * @template {EXPECTED_ANY[]} T
+ * @template V
+ * @typedef {WeakMap<EXPECTED_OBJECT, WeakTupleMap<T, V>>} W
+ */
+
+/**
+ * Reports whether a tuple element can be stored in a `WeakMap`.
+ * @param {EXPECTED_ANY} thing thing
+ * @returns {boolean} true if is weak
+ */
+const isWeakKey = (thing) => typeof thing === "object" && thing !== null;
+
+/**
+ * Extracts the element type from a tuple-like array.
+ * @template {unknown[]} T
+ * @typedef {T extends ReadonlyArray<infer ElementType> ? ElementType : never} ArrayElement
+ */
+
+/**
+ * Stores values by tuple keys while using `WeakMap` for object elements so the
+ * cache can release entries when those objects are collected.
+ * @template {EXPECTED_ANY[]} K
+ * @template V
+ */
+class WeakTupleMap {
+	/**
+	 * Initializes an empty tuple trie node with optional value and child maps.
+	 */
+	constructor() {
+		/** @private */
+		this.f = 0;
+		/**
+		 * @private
+		 * @type {V | undefined}
+		 */
+		this.v = undefined;
+		/**
+		 * @private
+		 * @type {M<K, V> | undefined}
+		 */
+		this.m = undefined;
+		/**
+		 * @private
+		 * @type {W<K, V> | undefined}
+		 */
+		this.w = undefined;
+	}
+
+	/**
+	 * Stores a value at the node identified by the provided tuple key.
+	 * @param {[...K, V]} args tuple
+	 * @returns {void}
+	 */
+	set(...args) {
+		/** @type {WeakTupleMap<K, V>} */
+		let node = this;
+		for (let i = 0; i < args.length - 1; i++) {
+			node = node._get(/** @type {ArrayElement<K>} */ (args[i]));
+		}
+		node._setValue(/** @type {V} */ (args[args.length - 1]));
+	}
+
+	/**
+	 * Checks whether the exact tuple key has a stored value.
+	 * @param {K} args tuple
+	 * @returns {boolean} true, if the tuple is in the Set
+	 */
+	has(...args) {
+		/** @type {WeakTupleMap<K, V> | undefined} */
+		let node = this;
+		for (let i = 0; i < args.length; i++) {
+			node = node._peek(/** @type {ArrayElement<K>} */ (args[i]));
+			if (node === undefined) return false;
+		}
+		return node._hasValue();
+	}
+
+	/**
+	 * Returns the value stored for the exact tuple key, if any.
+	 * @param {K} args tuple
+	 * @returns {V | undefined} the value
+	 */
+	get(...args) {
+		/** @type {WeakTupleMap<K, V> | undefined} */
+		let node = this;
+		for (let i = 0; i < args.length; i++) {
+			node = node._peek(/** @type {ArrayElement<K>} */ (args[i]));
+			if (node === undefined) return;
+		}
+		return node._getValue();
+	}
+
+	/**
+	 * Returns an existing value for the tuple or computes, stores, and returns a
+	 * new one when the tuple is missing.
+	 * @param {[...K, (...args: K) => V]} args tuple
+	 * @returns {V} the value
+	 */
+	provide(...args) {
+		/** @type {WeakTupleMap<K, V>} */
+		let node = this;
+		for (let i = 0; i < args.length - 1; i++) {
+			node = node._get(/** @type {ArrayElement<K>} */ (args[i]));
+		}
+		if (node._hasValue()) return /** @type {V} */ (node._getValue());
+		const fn = /** @type {(...args: K) => V} */ (args[args.length - 1]);
+		const newValue = fn(.../** @type {K} */ (args.slice(0, -1)));
+		node._setValue(newValue);
+		return newValue;
+	}
+
+	/**
+	 * Removes the value stored for the tuple key without pruning the trie.
+	 * @param {K} args tuple
+	 * @returns {void}
+	 */
+	delete(...args) {
+		/** @type {WeakTupleMap<K, V> | undefined} */
+		let node = this;
+		for (let i = 0; i < args.length; i++) {
+			node = node._peek(/** @type {ArrayElement<K>} */ (args[i]));
+			if (node === undefined) return;
+		}
+		node._deleteValue();
+	}
+
+	/**
+	 * Clears the stored value and all strong and weak child maps from this node.
+	 * @returns {void}
+	 */
+	clear() {
+		this.f = 0;
+		this.v = undefined;
+		this.w = undefined;
+		this.m = undefined;
+	}
+
+	/**
+	 * Returns the value stored directly on this trie node.
+	 * @returns {V | undefined} stored value
+	 */
+	_getValue() {
+		return this.v;
+	}
+
+	/**
+	 * Reports whether this trie node currently stores a value.
+	 * @returns {boolean} true when a value is present
+	 */
+	_hasValue() {
+		return (this.f & 1) === 1;
+	}
+
+	/**
+	 * Stores a value directly on this trie node.
+	 * @param {V} v value
+	 * @private
+	 */
+	_setValue(v) {
+		this.f |= 1;
+		this.v = v;
+	}
+
+	/**
+	 * Removes the value stored directly on this trie node.
+	 */
+	_deleteValue() {
+		this.f &= 6;
+		this.v = undefined;
+	}
+
+	/**
+	 * Returns the child node for a tuple element without creating one.
+	 * @param {ArrayElement<K>} thing thing
+	 * @returns {WeakTupleMap<K, V> | undefined} thing
+	 * @private
+	 */
+	_peek(thing) {
+		if (isWeakKey(thing)) {
+			if ((this.f & 4) !== 4) return;
+			return /** @type {WeakMap<ArrayElement<K>, WeakTupleMap<K, V>>} */ (
+				this.w
+			).get(thing);
+		}
+		if ((this.f & 2) !== 2) return;
+		return /** @type {Map<ArrayElement<K>, WeakTupleMap<K, V>>} */ (this.m).get(
+			thing
+		);
+	}
+
+	/**
+	 * Returns the child node for a tuple element, creating and storing it when
+	 * necessary.
+	 * @private
+	 * @param {ArrayElement<K>} thing thing
+	 * @returns {WeakTupleMap<K, V>} value
+	 */
+	_get(thing) {
+		if (isWeakKey(thing)) {
+			if ((this.f & 4) !== 4) {
+				/** @type {W<K, V>} */
+				const newMap = new WeakMap();
+				this.f |= 4;
+				/** @type {WeakTupleMap<K, V>} */
+				const newNode = new WeakTupleMap();
+				(this.w = newMap).set(thing, newNode);
+				return newNode;
+			}
+			const entry = /** @type {W<K, V>} */ (this.w).get(thing);
+			if (entry !== undefined) {
+				return entry;
+			}
+			/** @type {WeakTupleMap<K, V>} */
+			const newNode = new WeakTupleMap();
+			/** @type {W<K, V>} */
+			(this.w).set(thing, newNode);
+			return newNode;
+		}
+		if ((this.f & 2) !== 2) {
+			/** @type {M<K, V>} */
+			const newMap = new Map();
+			this.f |= 2;
+			/** @type {WeakTupleMap<K, V>} */
+			const newNode = new WeakTupleMap();
+			(this.m = newMap).set(thing, newNode);
+			return newNode;
+		}
+		const entry =
+			/** @type {M<K, V>} */
+			(this.m).get(thing);
+		if (entry !== undefined) {
+			return entry;
+		}
+		/** @type {WeakTupleMap<K, V>} */
+		const newNode = new WeakTupleMap();
+		/** @type {M<K, V>} */
+		(this.m).set(thing, newNode);
+		return newNode;
+	}
+}
+
+module.exports = WeakTupleMap;
Index: frontend/node_modules/webpack/lib/util/binarySearchBounds.js
===================================================================
--- frontend/node_modules/webpack/lib/util/binarySearchBounds.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/binarySearchBounds.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,137 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Mikola Lysenko @mikolalysenko
+*/
+
+"use strict";
+
+/* cspell:disable-next-line */
+// Refactor: Peter Somogyvari @petermetz
+
+/** @typedef {">=" | "<=" | "<" | ">" | "-"} BinarySearchPredicate */
+/** @typedef {"GE" | "GT" | "LT" | "LE" | "EQ"} SearchPredicateSuffix */
+
+/**
+ * Helper function for compiling binary search functions.
+ *
+ * The generated code uses a while loop to repeatedly divide the search interval
+ * in half until the desired element is found, or the search interval is empty.
+ *
+ * The following is an example of a generated function for calling `compileSearch("P", "c(x,y)<=0", true, ["y", "c"], false)`:
+ *
+ * ```js
+ * function P(a,l,h,y,c){var i=l-1;while(l<=h){var m=(l+h)>>>1,x=a[m];if(c(x,y)<=0){i=m;l=m+1}else{h=m-1}}return i};
+ * ```
+ * @param {string} funcName The name of the function to be compiled.
+ * @param {string} predicate The predicate / comparison operator to be used in the binary search.
+ * @param {boolean} reversed Whether the search should be reversed.
+ * @param {string[]} extraArgs Extra arguments to be passed to the function.
+ * @param {boolean=} earlyOut Whether the search should return as soon as a match is found.
+ * @returns {string} The compiled binary search function.
+ */
+const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => {
+	const code = [
+		"function ",
+		funcName,
+		"(a,l,h,",
+		extraArgs.join(","),
+		"){",
+		earlyOut ? "" : "var i=",
+		reversed ? "l-1" : "h+1",
+		";while(l<=h){var m=(l+h)>>>1,x=a[m]"
+	];
+
+	if (earlyOut) {
+		if (!predicate.includes("c")) {
+			code.push(";if(x===y){return m}else if(x<=y){");
+		} else {
+			code.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){");
+		}
+	} else {
+		code.push(";if(", predicate, "){i=m;");
+	}
+	if (reversed) {
+		code.push("l=m+1}else{h=m-1}");
+	} else {
+		code.push("h=m-1}else{l=m+1}");
+	}
+	code.push("}");
+	if (earlyOut) {
+		code.push("return -1};");
+	} else {
+		code.push("return i};");
+	}
+	return code.join("");
+};
+
+/**
+ * Defines the search type used by this module.
+ * @template T
+ * @typedef {(items: T[], start: number, compareFn?: number | ((item: T, needle: number) => number), l?: number, h?: number) => number} Search
+ */
+
+/**
+ * This helper functions generate code for two binary search functions:
+ * A(): Performs a binary search on an array using the comparison operator specified.
+ * P(): Performs a binary search on an array using a _custom comparison function_
+ * `c(x,y)` **and** comparison operator specified by `predicate`.
+ * @template T
+ * @param {BinarySearchPredicate} predicate The predicate / comparison operator to be used in the binary search.
+ * @param {boolean} reversed Whether the search should be reversed.
+ * @param {SearchPredicateSuffix} suffix The suffix to be used in the function name.
+ * @param {boolean=} earlyOut Whether the search should return as soon as a match is found.
+ * @returns {Search<T>} The compiled binary search function.
+ */
+const compileBoundsSearch = (predicate, reversed, suffix, earlyOut) => {
+	const arg1 = compileSearch("A", `x${predicate}y`, reversed, ["y"], earlyOut);
+
+	const arg2 = compileSearch(
+		"P",
+		`c(x,y)${predicate}0`,
+		reversed,
+		["y", "c"],
+		earlyOut
+	);
+
+	const fnHeader = "function dispatchBinarySearch";
+
+	const fnBody =
+		// eslint-disable-next-line no-multi-str
+		"(a,y,c,l,h){\
+if(typeof(c)==='function'){\
+return P(a,(l===void 0)?0:l|0,(h===void 0)?a.length-1:h|0,y,c)\
+}else{\
+return A(a,(c===void 0)?0:c|0,(l===void 0)?a.length-1:l|0,y)\
+}}\
+return dispatchBinarySearch";
+
+	const fnArgList = [arg1, arg2, fnHeader, suffix, fnBody, suffix];
+	const fnSource = fnArgList.join("");
+	// eslint-disable-next-line no-new-func
+	const result = new Function(fnSource);
+	return result();
+};
+
+const fns = {
+	ge: compileBoundsSearch(">=", false, "GE"),
+	gt: compileBoundsSearch(">", false, "GT"),
+	lt: compileBoundsSearch("<", true, "LT"),
+	le: compileBoundsSearch("<=", true, "LE"),
+	eq: compileBoundsSearch("-", true, "EQ", true)
+};
+
+/**
+ * These functions are used to perform binary searches on arrays.
+ * @example
+ * ```js
+ * const { gt, le} = require("./binarySearchBounds");
+ * const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+ *
+ * // Find the index of the first element greater than 5
+ * const index1 = gt(arr, 5); // index1 === 3
+ *
+ * // Find the index of the first element less than or equal to 5
+ * const index2 = le(arr, 5); // index2 === 4
+ * ```
+ */
+module.exports = fns;
Index: frontend/node_modules/webpack/lib/util/chainedImports.js
===================================================================
--- frontend/node_modules/webpack/lib/util/chainedImports.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/chainedImports.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,99 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+/** @typedef {Range[]} IdRanges */
+
+/**
+ * @summary Get the subset of ids and their corresponding range in an id chain that should be re-rendered by webpack.
+ * Only those in the chain that are actually referring to namespaces or imports should be re-rendered.
+ * Deeper member accessors on the imported object should not be re-rendered.  If deeper member accessors are re-rendered,
+ * there is a potential loss of meaning with rendering a quoted accessor as an unquoted accessor, or vice versa,
+ * because minifiers treat quoted accessors differently.  e.g. import { a } from "./module"; a["b"] vs a.b
+ * @param {string[]} untrimmedIds chained ids
+ * @param {Range} untrimmedRange range encompassing allIds
+ * @param {IdRanges | undefined} ranges cumulative range of ids for each of allIds
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @param {Dependency} dependency dependency
+ * @returns {{ trimmedIds: string[], trimmedRange: Range }} computed trimmed ids and cumulative range of those ids
+ */
+module.exports.getTrimmedIdsAndRange = (
+	untrimmedIds,
+	untrimmedRange,
+	ranges,
+	moduleGraph,
+	dependency
+) => {
+	let trimmedIds = trimIdsToThoseImported(
+		untrimmedIds,
+		moduleGraph,
+		dependency
+	);
+	let trimmedRange = untrimmedRange;
+	if (trimmedIds.length !== untrimmedIds.length) {
+		// The array returned from dep.idRanges is right-aligned with the array returned from dep.names.
+		// Meaning, the two arrays may not always have the same number of elements, but the last element of
+		// dep.idRanges corresponds to [the expression fragment to the left of] the last element of dep.names.
+		// Use this to find the correct replacement range based on the number of ids that were trimmed.
+		const idx =
+			ranges === undefined
+				? -1 /* trigger failure case below */
+				: ranges.length + (trimmedIds.length - untrimmedIds.length);
+		if (idx < 0 || idx >= /** @type {Range[]} */ (ranges).length) {
+			// cspell:ignore minifiers
+			// Should not happen but we can't throw an error here because of backward compatibility with
+			// external plugins in wp5.  Instead, we just disable trimming for now.  This may break some minifiers.
+			trimmedIds = untrimmedIds;
+			// TODO webpack 6 remove the "trimmedIds = ids" above and uncomment the following line instead.
+			// throw new Error("Missing range starts data for id replacement trimming.");
+		} else {
+			trimmedRange = /** @type {Range[]} */ (ranges)[idx];
+		}
+	}
+
+	return { trimmedIds, trimmedRange };
+};
+
+/**
+ * @summary Determine which IDs in the id chain are actually referring to namespaces or imports,
+ * and which are deeper member accessors on the imported object.
+ * @param {string[]} ids untrimmed ids
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @param {Dependency} dependency dependency
+ * @returns {string[]} trimmed ids
+ */
+function trimIdsToThoseImported(ids, moduleGraph, dependency) {
+	/** @type {string[]} */
+	let trimmedIds = [];
+	let currentExportsInfo = moduleGraph.getExportsInfo(
+		/** @type {Module} */ (moduleGraph.getModule(dependency))
+	);
+	for (let i = 0; i < ids.length; i++) {
+		if (i === 0 && ids[i] === "default") {
+			continue; // ExportInfo for the next level under default is still at the root ExportsInfo, so don't advance currentExportsInfo
+		}
+		const exportInfo = currentExportsInfo.getExportInfo(ids[i]);
+		if (exportInfo.provided === false) {
+			// json imports have nested ExportInfo for elements that things that are not actually exported, so check .provided
+			trimmedIds = ids.slice(0, i);
+			break;
+		}
+		const nestedInfo = exportInfo.getNestedExportsInfo();
+		if (!nestedInfo) {
+			// once all nested exports are traversed, the next item is the actual import so stop there
+			trimmedIds = ids.slice(0, i + 1);
+			break;
+		}
+		currentExportsInfo = nestedInfo;
+	}
+	// Never trim to nothing.  This can happen for invalid imports (e.g. import { notThere } from "./module", or import { anything } from "./missingModule")
+	return trimmedIds.length ? trimmedIds : ids;
+}
Index: frontend/node_modules/webpack/lib/util/cleverMerge.js
===================================================================
--- frontend/node_modules/webpack/lib/util/cleverMerge.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/cleverMerge.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,693 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @type {WeakMap<EXPECTED_OBJECT, WeakMap<EXPECTED_OBJECT, EXPECTED_OBJECT>>} */
+const mergeCache = new WeakMap();
+/** @typedef {Map<string, Map<string | number | boolean, EXPECTED_OBJECT>>} InnerPropertyCache */
+/** @type {WeakMap<EXPECTED_OBJECT, InnerPropertyCache>} */
+const setPropertyCache = new WeakMap();
+const DELETE = Symbol("DELETE");
+const DYNAMIC_INFO = Symbol("cleverMerge dynamic info");
+
+/**
+ * Merges two given objects and caches the result to avoid computation if same objects passed as arguments again.
+ * @template T
+ * @template O
+ * @example
+ * // performs cleverMerge(first, second), stores the result in WeakMap and returns result
+ * cachedCleverMerge({a: 1}, {a: 2})
+ * {a: 2}
+ *  // when same arguments passed, gets the result from WeakMap and returns it.
+ * cachedCleverMerge({a: 1}, {a: 2})
+ * {a: 2}
+ * @param {T | null | undefined} first first object
+ * @param {O | null | undefined} second second object
+ * @returns {T & O | T | O} merged object of first and second object
+ */
+const cachedCleverMerge = (first, second) => {
+	if (second === undefined) return /** @type {T} */ (first);
+	if (first === undefined) return /** @type {O} */ (second);
+	if (typeof second !== "object" || second === null) {
+		return /** @type {O} */ (second);
+	}
+	if (typeof first !== "object" || first === null) {
+		return /** @type {T} */ (first);
+	}
+
+	let innerCache = mergeCache.get(first);
+	if (innerCache === undefined) {
+		innerCache = new WeakMap();
+		mergeCache.set(first, innerCache);
+	}
+	const prevMerge = /** @type {T & O} */ (innerCache.get(second));
+	if (prevMerge !== undefined) return prevMerge;
+	const newMerge = _cleverMerge(first, second, true);
+	innerCache.set(second, newMerge);
+	return newMerge;
+};
+
+/**
+ * Caches d set property.
+ * @template T
+ * @param {Partial<T>} obj object
+ * @param {string} property property
+ * @param {string | number | boolean} value assignment value
+ * @returns {T} new object
+ */
+const cachedSetProperty = (obj, property, value) => {
+	let mapByProperty = setPropertyCache.get(obj);
+
+	if (mapByProperty === undefined) {
+		mapByProperty = new Map();
+		setPropertyCache.set(obj, mapByProperty);
+	}
+
+	let mapByValue = mapByProperty.get(property);
+
+	if (mapByValue === undefined) {
+		mapByValue = new Map();
+		mapByProperty.set(property, mapByValue);
+	}
+
+	let result = mapByValue.get(value);
+
+	if (result) return /** @type {T} */ (result);
+
+	result = {
+		...obj,
+		[property]: value
+	};
+	mapByValue.set(value, result);
+
+	return /** @type {T} */ (result);
+};
+
+/**
+ * Defines the by values type used by this module.
+ * @typedef {Map<string, EXPECTED_ANY>} ByValues
+ */
+
+/**
+ * Defines the object parsed property entry type used by this module.
+ * @template T
+ * @typedef {object} ObjectParsedPropertyEntry
+ * @property {T[keyof T] | undefined} base base value
+ * @property {`by${string}` | undefined} byProperty the name of the selector property
+ * @property {ByValues | undefined} byValues value depending on selector property, merged with base
+ */
+
+/** @typedef {(function(...EXPECTED_ANY): object) & { [DYNAMIC_INFO]: [DynamicFunction, object] }} DynamicFunction */
+
+/**
+ * Defines the parsed object static type used by this module.
+ * @template {object} T
+ * @typedef {Map<keyof T, ObjectParsedPropertyEntry<T>>} ParsedObjectStatic
+ */
+
+/**
+ * Defines the parsed object dynamic type used by this module.
+ * @template {object} T
+ * @typedef {{ byProperty: `by${string}`, fn: DynamicFunction }} ParsedObjectDynamic
+ */
+
+/**
+ * Defines the parsed object type used by this module.
+ * @template {object} T
+ * @typedef {object} ParsedObject
+ * @property {ParsedObjectStatic<T>} static static properties (key is property name)
+ * @property {ParsedObjectDynamic<T> | undefined} dynamic dynamic part
+ */
+
+/** @type {WeakMap<EXPECTED_OBJECT, ParsedObject<EXPECTED_ANY>>} */
+const parseCache = new WeakMap();
+
+/**
+ * Caches d parse object.
+ * @template {object} T
+ * @param {T} obj the object
+ * @returns {ParsedObject<T>} parsed object
+ */
+const cachedParseObject = (obj) => {
+	const entry = parseCache.get(obj);
+	if (entry !== undefined) return entry;
+	const result = parseObject(obj);
+	parseCache.set(obj, result);
+	return result;
+};
+
+/** @typedef {{ [p: string]: { [p: string]: EXPECTED_ANY } } | DynamicFunction} ByObject */
+
+/**
+ * Returns parsed object.
+ * @template {object} T
+ * @param {T} obj the object
+ * @returns {ParsedObject<T>} parsed object
+ */
+const parseObject = (obj) => {
+	/** @type {ParsedObjectStatic<T>} */
+	const info = new Map();
+	/** @type {ParsedObjectDynamic<T> | undefined} */
+	let dynamicInfo;
+	/**
+	 * Returns object parsed property entry.
+	 * @param {keyof T} p path
+	 * @returns {Partial<ObjectParsedPropertyEntry<T>>} object parsed property entry
+	 */
+	const getInfo = (p) => {
+		const entry = info.get(p);
+		if (entry !== undefined) return entry;
+		const newEntry = {
+			base: undefined,
+			byProperty: undefined,
+			byValues: undefined
+		};
+		info.set(p, newEntry);
+		return newEntry;
+	};
+	for (const key_ of Object.keys(obj)) {
+		const key = /** @type {keyof T} */ (key_);
+		if (typeof key === "string" && key.startsWith("by")) {
+			const byProperty = key;
+			const byObj = /** @type {ByObject} */ (obj[byProperty]);
+			if (typeof byObj === "object") {
+				for (const byValue of Object.keys(byObj)) {
+					const obj = byObj[/** @type {keyof (keyof T)} */ (byValue)];
+					for (const key of Object.keys(obj)) {
+						const entry = getInfo(/** @type {keyof T} */ (key));
+						if (entry.byProperty === undefined) {
+							entry.byProperty = /** @type {`by${string}`} */ (byProperty);
+							entry.byValues = new Map();
+						} else if (entry.byProperty !== byProperty) {
+							throw new Error(
+								`${/** @type {string} */ (byProperty)} and ${entry.byProperty} for a single property is not supported`
+							);
+						}
+						/** @type {ByValues} */
+						(entry.byValues).set(byValue, obj[key]);
+						if (byValue === "default") {
+							for (const otherByValue of Object.keys(byObj)) {
+								if (
+									!(
+										/** @type {ByValues} */
+										(entry.byValues).has(otherByValue)
+									)
+								) {
+									/** @type {ByValues} */
+									(entry.byValues).set(otherByValue, undefined);
+								}
+							}
+						}
+					}
+				}
+			} else if (typeof byObj === "function") {
+				if (dynamicInfo === undefined) {
+					dynamicInfo = {
+						byProperty: /** @type {`by${string}`} */ (key),
+						fn: byObj
+					};
+				} else {
+					throw new Error(
+						`${key} and ${dynamicInfo.byProperty} when both are functions is not supported`
+					);
+				}
+			} else {
+				const entry = getInfo(key);
+				entry.base = obj[key];
+			}
+		} else {
+			const entry = getInfo(key);
+			entry.base = obj[key];
+		}
+	}
+	return {
+		static: info,
+		dynamic: dynamicInfo
+	};
+};
+
+/**
+ * Returns the object.
+ * @template {object} T
+ * @param {ParsedObjectStatic<T>} info static properties (key is property name)
+ * @param {{ byProperty: `by${string}`, fn: DynamicFunction } | undefined} dynamicInfo dynamic part
+ * @returns {T} the object
+ */
+const serializeObject = (info, dynamicInfo) => {
+	const obj = /** @type {EXPECTED_ANY} */ ({});
+	// Setup byProperty structure
+	for (const entry of info.values()) {
+		if (entry.byProperty !== undefined) {
+			const byProperty = entry.byProperty;
+			const byObj = (obj[byProperty] = obj[byProperty] || {});
+			for (const byValue of /** @type {ByValues} */ (entry.byValues).keys()) {
+				byObj[byValue] = byObj[byValue] || {};
+			}
+		}
+	}
+	for (const [key, entry] of info) {
+		if (entry.base !== undefined) {
+			obj[key] = entry.base;
+		}
+		// Fill byProperty structure
+		if (entry.byProperty !== undefined) {
+			const byProperty = entry.byProperty;
+			const byObj = (obj[byProperty] = obj[byProperty] || {});
+			for (const byValue of Object.keys(byObj)) {
+				const value = getFromByValues(
+					/** @type {ByValues} */
+					(entry.byValues),
+					byValue
+				);
+				if (value !== undefined) byObj[byValue][key] = value;
+			}
+		}
+	}
+	if (dynamicInfo !== undefined) {
+		obj[dynamicInfo.byProperty] = dynamicInfo.fn;
+	}
+	return obj;
+};
+
+const VALUE_TYPE_UNDEFINED = 0;
+const VALUE_TYPE_ATOM = 1;
+const VALUE_TYPE_ARRAY_EXTEND = 2;
+const VALUE_TYPE_OBJECT = 3;
+const VALUE_TYPE_DELETE = 4;
+
+/**
+ * Returns value type.
+ * @template T
+ * @param {T} value a single value
+ * @returns {VALUE_TYPE_UNDEFINED | VALUE_TYPE_ATOM | VALUE_TYPE_ARRAY_EXTEND | VALUE_TYPE_OBJECT | VALUE_TYPE_DELETE} value type
+ */
+const getValueType = (value) => {
+	if (value === undefined) {
+		return VALUE_TYPE_UNDEFINED;
+	} else if (value === DELETE) {
+		return VALUE_TYPE_DELETE;
+	} else if (Array.isArray(value)) {
+		if (value.includes("...")) return VALUE_TYPE_ARRAY_EXTEND;
+		return VALUE_TYPE_ATOM;
+	} else if (
+		typeof value === "object" &&
+		value !== null &&
+		(!value.constructor || value.constructor === Object)
+	) {
+		return VALUE_TYPE_OBJECT;
+	}
+	return VALUE_TYPE_ATOM;
+};
+
+/**
+ * Merges two objects. Objects are deeply clever merged.
+ * Arrays might reference the old value with "...".
+ * Non-object values take preference over object values.
+ * @template T
+ * @template O
+ * @param {T} first first object
+ * @param {O} second second object
+ * @returns {T & O | T | O} merged object of first and second object
+ */
+const cleverMerge = (first, second) => {
+	if (second === undefined) return first;
+	if (first === undefined) return second;
+	if (typeof second !== "object" || second === null) return second;
+	if (typeof first !== "object" || first === null) return first;
+
+	return /** @type {T & O} */ (_cleverMerge(first, second, false));
+};
+
+/**
+ * Returns merged object of first and second object.
+ * @template {object} T
+ * @template {object} O
+ * Merges two objects. Objects are deeply clever merged.
+ * @param {T} first first
+ * @param {O} second second
+ * @param {boolean} internalCaching should parsing of objects and nested merges be cached
+ * @returns {T & O} merged object of first and second object
+ */
+const _cleverMerge = (first, second, internalCaching = false) => {
+	const firstObject = internalCaching
+		? cachedParseObject(first)
+		: parseObject(first);
+	const { static: firstInfo, dynamic: firstDynamicInfo } = firstObject;
+
+	// If the first argument has a dynamic part we modify the dynamic part to merge the second argument
+	if (firstDynamicInfo !== undefined) {
+		let { byProperty, fn } = firstDynamicInfo;
+		const fnInfo = fn[DYNAMIC_INFO];
+		if (fnInfo) {
+			second =
+				/** @type {O} */
+				(
+					internalCaching
+						? cachedCleverMerge(fnInfo[1], second)
+						: cleverMerge(fnInfo[1], second)
+				);
+			fn = fnInfo[0];
+		}
+		/** @type {DynamicFunction} */
+		const newFn = (...args) => {
+			const fnResult = fn(...args);
+			return internalCaching
+				? cachedCleverMerge(fnResult, second)
+				: cleverMerge(fnResult, second);
+		};
+		newFn[DYNAMIC_INFO] = [fn, second];
+		return /** @type {T & O} */ (
+			serializeObject(firstObject.static, { byProperty, fn: newFn })
+		);
+	}
+
+	// If the first part is static only, we merge the static parts and keep the dynamic part of the second argument
+	const secondObject = internalCaching
+		? cachedParseObject(second)
+		: parseObject(second);
+	const { static: secondInfo, dynamic: secondDynamicInfo } = secondObject;
+	const resultInfo = new Map();
+	for (const [key, firstEntry] of firstInfo) {
+		const secondEntry = secondInfo.get(
+			/** @type {keyof (T | O)} */
+			(key)
+		);
+		const entry =
+			secondEntry !== undefined
+				? mergeEntries(firstEntry, secondEntry, internalCaching)
+				: firstEntry;
+		resultInfo.set(key, entry);
+	}
+	for (const [key, secondEntry] of secondInfo) {
+		if (!firstInfo.has(/** @type {keyof (T | O)} */ (key))) {
+			resultInfo.set(key, secondEntry);
+		}
+	}
+	return /** @type {T & O} */ (serializeObject(resultInfo, secondDynamicInfo));
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @template T, O
+ * @param {ObjectParsedPropertyEntry<T>} firstEntry a
+ * @param {ObjectParsedPropertyEntry<O>} secondEntry b
+ * @param {boolean} internalCaching should parsing of objects and nested merges be cached
+ * @returns {ObjectParsedPropertyEntry<T> | ObjectParsedPropertyEntry<O> | ObjectParsedPropertyEntry<T & O>} new entry
+ */
+const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
+	switch (getValueType(secondEntry.base)) {
+		case VALUE_TYPE_ATOM:
+		case VALUE_TYPE_DELETE:
+			// No need to consider firstEntry at all
+			// second value override everything
+			// = second.base + second.byProperty
+			return secondEntry;
+		case VALUE_TYPE_UNDEFINED:
+			if (!firstEntry.byProperty) {
+				// = first.base + second.byProperty
+				return {
+					base: firstEntry.base,
+					byProperty: secondEntry.byProperty,
+					byValues: secondEntry.byValues
+				};
+			} else if (firstEntry.byProperty !== secondEntry.byProperty) {
+				throw new Error(
+					`${firstEntry.byProperty} and ${secondEntry.byProperty} for a single property is not supported`
+				);
+			} else {
+				// = first.base + (first.byProperty + second.byProperty)
+				// need to merge first and second byValues
+				/** @type {Map<string, T & O>} */
+				const newByValues = new Map(firstEntry.byValues);
+				for (const [key, value] of /** @type {ByValues} */ (
+					secondEntry.byValues
+				)) {
+					const firstValue = getFromByValues(
+						/** @type {ByValues} */
+						(firstEntry.byValues),
+						key
+					);
+					newByValues.set(
+						key,
+						mergeSingleValue(firstValue, value, internalCaching)
+					);
+				}
+				return {
+					base: firstEntry.base,
+					byProperty: firstEntry.byProperty,
+					byValues: newByValues
+				};
+			}
+		default: {
+			if (!firstEntry.byProperty) {
+				// The simple case
+				// = (first.base + second.base) + second.byProperty
+				return {
+					base:
+						/** @type {T[keyof T] & O[keyof O]} */
+						(
+							mergeSingleValue(
+								firstEntry.base,
+								secondEntry.base,
+								internalCaching
+							)
+						),
+					byProperty: secondEntry.byProperty,
+					byValues: secondEntry.byValues
+				};
+			}
+			/** @type {O[keyof O] | T[keyof T] | (T[keyof T] & O[keyof O]) | (T[keyof T] | undefined)[] | (O[keyof O] | undefined)[] | (O[keyof O] | T[keyof T] | undefined)[] | undefined} */
+			let newBase;
+			/** @type {Map<string, (T & O) | O[keyof O] | (O[keyof O] | undefined)[] | ((T & O) | undefined)[] | (T & O & O[keyof O]) | ((T & O) | O[keyof O] | undefined)[] | undefined>} */
+			const intermediateByValues = new Map(firstEntry.byValues);
+			for (const [key, value] of intermediateByValues) {
+				intermediateByValues.set(
+					key,
+					mergeSingleValue(value, secondEntry.base, internalCaching)
+				);
+			}
+			if (
+				[.../** @type {ByValues} */ (firstEntry.byValues).values()].every(
+					(value) => {
+						const type = getValueType(value);
+						return type === VALUE_TYPE_ATOM || type === VALUE_TYPE_DELETE;
+					}
+				)
+			) {
+				// = (first.base + second.base) + ((first.byProperty + second.base) + second.byProperty)
+				newBase = mergeSingleValue(
+					firstEntry.base,
+					secondEntry.base,
+					internalCaching
+				);
+			} else {
+				// = first.base + ((first.byProperty (+default) + second.base) + second.byProperty)
+				newBase = firstEntry.base;
+				if (!intermediateByValues.has("default")) {
+					intermediateByValues.set("default", secondEntry.base);
+				}
+			}
+			if (!secondEntry.byProperty) {
+				// = first.base + (first.byProperty + second.base)
+				return {
+					base: /** @type {T[keyof T] & O[keyof O]} */ (newBase),
+					byProperty: firstEntry.byProperty,
+					byValues: intermediateByValues
+				};
+			} else if (firstEntry.byProperty !== secondEntry.byProperty) {
+				throw new Error(
+					`${firstEntry.byProperty} and ${secondEntry.byProperty} for a single property is not supported`
+				);
+			}
+			/** @type {Map<string, (T & O) | O[keyof O] | (O[keyof O] | undefined)[] | (T & O & O[keyof O]) | ((T & O) | undefined)[] | ((T & O) | O[keyof O] | undefined)[] | undefined>} */
+			const newByValues = new Map(intermediateByValues);
+			for (const [key, value] of /** @type {ByValues} */ (
+				secondEntry.byValues
+			)) {
+				const firstValue = getFromByValues(intermediateByValues, key);
+				newByValues.set(
+					key,
+					mergeSingleValue(firstValue, value, internalCaching)
+				);
+			}
+			return {
+				base: /** @type {T[keyof T] & O[keyof O]} */ (newBase),
+				byProperty: firstEntry.byProperty,
+				byValues: newByValues
+			};
+		}
+	}
+};
+
+/**
+ * Gets from by values.
+ * @template V
+ * @param {ByValues} byValues all values
+ * @param {string} key value of the selector
+ * @returns {V | undefined} value
+ */
+const getFromByValues = (byValues, key) => {
+	if (key !== "default" && byValues.has(key)) {
+		return byValues.get(key);
+	}
+	return byValues.get("default");
+};
+
+/**
+ * Merges single value.
+ * @template A
+ * @template B
+ * @param {A | A[]} a value
+ * @param {B | B[]} b value
+ * @param {boolean} internalCaching should parsing of objects and nested merges be cached
+ * @returns {A & B | (A | B)[] | A | A[] | B | B[]} value
+ */
+const mergeSingleValue = (a, b, internalCaching) => {
+	const bType = getValueType(b);
+	const aType = getValueType(a);
+	switch (bType) {
+		case VALUE_TYPE_DELETE:
+		case VALUE_TYPE_ATOM:
+			return b;
+		case VALUE_TYPE_OBJECT: {
+			return aType !== VALUE_TYPE_OBJECT
+				? b
+				: internalCaching
+					? cachedCleverMerge(a, b)
+					: cleverMerge(a, b);
+		}
+		case VALUE_TYPE_UNDEFINED:
+			return a;
+		case VALUE_TYPE_ARRAY_EXTEND:
+			switch (
+				aType !== VALUE_TYPE_ATOM
+					? aType
+					: Array.isArray(a)
+						? VALUE_TYPE_ARRAY_EXTEND
+						: VALUE_TYPE_OBJECT
+			) {
+				case VALUE_TYPE_UNDEFINED:
+					return b;
+				case VALUE_TYPE_DELETE:
+					return /** @type {B[]} */ (b).filter((item) => item !== "...");
+				case VALUE_TYPE_ARRAY_EXTEND: {
+					/** @type {(A | B)[]} */
+					const newArray = [];
+					for (const item of /** @type {B[]} */ (b)) {
+						if (item === "...") {
+							for (const item of /** @type {A[]} */ (a)) {
+								newArray.push(item);
+							}
+						} else {
+							newArray.push(item);
+						}
+					}
+					return newArray;
+				}
+				case VALUE_TYPE_OBJECT:
+					return /** @type {(A | B)[]} */ (b).map((item) =>
+						item === "..." ? /** @type {A} */ (a) : item
+					);
+				default:
+					throw new Error("Not implemented");
+			}
+		default:
+			throw new Error("Not implemented");
+	}
+};
+
+/**
+ * Removes operations.
+ * @template {object} T
+ * @param {T} obj the object
+ * @param {(keyof T)[]=} keysToKeepOriginalValue keys to keep original value
+ * @returns {T} the object without operations like "..." or DELETE
+ */
+const removeOperations = (obj, keysToKeepOriginalValue = []) => {
+	const newObj = /** @type {T} */ ({});
+	for (const _key of Object.keys(obj)) {
+		const key = /** @type {keyof T} */ (_key);
+		const value = obj[key];
+		const type = getValueType(value);
+		if (type === VALUE_TYPE_OBJECT && keysToKeepOriginalValue.includes(key)) {
+			newObj[key] = value;
+			continue;
+		}
+		switch (type) {
+			case VALUE_TYPE_UNDEFINED:
+			case VALUE_TYPE_DELETE:
+				break;
+			case VALUE_TYPE_OBJECT:
+				newObj[key] =
+					/** @type {T[keyof T]} */
+					(
+						removeOperations(
+							/** @type {T} */
+							(value),
+							keysToKeepOriginalValue
+						)
+					);
+				break;
+			case VALUE_TYPE_ARRAY_EXTEND:
+				newObj[key] =
+					/** @type {T[keyof T]} */
+					(
+						/** @type {EXPECTED_ANY[]} */
+						(value).filter((i) => i !== "...")
+					);
+				break;
+			default:
+				newObj[key] = value;
+				break;
+		}
+	}
+	return newObj;
+};
+
+/**
+ * Resolves by property.
+ * @template T
+ * @template {keyof T} P
+ * @template V
+ * @param {T} obj the object
+ * @param {P} byProperty the by description
+ * @param {...V} values values
+ * @returns {Omit<T, P>} object with merged byProperty
+ */
+const resolveByProperty = (obj, byProperty, ...values) => {
+	if (typeof obj !== "object" || obj === null || !(byProperty in obj)) {
+		return obj;
+	}
+	const { [byProperty]: _byValue, ..._remaining } = obj;
+	const remaining = /** @type {T} */ (_remaining);
+	const byValue =
+		/** @type {Record<string, T> | ((...args: V[]) => T)} */
+		(_byValue);
+	if (typeof byValue === "object") {
+		const key = /** @type {string} */ (values[0]);
+		if (key in byValue) {
+			return cachedCleverMerge(remaining, byValue[key]);
+		} else if ("default" in byValue) {
+			return cachedCleverMerge(remaining, byValue.default);
+		}
+		return remaining;
+	} else if (typeof byValue === "function") {
+		// eslint-disable-next-line prefer-spread
+		const result = byValue.apply(null, values);
+		return cachedCleverMerge(
+			remaining,
+			resolveByProperty(result, byProperty, ...values)
+		);
+	}
+	return obj;
+};
+
+module.exports.DELETE = DELETE;
+module.exports.cachedCleverMerge = cachedCleverMerge;
+module.exports.cachedSetProperty = cachedSetProperty;
+module.exports.cleverMerge = cleverMerge;
+module.exports.removeOperations = removeOperations;
+module.exports.resolveByProperty = resolveByProperty;
Index: frontend/node_modules/webpack/lib/util/comparators.js
===================================================================
--- frontend/node_modules/webpack/lib/util/comparators.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/comparators.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,676 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { getFullModuleName } = require("../ids/IdHelpers");
+const { compareRuntime } = require("./runtime");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkName} ChunkName */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
+/** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../dependencies/ModuleDependency")} ModuleDependency */
+
+/**
+ * Defines the dependency source order type used by this module.
+ * @typedef {object} DependencySourceOrder
+ * @property {number} main the main source order
+ * @property {number} sub the sub source order
+ */
+
+/**
+ * Defines the comparator type used by this module.
+ * @template T
+ * @typedef {(a: T, b: T) => -1 | 0 | 1} Comparator
+ */
+/**
+ * Defines the raw parameterized comparator type used by this module.
+ * @template {object} TArg
+ * @template T
+ * @typedef {(tArg: TArg, a: T, b: T) => -1 | 0 | 1} RawParameterizedComparator
+ */
+/**
+ * Defines the parameterized comparator type used by this module.
+ * @template {object} TArg
+ * @template T
+ * @typedef {(tArg: TArg) => Comparator<T>} ParameterizedComparator
+ */
+
+/**
+ * Creates a cached parameterized comparator.
+ * @template {object} TArg
+ * @template {object} T
+ * @param {RawParameterizedComparator<TArg, T>} fn comparator with argument
+ * @returns {ParameterizedComparator<TArg, T>} comparator
+ */
+const createCachedParameterizedComparator = (fn) => {
+	/** @type {WeakMap<TArg, Comparator<T>>} */
+	const map = new WeakMap();
+	return (arg) => {
+		const cachedResult = map.get(arg);
+		if (cachedResult !== undefined) return cachedResult;
+		/**
+		 * Returns compare result.
+		 * @param {T} a first item
+		 * @param {T} b second item
+		 * @returns {-1 | 0 | 1} compare result
+		 */
+		const result = fn.bind(null, arg);
+		map.set(arg, result);
+		return result;
+	};
+};
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @param {string | number} a first id
+ * @param {string | number} b second id
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareIds = (a, b) => {
+	if (typeof a !== typeof b) {
+		return typeof a < typeof b ? -1 : 1;
+	}
+	if (a < b) return -1;
+	if (a > b) return 1;
+	return 0;
+};
+
+/**
+ * Compares iterables.
+ * @template T
+ * @param {Comparator<T>} elementComparator comparator for elements
+ * @returns {Comparator<Iterable<T>>} comparator for iterables of elements
+ */
+const compareIterables = (elementComparator) => {
+	const cacheEntry = compareIteratorsCache.get(elementComparator);
+	if (cacheEntry !== undefined) return cacheEntry;
+	/**
+	 * Returns compare result.
+	 * @param {Iterable<T>} a first value
+	 * @param {Iterable<T>} b second value
+	 * @returns {-1 | 0 | 1} compare result
+	 */
+	const result = (a, b) => {
+		const aI = a[Symbol.iterator]();
+		const bI = b[Symbol.iterator]();
+		while (true) {
+			const aItem = aI.next();
+			const bItem = bI.next();
+			if (aItem.done) {
+				return bItem.done ? 0 : -1;
+			} else if (bItem.done) {
+				return 1;
+			}
+			const res = elementComparator(aItem.value, bItem.value);
+			if (res !== 0) return res;
+		}
+	};
+	compareIteratorsCache.set(elementComparator, result);
+	return result;
+};
+
+/**
+ * Compare two locations
+ * @param {DependencyLocation} a A location node
+ * @param {DependencyLocation} b A location node
+ * @returns {-1 | 0 | 1} sorting comparator value
+ */
+const compareLocations = (a, b) => {
+	const isObjectA = typeof a === "object" && a !== null;
+	const isObjectB = typeof b === "object" && b !== null;
+	if (!isObjectA || !isObjectB) {
+		if (isObjectA) return 1;
+		if (isObjectB) return -1;
+		return 0;
+	}
+	if ("start" in a) {
+		if ("start" in b) {
+			const ap = a.start;
+			const bp = b.start;
+			if (ap.line < bp.line) return -1;
+			if (ap.line > bp.line) return 1;
+			if (
+				/** @type {number} */ (ap.column) < /** @type {number} */ (bp.column)
+			) {
+				return -1;
+			}
+			if (
+				/** @type {number} */ (ap.column) > /** @type {number} */ (bp.column)
+			) {
+				return 1;
+			}
+		} else {
+			return -1;
+		}
+	} else if ("start" in b) {
+		return 1;
+	}
+	if ("name" in a) {
+		if ("name" in b) {
+			if (a.name < b.name) return -1;
+			if (a.name > b.name) return 1;
+		} else {
+			return -1;
+		}
+	} else if ("name" in b) {
+		return 1;
+	}
+	if ("index" in a) {
+		if ("index" in b) {
+			if (/** @type {number} */ (a.index) < /** @type {number} */ (b.index)) {
+				return -1;
+			}
+			if (/** @type {number} */ (a.index) > /** @type {number} */ (b.index)) {
+				return 1;
+			}
+		} else {
+			return -1;
+		}
+	} else if ("index" in b) {
+		return 1;
+	}
+	return 0;
+};
+
+/**
+ * Compares modules by id.
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Module} a module
+ * @param {Module} b module
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareModulesById = (chunkGraph, a, b) =>
+	compareIds(
+		/** @type {ModuleId} */ (chunkGraph.getModuleId(a)),
+		/** @type {ModuleId} */ (chunkGraph.getModuleId(b))
+	);
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @param {number} a number
+ * @param {number} b number
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareNumbers = (a, b) => {
+	if (typeof a !== typeof b) {
+		return typeof a < typeof b ? -1 : 1;
+	}
+	if (a < b) return -1;
+	if (a > b) return 1;
+	return 0;
+};
+
+/**
+ * Compares strings numeric.
+ * @param {string} a string
+ * @param {string} b string
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareStringsNumeric = (a, b) => {
+	const aLength = a.length;
+	const bLength = b.length;
+
+	let aChar = 0;
+	let bChar = 0;
+
+	let aIsDigit = false;
+	let bIsDigit = false;
+	let i = 0;
+	let j = 0;
+	while (i < aLength && j < bLength) {
+		aChar = a.charCodeAt(i);
+		bChar = b.charCodeAt(j);
+
+		aIsDigit = aChar >= 48 && aChar <= 57;
+		bIsDigit = bChar >= 48 && bChar <= 57;
+
+		if (!aIsDigit && !bIsDigit) {
+			if (aChar < bChar) return -1;
+			if (aChar > bChar) return 1;
+			i++;
+			j++;
+		} else if (aIsDigit && !bIsDigit) {
+			// This segment of a is shorter than in b
+			return 1;
+		} else if (!aIsDigit && bIsDigit) {
+			// This segment of b is shorter than in a
+			return -1;
+		} else {
+			let aNumber = aChar - 48;
+			let bNumber = bChar - 48;
+
+			while (++i < aLength) {
+				aChar = a.charCodeAt(i);
+				if (aChar < 48 || aChar > 57) break;
+				aNumber = aNumber * 10 + aChar - 48;
+			}
+
+			while (++j < bLength) {
+				bChar = b.charCodeAt(j);
+				if (bChar < 48 || bChar > 57) break;
+				bNumber = bNumber * 10 + bChar - 48;
+			}
+
+			if (aNumber < bNumber) return -1;
+			if (aNumber > bNumber) return 1;
+		}
+	}
+
+	if (j < bLength) {
+		// a is shorter than b
+		bChar = b.charCodeAt(j);
+		bIsDigit = bChar >= 48 && bChar <= 57;
+		return bIsDigit ? -1 : 1;
+	}
+	if (i < aLength) {
+		// b is shorter than a
+		aChar = a.charCodeAt(i);
+		aIsDigit = aChar >= 48 && aChar <= 57;
+		return aIsDigit ? 1 : -1;
+	}
+
+	return 0;
+};
+
+/**
+ * Compares modules by post order index or identifier.
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {Module} a module
+ * @param {Module} b module
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => {
+	const cmp = compareNumbers(
+		/** @type {number} */ (moduleGraph.getPostOrderIndex(a)),
+		/** @type {number} */ (moduleGraph.getPostOrderIndex(b))
+	);
+	if (cmp !== 0) return cmp;
+	return compareIds(a.identifier(), b.identifier());
+};
+
+/**
+ * Compares modules by pre order index or identifier.
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {Module} a module
+ * @param {Module} b module
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => {
+	const cmp = compareNumbers(
+		/** @type {number} */ (moduleGraph.getPreOrderIndex(a)),
+		/** @type {number} */ (moduleGraph.getPreOrderIndex(b))
+	);
+	if (cmp !== 0) return cmp;
+	return compareIds(a.identifier(), b.identifier());
+};
+
+/**
+ * Compares modules by id or identifier.
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Module} a module
+ * @param {Module} b module
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareModulesByIdOrIdentifier = (chunkGraph, a, b) => {
+	const cmp = compareIds(
+		/** @type {ModuleId} */ (chunkGraph.getModuleId(a)),
+		/** @type {ModuleId} */ (chunkGraph.getModuleId(b))
+	);
+	if (cmp !== 0) return cmp;
+	return compareIds(a.identifier(), b.identifier());
+};
+
+/**
+ * Compare modules by their full name. This differs from comparing by identifier in that the values have been normalized to be relative to the compiler context.
+ * @param {{ context: string, root: object }} compiler the compiler, used for context and cache
+ * @param {Module} a module
+ * @param {Module} b module
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareModulesByFullName = (compiler, a, b) => {
+	const aName = getFullModuleName(a, compiler.context, compiler.root);
+	const bName = getFullModuleName(b, compiler.context, compiler.root);
+	return compareIds(aName, bName);
+};
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Chunk} a chunk
+ * @param {Chunk} b chunk
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareChunks = (chunkGraph, a, b) => chunkGraph.compareChunks(a, b);
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @param {string} a first string
+ * @param {string} b second string
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareStrings = (a, b) => {
+	if (a < b) return -1;
+	if (a > b) return 1;
+	return 0;
+};
+
+/**
+ * Compares chunk groups by index.
+ * @param {ChunkGroup} a first chunk group
+ * @param {ChunkGroup} b second chunk group
+ * @returns {-1 | 0 | 1} compare result
+ */
+const compareChunkGroupsByIndex = (a, b) =>
+	/** @type {number} */ (a.index) < /** @type {number} */ (b.index) ? -1 : 1;
+
+/**
+ * Represents TwoKeyWeakMap.
+ * @template {EXPECTED_OBJECT} K1
+ * @template {EXPECTED_OBJECT} K2
+ * @template T
+ */
+class TwoKeyWeakMap {
+	constructor() {
+		/**
+		 * @private
+		 * @type {WeakMap<K1, WeakMap<K2, T | undefined>>}
+		 */
+		this._map = new WeakMap();
+	}
+
+	/**
+	 * Returns value.
+	 * @param {K1} key1 first key
+	 * @param {K2} key2 second key
+	 * @returns {T | undefined} value
+	 */
+	get(key1, key2) {
+		const childMap = this._map.get(key1);
+		if (childMap === undefined) {
+			return;
+		}
+		return childMap.get(key2);
+	}
+
+	/**
+	 * Updates value using the provided key1.
+	 * @param {K1} key1 first key
+	 * @param {K2} key2 second key
+	 * @param {T | undefined} value new value
+	 * @returns {void}
+	 */
+	set(key1, key2, value) {
+		let childMap = this._map.get(key1);
+		if (childMap === undefined) {
+			childMap = new WeakMap();
+			this._map.set(key1, childMap);
+		}
+		childMap.set(key2, value);
+	}
+}
+
+/** @type {TwoKeyWeakMap<Comparator<EXPECTED_ANY>, Comparator<EXPECTED_ANY>, Comparator<EXPECTED_ANY>>}} */
+const concatComparatorsCache = new TwoKeyWeakMap();
+
+/**
+ * Concat comparators.
+ * @template T
+ * @param {Comparator<T>} c1 comparator
+ * @param {Comparator<T>} c2 comparator
+ * @param {Comparator<T>[]} cRest comparators
+ * @returns {Comparator<T>} comparator
+ */
+const concatComparators = (c1, c2, ...cRest) => {
+	if (cRest.length > 0) {
+		const [c3, ...cRest2] = cRest;
+		return concatComparators(c1, concatComparators(c2, c3, ...cRest2));
+	}
+	const cacheEntry = /** @type {Comparator<T>} */ (
+		concatComparatorsCache.get(c1, c2)
+	);
+	if (cacheEntry !== undefined) return cacheEntry;
+	/**
+	 * Returns compare result.
+	 * @param {T} a first value
+	 * @param {T} b second value
+	 * @returns {-1 | 0 | 1} compare result
+	 */
+	const result = (a, b) => {
+		const res = c1(a, b);
+		if (res !== 0) return res;
+		return c2(a, b);
+	};
+	concatComparatorsCache.set(c1, c2, result);
+	return result;
+};
+
+/**
+ * Defines the selector type used by this module.
+ * @template A, B
+ * @typedef {(input: A) => B | undefined | null} Selector
+ */
+
+/** @type {TwoKeyWeakMap<Selector<EXPECTED_ANY, EXPECTED_ANY>, Comparator<EXPECTED_ANY>, Comparator<EXPECTED_ANY>>}} */
+const compareSelectCache = new TwoKeyWeakMap();
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @template T
+ * @template R
+ * @param {Selector<T, R>} getter getter for value
+ * @param {Comparator<R>} comparator comparator
+ * @returns {Comparator<T>} comparator
+ */
+const compareSelect = (getter, comparator) => {
+	const cacheEntry = compareSelectCache.get(getter, comparator);
+	if (cacheEntry !== undefined) return cacheEntry;
+	/**
+	 * Returns compare result.
+	 * @param {T} a first value
+	 * @param {T} b second value
+	 * @returns {-1 | 0 | 1} compare result
+	 */
+	const result = (a, b) => {
+		const aValue = getter(a);
+		const bValue = getter(b);
+		if (aValue !== undefined && aValue !== null) {
+			if (bValue !== undefined && bValue !== null) {
+				return comparator(aValue, bValue);
+			}
+			return -1;
+		}
+		if (bValue !== undefined && bValue !== null) {
+			return 1;
+		}
+		return 0;
+	};
+	compareSelectCache.set(getter, comparator, result);
+	return result;
+};
+
+/** @type {WeakMap<Comparator<EXPECTED_ANY>, Comparator<Iterable<EXPECTED_ANY>>>} */
+const compareIteratorsCache = new WeakMap();
+
+// TODO this is no longer needed when minimum node.js version is >= 12
+// since these versions ship with a stable sort function
+/**
+ * Keep original order.
+ * @template T
+ * @param {Iterable<T>} iterable original ordered list
+ * @returns {Comparator<T>} comparator
+ */
+const keepOriginalOrder = (iterable) => {
+	/** @type {Map<T, number>} */
+	const map = new Map();
+	let i = 0;
+	for (const item of iterable) {
+		map.set(item, i++);
+	}
+	return (a, b) =>
+		compareNumbers(
+			/** @type {number} */ (map.get(a)),
+			/** @type {number} */ (map.get(b))
+		);
+};
+
+/**
+ * Compares chunks natural.
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @returns {Comparator<Chunk>} comparator
+ */
+const compareChunksNatural = (chunkGraph) => {
+	const cmpFn = module.exports.compareModulesById(chunkGraph);
+	const cmpIterableFn = compareIterables(cmpFn);
+	return concatComparators(
+		compareSelect((chunk) => /** @type {ChunkName} */ (chunk.name), compareIds),
+		compareSelect((chunk) => chunk.runtime, compareRuntime),
+		compareSelect(
+			/**
+			 * Handles the callback logic for this hook.
+			 * @param {Chunk} chunk a chunk
+			 * @returns {Iterable<Module>} modules
+			 */
+			(chunk) => chunkGraph.getOrderedChunkModulesIterable(chunk, cmpFn),
+			cmpIterableFn
+		)
+	);
+};
+
+/**
+ * For HarmonyImportSideEffectDependency and HarmonyImportSpecifierDependency, we should prioritize import order to match the behavior of running modules directly in a JS engine without a bundler.
+ * For other types like ConstDependency, we can instead prioritize usage order.
+ * https://github.com/webpack/webpack/pull/19686
+ * @param {Dependency[]} dependencies dependencies
+ * @param {WeakMap<Dependency, DependencySourceOrder>} dependencySourceOrderMap dependency source order map
+ * @param {((dep: Dependency, index: number) => void)=} onDependencyReSort optional callback to set index for each dependency
+ * @returns {void}
+ */
+const sortWithSourceOrder = (
+	dependencies,
+	dependencySourceOrderMap,
+	onDependencyReSort
+) => {
+	/** @type {{ dep: Dependency, main: number, sub: number }[]} */
+	const withSourceOrder = [];
+	/** @type {number[]} */
+	const positions = [];
+
+	for (let i = 0; i < dependencies.length; i++) {
+		const dep = dependencies[i];
+		const cached = dependencySourceOrderMap.get(dep);
+
+		if (cached) {
+			positions.push(i);
+			withSourceOrder.push({
+				dep,
+				main: cached.main,
+				sub: cached.sub
+			});
+		} else {
+			const sourceOrder = /** @type {number | undefined} */ (
+				/** @type {ModuleDependency} */ (dep).sourceOrder
+			);
+			if (typeof sourceOrder === "number") {
+				positions.push(i);
+				withSourceOrder.push({
+					dep,
+					main: sourceOrder,
+					sub: 0
+				});
+			}
+		}
+	}
+
+	if (withSourceOrder.length <= 1) {
+		return;
+	}
+
+	withSourceOrder.sort((a, b) => {
+		if (a.main !== b.main) {
+			return compareNumbers(a.main, b.main);
+		}
+		return compareNumbers(a.sub, b.sub);
+	});
+
+	// Second pass: place sorted deps back to original positions
+	for (let i = 0; i < positions.length; i++) {
+		const depIndex = positions[i];
+		dependencies[depIndex] = withSourceOrder[i].dep;
+		if (onDependencyReSort) {
+			onDependencyReSort(dependencies[depIndex], depIndex);
+		}
+	}
+};
+
+module.exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex;
+/** @type {ParameterizedComparator<ChunkGraph, Chunk>} */
+module.exports.compareChunks =
+	createCachedParameterizedComparator(compareChunks);
+/**
+ * Returns compare result.
+ * @param {Chunk} a chunk
+ * @param {Chunk} b chunk
+ * @returns {-1 | 0 | 1} compare result
+ */
+module.exports.compareChunksById = (a, b) =>
+	compareIds(/** @type {ChunkId} */ (a.id), /** @type {ChunkId} */ (b.id));
+module.exports.compareChunksNatural = compareChunksNatural;
+
+module.exports.compareIds = compareIds;
+
+module.exports.compareIterables = compareIterables;
+
+module.exports.compareLocations = compareLocations;
+
+/** @type {ParameterizedComparator<Compiler, Module>} */
+module.exports.compareModulesByFullName = createCachedParameterizedComparator(
+	compareModulesByFullName
+);
+
+/** @type {ParameterizedComparator<ChunkGraph, Module>} */
+module.exports.compareModulesById =
+	createCachedParameterizedComparator(compareModulesById);
+/** @type {ParameterizedComparator<ChunkGraph, Module>} */
+module.exports.compareModulesByIdOrIdentifier =
+	createCachedParameterizedComparator(compareModulesByIdOrIdentifier);
+/**
+ * Returns compare result.
+ * @param {Module} a module
+ * @param {Module} b module
+ * @returns {-1 | 0 | 1} compare result
+ */
+module.exports.compareModulesByIdentifier = (a, b) =>
+	compareIds(a.identifier(), b.identifier());
+/** @type {ParameterizedComparator<ModuleGraph, Module>} */
+module.exports.compareModulesByPostOrderIndexOrIdentifier =
+	createCachedParameterizedComparator(
+		compareModulesByPostOrderIndexOrIdentifier
+	);
+/** @type {ParameterizedComparator<ModuleGraph, Module>} */
+module.exports.compareModulesByPreOrderIndexOrIdentifier =
+	createCachedParameterizedComparator(
+		compareModulesByPreOrderIndexOrIdentifier
+	);
+
+module.exports.compareNumbers = compareNumbers;
+module.exports.compareSelect = compareSelect;
+module.exports.compareStrings = compareStrings;
+module.exports.compareStringsNumeric = compareStringsNumeric;
+
+module.exports.concatComparators = concatComparators;
+
+module.exports.keepOriginalOrder = keepOriginalOrder;
+module.exports.sortWithSourceOrder = sortWithSourceOrder;
Index: frontend/node_modules/webpack/lib/util/compileBooleanMatcher.js
===================================================================
--- frontend/node_modules/webpack/lib/util/compileBooleanMatcher.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/compileBooleanMatcher.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,322 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Returns quoted meta.
+ * @param {string} str string
+ * @returns {string} quoted meta
+ */
+const quoteMeta = (str) => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
+
+/**
+ * Quote meta in char class.
+ * @param {string} char character to escape for use in character class
+ * @returns {string} escaped character
+ */
+const quoteMetaInCharClass = (char) => {
+	// In character class, only these need escaping: ] \ ^ -
+	if (char === "]" || char === "\\" || char === "^" || char === "-") {
+		return `\\${char}`;
+	}
+	return char;
+};
+
+/**
+ * Converts an array of single characters into an optimized character class string
+ * using ranges where possible. E.g., ["1","2","3","4","a"] => "1-4a"
+ * @param {string[]} chars array of single characters (should be sorted)
+ * @returns {string} optimized character class content (without the brackets)
+ */
+const charsToCharClassContent = (chars) => {
+	if (chars.length === 0) return "";
+	if (chars.length === 1) return quoteMetaInCharClass(chars[0]);
+
+	// Sort by char code
+	const sorted = [...chars].sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0));
+
+	/** @type {string[]} */
+	const parts = [];
+	let rangeStart = sorted[0];
+	let rangeEnd = sorted[0];
+
+	for (let i = 1; i < sorted.length; i++) {
+		const char = sorted[i];
+		const prevCode = rangeEnd.charCodeAt(0);
+		const currCode = char.charCodeAt(0);
+
+		if (currCode === prevCode + 1) {
+			// Extend the range
+			rangeEnd = char;
+		} else {
+			// Flush the current range
+			parts.push(formatRange(rangeStart, rangeEnd));
+			rangeStart = char;
+			rangeEnd = char;
+		}
+	}
+	// Flush the last range
+	parts.push(formatRange(rangeStart, rangeEnd));
+
+	return parts.join("");
+};
+
+/**
+ * Formats a range of characters for use in a character class
+ * @param {string} start start character
+ * @param {string} end end character
+ * @returns {string} formatted range
+ */
+const formatRange = (start, end) => {
+	const startCode = start.charCodeAt(0);
+	const endCode = end.charCodeAt(0);
+	const length = endCode - startCode + 1;
+
+	if (length === 1) {
+		return quoteMetaInCharClass(start);
+	}
+	if (length === 2) {
+		// For 2 chars, just list them (e.g., "ab" instead of "a-b")
+		return quoteMetaInCharClass(start) + quoteMetaInCharClass(end);
+	}
+	// For 3+ chars, use range notation
+	return `${quoteMetaInCharClass(start)}-${quoteMetaInCharClass(end)}`;
+};
+
+/**
+ * Returns string.
+ * @param {string} str string
+ * @returns {string} string
+ */
+const toSimpleString = (str) => {
+	if (`${Number(str)}` === str) {
+		return str;
+	}
+	return JSON.stringify(str);
+};
+
+/**
+ * Compile boolean matcher.
+ * @param {Record<string | number, boolean>} map value map
+ * @returns {boolean | ((value: string) => string)} true/false, when unconditionally true/false, or a template function to determine the value at runtime
+ */
+const compileBooleanMatcher = (map) => {
+	const positiveItems = Object.keys(map).filter((i) => map[i]);
+	const negativeItems = Object.keys(map).filter((i) => !map[i]);
+	if (positiveItems.length === 0) return false;
+	if (negativeItems.length === 0) return true;
+	return compileBooleanMatcherFromLists(positiveItems, negativeItems);
+};
+
+/**
+ * Compile boolean matcher from lists.
+ * @param {string[]} positiveItems positive items
+ * @param {string[]} negativeItems negative items
+ * @returns {(value: string) => string} a template function to determine the value at runtime
+ */
+const compileBooleanMatcherFromLists = (positiveItems, negativeItems) => {
+	if (positiveItems.length === 0) return () => "false";
+	if (negativeItems.length === 0) return () => "true";
+	if (positiveItems.length === 1) {
+		return (value) => `${toSimpleString(positiveItems[0])} == ${value}`;
+	}
+	if (negativeItems.length === 1) {
+		return (value) => `${toSimpleString(negativeItems[0])} != ${value}`;
+	}
+	const positiveRegexp = itemsToRegexp(positiveItems);
+	const negativeRegexp = itemsToRegexp(negativeItems);
+	if (positiveRegexp.length <= negativeRegexp.length) {
+		return (value) => `/^${positiveRegexp}$/.test(${value})`;
+	}
+	return (value) => `!/^${negativeRegexp}$/.test(${value})`;
+};
+
+/** @typedef {string[][]} ListOfCommonItems */
+
+/**
+ * Returns list of common items.
+ * @param {Set<string>} itemsSet items set
+ * @param {(str: string) => string | false} getKey get key function
+ * @param {(str: string[]) => boolean} condition condition
+ * @returns {ListOfCommonItems} list of common items
+ */
+const popCommonItems = (itemsSet, getKey, condition) => {
+	/** @type {Map<string, string[]>} */
+	const map = new Map();
+	for (const item of itemsSet) {
+		const key = getKey(item);
+		if (key) {
+			let list = map.get(key);
+			if (list === undefined) {
+				/** @type {string[]} */
+				list = [];
+				map.set(key, list);
+			}
+			list.push(item);
+		}
+	}
+	/** @type {ListOfCommonItems} */
+	const result = [];
+	for (const list of map.values()) {
+		if (condition(list)) {
+			for (const item of list) {
+				itemsSet.delete(item);
+			}
+			result.push(list);
+		}
+	}
+	return result;
+};
+
+/**
+ * Gets common prefix.
+ * @param {string[]} items items
+ * @returns {string} common prefix
+ */
+const getCommonPrefix = (items) => {
+	let prefix = items[0];
+	for (let i = 1; i < items.length; i++) {
+		const item = items[i];
+		for (let p = 0; p < prefix.length; p++) {
+			if (item[p] !== prefix[p]) {
+				prefix = prefix.slice(0, p);
+				break;
+			}
+		}
+	}
+	return prefix;
+};
+
+/**
+ * Gets common suffix.
+ * @param {string[]} items items
+ * @returns {string} common suffix
+ */
+const getCommonSuffix = (items) => {
+	let suffix = items[0];
+	for (let i = 1; i < items.length; i++) {
+		const item = items[i];
+		for (let p = item.length - 1, s = suffix.length - 1; s >= 0; p--, s--) {
+			if (item[p] !== suffix[s]) {
+				suffix = suffix.slice(s + 1);
+				break;
+			}
+		}
+	}
+	return suffix;
+};
+
+/**
+ * Returns regexp.
+ * @param {string[]} itemsArr array of items
+ * @returns {string} regexp
+ */
+const itemsToRegexp = (itemsArr) => {
+	if (itemsArr.length === 1) {
+		return quoteMeta(itemsArr[0]);
+	}
+	/** @type {string[]} */
+	const finishedItems = [];
+
+	// merge single char items: (a|b|c|d|ef) => ([abcd]|ef)
+	let countOfSingleCharItems = 0;
+	for (const item of itemsArr) {
+		if (item.length === 1) {
+			countOfSingleCharItems++;
+		}
+	}
+	// special case for only single char items
+	if (countOfSingleCharItems === itemsArr.length) {
+		return `[${charsToCharClassContent(itemsArr)}]`;
+	}
+	/** @type {Set<string>} */
+	const items = new Set(itemsArr.sort());
+	if (countOfSingleCharItems > 2) {
+		/** @type {string[]} */
+		const singleCharItems = [];
+		for (const item of items) {
+			if (item.length === 1) {
+				singleCharItems.push(item);
+				items.delete(item);
+			}
+		}
+		finishedItems.push(`[${charsToCharClassContent(singleCharItems)}]`);
+	}
+
+	// special case for 2 items with common prefix/suffix
+	if (finishedItems.length === 0 && items.size === 2) {
+		const prefix = getCommonPrefix(itemsArr);
+		const suffix = getCommonSuffix(
+			itemsArr.map((item) => item.slice(prefix.length))
+		);
+		if (prefix.length > 0 || suffix.length > 0) {
+			return `${quoteMeta(prefix)}${itemsToRegexp(
+				itemsArr.map((i) => i.slice(prefix.length, -suffix.length || undefined))
+			)}${quoteMeta(suffix)}`;
+		}
+	}
+
+	// special case for 2 items with common suffix
+	if (finishedItems.length === 0 && items.size === 2) {
+		/** @type {SetIterator<string>} */
+		const it = items[Symbol.iterator]();
+		const a = /** @type {string} */ (it.next().value);
+		const b = /** @type {string} */ (it.next().value);
+		if (a.length > 0 && b.length > 0 && a.slice(-1) === b.slice(-1)) {
+			return `${itemsToRegexp([a.slice(0, -1), b.slice(0, -1)])}${quoteMeta(
+				a.slice(-1)
+			)}`;
+		}
+	}
+
+	// find common prefix: (a1|a2|a3|a4|b5) => (a(1|2|3|4)|b5)
+	const prefixed = popCommonItems(
+		items,
+		(item) => (item.length >= 1 ? item[0] : false),
+		(list) => {
+			if (list.length >= 3) return true;
+			if (list.length <= 1) return false;
+			return list[0][1] === list[1][1];
+		}
+	);
+	for (const prefixedItems of prefixed) {
+		const prefix = getCommonPrefix(prefixedItems);
+		finishedItems.push(
+			`${quoteMeta(prefix)}${itemsToRegexp(
+				prefixedItems.map((i) => i.slice(prefix.length))
+			)}`
+		);
+	}
+
+	// find common suffix: (a1|b1|c1|d1|e2) => ((a|b|c|d)1|e2)
+	const suffixed = popCommonItems(
+		items,
+		(item) => (item.length >= 1 ? item.slice(-1) : false),
+		(list) => {
+			if (list.length >= 3) return true;
+			if (list.length <= 1) return false;
+			return list[0].slice(-2) === list[1].slice(-2);
+		}
+	);
+	for (const suffixedItems of suffixed) {
+		const suffix = getCommonSuffix(suffixedItems);
+		finishedItems.push(
+			`${itemsToRegexp(
+				suffixedItems.map((i) => i.slice(0, -suffix.length))
+			)}${quoteMeta(suffix)}`
+		);
+	}
+
+	/** @type {string[]} */
+	const conditional = [...finishedItems, ...Array.from(items, quoteMeta)];
+	if (conditional.length === 1) return conditional[0];
+	return `(${conditional.join("|")})`;
+};
+
+compileBooleanMatcher.fromLists = compileBooleanMatcherFromLists;
+compileBooleanMatcher.itemsToRegexp = itemsToRegexp;
+
+module.exports = compileBooleanMatcher;
Index: frontend/node_modules/webpack/lib/util/concatenate.js
===================================================================
--- frontend/node_modules/webpack/lib/util/concatenate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/concatenate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,238 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Template = require("../Template");
+
+/** @typedef {import("estree").Node} Node */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").Scope} Scope */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").Reference} Reference */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").Variable} Variable */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {Set<string>} UsedNames */
+
+const DEFAULT_EXPORT = "__WEBPACK_DEFAULT_EXPORT__";
+const NAMESPACE_OBJECT_EXPORT = "__WEBPACK_NAMESPACE_OBJECT__";
+
+/**
+ * Gets all references.
+ * @param {Variable} variable variable
+ * @returns {Reference[]} references
+ */
+const getAllReferences = (variable) => {
+	let set = variable.references;
+	// Look for inner scope variables too (like in class Foo { t() { Foo } })
+	const identifiers = new Set(variable.identifiers);
+	for (const scope of variable.scope.childScopes) {
+		for (const innerVar of scope.variables) {
+			if (innerVar.identifiers.some((id) => identifiers.has(id))) {
+				set = [...set, ...innerVar.references];
+				break;
+			}
+		}
+	}
+	return set;
+};
+
+/**
+ * Returns result.
+ * @param {Node | Node[]} ast ast
+ * @param {Node} node node
+ * @returns {undefined | Node[]} result
+ */
+const getPathInAst = (ast, node) => {
+	if (ast === node) {
+		return [];
+	}
+
+	const nr = /** @type {Range} */ (node.range);
+
+	/**
+	 * Returns result.
+	 * @param {Node} n node
+	 * @returns {Node[] | undefined} result
+	 */
+	const enterNode = (n) => {
+		if (!n) return;
+		const r = n.range;
+		if (r && r[0] <= nr[0] && r[1] >= nr[1]) {
+			const path = getPathInAst(n, node);
+			if (path) {
+				path.push(n);
+				return path;
+			}
+		}
+	};
+
+	if (Array.isArray(ast)) {
+		for (let i = 0; i < ast.length; i++) {
+			const enterResult = enterNode(ast[i]);
+			if (enterResult !== undefined) return enterResult;
+		}
+	} else if (ast && typeof ast === "object") {
+		const keys =
+			/** @type {(keyof Node)[]} */
+			(Object.keys(ast));
+		for (let i = 0; i < keys.length; i++) {
+			// We are making the faster check in `enterNode` using `n.range`
+			const value =
+				ast[
+					/** @type {Exclude<keyof Node, "range" | "loc" | "leadingComments" | "trailingComments">} */
+					(keys[i])
+				];
+			if (Array.isArray(value)) {
+				const pathResult = getPathInAst(value, node);
+				if (pathResult !== undefined) return pathResult;
+			} else if (value && typeof value === "object") {
+				const enterResult = enterNode(value);
+				if (enterResult !== undefined) return enterResult;
+			}
+		}
+	}
+};
+
+/**
+ * Returns found new name.
+ * @param {string} oldName old name
+ * @param {UsedNames} usedNamed1 used named 1
+ * @param {UsedNames} usedNamed2 used named 2
+ * @param {string} extraInfo extra info
+ * @returns {string} found new name
+ */
+function findNewName(oldName, usedNamed1, usedNamed2, extraInfo) {
+	let name = oldName;
+
+	if (name === DEFAULT_EXPORT) {
+		name = "";
+	}
+	if (name === NAMESPACE_OBJECT_EXPORT) {
+		name = "namespaceObject";
+	}
+
+	// Remove uncool stuff
+	extraInfo = extraInfo.replace(
+		/\.+\/|(?:\/index)?\.[a-zA-Z0-9]{1,4}(?:$|\s|\?)|\s*\+\s*\d+\s*modules/g,
+		""
+	);
+
+	const splittedInfo = extraInfo.split("/");
+	while (splittedInfo.length) {
+		name = splittedInfo.pop() + (name ? `_${name}` : "");
+		const nameIdent = Template.toIdentifier(name);
+		if (
+			!usedNamed1.has(nameIdent) &&
+			(!usedNamed2 || !usedNamed2.has(nameIdent))
+		) {
+			return nameIdent;
+		}
+	}
+
+	let i = 0;
+	let nameWithNumber = Template.toIdentifier(`${name}_${i}`);
+	while (
+		usedNamed1.has(nameWithNumber) ||
+		// eslint-disable-next-line no-unmodified-loop-condition
+		(usedNamed2 && usedNamed2.has(nameWithNumber))
+	) {
+		i++;
+		nameWithNumber = Template.toIdentifier(`${name}_${i}`);
+	}
+	return nameWithNumber;
+}
+
+/** @typedef {Set<Scope>} ScopeSet */
+
+/**
+ * Adds scope symbols.
+ * @param {Scope | null} s scope
+ * @param {UsedNames} nameSet name set
+ * @param {ScopeSet} scopeSet1 scope set 1
+ * @param {ScopeSet} scopeSet2 scope set 2
+ */
+const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => {
+	let scope = s;
+	while (scope) {
+		if (scopeSet1.has(scope)) break;
+		if (scopeSet2.has(scope)) break;
+		scopeSet1.add(scope);
+		for (const variable of scope.variables) {
+			nameSet.add(variable.name);
+		}
+		scope = scope.upper;
+	}
+};
+
+const RESERVED_NAMES = new Set(
+	[
+		// internal names (should always be renamed)
+		DEFAULT_EXPORT,
+		NAMESPACE_OBJECT_EXPORT,
+
+		// keywords
+		"abstract,arguments,async,await,boolean,break,byte,case,catch,char,class,const,continue",
+		"debugger,default,delete,do,double,else,enum,eval,export,extends,false,final,finally,float",
+		"for,function,goto,if,implements,import,in,instanceof,int,interface,let,long,native,new,null",
+		"package,private,protected,public,return,short,static,super,switch,synchronized,this,throw",
+		"throws,transient,true,try,typeof,var,void,volatile,while,with,yield",
+
+		// commonjs/amd
+		"module,__dirname,__filename,exports,require,define",
+
+		// js globals
+		"Array,Date,eval,function,hasOwnProperty,Infinity,isFinite,isNaN,isPrototypeOf,length,Math",
+		"NaN,name,Number,Object,prototype,String,Symbol,toString,undefined,valueOf",
+
+		// browser globals
+		"alert,all,anchor,anchors,area,assign,blur,button,checkbox,clearInterval,clearTimeout",
+		"clientInformation,close,closed,confirm,constructor,crypto,decodeURI,decodeURIComponent",
+		"defaultStatus,document,element,elements,embed,embeds,encodeURI,encodeURIComponent,escape",
+		"event,fileUpload,focus,form,forms,frame,innerHeight,innerWidth,layer,layers,link,location",
+		"mimeTypes,navigate,navigator,frames,frameRate,hidden,history,image,images,offscreenBuffering",
+		"open,opener,option,outerHeight,outerWidth,packages,pageXOffset,pageYOffset,parent,parseFloat",
+		"parseInt,password,pkcs11,plugin,prompt,propertyIsEnum,radio,reset,screenX,screenY,scroll",
+		"secure,select,self,setInterval,setTimeout,status,submit,taint,text,textarea,top,unescape",
+		"untaint,window",
+
+		// window events
+		"onblur,onclick,onerror,onfocus,onkeydown,onkeypress,onkeyup,onmouseover,onload,onmouseup,onmousedown,onsubmit"
+	]
+		.join(",")
+		.split(",")
+);
+
+/** @typedef {{ usedNames: UsedNames, alreadyCheckedScopes: ScopeSet }} ScopeInfo */
+/** @typedef {Map<string, ScopeInfo>} UsedNamesInScopeInfo */
+
+/**
+ * Gets used names in scope info.
+ * @param {UsedNamesInScopeInfo} usedNamesInScopeInfo used names in scope info
+ * @param {string} module module identifier
+ * @param {string} id export id
+ * @returns {ScopeInfo} info
+ */
+const getUsedNamesInScopeInfo = (usedNamesInScopeInfo, module, id) => {
+	const key = `${module}-${id}`;
+	let info = usedNamesInScopeInfo.get(key);
+	if (info === undefined) {
+		info = {
+			usedNames: new Set(),
+			alreadyCheckedScopes: new Set()
+		};
+		usedNamesInScopeInfo.set(key, info);
+	}
+	return info;
+};
+
+module.exports = {
+	DEFAULT_EXPORT,
+	NAMESPACE_OBJECT_EXPORT,
+	RESERVED_NAMES,
+	addScopeSymbols,
+	findNewName,
+	getAllReferences,
+	getPathInAst,
+	getUsedNamesInScopeInfo
+};
Index: frontend/node_modules/webpack/lib/util/conventions.js
===================================================================
--- frontend/node_modules/webpack/lib/util/conventions.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/conventions.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,171 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Gengkun He @ahabhgk
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
+// Copy from css-loader
+/**
+ * Preserve camel case.
+ * @param {string} string string
+ * @returns {string} result
+ */
+const preserveCamelCase = (string) => {
+	let result = string;
+	let isLastCharLower = false;
+	let isLastCharUpper = false;
+	let isLastLastCharUpper = false;
+
+	for (let i = 0; i < result.length; i++) {
+		const character = result[i];
+
+		if (isLastCharLower && /\p{Lu}/u.test(character)) {
+			result = `${result.slice(0, i)}-${result.slice(i)}`;
+			isLastCharLower = false;
+			isLastLastCharUpper = isLastCharUpper;
+			isLastCharUpper = true;
+			i += 1;
+		} else if (
+			isLastCharUpper &&
+			isLastLastCharUpper &&
+			/\p{Ll}/u.test(character)
+		) {
+			result = `${result.slice(0, i - 1)}-${result.slice(i - 1)}`;
+			isLastLastCharUpper = isLastCharUpper;
+			isLastCharUpper = false;
+			isLastCharLower = true;
+		} else {
+			isLastCharLower =
+				character.toLowerCase() === character &&
+				character.toUpperCase() !== character;
+			isLastLastCharUpper = isLastCharUpper;
+			isLastCharUpper =
+				character.toUpperCase() === character &&
+				character.toLowerCase() !== character;
+		}
+	}
+
+	return result;
+};
+
+// Copy from css-loader
+/**
+ * Returns result.
+ * @param {string} input input
+ * @returns {string} result
+ */
+module.exports.camelCase = (input) => {
+	let result = input.trim();
+
+	if (result.length === 0) {
+		return "";
+	}
+
+	if (result.length === 1) {
+		return result.toLowerCase();
+	}
+
+	const hasUpperCase = result !== result.toLowerCase();
+
+	if (hasUpperCase) {
+		result = preserveCamelCase(result);
+	}
+
+	return result
+		.replace(/^[_.\- ]+/, "")
+		.toLowerCase()
+		.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toUpperCase())
+		.replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, (m) => m.toUpperCase());
+};
+
+/**
+ * Safely stringify an arbitrary value for an error message — falls back to
+ * `String(...)` when JSON.stringify would throw (BigInt, circular, etc.).
+ * @param {EXPECTED_ANY} value value to stringify
+ * @returns {string} stringified value
+ */
+const safeStringify = (value) => {
+	try {
+		const json = JSON.stringify(value);
+		if (json !== undefined) return json;
+	} catch (_err) {
+		// fall through to String fallback
+	}
+	try {
+		return String(value);
+	} catch (_err) {
+		return "[value cannot be converted to string]";
+	}
+};
+
+/**
+ * Returns results.
+ * @param {string} input input
+ * @param {CssGeneratorExportsConvention | undefined} convention convention
+ * @returns {string[]} results
+ */
+module.exports.cssExportConvention = (input, convention) => {
+	/** @type {Set<string>} */
+	const set = new Set();
+	if (typeof convention === "function") {
+		const result = convention(input);
+		const validate = (/** @type {string} */ name) => {
+			if (typeof name !== "string" || name.length === 0) {
+				throw new Error(
+					`exportsConvention function must return a non-empty string or an array of non-empty strings, got ${safeStringify(result)}`
+				);
+			}
+		};
+		if (Array.isArray(result)) {
+			if (result.length === 0) {
+				throw new Error(
+					"exportsConvention function returned an empty array; it must return at least one name"
+				);
+			}
+			for (const name of result) {
+				validate(name);
+				set.add(name);
+			}
+		} else {
+			validate(result);
+			set.add(result);
+		}
+	} else {
+		switch (convention) {
+			case "camel-case": {
+				set.add(input);
+				set.add(module.exports.camelCase(input));
+				break;
+			}
+			case "camel-case-only": {
+				set.add(module.exports.camelCase(input));
+				break;
+			}
+			case "dashes": {
+				set.add(input);
+				set.add(module.exports.dashesCamelCase(input));
+				break;
+			}
+			case "dashes-only": {
+				set.add(module.exports.dashesCamelCase(input));
+				break;
+			}
+			case "as-is": {
+				set.add(input);
+				break;
+			}
+		}
+	}
+	return [...set];
+};
+
+// Copy from css-loader
+/**
+ * Returns result.
+ * @param {string} input input
+ * @returns {string} result
+ */
+module.exports.dashesCamelCase = (input) =>
+	input.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
Index: frontend/node_modules/webpack/lib/util/createHash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/createHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/createHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Hash")} Hash */
+/** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
+
+/** @type {typeof import("crypto") | undefined} */
+let crypto;
+/** @type {typeof import("./hash/xxhash64") | undefined} */
+let createXXHash64;
+/** @type {typeof import("./hash/md4") | undefined} */
+let createMd4;
+/** @type {typeof import("./hash/DebugHash") | undefined} */
+let DebugHash;
+/** @type {typeof import("./hash/BatchedHash") | undefined} */
+let BatchedHash;
+/** @type {typeof import("./hash/BulkUpdateHash") | undefined} */
+let BulkUpdateHash;
+
+/**
+ * Creates a hash by name or function
+ * @param {HashFunction} algorithm the algorithm name or a constructor creating a hash
+ * @returns {Hash} the hash
+ */
+module.exports = (algorithm) => {
+	if (typeof algorithm === "function") {
+		if (BulkUpdateHash === undefined) {
+			BulkUpdateHash = require("./hash/BulkUpdateHash");
+		}
+		// eslint-disable-next-line new-cap
+		return new BulkUpdateHash(() => new algorithm());
+	}
+	switch (algorithm) {
+		// TODO add non-cryptographic algorithm here
+		case "debug":
+			if (DebugHash === undefined) {
+				DebugHash = require("./hash/DebugHash");
+			}
+			return new DebugHash();
+		case "xxhash64":
+			if (createXXHash64 === undefined) {
+				createXXHash64 = require("./hash/xxhash64");
+				if (BatchedHash === undefined) {
+					BatchedHash = require("./hash/BatchedHash");
+				}
+			}
+			return new /** @type {typeof import("./hash/BatchedHash")} */ (
+				BatchedHash
+			)(createXXHash64());
+		case "md4":
+			if (createMd4 === undefined) {
+				createMd4 = require("./hash/md4");
+				if (BatchedHash === undefined) {
+					BatchedHash = require("./hash/BatchedHash");
+				}
+			}
+			return new /** @type {typeof import("./hash/BatchedHash")} */ (
+				BatchedHash
+			)(createMd4());
+		case "native-md4":
+			if (crypto === undefined) crypto = require("crypto");
+			if (BulkUpdateHash === undefined) {
+				BulkUpdateHash = require("./hash/BulkUpdateHash");
+			}
+			return new BulkUpdateHash(
+				() =>
+					/** @type {Hash} */ (
+						/** @type {typeof import("crypto")} */
+						(crypto).createHash("md4")
+					),
+				"md4"
+			);
+		default:
+			if (crypto === undefined) crypto = require("crypto");
+			if (BulkUpdateHash === undefined) {
+				BulkUpdateHash = require("./hash/BulkUpdateHash");
+			}
+			return new BulkUpdateHash(
+				() =>
+					/** @type {Hash} */ (
+						/** @type {typeof import("crypto")} */
+						(crypto).createHash(algorithm)
+					),
+				algorithm
+			);
+	}
+};
Index: frontend/node_modules/webpack/lib/util/createMappings.js
===================================================================
--- frontend/node_modules/webpack/lib/util/createMappings.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/createMappings.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,118 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/**
+ * Utilities for building V3 source-map `mappings` strings without pulling in a
+ * full source-map library. The shape of the input is intentionally minimal —
+ * one slot per generated line, each holding zero, one, or many segments — so
+ * call sites that have a "one mapping per line" structure (like the CSS-module
+ * exports emit in `lib/css/CssGenerator.js`) can build mappings directly,
+ * while richer call sites can pass arrays of segments.
+ *
+ * TODO move this encoder into `webpack-sources` and replace the body of this
+ * file with re-exports. The public shape (`encodeVLQ`, `encodeMappings(lines)`,
+ * `MappingSegment`, `LineMappings`) is intended to match what would land
+ * upstream so call sites don't have to change.
+ */
+
+const VLQ_BASE64 =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * Encode a signed integer as a base64 VLQ string per the source-map V3 spec.
+ * @param {number} value signed integer to encode
+ * @returns {string} base64 VLQ encoded value
+ */
+const encodeVLQ = (value) => {
+	let vlq = value < 0 ? (-value << 1) | 1 : value << 1;
+	let result = "";
+	do {
+		let digit = vlq & 0x1f;
+		vlq >>>= 5;
+		if (vlq > 0) digit |= 0x20;
+		result += VLQ_BASE64[digit];
+	} while (vlq > 0);
+	return result;
+};
+
+/**
+ * @typedef {object} MappingSegment
+ * @property {number=} generatedColumn 0-based generated column (defaults to 0)
+ * @property {number=} sourceIndex index into the surrounding source map's `sources` array; omit for a generated-only segment
+ * @property {number=} originalLine 0-based line in the original source (required when `sourceIndex` is set)
+ * @property {number=} originalColumn 0-based column in the original source (required when `sourceIndex` is set)
+ * @property {number=} nameIndex index into the surrounding source map's `names` array
+ */
+
+/** @typedef {null | MappingSegment | MappingSegment[]} LineMappings */
+
+/**
+ * Encode a V3 source-map `mappings` string from a per-generated-line
+ * description of segments.
+ *
+ * Each entry of `lines` describes the mappings for one generated line:
+ *
+ * - `null` (or `undefined`) — the line has no mappings.
+ * - a single `MappingSegment` — convenience for the common "one mapping at
+ * column 0" case.
+ * - `MappingSegment[]` — multiple segments on the same line.
+ *
+ * Lines are joined with `;`, segments within a line with `,`. All numeric
+ * fields are encoded as deltas relative to the previous emitted segment, per
+ * the V3 spec.
+ * @param {LineMappings[]} lines per-generated-line mapping segments
+ * @returns {string} VLQ-encoded V3 mappings string
+ */
+const encodeMappings = (lines) => {
+	let prevSourceIndex = 0;
+	let prevOriginalLine = 0;
+	let prevOriginalColumn = 0;
+	let prevNameIndex = 0;
+
+	const encodedLines = [];
+
+	for (const line of lines) {
+		if (line === null || line === undefined) {
+			encodedLines.push("");
+			continue;
+		}
+
+		const segments = Array.isArray(line) ? line : [line];
+		let prevGeneratedColumn = 0;
+		const encodedSegments = [];
+
+		for (const segment of segments) {
+			const generatedColumn = segment.generatedColumn || 0;
+			let encoded = encodeVLQ(generatedColumn - prevGeneratedColumn);
+			prevGeneratedColumn = generatedColumn;
+
+			if (segment.sourceIndex !== undefined) {
+				const originalLine = /** @type {number} */ (segment.originalLine);
+				const originalColumn = /** @type {number} */ (segment.originalColumn);
+				encoded += encodeVLQ(segment.sourceIndex - prevSourceIndex);
+				encoded += encodeVLQ(originalLine - prevOriginalLine);
+				encoded += encodeVLQ(originalColumn - prevOriginalColumn);
+				prevSourceIndex = segment.sourceIndex;
+				prevOriginalLine = originalLine;
+				prevOriginalColumn = originalColumn;
+
+				if (segment.nameIndex !== undefined) {
+					encoded += encodeVLQ(segment.nameIndex - prevNameIndex);
+					prevNameIndex = segment.nameIndex;
+				}
+			}
+
+			encodedSegments.push(encoded);
+		}
+
+		encodedLines.push(encodedSegments.join(","));
+	}
+
+	return encodedLines.join(";");
+};
+
+module.exports.encodeMappings = encodeMappings;
+module.exports.encodeVLQ = encodeVLQ;
Index: frontend/node_modules/webpack/lib/util/dataURL.js
===================================================================
--- frontend/node_modules/webpack/lib/util/dataURL.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/dataURL.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+// data URL scheme: "data:text/javascript;charset=utf-8;base64,some-string"
+// http://www.ietf.org/rfc/rfc2397.txt
+const URIRegEx = /^data:([^;,]+)?((?:;[^;,]+)*?)(?:;(base64)?)?,(.*)$/i;
+
+/**
+ * Decodes the provided uri.
+ * @param {string} uri data URI
+ * @returns {Buffer | null} decoded data
+ */
+const decodeDataURI = (uri) => {
+	const match = URIRegEx.exec(uri);
+	if (!match) return null;
+
+	const isBase64 = match[3];
+	const body = match[4];
+
+	if (isBase64) {
+		return Buffer.from(body, "base64");
+	}
+
+	// CSS allows to use `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" style="stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px" /></svg>`
+	// so we return original body if we can't `decodeURIComponent`
+	try {
+		return Buffer.from(decodeURIComponent(body), "ascii");
+	} catch (_) {
+		return Buffer.from(body, "ascii");
+	}
+};
+
+module.exports = {
+	URIRegEx,
+	decodeDataURI
+};
Index: frontend/node_modules/webpack/lib/util/deprecation.js
===================================================================
--- frontend/node_modules/webpack/lib/util/deprecation.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/deprecation.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,369 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+
+/** @type {Map<string, () => void>} */
+const deprecationCache = new Map();
+
+/**
+ * Defines the fake hook marker type used by this module.
+ * @typedef {object} FakeHookMarker
+ * @property {true} _fakeHook it's a fake hook
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {T & FakeHookMarker} FakeHook<T>
+ */
+
+/**
+ * Creates a deprecation.
+ * @param {string} message deprecation message
+ * @param {string} code deprecation code
+ * @returns {() => void} function to trigger deprecation
+ */
+const createDeprecation = (message, code) => {
+	const cached = deprecationCache.get(message);
+	if (cached !== undefined) return cached;
+	const fn = util.deprecate(
+		() => {},
+		message,
+		`DEP_WEBPACK_DEPRECATION_${code}`
+	);
+	deprecationCache.set(message, fn);
+	return fn;
+};
+
+/** @typedef {"concat" | "entry" | "filter" | "find" | "findIndex" | "includes" | "indexOf" | "join" | "lastIndexOf" | "map" | "reduce" | "reduceRight" | "slice" | "some"} COPY_METHODS_NAMES */
+
+/** @type {COPY_METHODS_NAMES[]} */
+const COPY_METHODS = [
+	"concat",
+	"entry",
+	"filter",
+	"find",
+	"findIndex",
+	"includes",
+	"indexOf",
+	"join",
+	"lastIndexOf",
+	"map",
+	"reduce",
+	"reduceRight",
+	"slice",
+	"some"
+];
+
+/** @typedef {"copyWithin" | "entries" | "fill" | "keys" | "pop" | "reverse" | "shift" | "splice" | "sort" | "unshift"} DISABLED_METHODS_NAMES */
+
+/** @type {DISABLED_METHODS_NAMES[]} */
+const DISABLED_METHODS = [
+	"copyWithin",
+	"entries",
+	"fill",
+	"keys",
+	"pop",
+	"reverse",
+	"shift",
+	"splice",
+	"sort",
+	"unshift"
+];
+
+/**
+ * Defines the set with deprecated array methods type used by this module.
+ * @template T
+ * @typedef {Set<T> & { [Symbol.isConcatSpreadable]: boolean } & { push: (...items: T[]) => void, length?: number } & { [P in DISABLED_METHODS_NAMES]: () => void } & { [P in COPY_METHODS_NAMES]: P extends keyof Array<T> ? () => Pick<Array<T>, P> : never }} SetWithDeprecatedArrayMethods
+ */
+
+/**
+ * Processes the provided set.
+ * @template T
+ * @param {Set<T>} set new set
+ * @param {string} name property name
+ * @returns {void}
+ */
+module.exports.arrayToSetDeprecation = (set, name) => {
+	for (const method of COPY_METHODS) {
+		if (/** @type {SetWithDeprecatedArrayMethods<T>} */ (set)[method]) continue;
+		const d = createDeprecation(
+			`${name} was changed from Array to Set (using Array method '${method}' is deprecated)`,
+			"ARRAY_TO_SET"
+		);
+		/** @type {EXPECTED_ANY} */
+		(set)[method] =
+			// eslint-disable-next-line func-names
+			function () {
+				d();
+				// eslint-disable-next-line unicorn/prefer-spread
+				const array = Array.from(this);
+				return Array.prototype[
+					/** @type {keyof COPY_METHODS} */ (method)
+				].apply(
+					array,
+					// eslint-disable-next-line prefer-rest-params
+					arguments
+				);
+			};
+	}
+	const dPush = createDeprecation(
+		`${name} was changed from Array to Set (using Array method 'push' is deprecated)`,
+		"ARRAY_TO_SET_PUSH"
+	);
+	const dLength = createDeprecation(
+		`${name} was changed from Array to Set (using Array property 'length' is deprecated)`,
+		"ARRAY_TO_SET_LENGTH"
+	);
+	const dIndexer = createDeprecation(
+		`${name} was changed from Array to Set (indexing Array is deprecated)`,
+		"ARRAY_TO_SET_INDEXER"
+	);
+	/** @type {SetWithDeprecatedArrayMethods<T>} */
+	(set).push = function push() {
+		dPush();
+		// eslint-disable-next-line prefer-rest-params, unicorn/prefer-spread
+		for (const item of Array.from(arguments)) {
+			this.add(item);
+		}
+		return this.size;
+	};
+	for (const method of DISABLED_METHODS) {
+		if (/** @type {SetWithDeprecatedArrayMethods<T>} */ (set)[method]) continue;
+
+		/** @type {SetWithDeprecatedArrayMethods<T>} */
+		(set)[method] = () => {
+			throw new Error(
+				`${name} was changed from Array to Set (using Array method '${method}' is not possible)`
+			);
+		};
+	}
+	/**
+	 * Creates an index getter.
+	 * @param {number} index index
+	 * @returns {() => T | undefined} value
+	 */
+	const createIndexGetter = (index) => {
+		/**
+		 * Returns the value at this location.
+		 * @this {Set<T>} a Set
+		 * @returns {T | undefined} the value at this location
+		 */
+		// eslint-disable-next-line func-style
+		const fn = function () {
+			dIndexer();
+			let i = 0;
+			for (const item of this) {
+				if (i++ === index) return item;
+			}
+		};
+		return fn;
+	};
+	/**
+	 * Define index getter.
+	 * @param {number} index index
+	 */
+	const defineIndexGetter = (index) => {
+		Object.defineProperty(set, index, {
+			get: createIndexGetter(index),
+			set(value) {
+				throw new Error(
+					`${name} was changed from Array to Set (indexing Array with write is not possible)`
+				);
+			}
+		});
+	};
+	defineIndexGetter(0);
+	let indexerDefined = 1;
+	Object.defineProperty(set, "length", {
+		get() {
+			dLength();
+			const length = this.size;
+			for (indexerDefined; indexerDefined < length + 1; indexerDefined++) {
+				defineIndexGetter(indexerDefined);
+			}
+			return length;
+		},
+		set(value) {
+			throw new Error(
+				`${name} was changed from Array to Set (writing to Array property 'length' is not possible)`
+			);
+		}
+	});
+	/** @type {SetWithDeprecatedArrayMethods<T>} */
+	(set)[Symbol.isConcatSpreadable] = true;
+};
+
+/**
+ * Returns } SetDeprecatedArray.
+ * @template T
+ * @param {string} name name
+ * @returns {{ new <T = EXPECTED_ANY>(values?: ReadonlyArray<T> | null): SetDeprecatedArray<T> }} SetDeprecatedArray
+ */
+module.exports.createArrayToSetDeprecationSet = (name) => {
+	let initialized = false;
+
+	/**
+	 * Represents SetDeprecatedArray.
+	 * @template T
+	 */
+	class SetDeprecatedArray extends Set {
+		/**
+		 * Creates an instance of SetDeprecatedArray.
+		 * @param {ReadonlyArray<T> | null=} items items
+		 */
+		constructor(items) {
+			super(items);
+			if (!initialized) {
+				initialized = true;
+				module.exports.arrayToSetDeprecation(
+					/** @type {SetWithDeprecatedArrayMethods<T>} */
+					(SetDeprecatedArray.prototype),
+					name
+				);
+			}
+		}
+	}
+	return SetDeprecatedArray;
+};
+
+/**
+ * Returns fake hook which redirects.
+ * @template {object} T
+ * @param {T} fakeHook fake hook implementation
+ * @param {string=} message deprecation message (not deprecated when unset)
+ * @param {string=} code deprecation code (not deprecated when unset)
+ * @returns {FakeHook<T>} fake hook which redirects
+ */
+module.exports.createFakeHook = (fakeHook, message, code) => {
+	if (message && code) {
+		fakeHook = deprecateAllProperties(fakeHook, message, code);
+	}
+	return Object.freeze(
+		Object.assign(fakeHook, { _fakeHook: /** @type {true} */ (true) })
+	);
+};
+
+/**
+ * Deprecate all properties.
+ * @template T
+ * @param {T} obj object
+ * @param {string} message deprecation message
+ * @param {string} code deprecation code
+ * @returns {T} object with property access deprecated
+ */
+const deprecateAllProperties = (obj, message, code) => {
+	const newObj = {};
+	const descriptors = Object.getOwnPropertyDescriptors(obj);
+	for (const name of Object.keys(descriptors)) {
+		const descriptor = descriptors[name];
+		if (typeof descriptor.value === "function") {
+			Object.defineProperty(newObj, name, {
+				...descriptor,
+				value: util.deprecate(descriptor.value, message, code)
+			});
+		} else if (descriptor.get || descriptor.set) {
+			Object.defineProperty(newObj, name, {
+				...descriptor,
+				get: descriptor.get && util.deprecate(descriptor.get, message, code),
+				set: descriptor.set && util.deprecate(descriptor.set, message, code)
+			});
+		} else {
+			let value = descriptor.value;
+			Object.defineProperty(newObj, name, {
+				configurable: descriptor.configurable,
+				enumerable: descriptor.enumerable,
+				get: util.deprecate(() => value, message, code),
+				set: descriptor.writable
+					? util.deprecate(
+							/**
+							 * Handles the callback logic for this hook.
+							 * @template T
+							 * @param {T} v value
+							 * @returns {T} result
+							 */
+							(v) => (value = v),
+							message,
+							code
+						)
+					: undefined
+			});
+		}
+	}
+	return /** @type {T} */ (newObj);
+};
+
+module.exports.deprecateAllProperties = deprecateAllProperties;
+
+/**
+ * Returns frozen object with deprecation when modifying.
+ * @template {object} T
+ * @param {T} obj object
+ * @param {string} name property name
+ * @param {string} code deprecation code
+ * @param {string} note additional note
+ * @returns {T} frozen object with deprecation when modifying
+ */
+module.exports.soonFrozenObjectDeprecation = (obj, name, code, note = "") => {
+	const message = `${name} will be frozen in future, all modifications are deprecated.${
+		note && `\n${note}`
+	}`;
+	return /** @type {T} */ (
+		new Proxy(obj, {
+			set: util.deprecate(
+				/**
+				 * Handles the callback logic for this hook.
+				 * @param {object} target target
+				 * @param {string | symbol} property property
+				 * @param {EXPECTED_ANY} value value
+				 * @param {EXPECTED_ANY} receiver receiver
+				 * @returns {boolean} result
+				 */
+				(target, property, value, receiver) =>
+					Reflect.set(target, property, value, receiver),
+				message,
+				code
+			),
+			defineProperty: util.deprecate(
+				/**
+				 * Handles the define property callback for this hook.
+				 * @param {object} target target
+				 * @param {string | symbol} property property
+				 * @param {PropertyDescriptor} descriptor descriptor
+				 * @returns {boolean} result
+				 */
+				(target, property, descriptor) =>
+					Reflect.defineProperty(target, property, descriptor),
+				message,
+				code
+			),
+			deleteProperty: util.deprecate(
+				/**
+				 * Handles the delete property callback for this hook.
+				 * @param {object} target target
+				 * @param {string | symbol} property property
+				 * @returns {boolean} result
+				 */
+				(target, property) => Reflect.deleteProperty(target, property),
+				message,
+				code
+			),
+			setPrototypeOf: util.deprecate(
+				/**
+				 * Updates prototype of using the provided target.
+				 * @param {object} target target
+				 * @param {EXPECTED_OBJECT | null} proto proto
+				 * @returns {boolean} result
+				 */
+				(target, proto) => Reflect.setPrototypeOf(target, proto),
+				message,
+				code
+			)
+		})
+	);
+};
Index: frontend/node_modules/webpack/lib/util/deterministicGrouping.js
===================================================================
--- frontend/node_modules/webpack/lib/util/deterministicGrouping.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/deterministicGrouping.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,581 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+// Simulations show these probabilities for a single change
+// 93.1% that one group is invalidated
+// 4.8% that two groups are invalidated
+// 1.1% that 3 groups are invalidated
+// 0.1% that 4 or more groups are invalidated
+//
+// And these for removing/adding 10 lexically adjacent files
+// 64.5% that one group is invalidated
+// 24.8% that two groups are invalidated
+// 7.8% that 3 groups are invalidated
+// 2.7% that 4 or more groups are invalidated
+//
+// And these for removing/adding 3 random files
+// 0% that one group is invalidated
+// 3.7% that two groups are invalidated
+// 80.8% that 3 groups are invalidated
+// 12.3% that 4 groups are invalidated
+// 3.2% that 5 or more groups are invalidated
+
+/**
+ * Returns the similarity as number.
+ * @param {string} a key
+ * @param {string} b key
+ * @returns {number} the similarity as number
+ */
+const similarity = (a, b) => {
+	const l = Math.min(a.length, b.length);
+	let dist = 0;
+	for (let i = 0; i < l; i++) {
+		const ca = a.charCodeAt(i);
+		const cb = b.charCodeAt(i);
+		dist += Math.max(0, 10 - Math.abs(ca - cb));
+	}
+	return dist;
+};
+
+/**
+ * Returns the common part and a single char for the difference.
+ * @param {string} a key
+ * @param {string} b key
+ * @param {Set<string>} usedNames set of already used names
+ * @returns {string} the common part and a single char for the difference
+ */
+const getName = (a, b, usedNames) => {
+	const l = Math.min(a.length, b.length);
+	let i = 0;
+	while (i < l) {
+		if (a.charCodeAt(i) !== b.charCodeAt(i)) {
+			i++;
+			break;
+		}
+		i++;
+	}
+	while (i < l) {
+		const name = a.slice(0, i);
+		const lowerName = name.toLowerCase();
+		if (!usedNames.has(lowerName)) {
+			usedNames.add(lowerName);
+			return name;
+		}
+		i++;
+	}
+	// names always contain a hash, so this is always unique
+	// we don't need to check usedNames nor add it
+	return a;
+};
+
+/** @typedef {Record<string, number>} Sizes */
+
+/**
+ * Adds the provided total to this object.
+ * @param {Sizes} total total size
+ * @param {Sizes} size single size
+ * @returns {void}
+ */
+const addSizeTo = (total, size) => {
+	for (const key of Object.keys(size)) {
+		total[key] = (total[key] || 0) + size[key];
+	}
+};
+
+/**
+ * Subtract size from.
+ * @param {Sizes} total total size
+ * @param {Sizes} size single size
+ * @returns {void}
+ */
+const subtractSizeFrom = (total, size) => {
+	for (const key of Object.keys(size)) {
+		total[key] -= size[key];
+	}
+};
+
+/**
+ * Returns total size.
+ * @template T
+ * @param {Iterable<Node<T>>} nodes some nodes
+ * @returns {Sizes} total size
+ */
+const sumSize = (nodes) => {
+	/** @type {Sizes} */
+	const sum = Object.create(null);
+	for (const node of nodes) {
+		addSizeTo(sum, node.size);
+	}
+	return sum;
+};
+
+/**
+ * Checks whether this object is too big.
+ * @param {Sizes} size size
+ * @param {Sizes} maxSize minimum size
+ * @returns {boolean} true, when size is too big
+ */
+const isTooBig = (size, maxSize) => {
+	for (const key of Object.keys(size)) {
+		const s = size[key];
+		if (s === 0) continue;
+		const maxSizeValue = maxSize[key];
+		if (typeof maxSizeValue === "number" && s > maxSizeValue) return true;
+	}
+	return false;
+};
+
+/**
+ * Checks whether this object is too small.
+ * @param {Sizes} size size
+ * @param {Sizes} minSize minimum size
+ * @returns {boolean} true, when size is too small
+ */
+const isTooSmall = (size, minSize) => {
+	for (const key of Object.keys(size)) {
+		const s = size[key];
+		if (s === 0) continue;
+		const minSizeValue = minSize[key];
+		if (typeof minSizeValue === "number" && s < minSizeValue) return true;
+	}
+	return false;
+};
+
+/** @typedef {Set<string>} Types */
+
+/**
+ * Gets too small types.
+ * @param {Sizes} size size
+ * @param {Sizes} minSize minimum size
+ * @returns {Types} set of types that are too small
+ */
+const getTooSmallTypes = (size, minSize) => {
+	/** @type {Types} */
+	const types = new Set();
+	for (const key of Object.keys(size)) {
+		const s = size[key];
+		if (s === 0) continue;
+		const minSizeValue = minSize[key];
+		if (typeof minSizeValue === "number" && s < minSizeValue) types.add(key);
+	}
+	return types;
+};
+
+/**
+ * Gets number of matching size types.
+ * @template {object} T
+ * @param {T} size size
+ * @param {Types} types types
+ * @returns {number} number of matching size types
+ */
+const getNumberOfMatchingSizeTypes = (size, types) => {
+	let i = 0;
+	for (const key of Object.keys(size)) {
+		if (size[/** @type {keyof T} */ (key)] !== 0 && types.has(key)) i++;
+	}
+	return i;
+};
+
+/**
+ * Selective size sum.
+ * @param {Sizes} size size
+ * @param {Types} types types
+ * @returns {number} selective size sum
+ */
+const selectiveSizeSum = (size, types) => {
+	let sum = 0;
+	for (const key of Object.keys(size)) {
+		if (size[key] !== 0 && types.has(key)) sum += size[key];
+	}
+	return sum;
+};
+
+/**
+ * Represents the node runtime component.
+ * @template T
+ */
+class Node {
+	/**
+	 * Creates an instance of Node.
+	 * @param {T} item item
+	 * @param {string} key key
+	 * @param {Sizes} size size
+	 */
+	constructor(item, key, size) {
+		this.item = item;
+		this.key = key;
+		this.size = size;
+	}
+}
+
+/** @typedef {number[]} Similarities */
+
+/**
+ * Represents the group runtime component.
+ * @template T
+ */
+class Group {
+	/**
+	 * Creates an instance of Group.
+	 * @param {Node<T>[]} nodes nodes
+	 * @param {Similarities | null} similarities similarities between the nodes (length = nodes.length - 1)
+	 * @param {Sizes=} size size of the group
+	 */
+	constructor(nodes, similarities, size) {
+		this.nodes = nodes;
+		this.similarities = similarities;
+		this.size = size || sumSize(nodes);
+		/** @type {string | undefined} */
+		this.key = undefined;
+	}
+
+	/**
+	 * Returns removed nodes.
+	 * @param {(node: Node<T>) => boolean} filter filter function
+	 * @returns {Node<T>[] | undefined} removed nodes
+	 */
+	popNodes(filter) {
+		/** @type {Node<T>[]} */
+		const newNodes = [];
+		/** @type {Similarities} */
+		const newSimilarities = [];
+		/** @type {Node<T>[]} */
+		const resultNodes = [];
+		/** @type {undefined | Node<T>} */
+		let lastNode;
+		for (let i = 0; i < this.nodes.length; i++) {
+			const node = this.nodes[i];
+			if (filter(node)) {
+				resultNodes.push(node);
+			} else {
+				if (newNodes.length > 0) {
+					newSimilarities.push(
+						lastNode === this.nodes[i - 1]
+							? /** @type {Similarities} */ (this.similarities)[i - 1]
+							: similarity(/** @type {Node<T>} */ (lastNode).key, node.key)
+					);
+				}
+				newNodes.push(node);
+				lastNode = node;
+			}
+		}
+		if (resultNodes.length === this.nodes.length) return;
+		this.nodes = newNodes;
+		this.similarities = newSimilarities;
+		this.size = sumSize(newNodes);
+		return resultNodes;
+	}
+}
+
+/**
+ * Returns similarities.
+ * @template T
+ * @param {Iterable<Node<T>>} nodes nodes
+ * @returns {Similarities} similarities
+ */
+const getSimilarities = (nodes) => {
+	// calculate similarities between lexically adjacent nodes
+	/** @type {Similarities} */
+	const similarities = [];
+	/** @type {undefined | Node<T>} */
+	let last;
+	for (const node of nodes) {
+		if (last !== undefined) {
+			similarities.push(similarity(last.key, node.key));
+		}
+		last = node;
+	}
+	return similarities;
+};
+
+/**
+ * Defines the shared type used by this module.
+ * @template T
+ * @typedef {object} GroupedItems<T>
+ * @property {string} key
+ * @property {T[]} items
+ * @property {Sizes} size
+ */
+
+/**
+ * Defines the options type used by this module.
+ * @template T
+ * @typedef {object} Options
+ * @property {Sizes} maxSize maximum size of a group
+ * @property {Sizes} minSize minimum size of a group (preferred over maximum size)
+ * @property {Iterable<T>} items a list of items
+ * @property {(item: T) => Sizes} getSize function to get size of an item
+ * @property {(item: T) => string} getKey function to get the key of an item
+ */
+
+/**
+ * Returns grouped items.
+ * @template T
+ * @param {Options<T>} options options object
+ * @returns {GroupedItems<T>[]} grouped items
+ */
+module.exports = ({ maxSize, minSize, items, getSize, getKey }) => {
+	/** @type {Group<T>[]} */
+	const result = [];
+
+	const nodes = Array.from(
+		items,
+		(item) => new Node(item, getKey(item), getSize(item))
+	);
+
+	/** @type {Node<T>[]} */
+	const initialNodes = [];
+
+	// lexically ordering of keys
+	nodes.sort((a, b) => {
+		if (a.key < b.key) return -1;
+		if (a.key > b.key) return 1;
+		return 0;
+	});
+
+	// return nodes bigger than maxSize directly as group
+	// But make sure that minSize is not violated
+	for (const node of nodes) {
+		if (isTooBig(node.size, maxSize) && !isTooSmall(node.size, minSize)) {
+			result.push(new Group([node], []));
+		} else {
+			initialNodes.push(node);
+		}
+	}
+
+	if (initialNodes.length > 0) {
+		const initialGroup = new Group(initialNodes, getSimilarities(initialNodes));
+
+		/**
+		 * Removes problematic nodes.
+		 * @param {Group<T>} group group
+		 * @param {Sizes} consideredSize size of the group to consider
+		 * @returns {boolean} true, if the group was modified
+		 */
+		const removeProblematicNodes = (group, consideredSize = group.size) => {
+			const problemTypes = getTooSmallTypes(consideredSize, minSize);
+			if (problemTypes.size > 0) {
+				// We hit an edge case where the working set is already smaller than minSize
+				// We merge problematic nodes with the smallest result node to keep minSize intact
+				const problemNodes = group.popNodes(
+					(n) => getNumberOfMatchingSizeTypes(n.size, problemTypes) > 0
+				);
+				if (problemNodes === undefined) return false;
+				// Only merge it with result nodes that have the problematic size type
+				const possibleResultGroups = result.filter(
+					(n) => getNumberOfMatchingSizeTypes(n.size, problemTypes) > 0
+				);
+				if (possibleResultGroups.length > 0) {
+					const bestGroup = possibleResultGroups.reduce((min, group) => {
+						const minMatches = getNumberOfMatchingSizeTypes(min, problemTypes);
+						const groupMatches = getNumberOfMatchingSizeTypes(
+							group,
+							problemTypes
+						);
+						if (minMatches !== groupMatches) {
+							return minMatches < groupMatches ? group : min;
+						}
+						if (
+							selectiveSizeSum(min.size, problemTypes) >
+							selectiveSizeSum(group.size, problemTypes)
+						) {
+							return group;
+						}
+						return min;
+					});
+					for (const node of problemNodes) bestGroup.nodes.push(node);
+					bestGroup.nodes.sort((a, b) => {
+						if (a.key < b.key) return -1;
+						if (a.key > b.key) return 1;
+						return 0;
+					});
+				} else {
+					// There are no other nodes with the same size types
+					// We create a new group and have to accept that it's smaller than minSize
+					result.push(new Group(problemNodes, null));
+				}
+				return true;
+			}
+			return false;
+		};
+
+		if (initialGroup.nodes.length > 0) {
+			const queue = [initialGroup];
+
+			while (queue.length) {
+				const group = /** @type {Group<T>} */ (queue.pop());
+				// only groups bigger than maxSize need to be splitted
+				if (!isTooBig(group.size, maxSize)) {
+					result.push(group);
+					continue;
+				}
+				// If the group is already too small
+				// we try to work only with the unproblematic nodes
+				if (removeProblematicNodes(group)) {
+					// This changed something, so we try this group again
+					queue.push(group);
+					continue;
+				}
+
+				// find unsplittable area from left and right
+				// going minSize from left and right
+				// at least one node need to be included otherwise we get stuck
+				let left = 1;
+				/** @type {Sizes} */
+				const leftSize = Object.create(null);
+				addSizeTo(leftSize, group.nodes[0].size);
+				while (left < group.nodes.length && isTooSmall(leftSize, minSize)) {
+					addSizeTo(leftSize, group.nodes[left].size);
+					left++;
+				}
+				let right = group.nodes.length - 2;
+				/** @type {Sizes} */
+				const rightSize = Object.create(null);
+				addSizeTo(rightSize, group.nodes[group.nodes.length - 1].size);
+				while (right >= 0 && isTooSmall(rightSize, minSize)) {
+					addSizeTo(rightSize, group.nodes[right].size);
+					right--;
+				}
+
+				//      left v   v right
+				// [ O O O ] O O O [ O O O ]
+				// ^^^^^^^^^ leftSize
+				//       rightSize ^^^^^^^^^
+				// leftSize > minSize
+				// rightSize > minSize
+
+				// Perfect split: [ O O O ] [ O O O ]
+				//                right === left - 1
+
+				if (left - 1 > right) {
+					// We try to remove some problematic nodes to "fix" that
+					/** @type {Sizes} */
+					let prevSize;
+					if (right < group.nodes.length - left) {
+						subtractSizeFrom(rightSize, group.nodes[right + 1].size);
+						prevSize = rightSize;
+					} else {
+						subtractSizeFrom(leftSize, group.nodes[left - 1].size);
+						prevSize = leftSize;
+					}
+					if (removeProblematicNodes(group, prevSize)) {
+						// This changed something, so we try this group again
+						queue.push(group);
+						continue;
+					}
+					// can't split group while holding minSize
+					// because minSize is preferred of maxSize we return
+					// the problematic nodes as result here even while it's too big
+					// To avoid this make sure maxSize > minSize * 3
+					result.push(group);
+					continue;
+				}
+				if (left <= right) {
+					// when there is a area between left and right
+					// we look for best split point
+					// we split at the minimum similarity
+					// here key space is separated the most
+					// But we also need to make sure to not create too small groups
+					let best = -1;
+					let bestSimilarity = Infinity;
+					let pos = left;
+					const rightSize = sumSize(group.nodes.slice(pos));
+
+					//       pos v   v right
+					// [ O O O ] O O O [ O O O ]
+					// ^^^^^^^^^ leftSize
+					// rightSize ^^^^^^^^^^^^^^^
+
+					while (pos <= right + 1) {
+						const similarity =
+							/** @type {Similarities} */
+							(group.similarities)[pos - 1];
+						if (
+							similarity < bestSimilarity &&
+							!isTooSmall(leftSize, minSize) &&
+							!isTooSmall(rightSize, minSize)
+						) {
+							best = pos;
+							bestSimilarity = similarity;
+						}
+						addSizeTo(leftSize, group.nodes[pos].size);
+						subtractSizeFrom(rightSize, group.nodes[pos].size);
+						pos++;
+					}
+					if (best < 0) {
+						// This can't happen
+						// but if that assumption is wrong
+						// fallback to a big group
+						result.push(group);
+						continue;
+					}
+					left = best;
+					right = best - 1;
+				}
+
+				// create two new groups for left and right area
+				// and queue them up
+				/** @type {Node<T>[]} */
+				const rightNodes = [group.nodes[right + 1]];
+				/** @type {Similarities} */
+				const rightSimilarities = [];
+				for (let i = right + 2; i < group.nodes.length; i++) {
+					rightSimilarities.push(
+						/** @type {Similarities} */ (group.similarities)[i - 1]
+					);
+					rightNodes.push(group.nodes[i]);
+				}
+				queue.push(new Group(rightNodes, rightSimilarities));
+
+				/** @type {Node<T>[]} */
+				const leftNodes = [group.nodes[0]];
+				/** @type {Similarities} */
+				const leftSimilarities = [];
+				for (let i = 1; i < left; i++) {
+					leftSimilarities.push(
+						/** @type {Similarities} */ (group.similarities)[i - 1]
+					);
+					leftNodes.push(group.nodes[i]);
+				}
+				queue.push(new Group(leftNodes, leftSimilarities));
+			}
+		}
+	}
+
+	// lexically ordering
+	result.sort((a, b) => {
+		if (a.nodes[0].key < b.nodes[0].key) return -1;
+		if (a.nodes[0].key > b.nodes[0].key) return 1;
+		return 0;
+	});
+
+	// give every group a name
+	/** @type {Set<string>} */
+	const usedNames = new Set();
+	for (let i = 0; i < result.length; i++) {
+		const group = result[i];
+		if (group.nodes.length === 1) {
+			group.key = group.nodes[0].key;
+		} else {
+			const first = group.nodes[0];
+			const last = group.nodes[group.nodes.length - 1];
+			const name = getName(first.key, last.key, usedNames);
+			group.key = name;
+		}
+	}
+
+	// return the results
+	return result.map(
+		(group) =>
+			/** @type {GroupedItems<T>} */
+			({
+				key: group.key,
+				items: group.nodes.map((node) => node.item),
+				size: group.size
+			})
+	);
+};
Index: frontend/node_modules/webpack/lib/util/extractSourceMap.js
===================================================================
--- frontend/node_modules/webpack/lib/util/extractSourceMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/extractSourceMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,319 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Natsu @xiaoxiaojx
+*/
+
+"use strict";
+
+const path = require("path");
+const urlUtils = require("url");
+const { isAbsolute, join } = require("./fs");
+
+/** @typedef {import("./fs").InputFileSystem} InputFileSystem */
+/** @typedef {string | Buffer<ArrayBufferLike>} StringOrBuffer */
+/** @typedef {(input: StringOrBuffer, resourcePath: string, fs: InputFileSystem) => Promise<{ source: StringOrBuffer, sourceMap: string | RawSourceMap | undefined, fileDependencies: string[] }>} SourceMapExtractorFunction */
+/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
+/** @typedef {(resourcePath: string) => Promise<StringOrBuffer>} ReadResource */
+
+/**
+ * Defines the source mapping url type used by this module.
+ * @typedef {object} SourceMappingURL
+ * @property {string} sourceMappingURL
+ * @property {string} replacementString
+ */
+
+// Matches only the last occurrence of sourceMappingURL
+const innerRegex = /\s*[#@]\s*sourceMappingURL\s*=\s*([^\s'"]*)\s*/;
+
+const validProtocolPattern = /^[a-z][a-z0-9+.-]*:/i;
+
+const sourceMappingURLRegex = new RegExp(
+	"(?:" +
+		"/\\*" +
+		"(?:\\s*\r?\n(?://)?)?" +
+		`(?:${innerRegex.source})` +
+		"\\s*" +
+		"\\*/" +
+		"|" +
+		`//(?:${innerRegex.source})` +
+		")" +
+		"\\s*"
+);
+
+/**
+ * Extract source mapping URL from code comments
+ * @param {string} code source code content
+ * @returns {SourceMappingURL} source mapping information
+ */
+function getSourceMappingURL(code) {
+	const lines = code.split(/^/m);
+	/** @type {RegExpMatchArray | null | undefined} */
+	let match;
+
+	for (let i = lines.length - 1; i >= 0; i--) {
+		match = lines[i].match(sourceMappingURLRegex);
+		if (match) {
+			break;
+		}
+	}
+
+	const sourceMappingURL = match ? match[1] || match[2] || "" : "";
+
+	return {
+		sourceMappingURL: sourceMappingURL
+			? decodeURI(sourceMappingURL)
+			: sourceMappingURL,
+		replacementString: match ? match[0] : ""
+	};
+}
+
+/**
+ * Get absolute path for source file
+ * @param {string} context context directory
+ * @param {string} request file request
+ * @param {string} sourceRoot source root directory
+ * @returns {string} absolute path
+ */
+function getAbsolutePath(context, request, sourceRoot) {
+	if (sourceRoot) {
+		if (isAbsolute(sourceRoot)) {
+			return join(undefined, sourceRoot, request);
+		}
+
+		return join(undefined, join(undefined, context, sourceRoot), request);
+	}
+
+	return join(undefined, context, request);
+}
+
+/**
+ * Check if value is a URL
+ * @param {string} value string to check
+ * @returns {boolean} true if value is a URL
+ */
+function isURL(value) {
+	return validProtocolPattern.test(value) && !path.win32.isAbsolute(value);
+}
+
+/**
+ * Fetch from multiple possible file paths
+ * @param {ReadResource} readResource read resource function
+ * @param {string[]} possibleRequests array of possible file paths
+ * @param {string} errorsAccumulator accumulated error messages
+ * @returns {Promise<{ path: string, data?: string }>} source content promise
+ */
+async function fetchPathsFromURL(
+	readResource,
+	possibleRequests,
+	errorsAccumulator = ""
+) {
+	/** @type {StringOrBuffer} */
+	let result;
+
+	try {
+		result = await readResource(possibleRequests[0]);
+	} catch (error) {
+		errorsAccumulator += `${/** @type {Error} */ (error).message}\n\n`;
+
+		const [, ...tailPossibleRequests] = possibleRequests;
+
+		if (tailPossibleRequests.length === 0) {
+			/** @type {Error} */ (error).message = errorsAccumulator;
+
+			throw error;
+		}
+
+		return fetchPathsFromURL(
+			readResource,
+			tailPossibleRequests,
+			errorsAccumulator
+		);
+	}
+
+	return {
+		path: possibleRequests[0],
+		data: result.toString("utf8")
+	};
+}
+
+/**
+ * Fetch source content from URL
+ * @param {ReadResource} readResource The read resource function
+ * @param {string} context context directory
+ * @param {string} url source URL
+ * @param {string=} sourceRoot source root directory
+ * @param {boolean=} skipReading whether to skip reading file content
+ * @returns {Promise<{ sourceURL: string, sourceContent?: StringOrBuffer }>} source content promise
+ */
+async function fetchFromURL(
+	readResource,
+	context,
+	url,
+	sourceRoot,
+	skipReading = false
+) {
+	// 1. It's an absolute url and it is not `windows` path like `C:\dir\file`
+	if (isURL(url)) {
+		// eslint-disable-next-line n/no-deprecated-api
+		const { protocol } = urlUtils.parse(url);
+		if (protocol === "data:") {
+			const sourceContent = skipReading ? "" : await readResource(url);
+
+			return { sourceURL: "", sourceContent };
+		}
+
+		if (protocol === "file:") {
+			const pathFromURL = urlUtils.fileURLToPath(url);
+			const sourceURL = path.normalize(pathFromURL);
+			const sourceContent = skipReading ? "" : await readResource(sourceURL);
+
+			return { sourceURL, sourceContent };
+		}
+
+		const sourceContent = skipReading ? "" : await readResource(url);
+		return { sourceURL: url, sourceContent };
+	}
+
+	// 3. Absolute path
+	if (isAbsolute(url)) {
+		let sourceURL = path.normalize(url);
+
+		/** @type {undefined | StringOrBuffer} */
+		let sourceContent;
+
+		if (!skipReading) {
+			/** @type {string[]} */
+			const possibleRequests = [sourceURL];
+
+			if (url.startsWith("/")) {
+				possibleRequests.push(
+					getAbsolutePath(context, sourceURL.slice(1), sourceRoot || "")
+				);
+			}
+
+			const result = await fetchPathsFromURL(readResource, possibleRequests);
+
+			sourceURL = result.path;
+			sourceContent = result.data;
+		}
+
+		return { sourceURL, sourceContent };
+	}
+
+	// 4. Relative path
+	const sourceURL = getAbsolutePath(context, url, sourceRoot || "");
+	/** @type {undefined | StringOrBuffer} */
+	let sourceContent;
+
+	if (!skipReading) {
+		sourceContent = await readResource(sourceURL);
+	}
+
+	return { sourceURL, sourceContent };
+}
+
+/**
+ * Extract source map from code content
+ * @param {StringOrBuffer} stringOrBuffer The input code content as string or buffer
+ * @param {string} resourcePath The path to the resource file
+ * @param {ReadResource} readResource The read resource function
+ * @returns {Promise<{ source: StringOrBuffer, sourceMap: string | RawSourceMap | undefined }>} Promise resolving to extracted source map information
+ */
+async function extractSourceMap(stringOrBuffer, resourcePath, readResource) {
+	const input =
+		typeof stringOrBuffer === "string"
+			? stringOrBuffer
+			: stringOrBuffer.toString("utf8");
+	const inputSourceMap = undefined;
+	const output = {
+		source: stringOrBuffer,
+		sourceMap: inputSourceMap
+	};
+	const { sourceMappingURL, replacementString } = getSourceMappingURL(input);
+
+	if (!sourceMappingURL) {
+		return output;
+	}
+
+	const baseContext = path.dirname(resourcePath);
+
+	const { sourceURL, sourceContent } = await fetchFromURL(
+		readResource,
+		baseContext,
+		sourceMappingURL
+	);
+
+	if (!sourceContent) {
+		return output;
+	}
+
+	/** @type {RawSourceMap} */
+	const map = JSON.parse(
+		sourceContent.toString("utf8").replace(/^\)\]\}'/, "")
+	);
+
+	const context = sourceURL ? path.dirname(sourceURL) : baseContext;
+
+	const resolvedSources = await Promise.all(
+		map.sources.map(
+			async (/** @type {string} */ source, /** @type {number} */ i) => {
+				const originalSourceContent =
+					map.sourcesContent &&
+					typeof map.sourcesContent[i] !== "undefined" &&
+					map.sourcesContent[i] !== null
+						? map.sourcesContent[i]
+						: undefined;
+				const skipReading = typeof originalSourceContent !== "undefined";
+				// We do not skipReading here, because we need absolute paths in sources.
+				// This is necessary so that for sourceMaps with the same file structure in sources, name collisions do not occur.
+				// https://github.com/webpack-contrib/source-map-loader/issues/51
+				let { sourceURL, sourceContent } = await fetchFromURL(
+					readResource,
+					context,
+					source,
+					map.sourceRoot,
+					skipReading
+				);
+
+				if (skipReading) {
+					sourceContent = originalSourceContent;
+				}
+
+				// Return original value of `source` when error happens
+				return { sourceURL, sourceContent };
+			}
+		)
+	);
+
+	/** @type {RawSourceMap} */
+	const newMap = { ...map };
+
+	newMap.sources = [];
+	newMap.sourcesContent = [];
+
+	delete newMap.sourceRoot;
+
+	for (const source of resolvedSources) {
+		const { sourceURL, sourceContent } = source;
+
+		newMap.sources.push(sourceURL || "");
+		newMap.sourcesContent.push(
+			sourceContent ? sourceContent.toString("utf8") : ""
+		);
+	}
+
+	const sourcesContentIsEmpty =
+		newMap.sourcesContent.filter(Boolean).length === 0;
+
+	if (sourcesContentIsEmpty) {
+		delete newMap.sourcesContent;
+	}
+
+	return {
+		source: input.replace(replacementString, ""),
+		sourceMap: /** @type {RawSourceMap} */ (newMap)
+	};
+}
+
+module.exports = extractSourceMap;
+module.exports.getSourceMappingURL = getSourceMappingURL;
Index: frontend/node_modules/webpack/lib/util/extractUrlAndGlobal.js
===================================================================
--- frontend/node_modules/webpack/lib/util/extractUrlAndGlobal.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/extractUrlAndGlobal.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sam Chen @chenxsan
+*/
+
+"use strict";
+
+/**
+ * Returns script url and its global variable.
+ * @param {string} urlAndGlobal the script request
+ * @returns {string[]} script url and its global variable
+ */
+module.exports = function extractUrlAndGlobal(urlAndGlobal) {
+	const index = urlAndGlobal.indexOf("@");
+	if (index <= 0 || index === urlAndGlobal.length - 1) {
+		throw new Error(`Invalid request "${urlAndGlobal}"`);
+	}
+	return [urlAndGlobal.slice(index + 1), urlAndGlobal.slice(0, index)];
+};
Index: frontend/node_modules/webpack/lib/util/findGraphRoots.js
===================================================================
--- frontend/node_modules/webpack/lib/util/findGraphRoots.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/findGraphRoots.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,216 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const NO_MARKER = 0;
+const IN_PROGRESS_MARKER = 1;
+const DONE_MARKER = 2;
+const CANDIDATE_MARKER = 3;
+
+/**
+ * Defines the nodes type used by this module.
+ * @template T
+ * @typedef {Set<Node<T>>} Nodes
+ */
+
+/**
+ * Represents the node runtime component.
+ * @template T
+ */
+class Node {
+	/**
+	 * Creates an instance of Node.
+	 * @param {T} item the value of the node
+	 */
+	constructor(item) {
+		this.item = item;
+		/** @type {Nodes<T>} */
+		this.dependencies = new Set();
+		/** @type {SCC<T>} */
+		this.scc = new SCC();
+		// Each node starts as a single-node SCC
+		this.scc.nodes.add(this);
+		/** @type {number} */
+		this.incoming = 0;
+	}
+}
+
+/**
+ * SCC (strongly connected component)
+ * @template T
+ */
+class SCC {
+	constructor() {
+		/** @type {Nodes<T>} */
+		this.nodes = new Set();
+		this.marker = NO_MARKER;
+	}
+}
+
+/**
+ * Defines the stack entry type used by this module.
+ * @template T
+ * @typedef {object} StackEntry
+ * @property {Node<T>} node
+ * @property {Node<T>[]} openEdges
+ */
+
+/**
+ * Returns graph roots of the items.
+ * @template T
+ * @param {Iterable<T>} items list of items
+ * @param {(item: T) => Iterable<T>} getDependencies function to get dependencies of an item (items that are not in list are ignored)
+ * @returns {Iterable<T>} graph roots of the items
+ */
+module.exports = (items, getDependencies) => {
+	/** @type {Map<T, Node<T>>} */
+	const itemToNode = new Map();
+	for (const item of items) {
+		const node = new Node(item);
+		itemToNode.set(item, node);
+	}
+
+	// Early exit when there is only one node
+	if (itemToNode.size <= 1) return items;
+
+	// Build graph edges
+	for (const node of itemToNode.values()) {
+		for (const dep of getDependencies(node.item)) {
+			const depNode = itemToNode.get(dep);
+			if (depNode !== undefined) {
+				node.dependencies.add(depNode);
+			}
+		}
+	}
+
+	// All candidate root SCCs, they will be removed once an incoming edge is found
+	/** @type {Set<SCC<T>>} */
+	const rootSCCs = new Set();
+
+	for (const selectedNode of itemToNode.values()) {
+		// DFS walk only once per unseen SCC
+		if (selectedNode.scc.marker === NO_MARKER) {
+			selectedNode.scc.marker = IN_PROGRESS_MARKER;
+
+			// Keep a stack to avoid recursive walk
+			/** @type {StackEntry<T>[]} */
+			const stack = [
+				{
+					node: selectedNode,
+					openEdges: [...selectedNode.dependencies]
+				}
+			];
+
+			while (stack.length > 0) {
+				const topOfStack = stack[stack.length - 1];
+
+				// Process one unvisited outgoing edge if available
+				if (topOfStack.openEdges.length > 0) {
+					const dependency =
+						/** @type {Node<T>} */
+						(topOfStack.openEdges.pop());
+					const depSCC = dependency.scc;
+					switch (depSCC.marker) {
+						case NO_MARKER:
+							// First time we see this SCC: enter it
+							stack.push({
+								node: dependency,
+								openEdges: [...dependency.dependencies]
+							});
+							depSCC.marker = IN_PROGRESS_MARKER;
+							break;
+						case IN_PROGRESS_MARKER: {
+							// Back-edge to an SCC that is still on the stack
+							// Example:
+							//   A -> B -> C -> D
+							//        ^         |
+							//        |_________|
+							// If we are at `D` and traverse `D` -> `B`, then `B/C/D` must be in one SCC
+							/** @type {Set<SCC<T>>} */
+							const sccsToMerge = new Set();
+							for (
+								let i = stack.length - 1;
+								stack[i].node.scc !== depSCC;
+								i--
+							) {
+								sccsToMerge.add(stack[i].node.scc);
+							}
+							for (const sccToMerge of sccsToMerge) {
+								for (const nodeInMergedSCC of sccToMerge.nodes) {
+									nodeInMergedSCC.scc = depSCC;
+									depSCC.nodes.add(nodeInMergedSCC);
+								}
+							}
+							break;
+						}
+						case CANDIDATE_MARKER:
+							// This finished SCC was previously considered as root SCC
+							// We just found a new incoming edge, so it is no longer a candidate
+							rootSCCs.delete(/** @type {SCC<T>} */ (depSCC));
+							depSCC.marker = DONE_MARKER;
+							break;
+						case DONE_MARKER:
+							// Already finalized and not a candidate
+							break;
+					}
+				} else {
+					// All dependencies of the current node have been processed
+					// So we leave the node
+					stack.pop();
+					// Mark an SCC as DONE only when the popped node is the last
+					// node from that SCC remaining on the current stack.
+					//   A -> B -> C -> D
+					//        ^         |
+					//        |_________|
+					// If `B` is popped and the new stack top is `A`, they are in
+					// different SCCs, so B's SCC can be finalized.
+					if (
+						stack.length &&
+						topOfStack.node.scc !== stack[stack.length - 1].node.scc
+					) {
+						topOfStack.node.scc.marker = DONE_MARKER;
+					}
+				}
+			}
+			const scc = selectedNode.scc;
+			// This SCC is complete and currently has no known incoming edge
+			scc.marker = CANDIDATE_MARKER;
+			rootSCCs.add(scc);
+		}
+	}
+
+	/** @type {Set<T>} */
+	const rootNodes = new Set();
+
+	// For each root SCC, we select node with the most incoming edges
+	// from within the same SCC
+	for (const scc of rootSCCs) {
+		let max = 0;
+		/** @type {Nodes<T>} */
+		const nodes = new Set(scc.nodes);
+		for (const node of scc.nodes) {
+			for (const dep of node.dependencies) {
+				if (scc.nodes.has(dep)) {
+					dep.incoming++;
+					if (dep.incoming < max) continue;
+					if (dep.incoming > max) {
+						nodes.clear();
+						max = dep.incoming;
+					}
+					nodes.add(dep);
+				}
+			}
+		}
+		for (const node of nodes) {
+			rootNodes.add(node.item);
+		}
+	}
+
+	// When root nodes were found, return them
+	if (rootNodes.size > 0) return rootNodes;
+
+	throw new Error("Implementation of findGraphRoots is broken");
+};
Index: frontend/node_modules/webpack/lib/util/formatLocation.js
===================================================================
--- frontend/node_modules/webpack/lib/util/formatLocation.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/formatLocation.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,69 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Dependency").SourcePosition} SourcePosition */
+
+/**
+ * Returns formatted position.
+ * @param {SourcePosition} pos position
+ * @returns {string} formatted position
+ */
+const formatPosition = (pos) => {
+	if (pos && typeof pos === "object") {
+		if ("line" in pos && "column" in pos) {
+			return `${pos.line}:${pos.column}`;
+		} else if ("line" in pos) {
+			return `${pos.line}:?`;
+		}
+	}
+	return "";
+};
+
+/**
+ * Returns formatted location.
+ * @param {DependencyLocation} loc location
+ * @returns {string} formatted location
+ */
+const formatLocation = (loc) => {
+	if (loc && typeof loc === "object") {
+		if ("start" in loc && loc.start && "end" in loc && loc.end) {
+			if (
+				typeof loc.start === "object" &&
+				typeof loc.start.line === "number" &&
+				typeof loc.end === "object" &&
+				typeof loc.end.line === "number" &&
+				typeof loc.end.column === "number" &&
+				loc.start.line === loc.end.line
+			) {
+				return `${formatPosition(loc.start)}-${loc.end.column}`;
+			} else if (
+				typeof loc.start === "object" &&
+				typeof loc.start.line === "number" &&
+				typeof loc.start.column !== "number" &&
+				typeof loc.end === "object" &&
+				typeof loc.end.line === "number" &&
+				typeof loc.end.column !== "number"
+			) {
+				return `${loc.start.line}-${loc.end.line}`;
+			}
+			return `${formatPosition(loc.start)}-${formatPosition(loc.end)}`;
+		}
+		if ("start" in loc && loc.start) {
+			return formatPosition(loc.start);
+		}
+		if ("name" in loc && "index" in loc) {
+			return `${loc.name}[${loc.index}]`;
+		}
+		if ("name" in loc) {
+			return loc.name;
+		}
+	}
+	return "";
+};
+
+module.exports = formatLocation;
Index: frontend/node_modules/webpack/lib/util/formatSize.js
===================================================================
--- frontend/node_modules/webpack/lib/util/formatSize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/formatSize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sean Larkin @thelarkinn
+*/
+
+"use strict";
+
+/**
+ * Returns the formatted size.
+ * @param {number=} size the size in bytes
+ * @returns {string} the formatted size
+ */
+const formatSize = (size) => {
+	if (typeof size !== "number" || Number.isNaN(size) === true) {
+		return "unknown size";
+	}
+
+	if (size <= 0) {
+		return "0 bytes";
+	}
+
+	const abbreviations = ["bytes", "KiB", "MiB", "GiB"];
+	const index = Math.floor(Math.log(size) / Math.log(1024));
+
+	return `${Number((size / 1024 ** index).toPrecision(3))} ${abbreviations[index]}`;
+};
+
+module.exports = formatSize;
Index: frontend/node_modules/webpack/lib/util/fs.js
===================================================================
--- frontend/node_modules/webpack/lib/util/fs.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/fs.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,738 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const path = require("path");
+
+/** @typedef {import("../../declarations/WebpackOptions").WatchOptions} WatchOptions */
+/** @typedef {import("watchpack").Entry} Entry */
+/** @typedef {import("watchpack").OnlySafeTimeEntry} OnlySafeTimeEntry */
+/** @typedef {import("watchpack").ExistenceOnlyTimeEntry} ExistenceOnlyTimeEntry */
+
+/**
+ * Defines the i stats base type used by this module.
+ * @template T
+ * @typedef {object} IStatsBase
+ * @property {() => boolean} isFile
+ * @property {() => boolean} isDirectory
+ * @property {() => boolean} isBlockDevice
+ * @property {() => boolean} isCharacterDevice
+ * @property {() => boolean} isSymbolicLink
+ * @property {() => boolean} isFIFO
+ * @property {() => boolean} isSocket
+ * @property {T} dev
+ * @property {T} ino
+ * @property {T} mode
+ * @property {T} nlink
+ * @property {T} uid
+ * @property {T} gid
+ * @property {T} rdev
+ * @property {T} size
+ * @property {T} blksize
+ * @property {T} blocks
+ * @property {T} atimeMs
+ * @property {T} mtimeMs
+ * @property {T} ctimeMs
+ * @property {T} birthtimeMs
+ * @property {Date} atime
+ * @property {Date} mtime
+ * @property {Date} ctime
+ * @property {Date} birthtime
+ */
+
+/**
+ * Defines the i stats type used by this module.
+ * @typedef {IStatsBase<number>} IStats
+ */
+
+/**
+ * Defines the i big int stats type used by this module.
+ * @typedef {IStatsBase<bigint> & { atimeNs: bigint, mtimeNs: bigint, ctimeNs: bigint, birthtimeNs: bigint }} IBigIntStats
+ */
+
+/**
+ * Defines the dirent type used by this module.
+ * @template {string | Buffer} [T=string]
+ * @typedef {object} Dirent
+ * @property {() => boolean} isFile true when is file, otherwise false
+ * @property {() => boolean} isDirectory true when is directory, otherwise false
+ * @property {() => boolean} isBlockDevice true when is block device, otherwise false
+ * @property {() => boolean} isCharacterDevice true when is character device, otherwise false
+ * @property {() => boolean} isSymbolicLink true when is symbolic link, otherwise false
+ * @property {() => boolean} isFIFO true when is FIFO, otherwise false
+ * @property {() => boolean} isSocket true when is socket, otherwise false
+ * @property {T} name name
+ * @property {string} parentPath path
+ * @property {string=} path path
+ */
+
+/** @typedef {string | number | boolean | null} JsonPrimitive */
+/** @typedef {JsonValue[]} JsonArray */
+/** @typedef {{ [Key in string]?: JsonValue }} JsonObject */
+/** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */
+
+/** @typedef {(err: NodeJS.ErrnoException | null) => void} NoParamCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: string) => void} StringCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: Buffer) => void} BufferCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: string | Buffer) => void} StringOrBufferCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: string[]) => void} ReaddirStringCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: Buffer[]) => void} ReaddirBufferCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: string[] | Buffer[]) => void} ReaddirStringOrBufferCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: Dirent[]) => void} ReaddirDirentCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: Dirent<Buffer>[]) => void} ReaddirDirentBufferCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: IStats) => void} StatsCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: IBigIntStats) => void} BigIntStatsCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: IStats | IBigIntStats) => void} StatsOrBigIntStatsCallback */
+/** @typedef {(err: NodeJS.ErrnoException | null, result?: number) => void} NumberCallback */
+/** @typedef {(err: NodeJS.ErrnoException | Error | null, result?: JsonObject) => void} ReadJsonCallback */
+
+/** @typedef {Map<string, Entry | OnlySafeTimeEntry | ExistenceOnlyTimeEntry | null | "ignore">} TimeInfoEntries */
+
+/** @typedef {Set<string>} Changes */
+/** @typedef {Set<string>} Removals */
+
+/**
+ * Defines the watcher info type used by this module.
+ * @typedef {object} WatcherInfo
+ * @property {Changes | null} changes get current aggregated changes that have not yet send to callback
+ * @property {Removals | null} removals get current aggregated removals that have not yet send to callback
+ * @property {TimeInfoEntries} fileTimeInfoEntries get info about files
+ * @property {TimeInfoEntries} contextTimeInfoEntries get info about directories
+ */
+
+// TODO webpack 6 deprecate missing getInfo
+/**
+ * Defines the watcher type used by this module.
+ * @typedef {object} Watcher
+ * @property {() => void} close closes the watcher and all underlying file watchers
+ * @property {() => void} pause closes the watcher, but keeps underlying file watchers alive until the next watch call
+ * @property {(() => Changes | null)=} getAggregatedChanges get current aggregated changes that have not yet send to callback
+ * @property {(() => Removals | null)=} getAggregatedRemovals get current aggregated removals that have not yet send to callback
+ * @property {() => TimeInfoEntries} getFileTimeInfoEntries get info about files
+ * @property {() => TimeInfoEntries} getContextTimeInfoEntries get info about directories
+ * @property {() => WatcherInfo=} getInfo get info about timestamps and changes
+ */
+
+/**
+ * Defines the watch method callback.
+ * @callback WatchMethod
+ * @param {Iterable<string>} files watched files
+ * @param {Iterable<string>} directories watched directories
+ * @param {Iterable<string>} missing watched existence entries
+ * @param {number} startTime timestamp of start time
+ * @param {WatchOptions} options options object
+ * @param {(err: Error | null, timeInfoEntries1?: TimeInfoEntries, timeInfoEntries2?: TimeInfoEntries, changes?: Changes, removals?: Removals) => void} callback aggregated callback
+ * @param {(value: string, num: number) => void} callbackUndelayed callback when the first change was detected
+ * @returns {Watcher} a watcher
+ */
+
+// TODO webpack 6 make optional methods required and avoid using non standard methods like `join`, `relative`, `dirname`, move IntermediateFileSystemExtras methods to InputFilesystem or OutputFilesystem
+
+/**
+ * Defines the path like type used by this module.
+ * @typedef {string | Buffer | URL} PathLike
+ */
+
+/**
+ * Defines the path or file descriptor type used by this module.
+ * @typedef {PathLike | number} PathOrFileDescriptor
+ */
+
+/**
+ * Defines the object encoding options type used by this module.
+ * @typedef {object} ObjectEncodingOptions
+ * @property {BufferEncoding | null | undefined=} encoding
+ */
+
+/**
+ * Describes the read file shape.
+ * @typedef {{
+ * (path: PathOrFileDescriptor, options: ({ encoding?: null | undefined, flag?: string | undefined } & import("events").Abortable) | undefined | null, callback: BufferCallback): void,
+ * (path: PathOrFileDescriptor, options: ({ encoding: BufferEncoding, flag?: string | undefined } & import("events").Abortable) | BufferEncoding, callback: StringCallback): void,
+ * (path: PathOrFileDescriptor, options: (ObjectEncodingOptions & { flag?: string | undefined } & import("events").Abortable) | BufferEncoding | undefined | null, callback: StringOrBufferCallback): void,
+ * (path: PathOrFileDescriptor, callback: BufferCallback): void,
+ * }} ReadFile
+ */
+
+/**
+ * Describes the read file sync shape.
+ * @typedef {{
+ * (path: PathOrFileDescriptor, options?: { encoding?: null | undefined, flag?: string | undefined } | null): Buffer,
+ * (path: PathOrFileDescriptor, options: { encoding: BufferEncoding, flag?: string | undefined } | BufferEncoding): string,
+ * (path: PathOrFileDescriptor, options?: (ObjectEncodingOptions & { flag?: string | undefined }) | BufferEncoding | null): string | Buffer,
+ * }} ReadFileSync
+ */
+
+/**
+ * Defines the encoding option type used by this module.
+ * @typedef {ObjectEncodingOptions | BufferEncoding | undefined | null} EncodingOption
+ */
+
+/**
+ * Defines the buffer encoding option type used by this module.
+ * @typedef {"buffer" | { encoding: "buffer" }} BufferEncodingOption
+ */
+
+/**
+ * Defines the stat options type used by this module.
+ * @typedef {object} StatOptions
+ * @property {(boolean | undefined)=} bigint
+ */
+
+/**
+ * Defines the stat sync options type used by this module.
+ * @typedef {object} StatSyncOptions
+ * @property {(boolean | undefined)=} bigint
+ * @property {(boolean | undefined)=} throwIfNoEntry
+ */
+
+/**
+ * Describes the readlink shape.
+ * @typedef {{
+ * (path: PathLike, options: EncodingOption, callback: StringCallback): void,
+ * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void,
+ * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void,
+ * (path: PathLike, callback: StringCallback): void,
+ * }} Readlink
+ */
+
+/**
+ * Describes the readlink sync shape.
+ * @typedef {{
+ * (path: PathLike, options?: EncodingOption): string,
+ * (path: PathLike, options: BufferEncodingOption): Buffer,
+ * (path: PathLike, options?: EncodingOption): string | Buffer,
+ * }} ReadlinkSync
+ */
+
+/**
+ * Describes the readdir shape.
+ * @typedef {{
+ * (path: PathLike, options: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void,
+ * (path: PathLike, options: { encoding: "buffer", withFileTypes?: false | undefined, recursive?: boolean | undefined } | "buffer", callback: (err: NodeJS.ErrnoException | null, files?: Buffer[]) => void): void,
+ * (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[] | Buffer[]) => void): void,
+ * (path: PathLike, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void,
+ * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files?: Dirent<string>[]) => void): void,
+ * (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files: Dirent<Buffer>[]) => void): void,
+ * }} Readdir
+ */
+
+/**
+ * Describes the readdir sync shape.
+ * @typedef {{
+ * (path: PathLike, options?: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | null): string[],
+ * (path: PathLike, options: { encoding: "buffer", withFileTypes?: false | undefined, recursive?: boolean | undefined } | "buffer"): Buffer[],
+ * (path: PathLike, options?: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | null): string[] | Buffer[],
+ * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }): Dirent[],
+ * (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }): Dirent<Buffer>[],
+ * }} ReaddirSync
+ */
+
+/**
+ * Describes the stat shape.
+ * @typedef {{
+ * (path: PathLike, callback: StatsCallback): void,
+ * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void,
+ * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void,
+ * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void,
+ * }} Stat
+ */
+
+/**
+ * Describes the stat sync shape.
+ * @typedef {{
+ * (path: PathLike): IStats,
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry?: true | undefined }): IStats,
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry?: true | undefined }): IBigIntStats,
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined,
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined,
+ * (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: true | undefined }): IStats | IBigIntStats,
+ * (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined,
+ * }} StatSync
+ */
+
+/**
+ * Describes the l stat shape.
+ * @typedef {{
+ * (path: PathLike, callback: StatsCallback): void,
+ * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void,
+ * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void,
+ * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void,
+ * }} LStat
+ */
+
+/**
+ * Describes the l stat sync shape.
+ * @typedef {{
+ * (path: PathLike): IStats,
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry?: true | undefined }): IStats,
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry?: true | undefined }): IBigIntStats,
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined,
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined,
+ * (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: true | undefined }): IStats | IBigIntStats,
+ * (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined,
+ * }} LStatSync
+ */
+
+/**
+ * Describes the real path shape.
+ * @typedef {{
+ * (path: PathLike, options: EncodingOption, callback: StringCallback): void,
+ * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void,
+ * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void,
+ * (path: PathLike, callback: StringCallback): void,
+ * }} RealPath
+ */
+
+/**
+ * Describes the real path sync shape.
+ * @typedef {{
+ * (path: PathLike, options?: EncodingOption): string,
+ * (path: PathLike, options: BufferEncodingOption): Buffer,
+ * (path: PathLike, options?: EncodingOption): string | Buffer,
+ * }} RealPathSync
+ */
+
+/**
+ * Defines the read json type used by this module.
+ * @typedef {(pathOrFileDescriptor: PathOrFileDescriptor, callback: ReadJsonCallback) => void} ReadJson
+ */
+
+/**
+ * Defines the read json sync type used by this module.
+ * @typedef {(pathOrFileDescriptor: PathOrFileDescriptor) => JsonObject} ReadJsonSync
+ */
+
+/**
+ * Defines the purge type used by this module.
+ * @typedef {(value?: string | string[] | Set<string>) => void} Purge
+ */
+
+/**
+ * Defines the input file system type used by this module.
+ * @typedef {object} InputFileSystem
+ * @property {ReadFile} readFile
+ * @property {ReadFileSync=} readFileSync
+ * @property {Readlink} readlink
+ * @property {ReadlinkSync=} readlinkSync
+ * @property {Readdir} readdir
+ * @property {ReaddirSync=} readdirSync
+ * @property {Stat} stat
+ * @property {StatSync=} statSync
+ * @property {LStat=} lstat
+ * @property {LStatSync=} lstatSync
+ * @property {RealPath=} realpath
+ * @property {RealPathSync=} realpathSync
+ * @property {ReadJson=} readJson
+ * @property {ReadJsonSync=} readJsonSync
+ * @property {Purge=} purge
+ * @property {((path1: string, path2: string) => string)=} join
+ * @property {((from: string, to: string) => string)=} relative
+ * @property {((dirname: string) => string)=} dirname
+ */
+
+/**
+ * Defines the mode type used by this module.
+ * @typedef {number | string} Mode
+ */
+
+/**
+ * Defines the write file options type used by this module.
+ * @typedef {(ObjectEncodingOptions & import("events").Abortable & { mode?: Mode | undefined, flag?: string | undefined, flush?: boolean | undefined }) | BufferEncoding | null} WriteFileOptions
+ */
+
+/**
+ * Describes the write file shape.
+ * @typedef {{
+ * (file: PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, options: WriteFileOptions, callback: NoParamCallback): void,
+ * (file: PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, callback: NoParamCallback): void,
+ * }} WriteFile
+ */
+
+/**
+ * Defines the make directory options type used by this module.
+ * @typedef {{ recursive?: boolean | undefined, mode?: Mode | undefined }} MakeDirectoryOptions
+ */
+
+/**
+ * Describes the mkdir shape.
+ * @typedef {{
+ * (file: PathLike, options: MakeDirectoryOptions & { recursive: true }, callback: StringCallback): void,
+ * (file: PathLike, options: Mode | (MakeDirectoryOptions & { recursive?: false | undefined }) | null | undefined, callback: NoParamCallback): void,
+ * (file: PathLike, options: Mode | MakeDirectoryOptions | null | undefined, callback: StringCallback): void,
+ * (file: PathLike, callback: NoParamCallback): void,
+ * }} Mkdir
+ */
+
+/**
+ * Defines the rmdir type used by this module.
+ * @typedef {{ (file: PathLike, callback: NoParamCallback): void }} Rmdir
+ */
+
+/**
+ * Defines the unlink type used by this module.
+ * @typedef {(pathLike: PathLike, callback: NoParamCallback) => void} Unlink
+ */
+
+/**
+ * Defines the create read stream fs implementation type used by this module.
+ * @typedef {FSImplementation & { read: (...args: EXPECTED_ANY[]) => EXPECTED_ANY }} CreateReadStreamFSImplementation
+ */
+
+/**
+ * Defines the read stream options type used by this module.
+ * @typedef {StreamOptions & { fs?: CreateReadStreamFSImplementation | null | undefined, end?: number | undefined }} ReadStreamOptions
+ */
+
+/**
+ * Defines the create read stream type used by this module.
+ * @typedef {(path: PathLike, options?: BufferEncoding | ReadStreamOptions) => NodeJS.ReadableStream} CreateReadStream
+ */
+
+/**
+ * Defines the output file system type used by this module.
+ * @typedef {object} OutputFileSystem
+ * @property {Mkdir} mkdir
+ * @property {Readdir=} readdir
+ * @property {Rmdir=} rmdir
+ * @property {WriteFile} writeFile
+ * @property {Unlink=} unlink
+ * @property {Stat} stat
+ * @property {LStat=} lstat
+ * @property {ReadFile} readFile
+ * @property {CreateReadStream=} createReadStream
+ * @property {((path1: string, path2: string) => string)=} join
+ * @property {((from: string, to: string) => string)=} relative
+ * @property {((dirname: string) => string)=} dirname
+ */
+
+/**
+ * Defines the watch file system type used by this module.
+ * @typedef {object} WatchFileSystem
+ * @property {WatchMethod} watch
+ */
+
+/**
+ * Describes the mkdir sync shape.
+ * @typedef {{
+ * (path: PathLike, options: MakeDirectoryOptions & { recursive: true }): string | undefined,
+ * (path: PathLike, options?: Mode | (MakeDirectoryOptions & { recursive?: false | undefined }) | null): void,
+ * (path: PathLike, options?: Mode | MakeDirectoryOptions | null): string | undefined,
+ * }} MkdirSync
+ */
+
+/**
+ * Defines the stream options type used by this module.
+ * @typedef {object} StreamOptions
+ * @property {(string | undefined)=} flags
+ * @property {(BufferEncoding | undefined)} encoding
+ * @property {(number | EXPECTED_ANY | undefined)=} fd
+ * @property {(number | undefined)=} mode
+ * @property {(boolean | undefined)=} autoClose
+ * @property {(boolean | undefined)=} emitClose
+ * @property {(number | undefined)=} start
+ * @property {(AbortSignal | null | undefined)=} signal
+ */
+
+/**
+ * Defines the fs implementation type used by this module.
+ * @typedef {object} FSImplementation
+ * @property {((...args: EXPECTED_ANY[]) => EXPECTED_ANY)=} open
+ * @property {((...args: EXPECTED_ANY[]) => EXPECTED_ANY)=} close
+ */
+
+/**
+ * Defines the create write stream fs implementation type used by this module.
+ * @typedef {FSImplementation & { write: (...args: EXPECTED_ANY[]) => EXPECTED_ANY, close?: (...args: EXPECTED_ANY[]) => EXPECTED_ANY }} CreateWriteStreamFSImplementation
+ */
+
+/**
+ * Defines the write stream options type used by this module.
+ * @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined, flush?: boolean | undefined }} WriteStreamOptions
+ */
+
+/**
+ * Defines the create write stream type used by this module.
+ * @typedef {(pathLike: PathLike, result?: BufferEncoding | WriteStreamOptions) => NodeJS.WritableStream} CreateWriteStream
+ */
+
+/**
+ * Defines the open mode type used by this module.
+ * @typedef {number | string} OpenMode
+ */
+
+/**
+ * Describes the open shape.
+ * @typedef {{
+ * (file: PathLike, flags: OpenMode | undefined, mode: Mode | undefined | null, callback: NumberCallback): void,
+ * (file: PathLike, flags: OpenMode | undefined, callback: NumberCallback): void,
+ * (file: PathLike, callback: NumberCallback): void,
+ * }} Open
+ */
+
+/**
+ * Defines the read position type used by this module.
+ * @typedef {number | bigint} ReadPosition
+ */
+
+/**
+ * Defines the read sync options type used by this module.
+ * @typedef {object} ReadSyncOptions
+ * @property {(number | undefined)=} offset
+ * @property {(number | undefined)=} length
+ * @property {(ReadPosition | null | undefined)=} position
+ */
+
+/**
+ * Defines the read async options type used by this module.
+ * @template {NodeJS.ArrayBufferView} TBuffer
+ * @typedef {object} ReadAsyncOptions
+ * @property {(number | undefined)=} offset
+ * @property {(number | undefined)=} length
+ * @property {(ReadPosition | null | undefined)=} position
+ * @property {TBuffer=} buffer
+ */
+
+/**
+ * Defines the shared type used by this module.
+ * @template {NodeJS.ArrayBufferView} [TBuffer=NodeJS.ArrayBufferView]
+ * @typedef {{
+ * (fd: number, buffer: TBuffer, offset: number, length: number, position: ReadPosition | null, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: TBuffer) => void): void,
+ * (fd: number, options: ReadAsyncOptions<TBuffer>, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: TBuffer) => void): void,
+ * (fd: number, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: NodeJS.ArrayBufferView) => void): void,
+ * }} Read
+ */
+
+/** @typedef {(df: number, callback: NoParamCallback) => void} Close */
+
+/** @typedef {(a: PathLike, b: PathLike, callback: NoParamCallback) => void} Rename */
+
+/**
+ * Defines the intermediate file system extras type used by this module.
+ * @typedef {object} IntermediateFileSystemExtras
+ * @property {MkdirSync} mkdirSync
+ * @property {CreateWriteStream} createWriteStream
+ * @property {Open} open
+ * @property {Read} read
+ * @property {Close} close
+ * @property {Rename} rename
+ */
+
+/** @typedef {InputFileSystem & OutputFileSystem & IntermediateFileSystemExtras} IntermediateFileSystem */
+
+/**
+ * Returns location of targetPath relative to rootPath.
+ * @param {InputFileSystem | OutputFileSystem | undefined} fs a file system
+ * @param {string} rootPath the root path
+ * @param {string} targetPath the target path
+ * @returns {string} location of targetPath relative to rootPath
+ */
+const relative = (fs, rootPath, targetPath) => {
+	if (fs && fs.relative) {
+		return fs.relative(rootPath, targetPath);
+	} else if (path.posix.isAbsolute(rootPath)) {
+		return path.posix.relative(rootPath, targetPath);
+	} else if (path.win32.isAbsolute(rootPath)) {
+		return path.win32.relative(rootPath, targetPath);
+	}
+	throw new Error(
+		`${rootPath} is neither a posix nor a windows path, and there is no 'relative' method defined in the file system`
+	);
+};
+
+/**
+ * Returns the joined path.
+ * @param {InputFileSystem | OutputFileSystem | undefined} fs a file system
+ * @param {string} rootPath a path
+ * @param {string} filename a filename
+ * @returns {string} the joined path
+ */
+const join = (fs, rootPath, filename) => {
+	if (fs && fs.join) {
+		return fs.join(rootPath, filename);
+	} else if (path.posix.isAbsolute(rootPath)) {
+		return path.posix.join(rootPath, filename);
+	} else if (path.win32.isAbsolute(rootPath)) {
+		return path.win32.join(rootPath, filename);
+	}
+	throw new Error(
+		`${rootPath} is neither a posix nor a windows path, and there is no 'join' method defined in the file system`
+	);
+};
+
+/**
+ * Returns the parent directory of the absolute path.
+ * @param {InputFileSystem | OutputFileSystem | undefined} fs a file system
+ * @param {string} absPath an absolute path
+ * @returns {string} the parent directory of the absolute path
+ */
+const dirname = (fs, absPath) => {
+	if (fs && fs.dirname) {
+		return fs.dirname(absPath);
+	} else if (path.posix.isAbsolute(absPath)) {
+		return path.posix.dirname(absPath);
+	} else if (path.win32.isAbsolute(absPath)) {
+		return path.win32.dirname(absPath);
+	}
+	throw new Error(
+		`${absPath} is neither a posix nor a windows path, and there is no 'dirname' method defined in the file system`
+	);
+};
+
+/**
+ * Processes the provided f.
+ * @param {OutputFileSystem} fs a file system
+ * @param {string} p an absolute path
+ * @param {(err?: Error) => void} callback callback function for the error
+ * @returns {void}
+ */
+const mkdirp = (fs, p, callback) => {
+	fs.mkdir(p, (err) => {
+		if (err) {
+			if (err.code === "ENOENT") {
+				const dir = dirname(fs, p);
+				if (dir === p) {
+					callback(err);
+					return;
+				}
+				mkdirp(fs, dir, (err) => {
+					if (err) {
+						callback(err);
+						return;
+					}
+					fs.mkdir(p, (err) => {
+						if (err) {
+							if (err.code === "EEXIST") {
+								callback();
+								return;
+							}
+							callback(err);
+							return;
+						}
+						callback();
+					});
+				});
+				return;
+			} else if (err.code === "EEXIST") {
+				callback();
+				return;
+			}
+			callback(err);
+			return;
+		}
+		callback();
+	});
+};
+
+/**
+ * Processes the provided f.
+ * @param {IntermediateFileSystem} fs a file system
+ * @param {string} p an absolute path
+ * @returns {void}
+ */
+const mkdirpSync = (fs, p) => {
+	try {
+		fs.mkdirSync(p);
+	} catch (err) {
+		if (err) {
+			if (/** @type {NodeJS.ErrnoException} */ (err).code === "ENOENT") {
+				const dir = dirname(fs, p);
+				if (dir === p) {
+					throw err;
+				}
+				mkdirpSync(fs, dir);
+				fs.mkdirSync(p);
+				return;
+			} else if (/** @type {NodeJS.ErrnoException} */ (err).code === "EEXIST") {
+				return;
+			}
+			throw err;
+		}
+	}
+};
+
+/**
+ * Processes the provided f.
+ * @param {InputFileSystem} fs a file system
+ * @param {string} p an absolute path
+ * @param {ReadJsonCallback} callback callback
+ * @returns {void}
+ */
+const readJson = (fs, p, callback) => {
+	if ("readJson" in fs) {
+		return /** @type {NonNullable<InputFileSystem["readJson"]>} */ (
+			fs.readJson
+		)(p, callback);
+	}
+	fs.readFile(p, (err, buf) => {
+		if (err) return callback(err);
+		/** @type {JsonObject} */
+		let data;
+		try {
+			data = JSON.parse(/** @type {Buffer} */ (buf).toString("utf8"));
+		} catch (err1) {
+			return callback(/** @type {Error} */ (err1));
+		}
+		return callback(null, data);
+	});
+};
+
+/**
+ * Lstat readlink absolute.
+ * @param {InputFileSystem} fs a file system
+ * @param {string} p an absolute path
+ * @param {(err: NodeJS.ErrnoException | Error | null, stats?: IStats | string) => void} callback callback
+ * @returns {void}
+ */
+const lstatReadlinkAbsolute = (fs, p, callback) => {
+	let i = 3;
+	const doReadLink = () => {
+		fs.readlink(p, (err, target) => {
+			if (err && --i > 0) {
+				// It might was just changed from symlink to file
+				// we retry 2 times to catch this case before throwing the error
+				return doStat();
+			}
+			if (err) return callback(err);
+			const value = /** @type {string} */ (target).toString();
+			callback(null, join(fs, dirname(fs, p), value));
+		});
+	};
+	const doStat = () => {
+		if ("lstat" in fs) {
+			return /** @type {NonNullable<InputFileSystem["lstat"]>} */ (fs.lstat)(
+				p,
+				(err, stats) => {
+					if (err) return callback(err);
+					if (/** @type {IStats} */ (stats).isSymbolicLink()) {
+						return doReadLink();
+					}
+					callback(null, stats);
+				}
+			);
+		}
+		return fs.stat(p, callback);
+	};
+	if ("lstat" in fs) return doStat();
+	doReadLink();
+};
+
+/**
+ * Checks whether this object is absolute.
+ * @param {string} pathname a path
+ * @returns {boolean} is absolute
+ */
+const isAbsolute = (pathname) =>
+	path.posix.isAbsolute(pathname) || path.win32.isAbsolute(pathname);
+
+module.exports.dirname = dirname;
+module.exports.isAbsolute = isAbsolute;
+module.exports.join = join;
+module.exports.lstatReadlinkAbsolute = lstatReadlinkAbsolute;
+module.exports.mkdirp = mkdirp;
+module.exports.mkdirpSync = mkdirpSync;
+module.exports.readJson = readJson;
+module.exports.relative = relative;
Index: frontend/node_modules/webpack/lib/util/generateDebugId.js
===================================================================
--- frontend/node_modules/webpack/lib/util/generateDebugId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/generateDebugId.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const createHash = require("./createHash");
+
+/**
+ * Returns generated debug id.
+ * @param {string | Buffer} content content
+ * @param {string} file file
+ * @returns {string} generated debug id
+ */
+module.exports = (content, file) => {
+	// We need a uuid which is 128 bits so we need 2x 64 bit hashes.
+	// The first 64 bits is a hash of the source.
+	const sourceHash = createHash("xxhash64").update(content).digest("hex");
+	// The next 64 bits is a hash of the filename and sourceHash
+	const hash128 = `${sourceHash}${createHash("xxhash64")
+		.update(file)
+		.update(sourceHash)
+		.digest("hex")}`;
+
+	return [
+		hash128.slice(0, 8),
+		hash128.slice(8, 12),
+		`4${hash128.slice(12, 15)}`,
+		((Number.parseInt(hash128.slice(15, 16), 16) & 3) | 8).toString(16) +
+			hash128.slice(17, 20),
+		hash128.slice(20, 32)
+	].join("-");
+};
Index: frontend/node_modules/webpack/lib/util/hash/BatchedHash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/BatchedHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/BatchedHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,116 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Hash = require("../Hash");
+const { digest, update } = require("./hash-digest");
+/** @type {number} */
+const MAX_SHORT_STRING = require("./wasm-hash").MAX_SHORT_STRING;
+
+/** @typedef {import("../../../declarations/WebpackOptions").HashDigest} Encoding */
+
+class BatchedHash extends Hash {
+	/**
+	 * Creates an instance of BatchedHash.
+	 * @param {Hash} hash hash
+	 */
+	constructor(hash) {
+		super();
+		/** @type {undefined | string} */
+		this.string = undefined;
+		/** @type {undefined | Encoding} */
+		this.encoding = undefined;
+		/** @type {Hash} */
+		this.hash = hash;
+	}
+
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string | Buffer} data data
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string} data data
+	 * @param {Encoding} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @param {string | Buffer} data data
+	 * @param {Encoding=} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	update(data, inputEncoding) {
+		if (this.string !== undefined) {
+			if (
+				typeof data === "string" &&
+				inputEncoding === this.encoding &&
+				this.string.length + data.length < MAX_SHORT_STRING
+			) {
+				this.string += data;
+				return this;
+			}
+			if (this.encoding) {
+				update(this.hash, this.string, this.encoding);
+			} else {
+				update(this.hash, this.string);
+			}
+			this.string = undefined;
+		}
+		if (typeof data === "string") {
+			if (
+				data.length < MAX_SHORT_STRING &&
+				// base64 encoding is not valid since it may contain padding chars
+				(!inputEncoding || !inputEncoding.startsWith("ba"))
+			) {
+				this.string = data;
+				this.encoding = inputEncoding;
+			} else if (inputEncoding) {
+				update(this.hash, data, inputEncoding);
+			} else {
+				update(this.hash, data);
+			}
+		} else {
+			update(this.hash, data);
+		}
+		return this;
+	}
+
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @returns {Buffer} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @param {Encoding} encoding encoding of the return value
+	 * @returns {string} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @param {Encoding=} encoding encoding of the return value
+	 * @returns {string | Buffer} digest
+	 */
+	digest(encoding) {
+		if (this.string !== undefined) {
+			if (this.encoding) {
+				update(this.hash, this.string, this.encoding);
+			} else {
+				update(this.hash, this.string);
+			}
+		}
+		if (!encoding) {
+			return digest(this.hash);
+		}
+		return digest(this.hash, encoding);
+	}
+}
+
+module.exports = BatchedHash;
Index: frontend/node_modules/webpack/lib/util/hash/BulkUpdateHash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/BulkUpdateHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/BulkUpdateHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,146 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const Hash = require("../Hash");
+const { digest, update } = require("./hash-digest");
+
+/** @typedef {import("../../../declarations/WebpackOptions").HashDigest} Encoding */
+/** @typedef {() => Hash} HashFactory */
+
+const BULK_SIZE = 3;
+
+// We are using an object instead of a Map as this will stay static during the runtime
+// so access to it can be optimized by v8
+/** @type {{ [key: string]: Map<string, string> }} */
+const digestCaches = {};
+
+class BulkUpdateHash extends Hash {
+	/**
+	 * Creates an instance of BulkUpdateHash.
+	 * @param {Hash | HashFactory} hashOrFactory function to create a hash
+	 * @param {string=} hashKey key for caching
+	 */
+	constructor(hashOrFactory, hashKey) {
+		super();
+		/** @type {undefined | string} */
+		this.hashKey = hashKey;
+		if (typeof hashOrFactory === "function") {
+			/** @type {undefined | HashFactory} */
+			this.hashFactory = hashOrFactory;
+			/** @type {undefined | Hash} */
+			this.hash = undefined;
+		} else {
+			/** @type {undefined | HashFactory} */
+			this.hashFactory = undefined;
+			/** @type {undefined | Hash} */
+			this.hash = hashOrFactory;
+		}
+		/** @type {string} */
+		this.buffer = "";
+	}
+
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string | Buffer} data data
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string} data data
+	 * @param {Encoding} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @param {string | Buffer} data data
+	 * @param {Encoding=} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	update(data, inputEncoding) {
+		if (
+			inputEncoding !== undefined ||
+			typeof data !== "string" ||
+			data.length > BULK_SIZE
+		) {
+			if (this.hash === undefined) {
+				this.hash = /** @type {HashFactory} */ (this.hashFactory)();
+			}
+			if (this.buffer.length > 0) {
+				update(this.hash, this.buffer);
+				this.buffer = "";
+			}
+			if (typeof data === "string" && inputEncoding) {
+				update(this.hash, data, inputEncoding);
+			} else {
+				update(this.hash, data);
+			}
+		} else {
+			this.buffer += data;
+			if (this.buffer.length > BULK_SIZE) {
+				if (this.hash === undefined) {
+					this.hash = /** @type {HashFactory} */ (this.hashFactory)();
+				}
+				update(this.hash, this.buffer);
+				this.buffer = "";
+			}
+		}
+		return this;
+	}
+
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @returns {Buffer} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @param {Encoding} encoding encoding of the return value
+	 * @returns {string} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @param {Encoding=} encoding encoding of the return value
+	 * @returns {string | Buffer} digest
+	 */
+	digest(encoding) {
+		/** @type {undefined | Map<string, string | Buffer>} */
+		let digestCache;
+		const buffer = this.buffer;
+		if (this.hash === undefined) {
+			// short data for hash, we can use caching
+			const cacheKey = `${this.hashKey}-${encoding}`;
+			digestCache = digestCaches[cacheKey];
+			if (digestCache === undefined) {
+				digestCache = digestCaches[cacheKey] = new Map();
+			}
+			const cacheEntry = digestCache.get(buffer);
+			if (cacheEntry !== undefined) return cacheEntry;
+			this.hash = /** @type {HashFactory} */ (this.hashFactory)();
+		}
+
+		if (buffer.length > 0) {
+			update(this.hash, buffer);
+		}
+		if (!encoding) {
+			const result = digest(this.hash, undefined, Boolean(this.hashKey));
+			if (digestCache !== undefined) {
+				digestCache.set(buffer, result);
+			}
+			return result;
+		}
+		const result = digest(this.hash, encoding, Boolean(this.hashKey));
+		if (digestCache !== undefined) {
+			digestCache.set(buffer, result);
+		}
+		return result;
+	}
+}
+
+module.exports = BulkUpdateHash;
Index: frontend/node_modules/webpack/lib/util/hash/DebugHash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/DebugHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/DebugHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const Hash = require("../Hash");
+
+/** @typedef {import("../../../declarations/WebpackOptions").HashDigest} Encoding */
+
+/* istanbul ignore next */
+class DebugHash extends Hash {
+	constructor() {
+		super();
+		this.string = "";
+	}
+
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string | Buffer} data data
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string} data data
+	 * @param {Encoding} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @param {string | Buffer} data data
+	 * @param {Encoding=} inputEncoding data encoding
+	 * @returns {Hash} updated hash
+	 */
+	update(data, inputEncoding) {
+		if (typeof data !== "string") data = data.toString("utf8");
+		const prefix = Buffer.from("@webpack-debug-digest@").toString("hex");
+		if (data.startsWith(prefix)) {
+			data = Buffer.from(data.slice(prefix.length), "hex").toString();
+		}
+		this.string += `[${data}](${
+			/** @type {string} */
+			(
+				// eslint-disable-next-line unicorn/error-message
+				new Error().stack
+			).split("\n", 3)[2]
+		})\n`;
+		return this;
+	}
+
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @returns {Buffer} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @param {Encoding} encoding encoding of the return value
+	 * @returns {string} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @param {Encoding=} encoding encoding of the return value
+	 * @returns {string | Buffer} digest
+	 */
+	digest(encoding) {
+		return Buffer.from(`@webpack-debug-digest@${this.string}`).toString("hex");
+	}
+}
+
+module.exports = DebugHash;
Index: frontend/node_modules/webpack/lib/util/hash/hash-digest.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/hash-digest.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/hash-digest.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,225 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+/** @typedef {import("../Hash")} Hash */
+/** @typedef {import("../../../declarations/WebpackOptions").HashDigest} Encoding */
+
+/** @typedef {"26" | "32" | "36" | "49" | "52" | "58" | "62"} Base */
+
+/* cSpell:disable */
+
+/** @type {Record<Base, string>} */
+const ENCODE_TABLE = Object.freeze({
+	26: "abcdefghijklmnopqrstuvwxyz",
+	32: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
+	36: "0123456789abcdefghijklmnopqrstuvwxyz",
+	49: "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ",
+	52: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+	58: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
+	62: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+});
+
+/* cSpell:enable */
+
+const ZERO = BigInt("0");
+const EIGHT = BigInt("8");
+const FF = BigInt("0xff");
+
+/**
+ * It encodes octet arrays by doing long divisions on all significant digits in the array, creating a representation of that number in the new base.
+ * Then for every leading zero in the input (not significant as a number) it will encode as a single leader character.
+ * This is the first in the alphabet and will decode as 8 bits. The other characters depend upon the base.
+ * For example, a base58 alphabet packs roughly 5.858 bits per character.
+ * This means the encoded string 000f (using a base16, 0-f alphabet) will actually decode to 4 bytes unlike a canonical hex encoding which uniformly packs 4 bits into each character.
+ * While unusual, this does mean that no padding is required, and it works for bases like 43.
+ * @param {Buffer} buffer buffer
+ * @param {Base} base base
+ * @returns {string} encoded buffer
+ */
+const encode = (buffer, base) => {
+	if (buffer.length === 0) return "";
+	const bigIntBase = BigInt(ENCODE_TABLE[base].length);
+	// Convert buffer to BigInt efficiently using bitwise operations
+	let value = ZERO;
+	for (let i = 0; i < buffer.length; i++) {
+		value = (value << EIGHT) | BigInt(buffer[i]);
+	}
+	// Convert to baseX string efficiently using array
+	/** @type {string[]} */
+	const digits = [];
+	if (value === ZERO) return ENCODE_TABLE[base][0];
+	while (value > ZERO) {
+		const remainder = Number(value % bigIntBase);
+		digits.push(ENCODE_TABLE[base][remainder]);
+		value /= bigIntBase;
+	}
+	return digits.reverse().join("");
+};
+
+/**
+ * Returns buffer.
+ * @param {string} data string
+ * @param {Base} base base
+ * @returns {Buffer} buffer
+ */
+const decode = (data, base) => {
+	if (data.length === 0) return Buffer.from("");
+	const bigIntBase = BigInt(ENCODE_TABLE[base].length);
+	// Convert the baseX string to a BigInt value
+	let value = ZERO;
+	for (let i = 0; i < data.length; i++) {
+		const digit = ENCODE_TABLE[base].indexOf(data[i]);
+		if (digit === -1) {
+			throw new Error(`Invalid character at position ${i}: ${data[i]}`);
+		}
+		value = value * bigIntBase + BigInt(digit);
+	}
+	// If value is 0, return a single-byte buffer with value 0
+	if (value === ZERO) {
+		return Buffer.alloc(1);
+	}
+	// Determine buffer size efficiently by counting bytes
+	let temp = value;
+	let byteLength = 0;
+	while (temp > ZERO) {
+		temp >>= EIGHT;
+		byteLength++;
+	}
+	// Create buffer and fill it from right to left
+	const buffer = Buffer.alloc(byteLength);
+	for (let i = byteLength - 1; i >= 0; i--) {
+		buffer[i] = Number(value & FF);
+		value >>= EIGHT;
+	}
+	return buffer;
+};
+
+// Compatibility with the old hash libraries, they can return different structures, so let's stringify them firstly
+
+/**
+ * Returns a string representation.
+ * @param {string | { toString: (radix: number) => string }} value value
+ * @param {string} encoding encoding
+ * @returns {string} string
+ */
+const toString = (value, encoding) =>
+	typeof value === "string"
+		? value
+		: Buffer.from(value.toString(16), "hex").toString(
+				/** @type {NodeJS.BufferEncoding} */
+				(encoding)
+			);
+
+/**
+ * Returns buffer.
+ * @param {Buffer | { toString: (radix: number) => string }} value value
+ * @returns {Buffer} buffer
+ */
+const toBuffer = (value) =>
+	Buffer.isBuffer(value) ? value : Buffer.from(value.toString(16), "hex");
+
+let isBase64URLSupported = false;
+
+try {
+	isBase64URLSupported = Boolean(Buffer.from("", "base64url"));
+} catch (_err) {
+	// Nothing
+}
+
+/**
+ * Processes the provided hash.
+ * @param {Hash} hash hash
+ * @param {string | Buffer} data data
+ * @param {Encoding=} encoding encoding of the return value
+ * @returns {void}
+ */
+const update = (hash, data, encoding) => {
+	if (encoding === "base64url" && !isBase64URLSupported) {
+		const base64String = /** @type {string} */ (data)
+			.replace(/-/g, "+")
+			.replace(/_/g, "/");
+		const buf = Buffer.from(base64String, "base64");
+		hash.update(buf);
+		return;
+	} else if (
+		typeof data === "string" &&
+		encoding &&
+		typeof ENCODE_TABLE[/** @type {Base} */ (encoding.slice(4))] !== "undefined"
+	) {
+		const buf = decode(data, /** @type {Base} */ (encoding.slice(4)));
+		hash.update(buf);
+		return;
+	}
+
+	if (encoding) {
+		hash.update(/** @type {string} */ (data), encoding);
+	} else {
+		hash.update(data);
+	}
+};
+
+/**
+ * Returns digest.
+ * @overload
+ * @param {Hash} hash hash
+ * @returns {Buffer} digest
+ */
+/**
+ * Returns digest.
+ * @overload
+ * @param {Hash} hash hash
+ * @param {undefined} encoding encoding of the return value
+ * @param {boolean=} isSafe true when we await right types from digest(), otherwise false
+ * @returns {Buffer} digest
+ */
+/**
+ * Returns digest.
+ * @overload
+ * @param {Hash} hash hash
+ * @param {Encoding} encoding encoding of the return value
+ * @param {boolean=} isSafe true when we await right types from digest(), otherwise false
+ * @returns {string} digest
+ */
+/**
+ * Returns digest.
+ * @param {Hash} hash hash
+ * @param {Encoding=} encoding encoding of the return value
+ * @param {boolean=} isSafe true when we await right types from digest(), otherwise false
+ * @returns {string | Buffer} digest
+ */
+const digest = (hash, encoding, isSafe) => {
+	if (typeof encoding === "undefined") {
+		return isSafe ? hash.digest() : toBuffer(hash.digest());
+	}
+
+	if (encoding === "base64url" && !isBase64URLSupported) {
+		const digest = isSafe
+			? hash.digest("base64")
+			: toString(hash.digest("base64"), "base64");
+
+		return digest.replace(/\+/g, "-").replace(/\//g, "_").replace(/[=]+$/, "");
+	} else if (
+		typeof ENCODE_TABLE[/** @type {Base} */ (encoding.slice(4))] !== "undefined"
+	) {
+		const buf = isSafe ? hash.digest() : toBuffer(hash.digest());
+
+		return encode(
+			buf,
+			/** @type {Base} */
+			(encoding.slice(4))
+		);
+	}
+
+	return isSafe
+		? hash.digest(encoding)
+		: toString(hash.digest(encoding), encoding);
+};
+
+module.exports.decode = decode;
+module.exports.digest = digest;
+module.exports.encode = encode;
+module.exports.update = update;
Index: frontend/node_modules/webpack/lib/util/hash/md4.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/md4.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/md4.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const create = require("./wasm-hash");
+
+// #region wasm code: md4 (../../../assembly/hash/md4.asm.ts) --initialMemory 1
+const md4 = new WebAssembly.Module(
+	Buffer.from(
+		// 2150 bytes
+		"AGFzbQEAAAABCAJgAX8AYAAAAwUEAAABAAUDAQABBhoFfwFBAAt/AUEAC38BQQALfwFBAAt/AUEACwciBARpbml0AAIGdXBkYXRlAAEFZmluYWwAAwZtZW1vcnkCAAqFEATQCgEZfyMBIQUjAiECIwMhAyMEIQQDQCAAIAFLBEAgASgCBCIOIAQgAyABKAIAIg8gBSAEIAIgAyAEc3FzampBA3ciCCACIANzcXNqakEHdyEJIAEoAgwiBiACIAggASgCCCIQIAMgAiAJIAIgCHNxc2pqQQt3IgogCCAJc3FzampBE3chCyABKAIUIgcgCSAKIAEoAhAiESAIIAkgCyAJIApzcXNqakEDdyIMIAogC3Nxc2pqQQd3IQ0gASgCHCIJIAsgDCABKAIYIgggCiALIA0gCyAMc3FzampBC3ciEiAMIA1zcXNqakETdyETIAEoAiQiFCANIBIgASgCICIVIAwgDSATIA0gEnNxc2pqQQN3IgwgEiATc3FzampBB3chDSABKAIsIgsgEyAMIAEoAigiCiASIBMgDSAMIBNzcXNqakELdyISIAwgDXNxc2pqQRN3IRMgASgCNCIWIA0gEiABKAIwIhcgDCANIBMgDSASc3FzampBA3ciGCASIBNzcXNqakEHdyEZIBggASgCPCINIBMgGCABKAI4IgwgEiATIBkgEyAYc3FzampBC3ciEiAYIBlzcXNqakETdyITIBIgGXJxIBIgGXFyaiAPakGZ84nUBWpBA3ciGCATIBIgGSAYIBIgE3JxIBIgE3FyaiARakGZ84nUBWpBBXciEiATIBhycSATIBhxcmogFWpBmfOJ1AVqQQl3IhMgEiAYcnEgEiAYcXJqIBdqQZnzidQFakENdyIYIBIgE3JxIBIgE3FyaiAOakGZ84nUBWpBA3ciGSAYIBMgEiAZIBMgGHJxIBMgGHFyaiAHakGZ84nUBWpBBXciEiAYIBlycSAYIBlxcmogFGpBmfOJ1AVqQQl3IhMgEiAZcnEgEiAZcXJqIBZqQZnzidQFakENdyIYIBIgE3JxIBIgE3FyaiAQakGZ84nUBWpBA3ciGSAYIBMgEiAZIBMgGHJxIBMgGHFyaiAIakGZ84nUBWpBBXciEiAYIBlycSAYIBlxcmogCmpBmfOJ1AVqQQl3IhMgEiAZcnEgEiAZcXJqIAxqQZnzidQFakENdyIYIBIgE3JxIBIgE3FyaiAGakGZ84nUBWpBA3ciGSAYIBMgEiAZIBMgGHJxIBMgGHFyaiAJakGZ84nUBWpBBXciEiAYIBlycSAYIBlxcmogC2pBmfOJ1AVqQQl3IhMgEiAZcnEgEiAZcXJqIA1qQZnzidQFakENdyIYIBNzIBJzaiAPakGh1+f2BmpBA3ciDyAYIBMgEiAPIBhzIBNzaiAVakGh1+f2BmpBCXciEiAPcyAYc2ogEWpBodfn9gZqQQt3IhEgEnMgD3NqIBdqQaHX5/YGakEPdyIPIBFzIBJzaiAQakGh1+f2BmpBA3ciECAPIBEgEiAPIBBzIBFzaiAKakGh1+f2BmpBCXciCiAQcyAPc2ogCGpBodfn9gZqQQt3IgggCnMgEHNqIAxqQaHX5/YGakEPdyIMIAhzIApzaiAOakGh1+f2BmpBA3ciDiAMIAggCiAMIA5zIAhzaiAUakGh1+f2BmpBCXciCCAOcyAMc2ogB2pBodfn9gZqQQt3IgcgCHMgDnNqIBZqQaHX5/YGakEPdyIKIAdzIAhzaiAGakGh1+f2BmpBA3ciBiAFaiEFIAIgCiAHIAggBiAKcyAHc2ogC2pBodfn9gZqQQl3IgcgBnMgCnNqIAlqQaHX5/YGakELdyIIIAdzIAZzaiANakGh1+f2BmpBD3dqIQIgAyAIaiEDIAQgB2ohBCABQUBrIQEMAQsLIAUkASACJAIgAyQDIAQkBAsNACAAEAAjACAAaiQACyYAQYHGlLoGJAFBide2/n4kAkH+uevFeSQDQfaoyYEBJARBACQAC/sEAgN/AX4jACAAaq1CA4YhBCAAQcgAakFAcSICQQhrIAAiAUEBaiEAIAFBgAE6AAADQCAAIAJJQQAgAEEHcRsEQCAAQQA6AAAgAEEBaiEADAELCwNAIAAgAkkEQCAAQgA3AwAgAEEIaiEADAELCyAENwMAIAIQAEEAIwGtIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEIIwKtIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEQIwOtIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEYIwStIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAAs=",
+		"base64"
+	)
+);
+// #endregion
+
+module.exports = create.bind(null, md4, [], 64, 32);
Index: frontend/node_modules/webpack/lib/util/hash/wasm-hash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/wasm-hash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/wasm-hash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,237 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Hash = require("../Hash");
+
+// 65536 is the size of a wasm memory page
+// 64 is the maximum chunk size for every possible wasm hash implementation
+// 4 is the maximum number of bytes per char for string encoding (max is utf-8)
+// ~3 makes sure that it's always a block of 4 chars, so avoid partially encoded bytes for base64
+const MAX_SHORT_STRING = Math.floor((65536 - 64) / 4) & ~3;
+
+/**
+ * Represents the wasm hash runtime component.
+ * @typedef {object} WasmExports
+ * @property {WebAssembly.Memory} memory
+ * @property {() => void} init
+ * @property {(length: number) => void} update
+ * @property {(length: number) => void} final
+ */
+
+class WasmHash extends Hash {
+	/**
+	 * Creates an instance of WasmHash.
+	 * @param {WebAssembly.Instance} instance wasm instance
+	 * @param {WebAssembly.Instance[]} instancesPool pool of instances
+	 * @param {number} chunkSize size of data chunks passed to wasm
+	 * @param {number} digestSize size of digest returned by wasm
+	 */
+	constructor(instance, instancesPool, chunkSize, digestSize) {
+		super();
+
+		const exports = /** @type {WasmExports} */ (instance.exports);
+		exports.init();
+		/** @type {WasmExports} */
+		this.exports = exports;
+		/** @type {Buffer} */
+		this.mem = Buffer.from(exports.memory.buffer, 0, 65536);
+		/** @type {number} */
+		this.buffered = 0;
+		/** @type {WebAssembly.Instance[]} */
+		this.instancesPool = instancesPool;
+		/** @type {number} */
+		this.chunkSize = chunkSize;
+		/** @type {number} */
+		this.digestSize = digestSize;
+	}
+
+	reset() {
+		this.buffered = 0;
+		this.exports.init();
+	}
+
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string | Buffer} data data
+	 * @returns {Hash} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @overload
+	 * @param {string} data data
+	 * @param {string=} inputEncoding data encoding
+	 * @returns {this} updated hash
+	 */
+	/**
+	 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
+	 * @param {string | Buffer} data data
+	 * @param {string=} inputEncoding data encoding
+	 * @returns {this} updated hash
+	 */
+	update(data, inputEncoding) {
+		if (typeof data === "string") {
+			while (data.length > MAX_SHORT_STRING) {
+				this._updateWithShortString(
+					data.slice(0, MAX_SHORT_STRING),
+					/** @type {NodeJS.BufferEncoding} */
+					(inputEncoding)
+				);
+				data = data.slice(MAX_SHORT_STRING);
+			}
+			this._updateWithShortString(
+				data,
+				/** @type {NodeJS.BufferEncoding} */
+				(inputEncoding)
+			);
+			return this;
+		}
+		this._updateWithBuffer(data);
+		return this;
+	}
+
+	/**
+	 * Update with short string.
+	 * @param {string} data data
+	 * @param {BufferEncoding=} encoding encoding
+	 * @returns {void}
+	 */
+	_updateWithShortString(data, encoding) {
+		const { exports, buffered, mem, chunkSize } = this;
+		/** @type {number} */
+		let endPos;
+		if (data.length < 70) {
+			// eslint-disable-next-line unicorn/text-encoding-identifier-case
+			if (!encoding || encoding === "utf-8" || encoding === "utf8") {
+				endPos = buffered;
+				for (let i = 0; i < data.length; i++) {
+					const cc = data.charCodeAt(i);
+					if (cc < 0x80) {
+						mem[endPos++] = cc;
+					} else if (cc < 0x800) {
+						mem[endPos] = (cc >> 6) | 0xc0;
+						mem[endPos + 1] = (cc & 0x3f) | 0x80;
+						endPos += 2;
+					} else {
+						// bail-out for weird chars
+						endPos += mem.write(data.slice(i), endPos, encoding);
+						break;
+					}
+				}
+			} else if (encoding === "latin1") {
+				endPos = buffered;
+				for (let i = 0; i < data.length; i++) {
+					const cc = data.charCodeAt(i);
+					mem[endPos++] = cc;
+				}
+			} else {
+				endPos = buffered + mem.write(data, buffered, encoding);
+			}
+		} else {
+			endPos = buffered + mem.write(data, buffered, encoding);
+		}
+		if (endPos < chunkSize) {
+			this.buffered = endPos;
+		} else {
+			const l = endPos & ~(this.chunkSize - 1);
+			exports.update(l);
+			const newBuffered = endPos - l;
+			this.buffered = newBuffered;
+			if (newBuffered > 0) mem.copyWithin(0, l, endPos);
+		}
+	}
+
+	/**
+	 * Update with buffer.
+	 * @param {Buffer} data data
+	 * @returns {void}
+	 */
+	_updateWithBuffer(data) {
+		const { exports, buffered, mem } = this;
+		const length = data.length;
+		if (buffered + length < this.chunkSize) {
+			data.copy(mem, buffered, 0, length);
+			this.buffered += length;
+		} else {
+			const l = (buffered + length) & ~(this.chunkSize - 1);
+			if (l > 65536) {
+				let i = 65536 - buffered;
+				data.copy(mem, buffered, 0, i);
+				exports.update(65536);
+				const stop = l - buffered - 65536;
+				while (i < stop) {
+					data.copy(mem, 0, i, i + 65536);
+					exports.update(65536);
+					i += 65536;
+				}
+				data.copy(mem, 0, i, l - buffered);
+				exports.update(l - buffered - i);
+			} else {
+				data.copy(mem, buffered, 0, l - buffered);
+				exports.update(l);
+			}
+			const newBuffered = length + buffered - l;
+			this.buffered = newBuffered;
+			if (newBuffered > 0) data.copy(mem, 0, length - newBuffered, length);
+		}
+	}
+
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @returns {Buffer} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @overload
+	 * @param {string=} encoding encoding of the return value
+	 * @returns {string} digest
+	 */
+	/**
+	 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
+	 * @param {string=} encoding encoding of the return value
+	 * @returns {string | Buffer} digest
+	 */
+	digest(encoding) {
+		const { exports, buffered, mem, digestSize } = this;
+		exports.final(buffered);
+		this.instancesPool.push(this);
+		const hex = mem.toString("latin1", 0, digestSize);
+		if (encoding === "hex") return hex;
+		if (encoding === "binary" || !encoding) return Buffer.from(hex, "hex");
+		return Buffer.from(hex, "hex").toString(
+			/** @type {NodeJS.BufferEncoding} */ (encoding)
+		);
+	}
+}
+
+/**
+ * Returns wasm hash.
+ * @param {WebAssembly.Module} wasmModule wasm module
+ * @param {WasmHash[]} instancesPool pool of instances
+ * @param {number} chunkSize size of data chunks passed to wasm
+ * @param {number} digestSize size of digest returned by wasm
+ * @returns {WasmHash} wasm hash
+ */
+const create = (wasmModule, instancesPool, chunkSize, digestSize) => {
+	if (instancesPool.length > 0) {
+		const old = /** @type {WasmHash} */ (instancesPool.pop());
+		old.reset();
+		return old;
+	}
+
+	return new WasmHash(
+		new WebAssembly.Instance(wasmModule),
+		instancesPool,
+		chunkSize,
+		digestSize
+	);
+};
+
+create.MAX_SHORT_STRING = MAX_SHORT_STRING;
+
+module.exports = create;
Index: frontend/node_modules/webpack/lib/util/hash/xxhash64.js
===================================================================
--- frontend/node_modules/webpack/lib/util/hash/xxhash64.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/hash/xxhash64.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const create = require("./wasm-hash");
+
+// #region wasm code: xxhash64 (../../../assembly/hash/xxhash64.asm.ts) --initialMemory 1
+const xxhash64 = new WebAssembly.Module(
+	Buffer.from(
+		// 1160 bytes
+		"AGFzbQEAAAABCAJgAX8AYAAAAwQDAAEABQMBAAEGGgV+AUIAC34BQgALfgFCAAt+AUIAC34BQgALByIEBGluaXQAAQZ1cGRhdGUAAAVmaW5hbAACBm1lbW9yeQIACqgIA9QBAgF/BH4gAEUEQA8LIwQgAK18JAQjACECIwEhAyMCIQQjAyEFA0AgAiABKQMAQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+IQIgAyABKQMIQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+IQMgBCABKQMQQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+IQQgBSABKQMYQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+IQUgAUEgaiIBIABJDQALIAIkACADJAEgBCQCIAUkAwswAELW64Lu6v2J9eAAJABCz9bTvtLHq9lCJAFCACQCQvnq0NDnyaHk4QAkA0IAJAQLngYCAn8CfiMEQgBSBH4jAEIBiSMBQgeJfCMCQgyJfCMDQhKJfCMAQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9IwFCz9bTvtLHq9lCfkIfiUKHla+vmLbem55/foVCh5Wvr5i23puef35CnaO16oOxjYr6AH0jAkLP1tO+0ser2UJ+Qh+JQoeVr6+Ytt6bnn9+hUKHla+vmLbem55/fkKdo7Xqg7GNivoAfSMDQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9BULFz9my8eW66icLIwQgAK18fCEDA0AgAUEIaiICIABNBEAgAyABKQMAQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQhuJQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9IQMgAiEBDAELCyABQQRqIgIgAE0EQCADIAE1AgBCh5Wvr5i23puef36FQheJQs/W077Sx6vZQn5C+fPd8Zn2masWfCEDIAIhAQsDQCAAIAFHBEAgAyABMQAAQsXP2bLx5brqJ36FQguJQoeVr6+Ytt6bnn9+IQMgAUEBaiEBDAELC0EAIAMgA0IhiIVCz9bTvtLHq9lCfiIDQh2IIAOFQvnz3fGZ9pmrFn4iA0IgiCADhSIDQiCIIgRC//8Dg0IghiAEQoCA/P8Pg0IQiIQiBEL/gYCA8B+DQhCGIARCgP6DgIDgP4NCCIiEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEIIANC/////w+DIgNC//8Dg0IghiADQoCA/P8Pg0IQiIQiA0L/gYCA8B+DQhCGIANCgP6DgIDgP4NCCIiEIgNCj4C8gPCBwAeDQgiGIANC8IHAh4CegPgAg0IEiIQiA0KGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gA0Kw4MCBg4aMmDCEfDcDAAs=",
+		"base64"
+	)
+);
+// #endregion
+
+module.exports = create.bind(null, xxhash64, [], 32, 16);
Index: frontend/node_modules/webpack/lib/util/identifier.js
===================================================================
--- frontend/node_modules/webpack/lib/util/identifier.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/identifier.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,538 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const path = require("path");
+
+const WINDOWS_ABS_PATH_REGEXP = /^[a-z]:[\\/]/i;
+const SEGMENTS_SPLIT_REGEXP = /([|!])/;
+const WINDOWS_PATH_SEPARATOR_REGEXP = /\\/g;
+
+/**
+ * Relative path to request.
+ * @param {string} relativePath relative path
+ * @returns {string} request
+ */
+const relativePathToRequest = (relativePath) => {
+	if (relativePath === "") return "./.";
+	if (relativePath === "..") return "../.";
+	if (relativePath.startsWith("../")) return relativePath;
+	return `./${relativePath}`;
+};
+
+/**
+ * Absolute to request.
+ * @param {string} context context for relative path
+ * @param {string} maybeAbsolutePath path to make relative
+ * @returns {string} relative path in request style
+ */
+const absoluteToRequest = (context, maybeAbsolutePath) => {
+	if (maybeAbsolutePath[0] === "/") {
+		if (
+			maybeAbsolutePath.length > 1 &&
+			maybeAbsolutePath[maybeAbsolutePath.length - 1] === "/"
+		) {
+			// this 'path' is actually a regexp generated by dynamic requires.
+			// Don't treat it as an absolute path.
+			return maybeAbsolutePath;
+		}
+
+		const querySplitPos = maybeAbsolutePath.indexOf("?");
+		let resource =
+			querySplitPos === -1
+				? maybeAbsolutePath
+				: maybeAbsolutePath.slice(0, querySplitPos);
+		resource = relativePathToRequest(path.posix.relative(context, resource));
+		return querySplitPos === -1
+			? resource
+			: resource + maybeAbsolutePath.slice(querySplitPos);
+	}
+
+	if (WINDOWS_ABS_PATH_REGEXP.test(maybeAbsolutePath)) {
+		const querySplitPos = maybeAbsolutePath.indexOf("?");
+		let resource =
+			querySplitPos === -1
+				? maybeAbsolutePath
+				: maybeAbsolutePath.slice(0, querySplitPos);
+		resource = path.win32.relative(context, resource);
+		if (!WINDOWS_ABS_PATH_REGEXP.test(resource)) {
+			resource = relativePathToRequest(
+				resource.replace(WINDOWS_PATH_SEPARATOR_REGEXP, "/")
+			);
+		}
+		return querySplitPos === -1
+			? resource
+			: resource + maybeAbsolutePath.slice(querySplitPos);
+	}
+
+	// not an absolute path
+	return maybeAbsolutePath;
+};
+
+/**
+ * Request to absolute.
+ * @param {string} context context for relative path
+ * @param {string} relativePath path
+ * @returns {string} absolute path
+ */
+const requestToAbsolute = (context, relativePath) => {
+	if (relativePath.startsWith("./") || relativePath.startsWith("../")) {
+		return path.join(context, relativePath);
+	}
+	return relativePath;
+};
+
+/** @typedef {EXPECTED_OBJECT} AssociatedObjectForCache */
+
+/**
+ * Defines the make cacheable result type used by this module.
+ * @template T
+ * @typedef {(value: string, cache?: AssociatedObjectForCache) => T} MakeCacheableResult
+ */
+
+/**
+ * Defines the bind cache result fn type used by this module.
+ * @template T
+ * @typedef {(value: string) => T} BindCacheResultFn
+ */
+
+/**
+ * Defines the bind cache type used by this module.
+ * @template T
+ * @typedef {(cache: AssociatedObjectForCache) => BindCacheResultFn<T>} BindCache
+ */
+
+/**
+ * Returns } cacheable function.
+ * @template T
+ * @param {((value: string) => T)} realFn real function
+ * @returns {MakeCacheableResult<T> & { bindCache: BindCache<T> }} cacheable function
+ */
+const makeCacheable = (realFn) => {
+	/**
+	 * Defines the cache item type used by this module.
+	 * @template T
+	 * @typedef {Map<string, T>} CacheItem
+	 */
+	/** @type {WeakMap<AssociatedObjectForCache, CacheItem<T>>} */
+	const cache = new WeakMap();
+
+	/**
+	 * Returns cache item.
+	 * @param {AssociatedObjectForCache} associatedObjectForCache an object to which the cache will be attached
+	 * @returns {CacheItem<T>} cache item
+	 */
+	const getCache = (associatedObjectForCache) => {
+		const entry = cache.get(associatedObjectForCache);
+		if (entry !== undefined) return entry;
+		/** @type {Map<string, T>} */
+		const map = new Map();
+		cache.set(associatedObjectForCache, map);
+		return map;
+	};
+
+	/** @type {MakeCacheableResult<T> & { bindCache: BindCache<T> }} */
+	const fn = (str, associatedObjectForCache) => {
+		if (!associatedObjectForCache) return realFn(str);
+		const cache = getCache(associatedObjectForCache);
+		const entry = cache.get(str);
+		if (entry !== undefined) return entry;
+		const result = realFn(str);
+		cache.set(str, result);
+		return result;
+	};
+
+	/** @type {BindCache<T>} */
+	fn.bindCache = (associatedObjectForCache) => {
+		const cache = getCache(associatedObjectForCache);
+		/**
+		 * Returns value.
+		 * @param {string} str string
+		 * @returns {T} value
+		 */
+		return (str) => {
+			const entry = cache.get(str);
+			if (entry !== undefined) return entry;
+			const result = realFn(str);
+			cache.set(str, result);
+			return result;
+		};
+	};
+
+	return fn;
+};
+
+/** @typedef {(context: string, value: string, associatedObjectForCache?: AssociatedObjectForCache) => string} MakeCacheableWithContextResult */
+/** @typedef {(context: string, value: string) => string} BindCacheForContextResultFn */
+/** @typedef {(value: string) => string} BindContextCacheForContextResultFn */
+/** @typedef {(associatedObjectForCache?: AssociatedObjectForCache) => BindCacheForContextResultFn} BindCacheForContext */
+/** @typedef {(value: string, associatedObjectForCache?: AssociatedObjectForCache) => BindContextCacheForContextResultFn} BindContextCacheForContext */
+
+/**
+ * Creates cacheable with context.
+ * @param {(context: string, identifier: string) => string} fn function
+ * @returns {MakeCacheableWithContextResult & { bindCache: BindCacheForContext, bindContextCache: BindContextCacheForContext }} cacheable function with context
+ */
+const makeCacheableWithContext = (fn) => {
+	/** @typedef {Map<string, Map<string, string>>} InnerCache */
+	/** @type {WeakMap<AssociatedObjectForCache, InnerCache>} */
+	const cache = new WeakMap();
+
+	/** @type {MakeCacheableWithContextResult & { bindCache: BindCacheForContext, bindContextCache: BindContextCacheForContext }} */
+	const cachedFn = (context, identifier, associatedObjectForCache) => {
+		if (!associatedObjectForCache) return fn(context, identifier);
+
+		let innerCache = cache.get(associatedObjectForCache);
+		if (innerCache === undefined) {
+			innerCache = new Map();
+			cache.set(associatedObjectForCache, innerCache);
+		}
+
+		/** @type {undefined | string} */
+		let cachedResult;
+		let innerSubCache = innerCache.get(context);
+		if (innerSubCache === undefined) {
+			innerCache.set(context, (innerSubCache = new Map()));
+		} else {
+			cachedResult = innerSubCache.get(identifier);
+		}
+
+		if (cachedResult !== undefined) {
+			return cachedResult;
+		}
+		const result = fn(context, identifier);
+		innerSubCache.set(identifier, result);
+		return result;
+	};
+
+	/** @type {BindCacheForContext} */
+	cachedFn.bindCache = (associatedObjectForCache) => {
+		/** @type {undefined | InnerCache} */
+		let innerCache;
+		if (associatedObjectForCache) {
+			innerCache = cache.get(associatedObjectForCache);
+			if (innerCache === undefined) {
+				innerCache = new Map();
+				cache.set(associatedObjectForCache, innerCache);
+			}
+		} else {
+			innerCache = new Map();
+		}
+
+		/**
+		 * Returns the returned relative path.
+		 * @param {string} context context used to create relative path
+		 * @param {string} identifier identifier used to create relative path
+		 * @returns {string} the returned relative path
+		 */
+		const boundFn = (context, identifier) => {
+			/** @type {undefined | string} */
+			let cachedResult;
+			let innerSubCache = innerCache.get(context);
+			if (innerSubCache === undefined) {
+				innerCache.set(context, (innerSubCache = new Map()));
+			} else {
+				cachedResult = innerSubCache.get(identifier);
+			}
+
+			if (cachedResult !== undefined) {
+				return cachedResult;
+			}
+			const result = fn(context, identifier);
+			innerSubCache.set(identifier, result);
+			return result;
+		};
+
+		return boundFn;
+	};
+
+	/** @type {BindContextCacheForContext} */
+	cachedFn.bindContextCache = (context, associatedObjectForCache) => {
+		/** @type {undefined | Map<string, string>} */
+		let innerSubCache;
+		if (associatedObjectForCache) {
+			let innerCache = cache.get(associatedObjectForCache);
+			if (innerCache === undefined) {
+				innerCache = new Map();
+				cache.set(associatedObjectForCache, innerCache);
+			}
+
+			innerSubCache = innerCache.get(context);
+			if (innerSubCache === undefined) {
+				innerCache.set(context, (innerSubCache = new Map()));
+			}
+		} else {
+			innerSubCache = new Map();
+		}
+
+		/**
+		 * Returns the returned relative path.
+		 * @param {string} identifier identifier used to create relative path
+		 * @returns {string} the returned relative path
+		 */
+		const boundFn = (identifier) => {
+			const cachedResult = innerSubCache.get(identifier);
+			if (cachedResult !== undefined) {
+				return cachedResult;
+			}
+			const result = fn(context, identifier);
+			innerSubCache.set(identifier, result);
+			return result;
+		};
+
+		return boundFn;
+	};
+
+	return cachedFn;
+};
+
+/**
+ * Make paths relative.
+ * @param {string} context context for relative path
+ * @param {string} identifier identifier for path
+ * @returns {string} a converted relative path
+ */
+const _makePathsRelative = (context, identifier) =>
+	identifier
+		.split(SEGMENTS_SPLIT_REGEXP)
+		.map((str) => absoluteToRequest(context, str))
+		.join("");
+
+/**
+ * Make paths absolute.
+ * @param {string} context context for relative path
+ * @param {string} identifier identifier for path
+ * @returns {string} a converted relative path
+ */
+const _makePathsAbsolute = (context, identifier) =>
+	identifier
+		.split(SEGMENTS_SPLIT_REGEXP)
+		.map((str) => requestToAbsolute(context, str))
+		.join("");
+
+/**
+ * Returns a new request string avoiding absolute paths when possible.
+ * @param {string} context absolute context path
+ * @param {string} request any request string may containing absolute paths, query string, etc.
+ * @returns {string} a new request string avoiding absolute paths when possible
+ */
+const _contextify = (context, request) =>
+	request
+		.split("!")
+		.map((r) => absoluteToRequest(context, r))
+		.join("!");
+
+const contextify = makeCacheableWithContext(_contextify);
+
+/**
+ * Returns a new request string using absolute paths when possible.
+ * @param {string} context absolute context path
+ * @param {string} request any request string
+ * @returns {string} a new request string using absolute paths when possible
+ */
+const _absolutify = (context, request) =>
+	request
+		.split("!")
+		.map((r) => requestToAbsolute(context, r))
+		.join("!");
+
+const absolutify = makeCacheableWithContext(_absolutify);
+
+const PATH_QUERY_FRAGMENT_REGEXP =
+	/^((?:\0.|[^?#\0])*)(\?(?:\0.|[^#\0])*)?(#.*)?$/;
+const PATH_QUERY_REGEXP = /^((?:\0.|[^?\0])*)(\?.*)?$/;
+const ZERO_ESCAPE_REGEXP = /\0(.)/g;
+
+/** @typedef {{ resource: string, path: string, query: string, fragment: string }} ParsedResource */
+/** @typedef {{ resource: string, path: string, query: string }} ParsedResourceWithoutFragment */
+
+/**
+ * Returns parsed parts.
+ * @param {string} str the path with query and fragment
+ * @returns {ParsedResource} parsed parts
+ */
+const _parseResource = (str) => {
+	const firstEscape = str.indexOf("\0");
+
+	// Handle `\0`
+	if (firstEscape !== -1) {
+		const match =
+			/** @type {[string, string, string | undefined, string | undefined]} */
+			(/** @type {unknown} */ (PATH_QUERY_FRAGMENT_REGEXP.exec(str)));
+
+		return {
+			resource: str,
+			path: match[1].replace(ZERO_ESCAPE_REGEXP, "$1"),
+			query: match[2] ? match[2].replace(ZERO_ESCAPE_REGEXP, "$1") : "",
+			fragment: match[3] || ""
+		};
+	}
+
+	/** @type {ParsedResource} */
+	const result = { resource: str, path: "", query: "", fragment: "" };
+	const queryStart = str.indexOf("?");
+	const fragmentStart = str.indexOf("#");
+
+	if (fragmentStart < 0) {
+		if (queryStart < 0) {
+			result.path = result.resource;
+
+			// No fragment, no query
+			return result;
+		}
+
+		result.path = str.slice(0, queryStart);
+		result.query = str.slice(queryStart);
+
+		// Query, no fragment
+		return result;
+	}
+
+	if (queryStart < 0 || fragmentStart < queryStart) {
+		result.path = str.slice(0, fragmentStart);
+		result.fragment = str.slice(fragmentStart);
+
+		// Fragment, no query
+		return result;
+	}
+
+	result.path = str.slice(0, queryStart);
+	result.query = str.slice(queryStart, fragmentStart);
+	result.fragment = str.slice(fragmentStart);
+
+	// Query and fragment
+	return result;
+};
+
+/**
+ * Parse resource, skips fragment part
+ * @param {string} str the path with query and fragment
+ * @returns {ParsedResourceWithoutFragment} parsed parts
+ */
+const _parseResourceWithoutFragment = (str) => {
+	const firstEscape = str.indexOf("\0");
+
+	// Handle `\0`
+	if (firstEscape !== -1) {
+		const match =
+			/** @type {[string, string, string | undefined]} */
+			(/** @type {unknown} */ (PATH_QUERY_REGEXP.exec(str)));
+
+		return {
+			resource: str,
+			path: match[1].replace(ZERO_ESCAPE_REGEXP, "$1"),
+			query: match[2] ? match[2].replace(ZERO_ESCAPE_REGEXP, "$1") : ""
+		};
+	}
+
+	/** @type {ParsedResourceWithoutFragment} */
+	const result = { resource: str, path: "", query: "" };
+	const queryStart = str.indexOf("?");
+
+	if (queryStart < 0) {
+		result.path = result.resource;
+
+		// No query
+		return result;
+	}
+
+	result.path = str.slice(0, queryStart);
+	result.query = str.slice(queryStart);
+
+	// Query
+	return result;
+};
+
+/**
+ * Returns repeated ../ to leave the directory of the provided filename to be back on output dir.
+ * @param {string} filename the filename which should be undone
+ * @param {string} outputPath the output path that is restored (only relevant when filename contains "..")
+ * @param {boolean} enforceRelative true returns ./ for empty paths
+ * @returns {string} repeated ../ to leave the directory of the provided filename to be back on output dir
+ */
+const getUndoPath = (filename, outputPath, enforceRelative) => {
+	let depth = -1;
+	let append = "";
+	outputPath = outputPath.replace(/[\\/]$/, "");
+	for (const part of filename.split(/[/\\]+/)) {
+		if (part === "..") {
+			if (depth > -1) {
+				depth--;
+			} else {
+				const i = outputPath.lastIndexOf("/");
+				const j = outputPath.lastIndexOf("\\");
+				const pos = i < 0 ? j : j < 0 ? i : Math.max(i, j);
+				if (pos < 0) return `${outputPath}/`;
+				append = `${outputPath.slice(pos + 1)}/${append}`;
+				outputPath = outputPath.slice(0, pos);
+			}
+		} else if (part !== ".") {
+			depth++;
+		}
+	}
+	return depth > 0
+		? `${"../".repeat(depth)}${append}`
+		: enforceRelative
+			? `./${append}`
+			: append;
+};
+
+const HASH_REGEXP = /(?<!\0)#/g;
+
+/**
+ * Escape `#` characters that appear inside a path request's directory portion
+ * with the `\0#` escape recognized by enhanced-resolve, so a project located at
+ * a path like `/home/user/proj#1/` (or `./proj#1/`) resolves correctly. Applies
+ * to absolute paths (Unix or Windows) and relative paths (starting with `./` or
+ * `../`). Only triggers when a query string is present, because that is the case
+ * where the resolver's parseIdentifier fails (without a `?`, the resolver
+ * handles directory `#` via its own fallback). A `#` after the last path
+ * separator is left alone so that explicit fragment requests like
+ * `/abs/path/file.js#fragment` still behave the same. Bare module specifiers
+ * are not touched. Already-escaped `\0#` sequences are preserved so the
+ * explicit opt-out remains stable.
+ * @param {string} request request to potentially escape
+ * @returns {string} request with directory `#` characters escaped
+ */
+const escapeHashInPathRequest = (request) => {
+	if (request.length === 0) return request;
+	const queryStart = request.indexOf("?");
+	if (queryStart < 0) return request;
+	const hashStart = request.indexOf("#");
+	if (hashStart < 0 || hashStart >= queryStart) return request;
+	const c0 = request.charCodeAt(0);
+	const isAbsolute =
+		c0 === 47 /* "/" */ || WINDOWS_ABS_PATH_REGEXP.test(request);
+	let isRelative = false;
+	if (!isAbsolute && c0 === 46 /* "." */) {
+		const c1 = request.charCodeAt(1);
+		if (c1 === 47 || c1 === 92 /* "/" or "\" */) {
+			isRelative = true;
+		} else if (c1 === 46 /* "." */) {
+			const c2 = request.charCodeAt(2);
+			if (c2 === 47 || c2 === 92) isRelative = true;
+		}
+	}
+	if (!isAbsolute && !isRelative) return request;
+	const lastSep = Math.max(
+		request.lastIndexOf("/", queryStart - 1),
+		request.lastIndexOf("\\", queryStart - 1)
+	);
+	if (hashStart >= lastSep) return request;
+	const pathPart = request.slice(0, lastSep);
+	return pathPart.replace(HASH_REGEXP, "\0#") + request.slice(lastSep);
+};
+
+module.exports.absolutify = absolutify;
+module.exports.contextify = contextify;
+module.exports.escapeHashInPathRequest = escapeHashInPathRequest;
+module.exports.getUndoPath = getUndoPath;
+module.exports.makeCacheable = makeCacheable;
+module.exports.makePathsAbsolute = makeCacheableWithContext(_makePathsAbsolute);
+module.exports.makePathsRelative = makeCacheableWithContext(_makePathsRelative);
+module.exports.parseResource = makeCacheable(_parseResource);
+module.exports.parseResourceWithoutFragment = makeCacheable(
+	_parseResourceWithoutFragment
+);
Index: frontend/node_modules/webpack/lib/util/internalSerializables.js
===================================================================
--- frontend/node_modules/webpack/lib/util/internalSerializables.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/internalSerializables.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,238 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+// We need to include a list of requires here
+// to allow webpack to be bundled with only static requires
+// We could use a dynamic require(`../${request}`) but this
+// would include too many modules and not every tool is able
+// to process this
+module.exports = {
+	AsyncDependenciesBlock: () => require("../AsyncDependenciesBlock"),
+	ContextModule: () => require("../ContextModule"),
+	"cache/PackFileCacheStrategy": () =>
+		require("../cache/PackFileCacheStrategy"),
+	"cache/ResolverCachePlugin": () => require("../cache/ResolverCachePlugin"),
+	"container/ContainerEntryDependency": () =>
+		require("../container/ContainerEntryDependency"),
+	"container/ContainerEntryModule": () =>
+		require("../container/ContainerEntryModule"),
+	"container/ContainerExposedDependency": () =>
+		require("../container/ContainerExposedDependency"),
+	"container/FallbackDependency": () =>
+		require("../container/FallbackDependency"),
+	"container/FallbackItemDependency": () =>
+		require("../container/FallbackItemDependency"),
+	"container/FallbackModule": () => require("../container/FallbackModule"),
+	"container/RemoteModule": () => require("../container/RemoteModule"),
+	"container/RemoteToExternalDependency": () =>
+		require("../container/RemoteToExternalDependency"),
+	"dependencies/AMDDefineDependency": () =>
+		require("../dependencies/AMDDefineDependency"),
+	"dependencies/AMDRequireArrayDependency": () =>
+		require("../dependencies/AMDRequireArrayDependency"),
+	"dependencies/AMDRequireContextDependency": () =>
+		require("../dependencies/AMDRequireContextDependency"),
+	"dependencies/AMDRequireDependenciesBlock": () =>
+		require("../dependencies/AMDRequireDependenciesBlock"),
+	"dependencies/AMDRequireDependency": () =>
+		require("../dependencies/AMDRequireDependency"),
+	"dependencies/AMDRequireItemDependency": () =>
+		require("../dependencies/AMDRequireItemDependency"),
+	"dependencies/CachedConstDependency": () =>
+		require("../dependencies/CachedConstDependency"),
+	"dependencies/ExternalModuleDependency": () =>
+		require("../dependencies/ExternalModuleDependency"),
+	"dependencies/ExternalModuleInitFragment": () =>
+		require("../dependencies/ExternalModuleInitFragment"),
+	"dependencies/CreateScriptUrlDependency": () =>
+		require("../dependencies/CreateScriptUrlDependency"),
+	"dependencies/CommonJsRequireContextDependency": () =>
+		require("../dependencies/CommonJsRequireContextDependency"),
+	"dependencies/CommonJsExportRequireDependency": () =>
+		require("../dependencies/CommonJsExportRequireDependency"),
+	"dependencies/CommonJsExportsDependency": () =>
+		require("../dependencies/CommonJsExportsDependency"),
+	"dependencies/CommonJsFullRequireDependency": () =>
+		require("../dependencies/CommonJsFullRequireDependency"),
+	"dependencies/CommonJsRequireDependency": () =>
+		require("../dependencies/CommonJsRequireDependency"),
+	"dependencies/CommonJsSelfReferenceDependency": () =>
+		require("../dependencies/CommonJsSelfReferenceDependency"),
+	"dependencies/ConstDependency": () =>
+		require("../dependencies/ConstDependency"),
+	"dependencies/ContextDependency": () =>
+		require("../dependencies/ContextDependency"),
+	"dependencies/ContextElementDependency": () =>
+		require("../dependencies/ContextElementDependency"),
+	"dependencies/CriticalDependencyWarning": () =>
+		require("../dependencies/CriticalDependencyWarning"),
+	"dependencies/CssImportDependency": () =>
+		require("../dependencies/CssImportDependency"),
+	"dependencies/CssUrlDependency": () =>
+		require("../dependencies/CssUrlDependency"),
+	"dependencies/CssIcssImportDependency": () =>
+		require("../dependencies/CssIcssImportDependency"),
+	"dependencies/CssIcssExportDependency": () =>
+		require("../dependencies/CssIcssExportDependency"),
+	"dependencies/CssIcssSymbolDependency": () =>
+		require("../dependencies/CssIcssSymbolDependency"),
+	"dependencies/DelegatedSourceDependency": () =>
+		require("../dependencies/DelegatedSourceDependency"),
+	"dependencies/DllEntryDependency": () =>
+		require("../dependencies/DllEntryDependency"),
+	"dependencies/EntryDependency": () =>
+		require("../dependencies/EntryDependency"),
+	"dependencies/ExportsInfoDependency": () =>
+		require("../dependencies/ExportsInfoDependency"),
+	"dependencies/HarmonyAcceptDependency": () =>
+		require("../dependencies/HarmonyAcceptDependency"),
+	"dependencies/HarmonyAcceptImportDependency": () =>
+		require("../dependencies/HarmonyAcceptImportDependency"),
+	"dependencies/HarmonyCompatibilityDependency": () =>
+		require("../dependencies/HarmonyCompatibilityDependency"),
+	"dependencies/HarmonyExportExpressionDependency": () =>
+		require("../dependencies/HarmonyExportExpressionDependency"),
+	"dependencies/HarmonyExportHeaderDependency": () =>
+		require("../dependencies/HarmonyExportHeaderDependency"),
+	"dependencies/HarmonyExportImportedSpecifierDependency": () =>
+		require("../dependencies/HarmonyExportImportedSpecifierDependency"),
+	"dependencies/HarmonyExportSpecifierDependency": () =>
+		require("../dependencies/HarmonyExportSpecifierDependency"),
+	"dependencies/HarmonyImportSideEffectDependency": () =>
+		require("../dependencies/HarmonyImportSideEffectDependency"),
+	"dependencies/HarmonyImportSpecifierDependency": () =>
+		require("../dependencies/HarmonyImportSpecifierDependency"),
+	"dependencies/HarmonyEvaluatedImportSpecifierDependency": () =>
+		require("../dependencies/HarmonyEvaluatedImportSpecifierDependency"),
+	"dependencies/HtmlInlineScriptDependency": () =>
+		require("../dependencies/HtmlInlineScriptDependency"),
+	"dependencies/HtmlInlineStyleDependency": () =>
+		require("../dependencies/HtmlInlineStyleDependency"),
+	"dependencies/HtmlScriptSrcDependency": () =>
+		require("../dependencies/HtmlScriptSrcDependency"),
+	"dependencies/HtmlSourceDependency": () =>
+		require("../dependencies/HtmlSourceDependency"),
+	"dependencies/ImportContextDependency": () =>
+		require("../dependencies/ImportContextDependency"),
+	"dependencies/ImportDependency": () =>
+		require("../dependencies/ImportDependency"),
+	"dependencies/ImportEagerDependency": () =>
+		require("../dependencies/ImportEagerDependency"),
+	"dependencies/ImportWeakDependency": () =>
+		require("../dependencies/ImportWeakDependency"),
+	"dependencies/JsonExportsDependency": () =>
+		require("../dependencies/JsonExportsDependency"),
+	"dependencies/LocalModule": () => require("../dependencies/LocalModule"),
+	"dependencies/LocalModuleDependency": () =>
+		require("../dependencies/LocalModuleDependency"),
+	"dependencies/ModuleDecoratorDependency": () =>
+		require("../dependencies/ModuleDecoratorDependency"),
+	"dependencies/ModuleHotAcceptDependency": () =>
+		require("../dependencies/ModuleHotAcceptDependency"),
+	"dependencies/ModuleHotDeclineDependency": () =>
+		require("../dependencies/ModuleHotDeclineDependency"),
+	"dependencies/ImportMetaHotAcceptDependency": () =>
+		require("../dependencies/ImportMetaHotAcceptDependency"),
+	"dependencies/ImportMetaHotDeclineDependency": () =>
+		require("../dependencies/ImportMetaHotDeclineDependency"),
+	"dependencies/ImportMetaContextDependency": () =>
+		require("../dependencies/ImportMetaContextDependency"),
+	"dependencies/ProvidedDependency": () =>
+		require("../dependencies/ProvidedDependency"),
+	"dependencies/PureExpressionDependency": () =>
+		require("../dependencies/PureExpressionDependency"),
+	"dependencies/RequireContextDependency": () =>
+		require("../dependencies/RequireContextDependency"),
+	"dependencies/RequireEnsureDependenciesBlock": () =>
+		require("../dependencies/RequireEnsureDependenciesBlock"),
+	"dependencies/RequireEnsureDependency": () =>
+		require("../dependencies/RequireEnsureDependency"),
+	"dependencies/RequireEnsureItemDependency": () =>
+		require("../dependencies/RequireEnsureItemDependency"),
+	"dependencies/RequireHeaderDependency": () =>
+		require("../dependencies/RequireHeaderDependency"),
+	"dependencies/RequireIncludeDependency": () =>
+		require("../dependencies/RequireIncludeDependency"),
+	"dependencies/RequireIncludeDependencyParserPlugin": () =>
+		require("../dependencies/RequireIncludeDependencyParserPlugin"),
+	"dependencies/RequireResolveContextDependency": () =>
+		require("../dependencies/RequireResolveContextDependency"),
+	"dependencies/RequireResolveDependency": () =>
+		require("../dependencies/RequireResolveDependency"),
+	"dependencies/RequireResolveHeaderDependency": () =>
+		require("../dependencies/RequireResolveHeaderDependency"),
+	"dependencies/RuntimeRequirementsDependency": () =>
+		require("../dependencies/RuntimeRequirementsDependency"),
+	"dependencies/StaticExportsDependency": () =>
+		require("../dependencies/StaticExportsDependency"),
+	"dependencies/SystemPlugin": () => require("../dependencies/SystemPlugin"),
+	"dependencies/UnsupportedDependency": () =>
+		require("../dependencies/UnsupportedDependency"),
+	"dependencies/URLDependency": () => require("../dependencies/URLDependency"),
+	"dependencies/URLContextDependency": () =>
+		require("../dependencies/URLContextDependency"),
+	"dependencies/WebAssemblyExportImportedDependency": () =>
+		require("../dependencies/WebAssemblyExportImportedDependency"),
+	"dependencies/WebAssemblyImportDependency": () =>
+		require("../dependencies/WebAssemblyImportDependency"),
+	"dependencies/WebpackIsIncludedDependency": () =>
+		require("../dependencies/WebpackIsIncludedDependency"),
+	"dependencies/WorkerDependency": () =>
+		require("../dependencies/WorkerDependency"),
+	"json/JsonData": () => require("../json/JsonData"),
+	"optimize/ConcatenatedModule": () =>
+		require("../optimize/ConcatenatedModule"),
+
+	DependenciesBlock: () => require("../DependenciesBlock"),
+	ExternalModule: () => require("../ExternalModule"),
+	FileSystemInfo: () => require("../FileSystemInfo"),
+	InitFragment: () => require("../InitFragment"),
+	ModuleGraph: () => require("../ModuleGraph"),
+	NormalModule: () => require("../NormalModule"),
+	CssModule: () => require("../css/CssModule"),
+	RawDataUrlModule: () => require("../asset/RawDataUrlModule"),
+	RawModule: () => require("../RawModule"),
+	"sharing/ConsumeSharedModule": () =>
+		require("../sharing/ConsumeSharedModule"),
+	"sharing/ConsumeSharedFallbackDependency": () =>
+		require("../sharing/ConsumeSharedFallbackDependency"),
+	"sharing/ProvideSharedModule": () =>
+		require("../sharing/ProvideSharedModule"),
+	"sharing/ProvideSharedDependency": () =>
+		require("../sharing/ProvideSharedDependency"),
+	"sharing/ProvideForSharedDependency": () =>
+		require("../sharing/ProvideForSharedDependency"),
+
+	"errors/WebpackError": () => require("../errors/WebpackError"),
+	"errors/InvalidDependenciesModuleWarning": () =>
+		require("../errors/InvalidDependenciesModuleWarning"),
+	"errors/Module": () => require("../Module"),
+	"errors/ModuleParseError": () => require("../errors/ModuleParseError"),
+	"errors/ModuleWarning": () => require("../errors/ModuleWarning"),
+	"errors/ModuleBuildError": () => require("../errors/ModuleBuildError"),
+	"errors/ModuleDependencyWarning": () =>
+		require("../errors/ModuleDependencyWarning"),
+	"errors/ModuleError": () => require("../errors/ModuleError"),
+	"errors/UnhandledSchemeError": () =>
+		require("../errors/UnhandledSchemeError"),
+	"errors/UnsupportedFeatureWarning": () =>
+		require("../errors/UnsupportedFeatureWarning"),
+	"errors/EnvironmentNotSupportAsyncWarning": () =>
+		require("../errors/EnvironmentNotSupportAsyncWarning"),
+	"errors/CommentCompilationWarning": () =>
+		require("../errors/CommentCompilationWarning"),
+	"errors/NodeStuffInWebError": () => require("../errors/NodeStuffInWebError"),
+	"errors/JSONParseError": () => require("../errors/JSONParseError"),
+
+	"dll/DelegatedModule": () => require("../dll/DelegatedModule"),
+	"dll/DllModule": () => require("../dll/DllModule"),
+
+	"util/LazySet": () => require("../util/LazySet"),
+	"util/registerExternalSerializer": () => {
+		// already registered
+	}
+};
Index: frontend/node_modules/webpack/lib/util/magicComment.js
===================================================================
--- frontend/node_modules/webpack/lib/util/magicComment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/magicComment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,29 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const memoize = require("./memoize");
+
+const getVm = memoize(() => require("vm"));
+
+module.exports.CompilerHintNotationRegExp = Object.freeze({
+	Pure: /^\s*(?:#|@)__PURE__\s*$/,
+	NoSideEffects: /^\s*[#@]__NO_SIDE_EFFECTS__\s*$/
+});
+
+/**
+ * regexp to match at least one "magic comment"
+ * @returns {import("vm").Context} magic comment context
+ */
+module.exports.createMagicCommentContext = () =>
+	getVm().createContext(undefined, {
+		name: "Webpack Magic Comment Parser",
+		codeGeneration: { strings: false, wasm: false }
+	});
+
+module.exports.webpackCommentRegExp = new RegExp(
+	/(^|\W)webpack[A-Z][A-Za-z]+:/
+);
Index: frontend/node_modules/webpack/lib/util/makeSerializable.js
===================================================================
--- frontend/node_modules/webpack/lib/util/makeSerializable.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/makeSerializable.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,66 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { register } = require("./serialization");
+
+/** @typedef {import("../serialization/ObjectMiddleware").Constructor} Constructor */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+/** @typedef {{ serialize: (context: ObjectSerializerContext) => void, deserialize: (context: ObjectDeserializerContext) => void }} SerializableClass */
+/**
+ * Defines the serializable class constructor type used by this module.
+ * @template {SerializableClass} T
+ * @typedef {(new (...params: EXPECTED_ANY[]) => T) & { deserialize?: (context: ObjectDeserializerContext) => T }} SerializableClassConstructor
+ */
+
+/**
+ * Represents ClassSerializer.
+ * @template {SerializableClass} T
+ */
+class ClassSerializer {
+	/**
+	 * Creates an instance of ClassSerializer.
+	 * @param {SerializableClassConstructor<T>} Constructor constructor
+	 */
+	constructor(Constructor) {
+		this.Constructor = Constructor;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {T} obj obj
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(obj, context) {
+		obj.serialize(context);
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {T} obj
+	 */
+	deserialize(context) {
+		if (typeof this.Constructor.deserialize === "function") {
+			return this.Constructor.deserialize(context);
+		}
+		const obj = new this.Constructor();
+		obj.deserialize(context);
+		return obj;
+	}
+}
+
+/**
+ * Processes the provided constructor.
+ * @template {Constructor} T
+ * @param {T} Constructor the constructor
+ * @param {string} request the request which will be required when deserializing
+ * @param {string | null=} name the name to make multiple serializer unique when sharing a request
+ */
+module.exports = (Constructor, request, name = null) => {
+	register(Constructor, request, name, new ClassSerializer(Constructor));
+};
Index: frontend/node_modules/webpack/lib/util/memoize.js
===================================================================
--- frontend/node_modules/webpack/lib/util/memoize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/memoize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/**
+ * Defines the function returning type used by this module.
+ * @template T
+ * @typedef {() => T} FunctionReturning
+ */
+
+/**
+ * Returns new function.
+ * @template T
+ * @param {FunctionReturning<T>} fn memorized function
+ * @returns {FunctionReturning<T>} new function
+ */
+const memoize = (fn) => {
+	let cache = false;
+	/** @type {T | undefined} */
+	let result;
+	return () => {
+		if (cache) {
+			return /** @type {T} */ (result);
+		}
+
+		result = fn();
+		cache = true;
+		// Allow to clean up memory for fn
+		// and all dependent resources
+		/** @type {FunctionReturning<T> | undefined} */
+		(fn) = undefined;
+		return /** @type {T} */ (result);
+	};
+};
+
+module.exports = memoize;
Index: frontend/node_modules/webpack/lib/util/mimeTypes.js
===================================================================
--- frontend/node_modules/webpack/lib/util/mimeTypes.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/mimeTypes.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,176 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { extname } = require("path");
+const db = require("mime-db");
+
+/**
+ * RegExp to match type in RFC 6838
+ *
+ * type-name = restricted-name
+ * subtype-name = restricted-name
+ * restricted-name = restricted-name-first *126restricted-name-chars
+ * restricted-name-first  = ALPHA / DIGIT
+ * restricted-name-chars  = ALPHA / DIGIT / "!" / "#" / "$" / "&" / "-" / "^" / "_"
+ * restricted-name-chars =/ "." ; Characters before first dot always specify a facet name
+ * restricted-name-chars =/ "+" ; Characters after last plus always specify a structured syntax suffix
+ * ALPHA =  %x41-5A / %x61-7A   ; A-Z / a-z
+ * DIGIT =  %x30-39             ; 0-9
+ */
+const TYPE_REGEXP =
+	/^ *(([A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126})\/([A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126})) *(?:;.*)?$/;
+const extensions = Object.create(null);
+const types = Object.create(null);
+
+// Score RFC facets (see https://tools.ietf.org/html/rfc6838#section-3)
+
+/** @type {Record<string, number>} */
+const FACET_SCORES = {
+	"prs.": 100,
+	"x-": 200,
+	"x.": 300,
+	"vnd.": 400,
+	default: 900
+};
+
+/** @typedef {"nginx" | "apache" | "iana" | "default"} SourceScore */
+
+// Score mime source (Logic originally from `jshttp/mime-types` module)
+/** @type {Record<SourceScore, number>} */
+const SOURCE_SCORES = {
+	nginx: 10,
+	apache: 20,
+	iana: 40,
+	default: 30
+};
+
+/** @type {Record<string, number>} */
+const TYPE_SCORES = {
+	// prefer application/xml over text/xml
+	// prefer application/rtf over text/rtf
+	application: 1,
+
+	// prefer font/woff over application/font-woff
+	font: 2,
+
+	// prefer video/mp4 over audio/mp4 over application/mp4
+	// See https://www.rfc-editor.org/rfc/rfc4337.html#section-2
+	audio: 2,
+	video: 3,
+
+	default: 0
+};
+
+/**
+ * @param {string} mimeType mime type
+ * @param {SourceScore=} source source
+ * @returns {number} min score
+ */
+function mimeScore(mimeType, source = "default") {
+	if (mimeType === "application/octet-stream") {
+		return 0;
+	}
+
+	const [type, subtype] = mimeType.split("/");
+
+	const facet = subtype.replace(/(\.|x-).*/, "$1");
+
+	const facetScore = FACET_SCORES[facet] || FACET_SCORES.default;
+	const sourceScore = SOURCE_SCORES[source] || SOURCE_SCORES.default;
+	const typeScore = TYPE_SCORES[type] || TYPE_SCORES.default;
+
+	// All else being equal prefer shorter types
+	const lengthScore = 1 - mimeType.length / 100;
+
+	return facetScore + sourceScore + typeScore + lengthScore;
+}
+
+/**
+ * @param {string} ext extension
+ * @param {string} type0 the first type
+ * @param {string} type1 the second type
+ * @returns {string} preferred type
+ */
+const preferredType = (ext, type0, type1) => {
+	const score0 = type0 ? mimeScore(type0, db[type0].source) : 0;
+	const score1 = type1 ? mimeScore(type1, db[type1].source) : 0;
+
+	return score0 > score1 ? type0 : type1;
+};
+
+/**
+ * @param {Record<string, readonly string[]>} extensions extensions
+ * @param {Record<string, string>} types types
+ */
+const populate = (extensions, types) => {
+	for (const type of Object.keys(db)) {
+		const mime = db[type];
+		const foundExtensions = mime.extensions;
+
+		if (!foundExtensions || foundExtensions.length === 0) {
+			continue;
+		}
+
+		// mime -> extensions
+		extensions[type] = foundExtensions;
+
+		// extension -> mime
+		for (let i = 0; i < foundExtensions.length; i++) {
+			const extension = foundExtensions[i];
+
+			types[extension] = preferredType(extension, types[extension], type);
+		}
+	}
+};
+
+populate(extensions, types);
+
+/**
+ * Get the default extension for a MIME type.
+ * @param {string} type type
+ * @returns {undefined | string} resolve extension
+ */
+const extension = (type) => {
+	if (!type) {
+		return;
+	}
+
+	const match = TYPE_REGEXP.exec(type);
+
+	if (!match) {
+		return;
+	}
+
+	const possibleExtensions = extensions[match[1].toLowerCase()];
+
+	if (!possibleExtensions || possibleExtensions.length === 0) {
+		return;
+	}
+
+	return possibleExtensions[0];
+};
+
+/**
+ * Lookup the MIME type for a file path/extension.
+ * @param {string} path path
+ * @returns {undefined | string} resolved MIME type
+ */
+const lookup = (path) => {
+	if (!path) {
+		return;
+	}
+
+	// get the extension ("ext" or ".ext" or full path)
+	const extension = extname(`x.${path}`).toLowerCase().slice(1);
+
+	if (!extension) {
+		return;
+	}
+
+	return types[extension];
+};
+
+module.exports = { extension, lookup };
Index: frontend/node_modules/webpack/lib/util/nonNumericOnlyHash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/nonNumericOnlyHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/nonNumericOnlyHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const A_CODE = "a".charCodeAt(0);
+
+/**
+ * Returns hash that has at least one non numeric char.
+ * @param {string} hash hash
+ * @param {number} hashLength hash length
+ * @returns {string} returns hash that has at least one non numeric char
+ */
+module.exports = (hash, hashLength) => {
+	if (hashLength < 1) return "";
+	const slice = hash.slice(0, hashLength);
+	if (/[^\d]/.test(slice)) return slice;
+	return `${String.fromCharCode(
+		A_CODE + (Number.parseInt(hash[0], 10) % 6)
+	)}${slice.slice(1)}`;
+};
Index: frontend/node_modules/webpack/lib/util/numberHash.js
===================================================================
--- frontend/node_modules/webpack/lib/util/numberHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/numberHash.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,95 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Threshold for switching from 32-bit to 64-bit hashing. This is selected to ensure that the bias towards lower modulo results when using 32-bit hashing is <0.5%.
+ * @type {number}
+ */
+const FNV_64_THRESHOLD = 1 << 24;
+
+/**
+ * The FNV-1a offset basis for 32-bit hash values.
+ * @type {number}
+ */
+const FNV_OFFSET_32 = 2166136261;
+/**
+ * The FNV-1a prime for 32-bit hash values.
+ * @type {number}
+ */
+const FNV_PRIME_32 = 16777619;
+/**
+ * The mask for a positive 32-bit signed integer.
+ * @type {number}
+ */
+const MASK_31 = 0x7fffffff;
+
+/**
+ * The FNV-1a offset basis for 64-bit hash values.
+ * @type {bigint}
+ */
+const FNV_OFFSET_64 = BigInt("0xCBF29CE484222325");
+/**
+ * The FNV-1a prime for 64-bit hash values.
+ * @type {bigint}
+ */
+const FNV_PRIME_64 = BigInt("0x100000001B3");
+
+/**
+ * Computes a 32-bit FNV-1a hash value for the given string.
+ * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
+ * @param {string} str The input string to hash
+ * @returns {number} - The computed hash value.
+ */
+function fnv1a32(str) {
+	let hash = FNV_OFFSET_32;
+	for (let i = 0, len = str.length; i < len; i++) {
+		hash ^= str.charCodeAt(i);
+		// Use Math.imul to do c-style 32-bit multiplication and keep only the 32 least significant bits
+		hash = Math.imul(hash, FNV_PRIME_32);
+	}
+	// Force the result to be positive
+	return hash & MASK_31;
+}
+
+/**
+ * Computes a 64-bit FNV-1a hash value for the given string.
+ * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
+ * @param {string} str The input string to hash
+ * @returns {bigint} - The computed hash value.
+ */
+function fnv1a64(str) {
+	let hash = FNV_OFFSET_64;
+	for (let i = 0, len = str.length; i < len; i++) {
+		hash ^= BigInt(str.charCodeAt(i));
+		hash = BigInt.asUintN(64, hash * FNV_PRIME_64);
+	}
+	return hash;
+}
+
+/**
+ * Computes a hash value for the given string and range. This hashing algorithm is a modified
+ * version of the [FNV-1a algorithm](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function).
+ * It is optimized for speed and does **not** generate a cryptographic hash value.
+ *
+ * We use `numberHash` in `lib/ids/IdHelpers.js` to generate hash values for the module identifier. The generated
+ * hash is used as a prefix for the module id's to avoid collisions with other modules.
+ * @param {string} str The input string to hash.
+ * @param {number} range The range of the hash value (0 to range-1).
+ * @returns {number} - The computed hash value.
+ * @example
+ * ```js
+ * const numberHash = require("webpack/lib/util/numberHash");
+ * numberHash("hello", 1000); // 73
+ * numberHash("hello world"); // 72
+ * ```
+ */
+module.exports = (str, range) => {
+	if (range < FNV_64_THRESHOLD) {
+		return fnv1a32(str) % range;
+	}
+	return Number(fnv1a64(str) % BigInt(range));
+};
Index: frontend/node_modules/webpack/lib/util/objectToMap.js
===================================================================
--- frontend/node_modules/webpack/lib/util/objectToMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/objectToMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,15 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/**
+ * Convert an object into an ES6 map
+ * @template {object} T
+ * @param {T} obj any object type that works with Object.entries()
+ * @returns {Map<string, T[keyof T]>} an ES6 Map of KV pairs
+ */
+module.exports = function objectToMap(obj) {
+	return new Map(Object.entries(obj));
+};
Index: frontend/node_modules/webpack/lib/util/parseJson.js
===================================================================
--- frontend/node_modules/webpack/lib/util/parseJson.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/parseJson.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const JSONParseError = require("../errors/JSONParseError");
+
+/** @typedef {import("../util/fs").JsonValue} JsonValue */
+
+// Inspired by https://github.com/npm/json-parse-even-better-errors
+
+// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
+// because the buffer-to-string conversion in `fs.readFileSync()`
+// translates it to FEFF, the UTF-16 BOM.
+/**
+ * @param {string | Buffer} txt text
+ * @returns {string} text without BOM
+ */
+const stripBOM = (txt) => String(txt).replace(/^\uFEFF/, "");
+
+/**
+ * @template [R=JsonValue]
+ * @callback ParseJsonFn
+ * @param {string} raw text
+ * @param {(this: EXPECTED_ANY, key: string, value: EXPECTED_ANY) => EXPECTED_ANY=} reviver reviver
+ * @returns {R} parsed JSON
+ */
+
+/** @type {ParseJsonFn} */
+const parseJson = (raw, reviver) => {
+	const txt = stripBOM(raw);
+
+	try {
+		return JSON.parse(txt, reviver);
+	} catch (err) {
+		throw new JSONParseError(/** @type {Error} */ (err), raw, txt);
+	}
+};
+
+module.exports = parseJson;
Index: frontend/node_modules/webpack/lib/util/processAsyncTree.js
===================================================================
--- frontend/node_modules/webpack/lib/util/processAsyncTree.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/processAsyncTree.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,76 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Walks a dynamically expanding async work tree with bounded concurrency.
+ * Each processed item may enqueue more items through `push`, allowing callers
+ * to model breadth-first or depth-first discovery without managing the queue
+ * themselves.
+ * @template T
+ * @template {Error} E
+ * @param {Iterable<T>} items initial items
+ * @param {number} concurrency number of items running in parallel
+ * @param {(item: T, push: (item: T) => void, callback: (err?: E) => void) => void} processor worker which pushes more items
+ * @param {(err?: E) => void} callback all items processed
+ * @returns {void}
+ */
+const processAsyncTree = (items, concurrency, processor, callback) => {
+	const queue = [...items];
+	if (queue.length === 0) return callback();
+	let processing = 0;
+	let finished = false;
+	let processScheduled = true;
+
+	/**
+	 * Enqueues a newly discovered item and schedules queue processing when the
+	 * current concurrency budget allows more work to start.
+	 * @param {T} item item
+	 */
+	const push = (item) => {
+		queue.push(item);
+		if (!processScheduled && processing < concurrency) {
+			processScheduled = true;
+			process.nextTick(processQueue);
+		}
+	};
+
+	/**
+	 * Handles completion of a single processor call, propagating the first
+	 * error and scheduling more queued work when possible.
+	 * @param {E | null | undefined} err error
+	 */
+	const processorCallback = (err) => {
+		processing--;
+		if (err && !finished) {
+			finished = true;
+			callback(err);
+			return;
+		}
+		if (!processScheduled) {
+			processScheduled = true;
+			process.nextTick(processQueue);
+		}
+	};
+
+	const processQueue = () => {
+		if (finished) return;
+		while (processing < concurrency && queue.length > 0) {
+			processing++;
+			const item = /** @type {T} */ (queue.pop());
+			processor(item, push, processorCallback);
+		}
+		processScheduled = false;
+		if (queue.length === 0 && processing === 0 && !finished) {
+			finished = true;
+			callback();
+		}
+	};
+
+	processQueue();
+};
+
+module.exports = processAsyncTree;
Index: frontend/node_modules/webpack/lib/util/property.js
===================================================================
--- frontend/node_modules/webpack/lib/util/property.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/property.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,102 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const SAFE_IDENTIFIER = /^[_a-z$][_a-z$0-9]*$/i;
+const RESERVED_IDENTIFIER = new Set([
+	"break",
+	"case",
+	"catch",
+	"class",
+	"const",
+	"continue",
+	"debugger",
+	"default",
+	"delete",
+	"do",
+	"else",
+	"export",
+	"extends",
+	"finally",
+	"for",
+	"function",
+	"if",
+	"import",
+	"in",
+	"instanceof",
+	"new",
+	"return",
+	"super",
+	"switch",
+	"this",
+	"throw",
+	"try",
+	"typeof",
+	"var",
+	"void",
+	"while",
+	"with",
+	"enum",
+	// strict mode
+	"implements",
+	"interface",
+	"let",
+	"package",
+	"private",
+	"protected",
+	"public",
+	"static",
+	"yield",
+	// module code
+	"await",
+	// skip future reserved keywords defined under ES1 till ES3
+	// additional
+	"null",
+	"true",
+	"false"
+]);
+
+/**
+ * @summary Returns a valid JS property name for the given property.
+ * Certain strings like "default", "null", and names with whitespace are not
+ * valid JS property names, so they are returned as strings.
+ * @param {string} prop property name to analyze
+ * @returns {string} valid JS property name
+ */
+const propertyName = (prop) => {
+	if (SAFE_IDENTIFIER.test(prop) && !RESERVED_IDENTIFIER.has(prop)) {
+		return prop;
+	}
+	return JSON.stringify(prop);
+};
+
+/**
+ * Returns chain of property accesses.
+ * @param {ArrayLike<string>} properties properties
+ * @param {number} start start index
+ * @returns {string} chain of property accesses
+ */
+const propertyAccess = (properties, start = 0) => {
+	let str = "";
+	for (let i = start; i < properties.length; i++) {
+		const p = properties[i];
+		if (`${Number(p)}` === p) {
+			str += `[${p}]`;
+		} else if (SAFE_IDENTIFIER.test(p) && !RESERVED_IDENTIFIER.has(p)) {
+			str += `.${p}`;
+		} else {
+			str += `[${JSON.stringify(p)}]`;
+		}
+	}
+	return str;
+};
+
+module.exports = {
+	RESERVED_IDENTIFIER,
+	SAFE_IDENTIFIER,
+	propertyAccess,
+	propertyName
+};
Index: frontend/node_modules/webpack/lib/util/registerExternalSerializer.js
===================================================================
--- frontend/node_modules/webpack/lib/util/registerExternalSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/registerExternalSerializer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,354 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Position = require("acorn").Position;
+const SourceLocation = require("acorn").SourceLocation;
+const ValidationError = require("schema-utils").ValidationError;
+const {
+	CachedSource,
+	ConcatSource,
+	OriginalSource,
+	PrefixSource,
+	RawSource,
+	ReplaceSource,
+	SourceMapSource
+} = require("webpack-sources");
+const { register } = require("./serialization");
+
+/** @typedef {import("acorn").Position} Position */
+/** @typedef {import("../Dependency").RealDependencyLocation} RealDependencyLocation */
+/** @typedef {import("../Dependency").SourcePosition} SourcePosition */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+const CURRENT_MODULE = "webpack/lib/util/registerExternalSerializer";
+
+register(
+	CachedSource,
+	CURRENT_MODULE,
+	"webpack-sources/CachedSource",
+	new (class CachedSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {CachedSource} source the cached source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write, writeLazy }) {
+			if (writeLazy) {
+				writeLazy(source.originalLazy());
+			} else {
+				write(source.original());
+			}
+			write(source.getCachedData());
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {CachedSource} cached source
+		 */
+		deserialize({ read }) {
+			const source = read();
+			const cachedData = read();
+			return new CachedSource(source, cachedData);
+		}
+	})()
+);
+
+register(
+	RawSource,
+	CURRENT_MODULE,
+	"webpack-sources/RawSource",
+	new (class RawSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {RawSource} source the raw source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write }) {
+			write(source.buffer());
+			write(!source.isBuffer());
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {RawSource} raw source
+		 */
+		deserialize({ read }) {
+			const source = read();
+			const convertToString = read();
+			return new RawSource(source, convertToString);
+		}
+	})()
+);
+
+register(
+	ConcatSource,
+	CURRENT_MODULE,
+	"webpack-sources/ConcatSource",
+	new (class ConcatSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {ConcatSource} source the concat source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write }) {
+			write(source.getChildren());
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {ConcatSource} concat source
+		 */
+		deserialize({ read }) {
+			const source = new ConcatSource();
+			source.addAllSkipOptimizing(read());
+			return source;
+		}
+	})()
+);
+
+register(
+	PrefixSource,
+	CURRENT_MODULE,
+	"webpack-sources/PrefixSource",
+	new (class PrefixSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {PrefixSource} source the prefix source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write }) {
+			write(source.getPrefix());
+			write(source.original());
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {PrefixSource} prefix source
+		 */
+		deserialize({ read }) {
+			return new PrefixSource(read(), read());
+		}
+	})()
+);
+
+register(
+	ReplaceSource,
+	CURRENT_MODULE,
+	"webpack-sources/ReplaceSource",
+	new (class ReplaceSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {ReplaceSource} source the replace source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write }) {
+			write(source.original());
+			write(source.getName());
+			const replacements = source.getReplacements();
+			write(replacements.length);
+			for (const repl of replacements) {
+				write(repl.start);
+				write(repl.end);
+			}
+			for (const repl of replacements) {
+				write(repl.content);
+				write(repl.name);
+			}
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {ReplaceSource} replace source
+		 */
+		deserialize({ read }) {
+			const source = new ReplaceSource(read(), read());
+			const len = read();
+			/** @type {number[]} */
+			const startEndBuffer = [];
+			for (let i = 0; i < len; i++) {
+				startEndBuffer.push(read(), read());
+			}
+			let j = 0;
+			for (let i = 0; i < len; i++) {
+				source.replace(
+					startEndBuffer[j++],
+					startEndBuffer[j++],
+					read(),
+					read()
+				);
+			}
+			return source;
+		}
+	})()
+);
+
+register(
+	OriginalSource,
+	CURRENT_MODULE,
+	"webpack-sources/OriginalSource",
+	new (class OriginalSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {OriginalSource} source the original source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write }) {
+			write(source.buffer());
+			write(source.getName());
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {OriginalSource} original source
+		 */
+		deserialize({ read }) {
+			const buffer = read();
+			const name = read();
+			return new OriginalSource(buffer, name);
+		}
+	})()
+);
+
+register(
+	SourceLocation,
+	CURRENT_MODULE,
+	"acorn/SourceLocation",
+	new (class SourceLocationSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {SourceLocation} loc the location to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(loc, { write }) {
+			write(loc.start.line);
+			write(loc.start.column);
+			write(loc.end.line);
+			write(loc.end.column);
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {RealDependencyLocation} location
+		 */
+		deserialize({ read }) {
+			return {
+				start: {
+					line: read(),
+					column: read()
+				},
+				end: {
+					line: read(),
+					column: read()
+				}
+			};
+		}
+	})()
+);
+
+register(
+	Position,
+	CURRENT_MODULE,
+	"acorn/Position",
+	new (class PositionSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {Position} pos the position to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(pos, { write }) {
+			write(pos.line);
+			write(pos.column);
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {SourcePosition} position
+		 */
+		deserialize({ read }) {
+			return {
+				line: read(),
+				column: read()
+			};
+		}
+	})()
+);
+
+register(
+	SourceMapSource,
+	CURRENT_MODULE,
+	"webpack-sources/SourceMapSource",
+	new (class SourceMapSourceSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {SourceMapSource} source the source map source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(source, { write }) {
+			write(source.getArgsAsBuffers());
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {SourceMapSource} source source map source
+		 */
+		deserialize({ read }) {
+			// @ts-expect-error
+			return new SourceMapSource(...read());
+		}
+	})()
+);
+
+register(
+	ValidationError,
+	CURRENT_MODULE,
+	"schema-utils/ValidationError",
+	new (class ValidationErrorSerializer {
+		/**
+		 * Serializes this instance into the provided serializer context.
+		 * @param {ValidationError} error the source map source to be serialized
+		 * @param {ObjectSerializerContext} context context
+		 * @returns {void}
+		 */
+		serialize(error, { write }) {
+			write(error.errors);
+			write(error.schema);
+			write({
+				name: error.headerName,
+				baseDataPath: error.baseDataPath,
+				postFormatter: error.postFormatter
+			});
+		}
+
+		/**
+		 * Restores this instance from the provided deserializer context.
+		 * @param {ObjectDeserializerContext} context context
+		 * @returns {ValidationError} error
+		 */
+		deserialize({ read }) {
+			return new ValidationError(read(), read(), read());
+		}
+	})()
+);
Index: frontend/node_modules/webpack/lib/util/removeBOM.js
===================================================================
--- frontend/node_modules/webpack/lib/util/removeBOM.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/removeBOM.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+/**
+ * Returns result without BOM.
+ * @param {string | Buffer} strOrBuffer string or buffer
+ * @returns {string | Buffer} result without BOM
+ */
+module.exports = (strOrBuffer) => {
+	if (typeof strOrBuffer === "string" && strOrBuffer.charCodeAt(0) === 0xfeff) {
+		return strOrBuffer.slice(1);
+	} else if (
+		Buffer.isBuffer(strOrBuffer) &&
+		strOrBuffer[0] === 0xef &&
+		strOrBuffer[1] === 0xbb &&
+		strOrBuffer[2] === 0xbf
+	) {
+		return strOrBuffer.subarray(3);
+	}
+
+	return strOrBuffer;
+};
Index: frontend/node_modules/webpack/lib/util/runtime.js
===================================================================
--- frontend/node_modules/webpack/lib/util/runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/runtime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,749 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const SortableSet = require("./SortableSet");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
+
+/** @typedef {SortableSet<string>} RuntimeSpecSortableSet */
+/** @typedef {string | RuntimeSpecSortableSet | undefined} RuntimeSpec */
+/** @typedef {RuntimeSpec | boolean} RuntimeCondition */
+
+/**
+ * Gets entry runtime.
+ * @param {Compilation} compilation the compilation
+ * @param {string} name name of the entry
+ * @param {EntryOptions=} options optionally already received entry options
+ * @returns {RuntimeSpec} runtime
+ */
+const getEntryRuntime = (compilation, name, options) => {
+	/** @type {EntryOptions["dependOn"]} */
+	let dependOn;
+	/** @type {EntryOptions["runtime"]} */
+	let runtime;
+	if (options) {
+		({ dependOn, runtime } = options);
+	} else {
+		const entry = compilation.entries.get(name);
+		if (!entry) return name;
+		({ dependOn, runtime } = entry.options);
+	}
+	if (dependOn) {
+		/** @type {RuntimeSpec} */
+		let result;
+		const queue = new Set(dependOn);
+		for (const name of queue) {
+			const dep = compilation.entries.get(name);
+			if (!dep) continue;
+			const { dependOn, runtime } = dep.options;
+			if (dependOn) {
+				for (const name of dependOn) {
+					queue.add(name);
+				}
+			} else {
+				result = mergeRuntimeOwned(result, runtime || name);
+			}
+		}
+		return result || name;
+	}
+	return runtime || name;
+};
+
+/**
+ * Processes the provided runtime.
+ * @param {RuntimeSpec} runtime runtime
+ * @param {(runtime: string | undefined) => void} fn functor
+ * @param {boolean} deterministicOrder enforce a deterministic order
+ * @returns {void}
+ */
+const forEachRuntime = (runtime, fn, deterministicOrder = false) => {
+	if (runtime === undefined) {
+		fn(undefined);
+	} else if (typeof runtime === "string") {
+		fn(runtime);
+	} else {
+		if (deterministicOrder) runtime.sort();
+		for (const r of runtime) {
+			fn(r);
+		}
+	}
+};
+
+/**
+ * Returns runtime key.
+ * @template T
+ * @param {Exclude<RuntimeSpec, undefined | string>} set set
+ * @returns {string} runtime key
+ */
+const getRuntimesKey = (set) => {
+	set.sort();
+	return [...set].join("\n");
+};
+
+/**
+ * Returns key of runtimes.
+ * @param {RuntimeSpec} runtime runtime(s)
+ * @returns {string} key of runtimes
+ */
+const getRuntimeKey = (runtime) => {
+	if (runtime === undefined) return "*";
+	if (typeof runtime === "string") return runtime;
+	return runtime.getFromUnorderedCache(getRuntimesKey);
+};
+
+/**
+ * Returns runtime(s).
+ * @param {string} key key of runtimes
+ * @returns {RuntimeSpec} runtime(s)
+ */
+const keyToRuntime = (key) => {
+	if (key === "*") return;
+	const items = key.split("\n");
+	if (items.length === 1) return items[0];
+	return new SortableSet(items);
+};
+
+/**
+ * Gets runtimes string.
+ * @template T
+ * @param {Exclude<RuntimeSpec, undefined | string>} set set
+ * @returns {string} runtime string
+ */
+const getRuntimesString = (set) => {
+	set.sort();
+	return [...set].join("+");
+};
+
+/**
+ * Returns readable version.
+ * @param {RuntimeSpec} runtime runtime(s)
+ * @returns {string} readable version
+ */
+const runtimeToString = (runtime) => {
+	if (runtime === undefined) return "*";
+	if (typeof runtime === "string") return runtime;
+	return runtime.getFromUnorderedCache(getRuntimesString);
+};
+
+/**
+ * Runtime condition to string.
+ * @param {RuntimeCondition} runtimeCondition runtime condition
+ * @returns {string} readable version
+ */
+const runtimeConditionToString = (runtimeCondition) => {
+	if (runtimeCondition === true) return "true";
+	if (runtimeCondition === false) return "false";
+	return runtimeToString(runtimeCondition);
+};
+
+/**
+ * Returns true, when they are equal.
+ * @param {RuntimeSpec} a first
+ * @param {RuntimeSpec} b second
+ * @returns {boolean} true, when they are equal
+ */
+const runtimeEqual = (a, b) => {
+	if (a === b) {
+		return true;
+	} else if (
+		a === undefined ||
+		b === undefined ||
+		typeof a === "string" ||
+		typeof b === "string"
+	) {
+		return false;
+	} else if (a.size !== b.size) {
+		return false;
+	}
+	a.sort();
+	b.sort();
+	const aIt = a[Symbol.iterator]();
+	const bIt = b[Symbol.iterator]();
+	for (;;) {
+		const aV = aIt.next();
+		if (aV.done) return true;
+		const bV = bIt.next();
+		if (aV.value !== bV.value) return false;
+	}
+};
+
+/**
+ * Compares the provided values and returns their ordering.
+ * @param {RuntimeSpec} a first
+ * @param {RuntimeSpec} b second
+ * @returns {-1 | 0 | 1} compare
+ */
+const compareRuntime = (a, b) => {
+	if (a === b) {
+		return 0;
+	} else if (a === undefined) {
+		return -1;
+	} else if (b === undefined) {
+		return 1;
+	}
+	const aKey = getRuntimeKey(a);
+	const bKey = getRuntimeKey(b);
+	if (aKey < bKey) return -1;
+	if (aKey > bKey) return 1;
+	return 0;
+};
+
+/**
+ * Merges the provided values into a single result.
+ * @param {RuntimeSpec} a first
+ * @param {RuntimeSpec} b second
+ * @returns {RuntimeSpec} merged
+ */
+const mergeRuntime = (a, b) => {
+	if (a === undefined) {
+		return b;
+	} else if (b === undefined) {
+		return a;
+	} else if (a === b) {
+		return a;
+	} else if (typeof a === "string") {
+		if (typeof b === "string") {
+			/** @type {RuntimeSpecSortableSet} */
+			const set = new SortableSet();
+			set.add(a);
+			set.add(b);
+			return set;
+		} else if (b.has(a)) {
+			return b;
+		}
+		/** @type {RuntimeSpecSortableSet} */
+		const set = new SortableSet(b);
+		set.add(a);
+		return set;
+	}
+	if (typeof b === "string") {
+		if (a.has(b)) return a;
+		/** @type {RuntimeSpecSortableSet} */
+		const set = new SortableSet(a);
+		set.add(b);
+		return set;
+	}
+	/** @type {RuntimeSpecSortableSet} */
+	const set = new SortableSet(a);
+	for (const item of b) set.add(item);
+	if (set.size === a.size) return a;
+	return set;
+};
+
+/**
+ * Merges runtime condition.
+ * @param {RuntimeCondition} a first
+ * @param {RuntimeCondition} b second
+ * @param {RuntimeSpec} runtime full runtime
+ * @returns {RuntimeCondition} result
+ */
+const mergeRuntimeCondition = (a, b, runtime) => {
+	if (a === false) return b;
+	if (b === false) return a;
+	if (a === true || b === true) return true;
+	const merged = mergeRuntime(a, b);
+	if (merged === undefined) return;
+	if (typeof merged === "string") {
+		if (typeof runtime === "string" && merged === runtime) return true;
+		return merged;
+	}
+	if (typeof runtime === "string" || runtime === undefined) return merged;
+	if (merged.size === runtime.size) return true;
+	return merged;
+};
+
+/**
+ * Merges runtime condition non false.
+ * @param {RuntimeSpec | true} a first
+ * @param {RuntimeSpec | true} b second
+ * @param {RuntimeSpec} runtime full runtime
+ * @returns {RuntimeSpec | true} result
+ */
+const mergeRuntimeConditionNonFalse = (a, b, runtime) => {
+	if (a === true || b === true) return true;
+	const merged = mergeRuntime(a, b);
+	if (merged === undefined) return;
+	if (typeof merged === "string") {
+		if (typeof runtime === "string" && merged === runtime) return true;
+		return merged;
+	}
+	if (typeof runtime === "string" || runtime === undefined) return merged;
+	if (merged.size === runtime.size) return true;
+	return merged;
+};
+
+/**
+ * Merges runtime owned.
+ * @param {RuntimeSpec} a first (may be modified)
+ * @param {RuntimeSpec} b second
+ * @returns {RuntimeSpec} merged
+ */
+const mergeRuntimeOwned = (a, b) => {
+	if (b === undefined) {
+		return a;
+	} else if (a === b) {
+		return a;
+	} else if (a === undefined) {
+		if (typeof b === "string") {
+			return b;
+		}
+		/** @type {RuntimeSpecSortableSet} */
+		return new SortableSet(b);
+	} else if (typeof a === "string") {
+		if (typeof b === "string") {
+			/** @type {RuntimeSpecSortableSet} */
+			const set = new SortableSet();
+			set.add(a);
+			set.add(b);
+			return set;
+		}
+		/** @type {RuntimeSpecSortableSet} */
+		const set = new SortableSet(b);
+		set.add(a);
+		return set;
+	}
+	if (typeof b === "string") {
+		a.add(b);
+		return a;
+	}
+	for (const item of b) a.add(item);
+	return a;
+};
+
+/**
+ * Returns merged.
+ * @param {RuntimeSpec} a first
+ * @param {RuntimeSpec} b second
+ * @returns {RuntimeSpec} merged
+ */
+const intersectRuntime = (a, b) => {
+	if (a === undefined) {
+		return b;
+	} else if (b === undefined) {
+		return a;
+	} else if (a === b) {
+		return a;
+	} else if (typeof a === "string") {
+		if (typeof b === "string") {
+			return;
+		} else if (b.has(a)) {
+			return a;
+		}
+		return;
+	}
+	if (typeof b === "string") {
+		if (a.has(b)) return b;
+		return;
+	}
+	/** @type {RuntimeSpecSortableSet} */
+	const set = new SortableSet();
+	for (const item of b) {
+		if (a.has(item)) set.add(item);
+	}
+	if (set.size === 0) return;
+	if (set.size === 1) {
+		const [item] = set;
+		return item;
+	}
+	return set;
+};
+
+/**
+ * Returns result.
+ * @param {RuntimeSpec} a first
+ * @param {RuntimeSpec} b second
+ * @returns {RuntimeSpec} result
+ */
+const subtractRuntime = (a, b) => {
+	if (a === undefined) {
+		return;
+	} else if (b === undefined) {
+		return a;
+	} else if (a === b) {
+		return;
+	} else if (typeof a === "string") {
+		if (typeof b === "string") {
+			return a;
+		} else if (b.has(a)) {
+			return;
+		}
+		return a;
+	}
+	if (typeof b === "string") {
+		if (!a.has(b)) return a;
+		if (a.size === 2) {
+			for (const item of a) {
+				if (item !== b) return item;
+			}
+		}
+		/** @type {RuntimeSpecSortableSet} */
+		const set = new SortableSet(a);
+		set.delete(b);
+		return set;
+	}
+	/** @type {RuntimeSpecSortableSet} */
+	const set = new SortableSet();
+	for (const item of a) {
+		if (!b.has(item)) set.add(item);
+	}
+	if (set.size === 0) return;
+	if (set.size === 1) {
+		const [item] = set;
+		return item;
+	}
+	return set;
+};
+
+/**
+ * Subtract runtime condition.
+ * @param {RuntimeCondition} a first
+ * @param {RuntimeCondition} b second
+ * @param {RuntimeSpec} runtime runtime
+ * @returns {RuntimeCondition} result
+ */
+const subtractRuntimeCondition = (a, b, runtime) => {
+	if (b === true) return false;
+	if (b === false) return a;
+	if (a === false) return false;
+	const result = subtractRuntime(a === true ? runtime : a, b);
+	return result === undefined ? false : result;
+};
+
+/**
+ * Returns true/false if filter is constant for all runtimes, otherwise runtimes that are active.
+ * @param {RuntimeSpec} runtime runtime
+ * @param {(runtime?: RuntimeSpec) => boolean} filter filter function
+ * @returns {boolean | RuntimeSpec} true/false if filter is constant for all runtimes, otherwise runtimes that are active
+ */
+const filterRuntime = (runtime, filter) => {
+	if (runtime === undefined) return filter();
+	if (typeof runtime === "string") return filter(runtime);
+	let some = false;
+	let every = true;
+	/** @type {RuntimeSpec} */
+	let result;
+	for (const r of runtime) {
+		const v = filter(r);
+		if (v) {
+			some = true;
+			result = mergeRuntimeOwned(result, r);
+		} else {
+			every = false;
+		}
+	}
+	if (!some) return false;
+	if (every) return true;
+	return result;
+};
+
+/**
+ * Defines the runtime spec map inner map type used by this module.
+ * @template T
+ * @typedef {Map<string, T>} RuntimeSpecMapInnerMap
+ */
+
+/**
+ * Represents RuntimeSpecMap.
+ * @template T
+ * @template [R=T]
+ */
+class RuntimeSpecMap {
+	/**
+	 * Creates an instance of RuntimeSpecMap.
+	 * @param {RuntimeSpecMap<T, R>=} clone copy form this
+	 */
+	constructor(clone) {
+		/** @type {0 | 1 | 2} */
+		this._mode = clone ? clone._mode : 0; // 0 = empty, 1 = single entry, 2 = map
+		/** @type {RuntimeSpec} */
+		this._singleRuntime = clone ? clone._singleRuntime : undefined;
+		/** @type {R | undefined} */
+		this._singleValue = clone ? clone._singleValue : undefined;
+		/** @type {RuntimeSpecMapInnerMap<R> | undefined} */
+		this._map = clone && clone._map ? new Map(clone._map) : undefined;
+	}
+
+	/**
+	 * Returns value.
+	 * @param {RuntimeSpec} runtime the runtimes
+	 * @returns {R | undefined} value
+	 */
+	get(runtime) {
+		switch (this._mode) {
+			case 0:
+				return;
+			case 1:
+				return runtimeEqual(this._singleRuntime, runtime)
+					? this._singleValue
+					: undefined;
+			default:
+				return /** @type {RuntimeSpecMapInnerMap<R>} */ (this._map).get(
+					getRuntimeKey(runtime)
+				);
+		}
+	}
+
+	/**
+	 * Returns true, when the runtime is stored.
+	 * @param {RuntimeSpec} runtime the runtimes
+	 * @returns {boolean} true, when the runtime is stored
+	 */
+	has(runtime) {
+		switch (this._mode) {
+			case 0:
+				return false;
+			case 1:
+				return runtimeEqual(this._singleRuntime, runtime);
+			default:
+				return /** @type {RuntimeSpecMapInnerMap<R>} */ (this._map).has(
+					getRuntimeKey(runtime)
+				);
+		}
+	}
+
+	/**
+	 * Updates default using the provided runtime.
+	 * @param {RuntimeSpec} runtime the runtimes
+	 * @param {R} value the value
+	 */
+	set(runtime, value) {
+		switch (this._mode) {
+			case 0:
+				this._mode = 1;
+				this._singleRuntime = runtime;
+				this._singleValue = value;
+				break;
+			case 1:
+				if (runtimeEqual(this._singleRuntime, runtime)) {
+					this._singleValue = value;
+					break;
+				}
+				this._mode = 2;
+				this._map = new Map();
+				this._map.set(
+					getRuntimeKey(this._singleRuntime),
+					/** @type {R} */ (this._singleValue)
+				);
+				this._singleRuntime = undefined;
+				this._singleValue = undefined;
+			/* falls through */
+			default:
+				/** @type {RuntimeSpecMapInnerMap<R>} */
+				(this._map).set(getRuntimeKey(runtime), value);
+		}
+	}
+
+	/**
+	 * Returns the new value.
+	 * @param {RuntimeSpec} runtime the runtimes
+	 * @param {() => R} computer function to compute the value
+	 * @returns {R} the new value
+	 */
+	provide(runtime, computer) {
+		switch (this._mode) {
+			case 0:
+				this._mode = 1;
+				this._singleRuntime = runtime;
+				return (this._singleValue = computer());
+			case 1: {
+				if (runtimeEqual(this._singleRuntime, runtime)) {
+					return /** @type {R} */ (this._singleValue);
+				}
+				this._mode = 2;
+				this._map = new Map();
+				this._map.set(
+					getRuntimeKey(this._singleRuntime),
+					/** @type {R} */
+					(this._singleValue)
+				);
+				this._singleRuntime = undefined;
+				this._singleValue = undefined;
+				const newValue = computer();
+				this._map.set(getRuntimeKey(runtime), newValue);
+				return newValue;
+			}
+			default: {
+				const key = getRuntimeKey(runtime);
+				const value =
+					/** @type {RuntimeSpecMapInnerMap<R>} */
+					(this._map).get(key);
+				if (value !== undefined) return value;
+				const newValue = computer();
+				/** @type {RuntimeSpecMapInnerMap<R>} */
+				(this._map).set(key, newValue);
+				return newValue;
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided runtime.
+	 * @param {RuntimeSpec} runtime the runtimes
+	 */
+	delete(runtime) {
+		switch (this._mode) {
+			case 0:
+				return;
+			case 1:
+				if (runtimeEqual(this._singleRuntime, runtime)) {
+					this._mode = 0;
+					this._singleRuntime = undefined;
+					this._singleValue = undefined;
+				}
+				return;
+			default:
+				/** @type {RuntimeSpecMapInnerMap<R>} */
+				(this._map).delete(getRuntimeKey(runtime));
+		}
+	}
+
+	/**
+	 * Processes the provided runtime.
+	 * @param {RuntimeSpec} runtime the runtimes
+	 * @param {(value: R | undefined) => R} fn function to update the value
+	 */
+	update(runtime, fn) {
+		switch (this._mode) {
+			case 0:
+				throw new Error("runtime passed to update must exist");
+			case 1: {
+				if (runtimeEqual(this._singleRuntime, runtime)) {
+					this._singleValue = fn(this._singleValue);
+					break;
+				}
+				const newValue = fn(undefined);
+				if (newValue !== undefined) {
+					this._mode = 2;
+					this._map = new Map();
+					this._map.set(
+						getRuntimeKey(this._singleRuntime),
+						/** @type {R} */
+						(this._singleValue)
+					);
+					this._singleRuntime = undefined;
+					this._singleValue = undefined;
+					this._map.set(getRuntimeKey(runtime), newValue);
+				}
+				break;
+			}
+			default: {
+				const key = getRuntimeKey(runtime);
+				const oldValue =
+					/** @type {RuntimeSpecMapInnerMap<R>} */
+					(this._map).get(key);
+				const newValue = fn(oldValue);
+				if (newValue !== oldValue) {
+					/** @type {RuntimeSpecMapInnerMap<R>} */
+					(this._map).set(key, newValue);
+				}
+			}
+		}
+	}
+
+	keys() {
+		switch (this._mode) {
+			case 0:
+				return [];
+			case 1:
+				return [this._singleRuntime];
+			default:
+				return Array.from(
+					/** @type {RuntimeSpecMapInnerMap<R>} */
+					(this._map).keys(),
+					keyToRuntime
+				);
+		}
+	}
+
+	/**
+	 * Returns values.
+	 * @returns {IterableIterator<R>} values
+	 */
+	values() {
+		switch (this._mode) {
+			case 0:
+				return [][Symbol.iterator]();
+			case 1:
+				return [/** @type {R} */ (this._singleValue)][Symbol.iterator]();
+			default:
+				return /** @type {RuntimeSpecMapInnerMap<R>} */ (this._map).values();
+		}
+	}
+
+	get size() {
+		if (/** @type {number} */ (this._mode) <= 1) {
+			return /** @type {number} */ (this._mode);
+		}
+
+		return /** @type {RuntimeSpecMapInnerMap<R>} */ (this._map).size;
+	}
+}
+
+class RuntimeSpecSet {
+	/**
+	 * Creates an instance of RuntimeSpecSet.
+	 * @param {Iterable<RuntimeSpec>=} iterable iterable
+	 */
+	constructor(iterable) {
+		/** @type {Map<string, RuntimeSpec>} */
+		this._map = new Map();
+		if (iterable) {
+			for (const item of iterable) {
+				this.add(item);
+			}
+		}
+	}
+
+	/**
+	 * Processes the provided runtime.
+	 * @param {RuntimeSpec} runtime runtime
+	 */
+	add(runtime) {
+		this._map.set(getRuntimeKey(runtime), runtime);
+	}
+
+	/**
+	 * Returns true, when the runtime exists.
+	 * @param {RuntimeSpec} runtime runtime
+	 * @returns {boolean} true, when the runtime exists
+	 */
+	has(runtime) {
+		return this._map.has(getRuntimeKey(runtime));
+	}
+
+	/**
+	 * Returns iterable iterator.
+	 * @returns {IterableIterator<RuntimeSpec>} iterable iterator
+	 */
+	[Symbol.iterator]() {
+		return this._map.values();
+	}
+
+	get size() {
+		return this._map.size;
+	}
+}
+
+module.exports.RuntimeSpecMap = RuntimeSpecMap;
+module.exports.RuntimeSpecSet = RuntimeSpecSet;
+module.exports.compareRuntime = compareRuntime;
+module.exports.filterRuntime = filterRuntime;
+module.exports.forEachRuntime = forEachRuntime;
+module.exports.getEntryRuntime = getEntryRuntime;
+module.exports.getRuntimeKey = getRuntimeKey;
+module.exports.intersectRuntime = intersectRuntime;
+module.exports.keyToRuntime = keyToRuntime;
+module.exports.mergeRuntime = mergeRuntime;
+module.exports.mergeRuntimeCondition = mergeRuntimeCondition;
+module.exports.mergeRuntimeConditionNonFalse = mergeRuntimeConditionNonFalse;
+module.exports.mergeRuntimeOwned = mergeRuntimeOwned;
+module.exports.runtimeConditionToString = runtimeConditionToString;
+module.exports.runtimeEqual = runtimeEqual;
+module.exports.runtimeToString = runtimeToString;
+module.exports.subtractRuntime = subtractRuntime;
+module.exports.subtractRuntimeCondition = subtractRuntimeCondition;
Index: frontend/node_modules/webpack/lib/util/semver.js
===================================================================
--- frontend/node_modules/webpack/lib/util/semver.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/semver.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,619 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {string | number} VersionValue */
+/** @typedef {VersionValue | undefined} SemVerRangeItem */
+/** @typedef {(SemVerRangeItem | SemVerRangeItem[])[]} SemVerRange */
+
+/**
+ * Returns parsed version.
+ * @param {string} str version string
+ * @returns {SemVerRange} parsed version
+ */
+const parseVersion = (str) => {
+	/**
+	 * Returns result.
+	 * @param {str} str str
+	 * @returns {VersionValue[]} result
+	 */
+	var splitAndConvert = function (str) {
+		return str.split(".").map(function (item) {
+			// eslint-disable-next-line eqeqeq
+			return +item == /** @type {string | number} */ (item) ? +item : item;
+		});
+	};
+
+	var match =
+		/** @type {RegExpExecArray} */
+		(/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str));
+
+	/** @type {(VersionValue | undefined | [])[]} */
+	var ver = match[1] ? splitAndConvert(match[1]) : [];
+
+	if (match[2]) {
+		ver.length++;
+		ver.push.apply(ver, splitAndConvert(match[2]));
+	}
+
+	if (match[3]) {
+		ver.push([]);
+		ver.push.apply(ver, splitAndConvert(match[3]));
+	}
+
+	return ver;
+};
+module.exports.parseVersion = parseVersion;
+
+/* eslint-disable eqeqeq */
+/**
+ * Returns true, iff a < b.
+ * @param {string} a version
+ * @param {string} b version
+ * @returns {boolean} true, iff a < b
+ */
+const versionLt = (a, b) => {
+	// @ts-expect-error
+	a = parseVersion(a);
+	// @ts-expect-error
+	b = parseVersion(b);
+	var i = 0;
+	for (;;) {
+		// a       b  EOA     object  undefined  number  string
+		// EOA        a == b  a < b   b < a      a < b   a < b
+		// object     b < a   (0)     b < a      a < b   a < b
+		// undefined  a < b   a < b   (0)        a < b   a < b
+		// number     b < a   b < a   b < a      (1)     a < b
+		// string     b < a   b < a   b < a      b < a   (1)
+		// EOA end of array
+		// (0) continue on
+		// (1) compare them via "<"
+
+		// Handles first row in table
+		if (i >= a.length) return i < b.length && (typeof b[i])[0] != "u";
+
+		var aValue = a[i];
+		var aType = (typeof aValue)[0];
+
+		// Handles first column in table
+		if (i >= b.length) return aType == "u";
+
+		var bValue = b[i];
+		var bType = (typeof bValue)[0];
+
+		if (aType == bType) {
+			if (aType != "o" && aType != "u" && aValue != bValue) {
+				return aValue < bValue;
+			}
+			i++;
+		} else {
+			// Handles remaining cases
+			if (aType == "o" && bType == "n") return true;
+			return bType == "s" || aType == "u";
+		}
+	}
+};
+/* eslint-enable eqeqeq */
+module.exports.versionLt = versionLt;
+
+/**
+ * Returns parsed range.
+ * @param {string} str range string
+ * @returns {SemVerRange} parsed range
+ */
+module.exports.parseRange = (str) => {
+	/**
+	 * Returns result.
+	 * @param {string} str str
+	 * @returns {VersionValue[]} result
+	 */
+	const splitAndConvert = (str) => {
+		return str
+			.split(".")
+			.map((item) => (item !== "NaN" && `${+item}` === item ? +item : item));
+	};
+
+	// see https://docs.npmjs.com/misc/semver#range-grammar for grammar
+	/**
+	 * Returns the sem ver range item.
+	 * @param {string} str str
+	 * @returns {SemVerRangeItem[]}
+	 */
+	const parsePartial = (str) => {
+		const match =
+			/** @type {RegExpExecArray} */
+			(/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str));
+		/** @type {SemVerRangeItem[]} */
+		const ver = match[1] ? [0, ...splitAndConvert(match[1])] : [0];
+
+		if (match[2]) {
+			ver.length++;
+			ver.push.apply(ver, splitAndConvert(match[2]));
+		}
+
+		// remove trailing any matchers
+		let last = ver[ver.length - 1];
+		while (
+			ver.length &&
+			(last === undefined || /^[*xX]$/.test(/** @type {string} */ (last)))
+		) {
+			ver.pop();
+			last = ver[ver.length - 1];
+		}
+
+		return ver;
+	};
+
+	/**
+	 * Returns the sem ver range item.
+	 *
+	 * @param {SemVerRangeItem[]} range range
+	 * @returns {SemVerRangeItem[]}
+	 */
+	const toFixed = (range) => {
+		if (range.length === 1) {
+			// Special case for "*" is "x.x.x" instead of "="
+			return [0];
+		} else if (range.length === 2) {
+			// Special case for "1" is "1.x.x" instead of "=1"
+			return [1, ...range.slice(1)];
+		} else if (range.length === 3) {
+			// Special case for "1.2" is "1.2.x" instead of "=1.2"
+			return [2, ...range.slice(1)];
+		}
+
+		return [range.length, ...range.slice(1)];
+	};
+
+	/**
+	 * Returns result.
+	 *
+	 * @param {SemVerRangeItem[]} range
+	 * @returns {SemVerRangeItem[]} result
+	 */
+	const negate = (range) => {
+		return [-(/** @type { [number]} */ (range)[0]) - 1, ...range.slice(1)];
+	};
+
+	/**
+	 * Returns the sem ver range.
+	 * @param {string} str str
+	 * @returns {SemVerRange}
+	 */
+	const parseSimple = (str) => {
+		// simple       ::= primitive | partial | tilde | caret
+		// primitive    ::= ( '<' | '>' | '>=' | '<=' | '=' | '!' ) ( ' ' ) * partial
+		// tilde        ::= '~' ( ' ' ) * partial
+		// caret        ::= '^' ( ' ' ) * partial
+		const match = /^(\^|~|<=|<|>=|>|=|v|!)/.exec(str);
+		const start = match ? match[0] : "";
+		const remainder = parsePartial(
+			start.length ? str.slice(start.length).trim() : str.trim()
+		);
+
+		switch (start) {
+			case "^":
+				if (remainder.length > 1 && remainder[1] === 0) {
+					if (remainder.length > 2 && remainder[2] === 0) {
+						return [3, ...remainder.slice(1)];
+					}
+					return [2, ...remainder.slice(1)];
+				}
+				return [1, ...remainder.slice(1)];
+			case "~":
+				if (remainder.length === 2 && remainder[0] === 0) {
+					return [1, ...remainder.slice(1)];
+				}
+				return [2, ...remainder.slice(1)];
+			case ">=":
+				return remainder;
+			case "=":
+			case "v":
+			case "":
+				return toFixed(remainder);
+			case "<":
+				return negate(remainder);
+			case ">": {
+				// and( >=, not( = ) ) => >=, =, not, and
+				const fixed = toFixed(remainder);
+				// eslint-disable-next-line no-sparse-arrays
+				return [, fixed, 0, remainder, 2];
+			}
+			case "<=":
+				// or( <, = ) => <, =, or
+				// eslint-disable-next-line no-sparse-arrays
+				return [, toFixed(remainder), negate(remainder), 1];
+			case "!": {
+				// not =
+				const fixed = toFixed(remainder);
+				// eslint-disable-next-line no-sparse-arrays
+				return [, fixed, 0];
+			}
+			default:
+				throw new Error("Unexpected start value");
+		}
+	};
+
+	/**
+	 * Returns result.
+	 *
+	 * @param {SemVerRangeItem[][]} items items
+	 * @param {number} fn fn
+	 * @returns {SemVerRange} result
+	 */
+	const combine = (items, fn) => {
+		if (items.length === 1) return items[0];
+		const arr = [];
+		for (const item of items.slice().reverse()) {
+			if (0 in item) {
+				arr.push(item);
+			} else {
+				arr.push(...item.slice(1));
+			}
+		}
+
+		// eslint-disable-next-line no-sparse-arrays
+		return [, ...arr, ...items.slice(1).map(() => fn)];
+	};
+
+	/**
+	 * Returns the sem ver range.
+	 * @param {string} str str
+	 * @returns {SemVerRange}
+	 */
+	const parseRange = (str) => {
+		// range      ::= hyphen | simple ( ' ' ( ' ' ) * simple ) * | ''
+		// hyphen     ::= partial ( ' ' ) * ' - ' ( ' ' ) * partial
+		const items = str.split(/\s+-\s+/);
+
+		if (items.length === 1) {
+			str = str.trim();
+
+			/** @type {SemVerRangeItem[][]} */
+			const items = [];
+			const r = /[-0-9A-Za-z]\s+/g;
+			var start = 0;
+			/** @type {RegExpExecArray | null} */
+			var match;
+			while ((match = r.exec(str))) {
+				const end = match.index + 1;
+				items.push(
+					/** @type {SemVerRangeItem[]} */
+					(parseSimple(str.slice(start, end).trim()))
+				);
+				start = end;
+			}
+			items.push(
+				/** @type {SemVerRangeItem[]} */
+				(parseSimple(str.slice(start).trim()))
+			);
+			return combine(items, 2);
+		}
+
+		const a = parsePartial(items[0]);
+		const b = parsePartial(items[1]);
+		// >=a <=b => and( >=a, or( <b, =b ) ) => >=a, <b, =b, or, and
+		// eslint-disable-next-line no-sparse-arrays
+		return [, toFixed(b), negate(b), 1, a, 2];
+	};
+
+	/**
+	 * Returns the sem ver range.
+	 * @param {string} str str
+	 * @returns {SemVerRange}
+	 */
+	const parseLogicalOr = (str) => {
+		// range-set  ::= range ( logical-or range ) *
+		// logical-or ::= ( ' ' ) * '||' ( ' ' ) *
+		const items =
+			/** @type {SemVerRangeItem[][]} */
+			(str.split(/\s*\|\|\s*/).map(parseRange));
+
+		return combine(items, 1);
+	};
+
+	return parseLogicalOr(str);
+};
+
+/* eslint-disable eqeqeq */
+/**
+ * Returns the string.
+ * @param {SemVerRange} range
+ * @returns {string}
+ */
+const rangeToString = (range) => {
+	var fixCount = /** @type {number} */ (range[0]);
+	var str = "";
+	if (range.length === 1) {
+		return "*";
+	} else if (fixCount + 0.5) {
+		str +=
+			fixCount == 0
+				? ">="
+				: fixCount == -1
+					? "<"
+					: fixCount == 1
+						? "^"
+						: fixCount == 2
+							? "~"
+							: fixCount > 0
+								? "="
+								: "!=";
+		var needDot = 1;
+		for (var i = 1; i < range.length; i++) {
+			var item = range[i];
+			var t = (typeof item)[0];
+			needDot--;
+			str +=
+				t == "u"
+					? // undefined: prerelease marker, add an "-"
+						"-"
+					: // number or string: add the item, set flag to add an "." between two of them
+						(needDot > 0 ? "." : "") + ((needDot = 2), item);
+		}
+		return str;
+	}
+	/** @type {string[]} */
+	var stack = [];
+	// eslint-disable-next-line no-redeclare
+	for (var i = 1; i < range.length; i++) {
+		// eslint-disable-next-line no-redeclare
+		var item = range[i];
+		stack.push(
+			item === 0
+				? "not(" + pop() + ")"
+				: item === 1
+					? "(" + pop() + " || " + pop() + ")"
+					: item === 2
+						? stack.pop() + " " + stack.pop()
+						: rangeToString(/** @type {SemVerRange} */ (item))
+		);
+	}
+	return pop();
+
+	function pop() {
+		return /** @type {string} */ (stack.pop()).replace(/^\((.+)\)$/, "$1");
+	}
+};
+
+module.exports.rangeToString = rangeToString;
+
+/**
+ * Returns if version satisfy the range.
+ * @param {SemVerRange} range version range
+ * @param {string} version the version
+ * @returns {boolean} if version satisfy the range
+ */
+const satisfy = (range, version) => {
+	if (0 in range) {
+		// @ts-expect-error
+		version = parseVersion(version);
+		var fixCount = /** @type {number} */ (range[0]);
+		// when negated is set it swill set for < instead of >=
+		var negated = fixCount < 0;
+		if (negated) fixCount = -fixCount - 1;
+		for (var i = 0, j = 1, isEqual = true; ; j++, i++) {
+			// cspell:word nequal nequ
+
+			// when isEqual = true:
+			// range         version: EOA/object  undefined  number    string
+			// EOA                    equal       block      big-ver   big-ver
+			// undefined              bigger      next       big-ver   big-ver
+			// number                 smaller     block      cmp       big-cmp
+			// fixed number           smaller     block      cmp-fix   differ
+			// string                 smaller     block      differ    cmp
+			// fixed string           smaller     block      small-cmp cmp-fix
+
+			// when isEqual = false:
+			// range         version: EOA/object  undefined  number    string
+			// EOA                    nequal      block      next-ver  next-ver
+			// undefined              nequal      block      next-ver  next-ver
+			// number                 nequal      block      next      next
+			// fixed number           nequal      block      next      next   (this never happens)
+			// string                 nequal      block      next      next
+			// fixed string           nequal      block      next      next   (this never happens)
+
+			// EOA end of array
+			// equal (version is equal range):
+			//   when !negated: return true,
+			//   when negated: return false
+			// bigger (version is bigger as range):
+			//   when fixed: return false,
+			//   when !negated: return true,
+			//   when negated: return false,
+			// smaller (version is smaller as range):
+			//   when !negated: return false,
+			//   when negated: return true
+			// nequal (version is not equal range (> resp <)): return true
+			// block (version is in different prerelease area): return false
+			// differ (version is different from fixed range (string vs. number)): return false
+			// next: continues to the next items
+			// next-ver: when fixed: return false, continues to the next item only for the version, sets isEqual=false
+			// big-ver: when fixed || negated: return false, continues to the next item only for the version, sets isEqual=false
+			// next-nequ: continues to the next items, sets isEqual=false
+			// cmp (negated === false): version < range => return false, version > range => next-nequ, else => next
+			// cmp (negated === true): version > range => return false, version < range => next-nequ, else => next
+			// cmp-fix: version == range => next, else => return false
+			// big-cmp: when negated => return false, else => next-nequ
+			// small-cmp: when negated => next-nequ, else => return false
+
+			var rangeType =
+				/** @type {"s" | "n" | "u" | ""} */
+				(j < range.length ? (typeof range[j])[0] : "");
+
+			/** @type {VersionValue | undefined} */
+			var versionValue;
+			/** @type {"n" | "s" | "u" | "o" | undefined} */
+			var versionType;
+
+			// Handles first column in both tables (end of version or object)
+			if (
+				i >= version.length ||
+				((versionValue = version[i]),
+				(versionType = /** @type {"n" | "s" | "u" | "o"} */ (
+					(typeof versionValue)[0]
+				)) == "o")
+			) {
+				// Handles nequal
+				if (!isEqual) return true;
+				// Handles bigger
+				if (rangeType == "u") return j > fixCount && !negated;
+				// Handles equal and smaller: (range === EOA) XOR negated
+				return (rangeType == "") != negated; // equal + smaller
+			}
+
+			// Handles second column in both tables (version = undefined)
+			if (versionType == "u") {
+				if (!isEqual || rangeType != "u") {
+					return false;
+				}
+			}
+
+			// switch between first and second table
+			else if (isEqual) {
+				// Handle diagonal
+				if (rangeType == versionType) {
+					if (j <= fixCount) {
+						// Handles "cmp-fix" cases
+						if (versionValue != range[j]) {
+							return false;
+						}
+					} else {
+						// Handles "cmp" cases
+						if (
+							negated
+								? versionValue > /** @type {VersionValue[]} */ (range)[j]
+								: versionValue < /** @type {VersionValue[]} */ (range)[j]
+						) {
+							return false;
+						}
+						if (versionValue != range[j]) isEqual = false;
+					}
+				}
+
+				// Handle big-ver
+				else if (rangeType != "s" && rangeType != "n") {
+					if (negated || j <= fixCount) return false;
+					isEqual = false;
+					j--;
+				}
+
+				// Handle differ, big-cmp and small-cmp
+				else if (j <= fixCount || versionType < rangeType != negated) {
+					return false;
+				} else {
+					isEqual = false;
+				}
+			} else {
+				// Handles all "next-ver" cases in the second table
+				// eslint-disable-next-line no-lonely-if
+				if (rangeType != "s" && rangeType != "n") {
+					isEqual = false;
+					j--;
+				}
+
+				// next is applied by default
+			}
+		}
+	}
+
+	/** @type {(boolean | number)[]} */
+	var stack = [];
+	var p = stack.pop.bind(stack);
+	// eslint-disable-next-line no-redeclare
+	for (var i = 1; i < range.length; i++) {
+		var item = /** @type {SemVerRangeItem[] | 0 | 1 | 2} */ (range[i]);
+
+		stack.push(
+			item == 1
+				? /** @type {() => number} */ (p)() | /** @type {() => number} */ (p)()
+				: item == 2
+					? /** @type {() => number} */ (p)() &
+						/** @type {() => number} */ (p)()
+					: item
+						? satisfy(item, version)
+						: !p()
+		);
+	}
+	return !!p();
+};
+/* eslint-enable eqeqeq */
+module.exports.satisfy = satisfy;
+
+/**
+ * Returns the string.
+ * @param {SemVerRange | string | number | false | undefined} json
+ * @returns {string}
+ */
+module.exports.stringifyHoley = (json) => {
+	switch (typeof json) {
+		case "undefined":
+			return "";
+		case "object":
+			if (Array.isArray(json)) {
+				let str = "[";
+				for (let i = 0; i < json.length; i++) {
+					if (i !== 0) str += ",";
+					str += this.stringifyHoley(json[i]);
+				}
+				str += "]";
+				return str;
+			}
+
+			return JSON.stringify(json);
+		default:
+			return JSON.stringify(json);
+	}
+};
+
+//#region runtime code: parseVersion
+/**
+ * @param {RuntimeTemplate} runtimeTemplate
+ * @returns {string}
+ */
+exports.parseVersionRuntimeCode = (runtimeTemplate) =>
+	`var parseVersion = ${runtimeTemplate.basicFunction("str", [
+		"// see webpack/lib/util/semver.js for original code",
+		`var p=${runtimeTemplate.supportsArrowFunction() ? "p=>" : "function(p)"}{return p.split(".").map(${runtimeTemplate.supportsArrowFunction() ? "p=>" : "function(p)"}{return+p==p?+p:p})},n=/^([^-+]+)?(?:-([^+]+))?(?:\\+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;`
+	])}`;
+//#endregion
+
+//#region runtime code: versionLt
+/**
+ * @param {RuntimeTemplate} runtimeTemplate
+ * @returns {string}
+ */
+exports.versionLtRuntimeCode = (runtimeTemplate) =>
+	`var versionLt = ${runtimeTemplate.basicFunction("a, b", [
+		"// see webpack/lib/util/semver.js for original code",
+		'a=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r<b.length&&"u"!=(typeof b[r])[0];var e=a[r],n=(typeof e)[0];if(r>=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e<t;r++}'
+	])}`;
+//#endregion
+
+//#region runtime code: rangeToString
+/**
+ * @param {RuntimeTemplate} runtimeTemplate
+ * @returns {string}
+ */
+exports.rangeToStringRuntimeCode = (runtimeTemplate) =>
+	`var rangeToString = ${runtimeTemplate.basicFunction("range", [
+		"// see webpack/lib/util/semver.js for original code",
+		'var r=range[0],n="";if(1===range.length)return"*";if(r+.5){n+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a<range.length;a++){e--,n+="u"==(typeof(t=range[a]))[0]?"-":(e>0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a<range.length;a++){var t=range[a];g.push(0===t?"not("+o()+")":1===t?"("+o()+" || "+o()+")":2===t?g.pop()+" "+g.pop():rangeToString(t))}return o();function o(){return g.pop().replace(/^\\((.+)\\)$/,"$1")}'
+	])}`;
+//#endregion
+
+//#region runtime code: satisfy
+/**
+ * @param {RuntimeTemplate} runtimeTemplate
+ * @returns {string}
+ */
+exports.satisfyRuntimeCode = (runtimeTemplate) =>
+	`var satisfy = ${runtimeTemplate.basicFunction("range, version", [
+		"// see webpack/lib/util/semver.js for original code",
+		'if(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i<range.length?(typeof range[i])[0]:"";if(n>=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f<range[i])return!1;f!=range[i]&&(a=!1)}else if("s"!=g&&"n"!=g){if(r||i<=e)return!1;a=!1,i--}else{if(i<=e||s<g!=r)return!1;a=!1}else"s"!=g&&"n"!=g&&(a=!1,i--)}}var t=[],o=t.pop.bind(t);for(n=1;n<range.length;n++){var u=range[n];t.push(1==u?o()|o():2==u?o()&o():u?satisfy(u,version):!o())}return!!o();'
+	])}`;
+//#endregion
Index: frontend/node_modules/webpack/lib/util/serialization.js
===================================================================
--- frontend/node_modules/webpack/lib/util/serialization.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/serialization.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,155 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { DEFAULTS } = require("../config/defaults");
+const memoize = require("./memoize");
+
+/** @typedef {import("../serialization/BinaryMiddleware").MEASURE_END_OPERATION_TYPE} MEASURE_END_OPERATION */
+/** @typedef {import("../serialization/BinaryMiddleware").MEASURE_START_OPERATION_TYPE} MEASURE_START_OPERATION */
+/** @typedef {import("../util/Hash").HashFunction} HashFunction */
+/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
+
+/**
+ * Defines the serializer type used by this module.
+ * @template D, S, C
+ * @typedef {import("../serialization/Serializer")<D, S, C>} Serializer
+ */
+
+const getBinaryMiddleware = memoize(() =>
+	require("../serialization/BinaryMiddleware")
+);
+const getObjectMiddleware = memoize(() =>
+	require("../serialization/ObjectMiddleware")
+);
+const getSingleItemMiddleware = memoize(() =>
+	require("../serialization/SingleItemMiddleware")
+);
+const getSerializer = memoize(() => require("../serialization/Serializer"));
+const getSerializerMiddleware = memoize(() =>
+	require("../serialization/SerializerMiddleware")
+);
+
+const getBinaryMiddlewareInstance = memoize(
+	() => new (getBinaryMiddleware())()
+);
+
+const registerSerializers = memoize(() => {
+	require("./registerExternalSerializer");
+
+	// Load internal paths with a relative require
+	// This allows bundling all internal serializers
+	const internalSerializables = require("./internalSerializables");
+
+	getObjectMiddleware().registerLoader(/^webpack\/lib\//, (req) => {
+		const loader =
+			internalSerializables[
+				/** @type {keyof import("./internalSerializables")} */
+				(req.slice("webpack/lib/".length))
+			];
+		if (loader) {
+			loader();
+		} else {
+			// eslint-disable-next-line no-console
+			console.warn(`${req} not found in internalSerializables`);
+		}
+		return true;
+	});
+});
+
+/**
+ * @type {Serializer<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>}
+ */
+let buffersSerializer;
+
+// Expose serialization API
+module.exports = {
+	get register() {
+		return getObjectMiddleware().register;
+	},
+	get registerLoader() {
+		return getObjectMiddleware().registerLoader;
+	},
+	get registerNotSerializable() {
+		return getObjectMiddleware().registerNotSerializable;
+	},
+	get NOT_SERIALIZABLE() {
+		return getObjectMiddleware().NOT_SERIALIZABLE;
+	},
+	/** @type {MEASURE_START_OPERATION} */
+	get MEASURE_START_OPERATION() {
+		return getBinaryMiddleware().MEASURE_START_OPERATION;
+	},
+	/** @type {MEASURE_END_OPERATION} */
+	get MEASURE_END_OPERATION() {
+		return getBinaryMiddleware().MEASURE_END_OPERATION;
+	},
+	get buffersSerializer() {
+		if (buffersSerializer !== undefined) return buffersSerializer;
+		registerSerializers();
+		const Serializer = getSerializer();
+		const binaryMiddleware = getBinaryMiddlewareInstance();
+		const SerializerMiddleware = getSerializerMiddleware();
+		const SingleItemMiddleware = getSingleItemMiddleware();
+		return /** @type {Serializer<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>} */ (
+			buffersSerializer = new Serializer([
+				new SingleItemMiddleware(),
+				new (getObjectMiddleware())((context) => {
+					if ("write" in context) {
+						context.writeLazy = (value) => {
+							context.write(
+								SerializerMiddleware.createLazy(value, binaryMiddleware)
+							);
+						};
+					}
+				}, DEFAULTS.HASH_FUNCTION),
+				binaryMiddleware
+			])
+		);
+	},
+	/**
+	 * Creates a file serializer.
+	 * @template D, S, C
+	 * @param {IntermediateFileSystem} fs filesystem
+	 * @param {HashFunction} hashFunction hash function to use
+	 * @returns {Serializer<D, S, C>} file serializer
+	 */
+	createFileSerializer: (fs, hashFunction) => {
+		registerSerializers();
+		const Serializer = getSerializer();
+
+		const FileMiddleware = require("../serialization/FileMiddleware");
+
+		const fileMiddleware = new FileMiddleware(fs, hashFunction);
+		const binaryMiddleware = getBinaryMiddlewareInstance();
+		const SerializerMiddleware = getSerializerMiddleware();
+		const SingleItemMiddleware = getSingleItemMiddleware();
+		return /** @type {Serializer<D, S, C>} */ (
+			new Serializer([
+				new SingleItemMiddleware(),
+				new (getObjectMiddleware())((context) => {
+					if ("write" in context) {
+						context.writeLazy = (value) => {
+							context.write(
+								SerializerMiddleware.createLazy(value, binaryMiddleware)
+							);
+						};
+						context.writeSeparate = (value, options) => {
+							const lazy = SerializerMiddleware.createLazy(
+								value,
+								fileMiddleware,
+								options
+							);
+							context.write(lazy);
+							return lazy;
+						};
+					}
+				}, hashFunction),
+				binaryMiddleware,
+				fileMiddleware
+			])
+		);
+	}
+};
Index: frontend/node_modules/webpack/lib/util/smartGrouping.js
===================================================================
--- frontend/node_modules/webpack/lib/util/smartGrouping.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/smartGrouping.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,229 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * Defines the group options type used by this module.
+ * @typedef {object} GroupOptions
+ * @property {boolean=} groupChildren
+ * @property {boolean=} force
+ * @property {number=} targetGroupCount
+ */
+
+/**
+ * Defines the group config type used by this module.
+ * @template I
+ * @template G
+ * @typedef {object} GroupConfig
+ * @property {(item: I) => string[] | undefined} getKeys
+ * @property {(name: string, items: I[]) => GroupOptions=} getOptions
+ * @property {(key: string, children: I[], items: I[]) => G} createGroup
+ */
+
+/**
+ * Defines the group type used by this module.
+ * @template I
+ * @template G
+ * @typedef {{ config: GroupConfig<I, G>, name: string, alreadyGrouped: boolean, items: Items<I, G> | undefined }} Group
+ */
+
+/**
+ * Defines the groups type used by this module.
+ * @template I, G
+ * @typedef {Set<Group<I, G>>} Groups
+ */
+
+/**
+ * Defines the item with groups type used by this module.
+ * @template I
+ * @template G
+ * @typedef {object} ItemWithGroups
+ * @property {I} item
+ * @property {Groups<I, G>} groups
+ */
+
+/**
+ * Defines the items type used by this module.
+ * @template T, G
+ * @typedef {Set<ItemWithGroups<T, G>>} Items
+ */
+
+/**
+ * Returns grouped items.
+ * @template I
+ * @template G
+ * @template R
+ * @param {I[]} items the list of items
+ * @param {GroupConfig<I, G>[]} groupConfigs configuration
+ * @returns {(I | G)[]} grouped items
+ */
+const smartGrouping = (items, groupConfigs) => {
+	/** @type {Items<I, G>} */
+	const itemsWithGroups = new Set();
+	/** @type {Map<string, Group<I, G>>} */
+	const allGroups = new Map();
+	for (const item of items) {
+		/** @type {Groups<I, G>} */
+		const groups = new Set();
+		for (let i = 0; i < groupConfigs.length; i++) {
+			const groupConfig = groupConfigs[i];
+			const keys = groupConfig.getKeys(item);
+			if (keys) {
+				for (const name of keys) {
+					const key = `${i}:${name}`;
+					let group = allGroups.get(key);
+					if (group === undefined) {
+						allGroups.set(
+							key,
+							(group = {
+								config: groupConfig,
+								name,
+								alreadyGrouped: false,
+								items: undefined
+							})
+						);
+					}
+					groups.add(group);
+				}
+			}
+		}
+		itemsWithGroups.add({
+			item,
+			groups
+		});
+	}
+
+	/**
+	 * Returns groups items.
+	 * @param {Items<I, G>} itemsWithGroups input items with groups
+	 * @returns {(I | G)[]} groups items
+	 */
+	const runGrouping = (itemsWithGroups) => {
+		const totalSize = itemsWithGroups.size;
+		for (const entry of itemsWithGroups) {
+			for (const group of entry.groups) {
+				if (group.alreadyGrouped) continue;
+				const items = group.items;
+				if (items === undefined) {
+					group.items = new Set([entry]);
+				} else {
+					items.add(entry);
+				}
+			}
+		}
+		/** @type {Map<Group<I, G>, { items: Items<I, G>, options: GroupOptions | false | undefined, used: boolean }>} */
+		const groupMap = new Map();
+		for (const group of allGroups.values()) {
+			if (group.items) {
+				const items = group.items;
+				group.items = undefined;
+				groupMap.set(group, {
+					items,
+					options: undefined,
+					used: false
+				});
+			}
+		}
+		/** @type {(I | G)[]} */
+		const results = [];
+		for (;;) {
+			/** @type {Group<I, G> | undefined} */
+			let bestGroup;
+			let bestGroupSize = -1;
+			/** @type {Items<I, G> | undefined} */
+			let bestGroupItems;
+			/** @type {GroupOptions | false | undefined} */
+			let bestGroupOptions;
+			for (const [group, state] of groupMap) {
+				const { items, used } = state;
+				let options = state.options;
+				if (options === undefined) {
+					const groupConfig = group.config;
+					state.options = options =
+						(groupConfig.getOptions &&
+							groupConfig.getOptions(
+								group.name,
+								Array.from(items, ({ item }) => item)
+							)) ||
+						false;
+				}
+
+				const force = options && options.force;
+				if (!force) {
+					if (bestGroupOptions && bestGroupOptions.force) continue;
+					if (used) continue;
+					if (items.size <= 1 || totalSize - items.size <= 1) {
+						continue;
+					}
+				}
+				const targetGroupCount = (options && options.targetGroupCount) || 4;
+				const sizeValue = force
+					? items.size
+					: Math.min(
+							items.size,
+							(totalSize * 2) / targetGroupCount +
+								itemsWithGroups.size -
+								items.size
+						);
+				if (
+					sizeValue > bestGroupSize ||
+					(force && (!bestGroupOptions || !bestGroupOptions.force))
+				) {
+					bestGroup = group;
+					bestGroupSize = sizeValue;
+					bestGroupItems = items;
+					bestGroupOptions = options;
+				}
+			}
+			if (bestGroup === undefined) {
+				break;
+			}
+			const items = new Set(bestGroupItems);
+			const options = bestGroupOptions;
+
+			const groupChildren = !options || options.groupChildren !== false;
+
+			for (const item of items) {
+				itemsWithGroups.delete(item);
+				// Remove all groups that items have from the map to not select them again
+				for (const group of item.groups) {
+					const state = groupMap.get(group);
+					if (state !== undefined) {
+						state.items.delete(item);
+						if (state.items.size === 0) {
+							groupMap.delete(group);
+						} else {
+							state.options = undefined;
+							if (groupChildren) {
+								state.used = true;
+							}
+						}
+					}
+				}
+			}
+			groupMap.delete(bestGroup);
+
+			const key = bestGroup.name;
+			const groupConfig = bestGroup.config;
+
+			const allItems = Array.from(items, ({ item }) => item);
+
+			bestGroup.alreadyGrouped = true;
+			const children = groupChildren ? runGrouping(items) : allItems;
+			bestGroup.alreadyGrouped = false;
+			results.push(
+				groupConfig.createGroup(key, /** @type {I[]} */ (children), allItems)
+			);
+		}
+		for (const { item } of itemsWithGroups) {
+			results.push(item);
+		}
+		return results;
+	};
+	return runGrouping(itemsWithGroups);
+};
+
+module.exports = smartGrouping;
Index: frontend/node_modules/webpack/lib/util/source.js
===================================================================
--- frontend/node_modules/webpack/lib/util/source.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/source.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./Hash")} Hash */
+
+/** @type {WeakMap<Source, WeakMap<Source, boolean>>} */
+const equalityCache = new WeakMap();
+
+/**
+ * Checks whether source equal true, when both sources are equal.
+ * @param {Source} a a source
+ * @param {Source} b another source
+ * @returns {boolean} true, when both sources are equal
+ */
+const _isSourceEqual = (a, b) => {
+	// prefer .buffer(), it's called anyway during emit
+	/** @type {Buffer | string} */
+	let aSource = typeof a.buffer === "function" ? a.buffer() : a.source();
+	/** @type {Buffer | string} */
+	let bSource = typeof b.buffer === "function" ? b.buffer() : b.source();
+	if (aSource === bSource) return true;
+	if (typeof aSource === "string" && typeof bSource === "string") return false;
+	if (!Buffer.isBuffer(aSource)) aSource = Buffer.from(aSource, "utf8");
+	if (!Buffer.isBuffer(bSource)) bSource = Buffer.from(bSource, "utf8");
+	return aSource.equals(bSource);
+};
+
+/**
+ * Checks whether this object is source equal.
+ * @param {Source} a a source
+ * @param {Source} b another source
+ * @returns {boolean} true, when both sources are equal
+ */
+const isSourceEqual = (a, b) => {
+	if (a === b) return true;
+	const cache1 = equalityCache.get(a);
+	if (cache1 !== undefined) {
+		const result = cache1.get(b);
+		if (result !== undefined) return result;
+	}
+	const result = _isSourceEqual(a, b);
+	if (cache1 !== undefined) {
+		cache1.set(b, result);
+	} else {
+		const map = new WeakMap();
+		map.set(b, result);
+		equalityCache.set(a, map);
+	}
+	const cache2 = equalityCache.get(b);
+	if (cache2 !== undefined) {
+		cache2.set(a, result);
+	} else {
+		const map = new WeakMap();
+		map.set(a, result);
+		equalityCache.set(b, map);
+	}
+	return result;
+};
+
+// TODO remove in webpack 6, this is protection against authors who directly use `webpack-sources` outdated version
+/**
+ * Feeds the Source's content into a Hash without forcing a single
+ * concatenated Buffer. Uses webpack-sources >= 3.4.0 `buffers()` when
+ * available so `ConcatSource` can stream its children directly.
+ * @param {Hash} hash hash to update
+ * @param {Source} source source whose bytes are appended
+ * @returns {void}
+ */
+const updateHashFromSource = (hash, source) => {
+	// TODO webpack 6: drop the `buffers` check, require webpack-sources >= 3.4
+	// and call `source.buffers()` unconditionally.
+	if (typeof source.buffers === "function") {
+		for (const buf of source.buffers()) hash.update(buf);
+	} else {
+		hash.update(source.buffer());
+	}
+};
+
+module.exports.isSourceEqual = isSourceEqual;
+module.exports.updateHashFromSource = updateHashFromSource;
Index: frontend/node_modules/webpack/lib/util/topologicalSort.js
===================================================================
--- frontend/node_modules/webpack/lib/util/topologicalSort.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/topologicalSort.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,69 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+/**
+ * Topologically sort `nodes` using Kahn's algorithm with source-order
+ * tie-breaking. Nodes that participate in a cycle remain unvisited —
+ * `visit` is never called for them — so the caller can naturally keep
+ * them in their original position by treating "no visit" as "keep
+ * source order".
+ *
+ * Precondition: every node appearing in `graph` (as a key OR inside any
+ * successor set) must also appear in `nodes`. The caller owns this
+ * invariant; the function does not validate it.
+ *
+ * Complexity: O(V·(V + E)). Each outer iteration scans the ready set
+ * linearly to find the smallest source-index node. CSS composes graphs
+ * are small (a handful of files per module) so this is fine; if a much
+ * larger graph ever needs sorting here, swap in a min-heap.
+ * @template T
+ * @param {Map<T, Set<T>>} graph adjacency list (`a -> b` means `a` must come before `b`)
+ * @param {T[]} nodes nodes in source first-appearance order
+ * @param {(node: T, index: number) => void} visit called once per non-cyclic node in topological order
+ * @returns {void}
+ */
+module.exports = (graph, nodes, visit) => {
+	/** @type {Map<T, number>} */
+	const inDegree = new Map();
+	/** @type {Map<T, number>} */
+	const sourceIndex = new Map();
+	for (let i = 0; i < nodes.length; i++) {
+		inDegree.set(nodes[i], 0);
+		sourceIndex.set(nodes[i], i);
+	}
+	for (const successors of graph.values()) {
+		for (const to of successors) {
+			inDegree.set(to, /** @type {number} */ (inDegree.get(to)) + 1);
+		}
+	}
+
+	const ready = nodes.filter((n) => inDegree.get(n) === 0);
+	let index = 0;
+	while (ready.length > 0) {
+		// Smallest-source-index wins ties. Linear scan + swap-with-last
+		// + pop avoids re-sorting the ready set on every iteration.
+		let minIdx = 0;
+		for (let i = 1; i < ready.length; i++) {
+			if (
+				/** @type {number} */ (sourceIndex.get(ready[i])) <
+				/** @type {number} */ (sourceIndex.get(ready[minIdx]))
+			) {
+				minIdx = i;
+			}
+		}
+		const node = ready[minIdx];
+		ready[minIdx] = ready[ready.length - 1];
+		ready.pop();
+		visit(node, index++);
+		const successors = graph.get(node);
+		if (!successors) continue;
+		for (const to of successors) {
+			const newDeg = /** @type {number} */ (inDegree.get(to)) - 1;
+			inDegree.set(to, newDeg);
+			if (newDeg === 0) ready.push(to);
+		}
+	}
+};
Index: frontend/node_modules/webpack/lib/util/traverseDestructuringAssignmentProperties.js
===================================================================
--- frontend/node_modules/webpack/lib/util/traverseDestructuringAssignmentProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/util/traverseDestructuringAssignmentProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,45 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperties} DestructuringAssignmentProperties */
+/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */
+
+/**
+ * Deep first traverse the properties of a destructuring assignment.
+ * @param {DestructuringAssignmentProperties} properties destructuring assignment properties
+ * @param {((stack: DestructuringAssignmentProperty[]) => void) | undefined=} onLeftNode on left node callback
+ * @param {((stack: DestructuringAssignmentProperty[]) => void) | undefined=} enterNode enter node callback
+ * @param {((stack: DestructuringAssignmentProperty[]) => void) | undefined=} exitNode exit node callback
+ * @param {DestructuringAssignmentProperty[] | undefined=} stack stack of the walking nodes
+ */
+function traverseDestructuringAssignmentProperties(
+	properties,
+	onLeftNode,
+	enterNode,
+	exitNode,
+	stack = []
+) {
+	for (const property of properties) {
+		stack.push(property);
+		if (enterNode) enterNode(stack);
+		if (property.pattern) {
+			traverseDestructuringAssignmentProperties(
+				property.pattern,
+				onLeftNode,
+				enterNode,
+				exitNode,
+				stack
+			);
+		} else if (onLeftNode) {
+			onLeftNode(stack);
+		}
+		if (exitNode) exitNode(stack);
+		stack.pop();
+	}
+}
+
+module.exports = traverseDestructuringAssignmentProperties;
Index: frontend/node_modules/webpack/lib/validateSchema.js
===================================================================
--- frontend/node_modules/webpack/lib/validateSchema.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/validateSchema.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,178 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { validate } = require("schema-utils");
+
+/* cSpell:disable */
+const DID_YOU_MEAN = {
+	rules: "module.rules",
+	loaders: "module.rules or module.rules.*.use",
+	query: "module.rules.*.options (BREAKING CHANGE since webpack 5)",
+	noParse: "module.noParse",
+	filename: "output.filename or module.rules.*.generator.filename",
+	file: "output.filename",
+	chunkFilename: "output.chunkFilename",
+	chunkfilename: "output.chunkFilename",
+	ecmaVersion:
+		"output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)",
+	ecmaversion:
+		"output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)",
+	ecma: "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)",
+	path: "output.path",
+	pathinfo: "output.pathinfo",
+	pathInfo: "output.pathinfo",
+	jsonpFunction: "output.chunkLoadingGlobal (BREAKING CHANGE since webpack 5)",
+	chunkCallbackName:
+		"output.chunkLoadingGlobal (BREAKING CHANGE since webpack 5)",
+	jsonpScriptType: "output.scriptType (BREAKING CHANGE since webpack 5)",
+	hotUpdateFunction: "output.hotUpdateGlobal (BREAKING CHANGE since webpack 5)",
+	splitChunks: "optimization.splitChunks",
+	immutablePaths: "snapshot.immutablePaths",
+	managedPaths: "snapshot.managedPaths",
+	maxModules: "stats.modulesSpace (BREAKING CHANGE since webpack 5)",
+	hashedModuleIds:
+		'optimization.moduleIds: "hashed" (BREAKING CHANGE since webpack 5)',
+	namedChunks:
+		'optimization.chunkIds: "named" (BREAKING CHANGE since webpack 5)',
+	namedModules:
+		'optimization.moduleIds: "named" (BREAKING CHANGE since webpack 5)',
+	occurrenceOrder:
+		'optimization.chunkIds: "size" and optimization.moduleIds: "size" (BREAKING CHANGE since webpack 5)',
+	automaticNamePrefix:
+		"optimization.splitChunks.[cacheGroups.*].idHint (BREAKING CHANGE since webpack 5)",
+	noEmitOnErrors:
+		"optimization.emitOnErrors (BREAKING CHANGE since webpack 5: logic is inverted to avoid negative flags)",
+	Buffer:
+		"to use the ProvidePlugin to process the Buffer variable to modules as polyfill\n" +
+		"BREAKING CHANGE: webpack 5 no longer provided Node.js polyfills by default.\n" +
+		"Note: if you are using 'node.Buffer: false', you can just remove that as this is the default behavior now.\n" +
+		"To provide a polyfill to modules use:\n" +
+		'new ProvidePlugin({ Buffer: ["buffer", "Buffer"] }) and npm install buffer.',
+	process:
+		"to use the ProvidePlugin to process the process variable to modules as polyfill\n" +
+		"BREAKING CHANGE: webpack 5 no longer provided Node.js polyfills by default.\n" +
+		"Note: if you are using 'node.process: false', you can just remove that as this is the default behavior now.\n" +
+		"To provide a polyfill to modules use:\n" +
+		'new ProvidePlugin({ process: "process" }) and npm install buffer.'
+};
+
+const REMOVED = {
+	concord:
+		"BREAKING CHANGE: resolve.concord has been removed and is no longer available.",
+	devtoolLineToLine:
+		"BREAKING CHANGE: output.devtoolLineToLine has been removed and is no longer available."
+};
+/* cSpell:enable */
+
+/**
+ * Processes the provided schema.
+ * @param {Parameters<typeof validate>[0]} schema a json schema
+ * @param {Parameters<typeof validate>[1]} options the options that should be validated
+ * @param {Parameters<typeof validate>[2]=} validationConfiguration configuration for generating errors
+ * @returns {void}
+ */
+const validateSchema = (schema, options, validationConfiguration) => {
+	validate(
+		schema,
+		options,
+		validationConfiguration || {
+			name: "Webpack",
+			postFormatter: (formattedError, error) => {
+				const children = error.children;
+				if (
+					children &&
+					children.some(
+						(child) =>
+							child.keyword === "absolutePath" &&
+							child.instancePath === "/output/filename"
+					)
+				) {
+					return `${formattedError}\nPlease use output.path to specify absolute path and output.filename for the file name.`;
+				}
+
+				if (
+					children &&
+					children.some(
+						(child) =>
+							child.keyword === "pattern" && child.instancePath === "/devtool"
+					)
+				) {
+					return (
+						`${formattedError}\n` +
+						"BREAKING CHANGE since webpack 5: The devtool option is more strict.\n" +
+						"Please strictly follow the order of the keywords in the pattern."
+					);
+				}
+
+				if (error.keyword === "additionalProperties") {
+					const params = error.params;
+					if (
+						Object.prototype.hasOwnProperty.call(
+							DID_YOU_MEAN,
+							params.additionalProperty
+						)
+					) {
+						return `${formattedError}\nDid you mean ${
+							DID_YOU_MEAN[
+								/** @type {keyof DID_YOU_MEAN} */ (params.additionalProperty)
+							]
+						}?`;
+					}
+
+					if (
+						Object.prototype.hasOwnProperty.call(
+							REMOVED,
+							params.additionalProperty
+						)
+					) {
+						return `${formattedError}\n${
+							REMOVED[/** @type {keyof REMOVED} */ (params.additionalProperty)]
+						}?`;
+					}
+
+					if (!error.instancePath) {
+						if (params.additionalProperty === "debug") {
+							return (
+								`${formattedError}\n` +
+								"The 'debug' property was removed in webpack 2.0.0.\n" +
+								"Loaders should be updated to allow passing this option via loader options in module.rules.\n" +
+								"Until loaders are updated one can use the LoaderOptionsPlugin to switch loaders into debug mode:\n" +
+								"plugins: [\n" +
+								"  new webpack.LoaderOptionsPlugin({\n" +
+								"    debug: true\n" +
+								"  })\n" +
+								"]"
+							);
+						}
+
+						if (params.additionalProperty) {
+							return (
+								`${formattedError}\n` +
+								"For typos: please correct them.\n" +
+								"For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.\n" +
+								"  Loaders should be updated to allow passing options via loader options in module.rules.\n" +
+								"  Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:\n" +
+								"  plugins: [\n" +
+								"    new webpack.LoaderOptionsPlugin({\n" +
+								"      // test: /\\.xxx$/, // may apply this only for some modules\n" +
+								"      options: {\n" +
+								`        ${params.additionalProperty}: …\n` +
+								"      }\n" +
+								"    })\n" +
+								"  ]"
+							);
+						}
+					}
+				}
+
+				return formattedError;
+			}
+		}
+	);
+};
+
+module.exports = validateSchema;
Index: frontend/node_modules/webpack/lib/wasm-async/AsyncWasmCompileRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/AsyncWasmCompileRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/AsyncWasmCompileRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,149 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+
+/** @typedef {(wasmModuleSrcPath: string) => string} GenerateBeforeLoadBinaryCode */
+/** @typedef {(wasmModuleSrcPath: string) => string} GenerateLoadBinaryCode */
+/** @typedef {() => string} GenerateBeforeCompileStreaming */
+
+/**
+ * @typedef {object} AsyncWasmCompileRuntimeModuleOptions
+ * @property {GenerateLoadBinaryCode} generateLoadBinaryCode
+ * @property {GenerateBeforeLoadBinaryCode=} generateBeforeLoadBinaryCode
+ * @property {GenerateBeforeCompileStreaming=} generateBeforeCompileStreaming
+ * @property {boolean} supportsStreaming
+ */
+
+class AsyncWasmCompileRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {AsyncWasmCompileRuntimeModuleOptions} options options
+	 */
+	constructor({
+		generateLoadBinaryCode,
+		generateBeforeLoadBinaryCode,
+		generateBeforeCompileStreaming,
+		supportsStreaming
+	}) {
+		super("wasm compile", RuntimeModule.STAGE_NORMAL);
+		/** @type {GenerateLoadBinaryCode} */
+		this.generateLoadBinaryCode = generateLoadBinaryCode;
+		/** @type {GenerateBeforeLoadBinaryCode | undefined} */
+		this.generateBeforeLoadBinaryCode = generateBeforeLoadBinaryCode;
+		/** @type {GenerateBeforeCompileStreaming | undefined} */
+		this.generateBeforeCompileStreaming = generateBeforeCompileStreaming;
+		/** @type {boolean} */
+		this.supportsStreaming = supportsStreaming;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { outputOptions, runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.compileWasm;
+		const wasmModuleSrcPath = compilation.getPath(
+			JSON.stringify(outputOptions.webassemblyModuleFilename),
+			{
+				hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+				hashWithLength: (length) =>
+					`" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
+				module: {
+					id: '" + wasmModuleId + "',
+					hash: '" + wasmModuleHash + "',
+					hashWithLength(length) {
+						return `" + wasmModuleHash.slice(0, ${length}) + "`;
+					}
+				},
+				runtime: chunk.runtime
+			}
+		);
+
+		const loader = this.generateLoadBinaryCode(wasmModuleSrcPath);
+
+		// Fallback path: fetch -> arrayBuffer -> WebAssembly.compile
+		const fallback = [
+			`.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`,
+			`.then(${runtimeTemplate.returningFunction(
+				"WebAssembly.compile(bytes)",
+				"bytes"
+			)})`
+		];
+
+		const getStreaming = () => {
+			/**
+			 * @param {string[]} text text
+			 * @returns {string} merged text
+			 */
+			const concat = (...text) => text.join("");
+			return [
+				this.generateBeforeLoadBinaryCode
+					? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
+					: "",
+				`var req = ${loader};`,
+				`var fallback = ${runtimeTemplate.returningFunction(
+					Template.asString(["req", Template.indent(fallback)])
+				)};`,
+				concat(
+					"return req.then(",
+					runtimeTemplate.basicFunction("res", [
+						'if (typeof WebAssembly.compileStreaming === "function") {',
+						Template.indent(
+							this.generateBeforeCompileStreaming
+								? this.generateBeforeCompileStreaming()
+								: ""
+						),
+						Template.indent([
+							"return WebAssembly.compileStreaming(res)",
+							Template.indent([
+								".catch(",
+								Template.indent([
+									runtimeTemplate.basicFunction("e", [
+										'if(res.headers.get("Content-Type") !== "application/wasm") {',
+										Template.indent([
+											'console.warn("`WebAssembly.compileStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.compile` which is slower. Original error:\\n", e);',
+											"return fallback();"
+										]),
+										"}",
+										"throw e;"
+									])
+								]),
+								");"
+							])
+						]),
+						"}",
+						"return fallback();"
+					]),
+					");"
+				)
+			];
+		};
+
+		return `${fn} = ${runtimeTemplate.basicFunction(
+			"wasmModuleId, wasmModuleHash",
+			this.supportsStreaming
+				? getStreaming()
+				: [
+						this.generateBeforeLoadBinaryCode
+							? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
+							: "",
+						`return ${loader}`,
+						`${Template.indent(fallback)};`
+					]
+		)};`;
+	}
+}
+
+module.exports = AsyncWasmCompileRuntimeModule;
Index: frontend/node_modules/webpack/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,155 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+
+/** @typedef {(wasmModuleSrcPath: string) => string} GenerateBeforeLoadBinaryCode */
+/** @typedef {(wasmModuleSrcPath: string) => string} GenerateLoadBinaryCode */
+/** @typedef {() => string} GenerateBeforeInstantiateStreaming */
+
+/**
+ * @typedef {object} AsyncWasmLoadingRuntimeModuleOptions
+ * @property {GenerateLoadBinaryCode} generateLoadBinaryCode
+ * @property {GenerateBeforeLoadBinaryCode=} generateBeforeLoadBinaryCode
+ * @property {GenerateBeforeInstantiateStreaming=} generateBeforeInstantiateStreaming
+ * @property {boolean} supportsStreaming
+ */
+
+class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {AsyncWasmLoadingRuntimeModuleOptions} options options
+	 */
+	constructor({
+		generateLoadBinaryCode,
+		generateBeforeLoadBinaryCode,
+		generateBeforeInstantiateStreaming,
+		supportsStreaming
+	}) {
+		super("wasm loading", RuntimeModule.STAGE_NORMAL);
+		/** @type {GenerateLoadBinaryCode} */
+		this.generateLoadBinaryCode = generateLoadBinaryCode;
+		/** @type {generateBeforeLoadBinaryCode | undefined} */
+		this.generateBeforeLoadBinaryCode = generateBeforeLoadBinaryCode;
+		/** @type {generateBeforeInstantiateStreaming | undefined} */
+		this.generateBeforeInstantiateStreaming =
+			generateBeforeInstantiateStreaming;
+		/** @type {boolean} */
+		this.supportsStreaming = supportsStreaming;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const { outputOptions, runtimeTemplate } = compilation;
+		const fn = RuntimeGlobals.instantiateWasm;
+		const wasmModuleSrcPath = compilation.getPath(
+			JSON.stringify(outputOptions.webassemblyModuleFilename),
+			{
+				hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+				hashWithLength: (length) =>
+					`" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
+				module: {
+					id: '" + wasmModuleId + "',
+					hash: '" + wasmModuleHash + "',
+					hashWithLength(length) {
+						return `" + wasmModuleHash.slice(0, ${length}) + "`;
+					}
+				},
+				runtime: chunk.runtime
+			}
+		);
+
+		const loader = this.generateLoadBinaryCode(wasmModuleSrcPath);
+		const fallback = [
+			`.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`,
+			`.then(${runtimeTemplate.returningFunction(
+				"WebAssembly.instantiate(bytes, importsObj)",
+				"bytes"
+			)})`,
+			`.then(${runtimeTemplate.returningFunction(
+				"Object.assign(exports, res.instance.exports)",
+				"res"
+			)})`
+		];
+		const getStreaming = () => {
+			/**
+			 * @param {string[]} text text
+			 * @returns {string} merged text
+			 */
+			const concat = (...text) => text.join("");
+			return [
+				this.generateBeforeLoadBinaryCode
+					? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
+					: "",
+				`var req = ${loader};`,
+				`var fallback = ${runtimeTemplate.returningFunction(
+					Template.asString(["req", Template.indent(fallback)])
+				)};`,
+				concat(
+					"return req.then(",
+					runtimeTemplate.basicFunction("res", [
+						'if (typeof WebAssembly.instantiateStreaming === "function") {',
+						Template.indent(
+							this.generateBeforeInstantiateStreaming
+								? this.generateBeforeInstantiateStreaming()
+								: ""
+						),
+						Template.indent([
+							"return WebAssembly.instantiateStreaming(res, importsObj)",
+							Template.indent([
+								".then(",
+								Template.indent([
+									`${runtimeTemplate.returningFunction(
+										"Object.assign(exports, res.instance.exports)",
+										"res"
+									)},`,
+									runtimeTemplate.basicFunction("e", [
+										'if(res.headers.get("Content-Type") !== "application/wasm") {',
+										Template.indent([
+											'console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);',
+											"return fallback();"
+										]),
+										"}",
+										"throw e;"
+									])
+								]),
+								");"
+							])
+						]),
+						"}",
+						"return fallback();"
+					]),
+					");"
+				)
+			];
+		};
+
+		return `${fn} = ${runtimeTemplate.basicFunction(
+			"exports, wasmModuleId, wasmModuleHash, importsObj",
+			this.supportsStreaming
+				? getStreaming()
+				: [
+						this.generateBeforeLoadBinaryCode
+							? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
+							: "",
+						`return ${loader}`,
+						`${Template.indent(fallback)};`
+					]
+		)};`;
+	}
+}
+
+module.exports = AsyncWasmLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,80 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Generator = require("../Generator");
+const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypeConstants");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+/**
+ * Represents the async web assembly generator runtime component.
+ * @typedef {object} AsyncWebAssemblyGeneratorOptions
+ * @property {boolean=} mangleImports mangle imports
+ */
+
+class AsyncWebAssemblyGenerator extends Generator {
+	/**
+	 * Creates an instance of AsyncWebAssemblyGenerator.
+	 * @param {AsyncWebAssemblyGeneratorOptions} options options
+	 */
+	constructor(options) {
+		super();
+		/** @type {AsyncWebAssemblyGeneratorOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return WEBASSEMBLY_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const originalSource = module.originalSource();
+		if (!originalSource) {
+			return 0;
+		}
+		return originalSource.size();
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		return /** @type {Source} */ (module.originalSource());
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		return new RawSource(error.message);
+	}
+}
+
+module.exports = AsyncWebAssemblyGenerator;
Index: frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,271 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Generator = require("../Generator");
+const InitFragment = require("../InitFragment");
+const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("./AsyncWebAssemblyModulesPlugin").AsyncWasmModuleClass} AsyncWasmModule */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+/**
+ * Represents the async web assembly javascript generator runtime component.
+ * @typedef {{ request: string, importVar: string, dependency: WebAssemblyImportDependency }} ImportObjRequestItem
+ */
+
+class AsyncWebAssemblyJavascriptGenerator extends Generator {
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return WEBASSEMBLY_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		// it's only estimated so this number is probably fine
+		// Example: m.exports=s.v(e,_.id,"6db474f11db19c35388a")
+		if (/** @type {AsyncWasmModule} */ (module).phase === "source") {
+			return 44;
+		}
+
+		return 40 + module.dependencies.length * 10;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const {
+			runtimeTemplate,
+			chunkGraph,
+			moduleGraph,
+			runtimeRequirements,
+			runtime
+		} = generateContext;
+
+		// Check if this is a source phase import
+		if (/** @type {AsyncWasmModule} */ (module).phase === "source") {
+			return this._generateSourcePhase(module, generateContext);
+		}
+
+		runtimeRequirements.add(RuntimeGlobals.module);
+		runtimeRequirements.add(RuntimeGlobals.moduleId);
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.instantiateWasm);
+		/** @type {InitFragment<GenerateContext>[]} */
+		const initFragments = [];
+		/** @type {Map<Module, ImportObjRequestItem>} */
+		const depModules = new Map();
+		/** @type {Map<string, WebAssemblyImportDependency[]>} */
+		const wasmDepsByRequest = new Map();
+		for (const dep of module.dependencies) {
+			if (dep instanceof WebAssemblyImportDependency) {
+				const module = /** @type {Module} */ (moduleGraph.getModule(dep));
+				if (!depModules.has(module)) {
+					depModules.set(module, {
+						request: dep.request,
+						importVar: `WEBPACK_IMPORTED_MODULE_${depModules.size}`,
+						dependency: dep
+					});
+				}
+				let list = wasmDepsByRequest.get(dep.request);
+				if (list === undefined) {
+					list = [];
+					wasmDepsByRequest.set(dep.request, list);
+				}
+				list.push(dep);
+			}
+		}
+
+		/** @type {string[]} */
+		const promises = [];
+
+		const importStatements = Array.from(
+			depModules,
+			([importedModule, { request, importVar, dependency }]) => {
+				if (moduleGraph.isAsync(importedModule)) {
+					promises.push(importVar);
+				}
+				return runtimeTemplate.importStatement({
+					update: false,
+					module: importedModule,
+					moduleGraph,
+					chunkGraph,
+					request,
+					originModule: module,
+					importVar,
+					runtimeRequirements,
+					dependency
+				});
+			}
+		);
+		const importsCode = importStatements.map(([x]) => x).join("");
+		const importsCompatCode = importStatements.map(([_, x]) => x).join("");
+
+		const importObjRequestItems = Array.from(
+			wasmDepsByRequest,
+			([request, deps]) => {
+				const exportItems = deps.map((dep) => {
+					const importedModule =
+						/** @type {Module} */
+						(moduleGraph.getModule(dep));
+					const importVar =
+						/** @type {ImportObjRequestItem} */
+						(depModules.get(importedModule)).importVar;
+					return `${JSON.stringify(
+						dep.name
+					)}: ${runtimeTemplate.exportFromImport({
+						moduleGraph,
+						module: importedModule,
+						chunkGraph,
+						request,
+						exportName: dep.name,
+						originModule: module,
+						asiSafe: true,
+						isCall: false,
+						callContext: false,
+						defaultInterop: true,
+						importVar,
+						initFragments,
+						runtime,
+						runtimeRequirements,
+						dependency: dep
+					})}`;
+				});
+				return Template.asString([
+					`${JSON.stringify(request)}: {`,
+					Template.indent(exportItems.join(",\n")),
+					"}"
+				]);
+			}
+		);
+
+		const importsObj =
+			importObjRequestItems.length > 0
+				? Template.asString([
+						"{",
+						Template.indent(importObjRequestItems.join(",\n")),
+						"}"
+					])
+				: undefined;
+
+		const instantiateCall = `${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${
+			module.moduleArgument
+		}.id, ${JSON.stringify(
+			chunkGraph.getRenderedModuleHash(module, runtime)
+		)}${importsObj ? `, ${importsObj})` : ")"}`;
+
+		if (promises.length > 0) {
+			runtimeRequirements.add(RuntimeGlobals.asyncModule);
+		}
+
+		const source = new RawSource(
+			promises.length > 0
+				? Template.asString([
+						`var __webpack_instantiate__ = ${runtimeTemplate.basicFunction(
+							`[${promises.join(", ")}]`,
+							`${importsCompatCode}return ${instantiateCall};`
+						)}`,
+						`${RuntimeGlobals.asyncModule}(${
+							module.moduleArgument
+						}, async ${runtimeTemplate.basicFunction(
+							"__webpack_handle_async_dependencies__, __webpack_async_result__",
+							[
+								"try {",
+								importsCode,
+								`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${promises.join(
+									", "
+								)}]);`,
+								`var [${promises.join(
+									", "
+								)}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__;`,
+								`${importsCompatCode}await ${instantiateCall};`,
+								"__webpack_async_result__();",
+								"} catch(e) { __webpack_async_result__(e); }"
+							]
+						)}, 1);`
+					])
+				: `${importsCode}${importsCompatCode}module.exports = ${instantiateCall};`
+		);
+
+		return InitFragment.addToSource(source, initFragments, generateContext);
+	}
+
+	/**
+	 * Generate code for source phase import (returns WebAssembly.Module)
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source} generated code
+	 */
+	_generateSourcePhase(module, generateContext) {
+		const { chunkGraph, runtimeTemplate, runtimeRequirements, runtime } =
+			generateContext;
+
+		runtimeRequirements.add(RuntimeGlobals.module);
+		runtimeRequirements.add(RuntimeGlobals.moduleId);
+		runtimeRequirements.add(RuntimeGlobals.exports);
+		runtimeRequirements.add(RuntimeGlobals.compileWasm);
+		runtimeRequirements.add(RuntimeGlobals.asyncModule);
+		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+
+		// Source phase: export default WebAssembly.Module (via compileWasm)
+		const compileCall = `${RuntimeGlobals.compileWasm}(${
+			module.moduleArgument
+		}.id, ${JSON.stringify(chunkGraph.getRenderedModuleHash(module, runtime))})`;
+
+		// Use async module wrapper to handle the Promise from compileWasm
+		return new RawSource(
+			Template.asString([
+				`${RuntimeGlobals.asyncModule}(${
+					module.moduleArgument
+				}, async ${runtimeTemplate.basicFunction(
+					"__webpack_handle_async_dependencies__, __webpack_async_result__",
+					[
+						"try {",
+						`var __webpack_wasm_module__ = await ${compileCall};`,
+						`${RuntimeGlobals.definePropertyGetters}(${module.exportsArgument}, { "default": ${runtimeTemplate.returningFunction("__webpack_wasm_module__")} });`,
+						"__webpack_async_result__();",
+						"} catch(e) { __webpack_async_result__(e); }"
+					]
+				)}, 1);`
+			])
+		);
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
+	}
+}
+
+module.exports = AsyncWebAssemblyJavascriptGenerator;
Index: frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,322 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const Generator = require("../Generator");
+const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
+const NormalModule = require("../NormalModule");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+const { tryRunOrWebpackError } = require("../errors/HookWebpackError");
+const { compareModulesByFullName } = require("../util/comparators");
+const makeSerializable = require("../util/makeSerializable");
+const memoize = require("../util/memoize");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../dependencies/ImportPhase").ImportPhaseName} ImportPhaseName */
+/** @typedef {import("../NormalModule").NormalModuleCreateData} NormalModuleCreateData */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../errors/WebpackError")} WebpackError */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+const getAsyncWebAssemblyGenerator = memoize(() =>
+	require("./AsyncWebAssemblyGenerator")
+);
+const getAsyncWebAssemblyJavascriptGenerator = memoize(() =>
+	require("./AsyncWebAssemblyJavascriptGenerator")
+);
+const getAsyncWebAssemblyParser = memoize(() =>
+	require("./AsyncWebAssemblyParser")
+);
+
+/** @typedef {NormalModule & { phase: ImportPhaseName | undefined }} AsyncWasmModuleClass */
+
+class AsyncWasmModule extends NormalModule {
+	/**
+	 * @param {NormalModuleCreateData & { phase: ImportPhaseName | undefined }} options options object
+	 */
+	constructor(options) {
+		super(options);
+		this.phase = options.phase;
+	}
+
+	/**
+	 * Returns the unique identifier used to reference this module.
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		let str = super.identifier();
+
+		if (this.phase) {
+			str = `${str}|${this.phase}`;
+		}
+
+		return str;
+	}
+
+	/**
+	 * 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 {AsyncWasmModule} */ (module);
+		this.phase = m.phase;
+	}
+
+	/**
+	 * Serializes this instance into the provided serializer context.
+	 * @param {ObjectSerializerContext} context context
+	 */
+	serialize(context) {
+		const { write } = context;
+		write(this.phase);
+		super.serialize(context);
+	}
+
+	/**
+	 * @param {ObjectDeserializerContext} context context
+	 * @returns {AsyncWasmModule} the deserialized object
+	 */
+	static deserialize(context) {
+		const obj = new AsyncWasmModule({
+			// will be deserialized by Module
+			layer: /** @type {EXPECTED_ANY} */ (null),
+			type: "",
+			// will be filled by updateCacheModule
+			resource: "",
+			context: "",
+			request: /** @type {EXPECTED_ANY} */ (null),
+			userRequest: /** @type {EXPECTED_ANY} */ (null),
+			rawRequest: /** @type {EXPECTED_ANY} */ (null),
+			loaders: /** @type {EXPECTED_ANY} */ (null),
+			matchResource: /** @type {EXPECTED_ANY} */ (null),
+			parser: /** @type {EXPECTED_ANY} */ (null),
+			parserOptions: /** @type {EXPECTED_ANY} */ (null),
+			generator: /** @type {EXPECTED_ANY} */ (null),
+			generatorOptions: /** @type {EXPECTED_ANY} */ (null),
+			resolveOptions: /** @type {EXPECTED_ANY} */ (null),
+			extractSourceMap: /** @type {EXPECTED_ANY} */ (null),
+			phase: /** @type {EXPECTED_ANY} */ (null)
+		});
+		obj.deserialize(context);
+		return obj;
+	}
+
+	/**
+	 * Restores this instance from the provided deserializer context.
+	 * @param {ObjectDeserializerContext} context context
+	 */
+	deserialize(context) {
+		const { read } = context;
+		this.phase = read();
+		super.deserialize(context);
+	}
+}
+
+makeSerializable(AsyncWasmModule, "webpack/lib/wasm-async/AsyncWasmModule");
+
+/**
+ * Defines the web assembly render context type used by this module.
+ * @typedef {object} WebAssemblyRenderContext
+ * @property {Chunk} chunk the chunk
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
+ * @property {ModuleGraph} moduleGraph the module graph
+ * @property {ChunkGraph} chunkGraph the chunk graph
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
+ */
+
+/**
+ * Defines the compilation hooks type used by this module.
+ * @typedef {object} CompilationHooks
+ * @property {SyncWaterfallHook<[Source, Module, WebAssemblyRenderContext]>} renderModuleContent
+ */
+
+/**
+ * Defines the async web assembly modules plugin options type used by this module.
+ * @typedef {object} AsyncWebAssemblyModulesPluginOptions
+ * @property {boolean=} mangleImports mangle imports
+ */
+
+/** @type {WeakMap<Compilation, CompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+const PLUGIN_NAME = "AsyncWebAssemblyModulesPlugin";
+
+class AsyncWebAssemblyModulesPlugin {
+	/**
+	 * Returns the attached hooks.
+	 * @param {Compilation} compilation the compilation
+	 * @returns {CompilationHooks} the attached hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				renderModuleContent: new SyncWaterfallHook([
+					"source",
+					"module",
+					"renderContext"
+				])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * Creates an instance of AsyncWebAssemblyModulesPlugin.
+	 * @param {AsyncWebAssemblyModulesPluginOptions} options options
+	 */
+	constructor(options) {
+		/** @type {AsyncWebAssemblyModulesPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				const hooks =
+					AsyncWebAssemblyModulesPlugin.getCompilationHooks(compilation);
+				compilation.dependencyFactories.set(
+					WebAssemblyImportDependency,
+					normalModuleFactory
+				);
+
+				normalModuleFactory.hooks.createModuleClass
+					.for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
+					.tap(
+						PLUGIN_NAME,
+						(createData, resolveData) =>
+							new AsyncWasmModule({
+								...createData,
+								phase: resolveData.phase
+							})
+					);
+
+				normalModuleFactory.hooks.createParser
+					.for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
+					.tap(PLUGIN_NAME, () => {
+						const AsyncWebAssemblyParser = getAsyncWebAssemblyParser();
+
+						return new AsyncWebAssemblyParser();
+					});
+				normalModuleFactory.hooks.createGenerator
+					.for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
+					.tap(PLUGIN_NAME, () => {
+						const AsyncWebAssemblyJavascriptGenerator =
+							getAsyncWebAssemblyJavascriptGenerator();
+						const AsyncWebAssemblyGenerator = getAsyncWebAssemblyGenerator();
+
+						return Generator.byType({
+							javascript: new AsyncWebAssemblyJavascriptGenerator(),
+							webassembly: new AsyncWebAssemblyGenerator(this.options)
+						});
+					});
+
+				compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
+					const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
+					const {
+						chunk,
+						outputOptions,
+						dependencyTemplates,
+						codeGenerationResults
+					} = options;
+
+					for (const module of chunkGraph.getOrderedChunkModulesIterable(
+						chunk,
+						compareModulesByFullName(compiler)
+					)) {
+						if (module.type === WEBASSEMBLY_MODULE_TYPE_ASYNC) {
+							const filenameTemplate = outputOptions.webassemblyModuleFilename;
+
+							result.push({
+								render: () =>
+									this.renderModule(
+										module,
+										{
+											chunk,
+											dependencyTemplates,
+											runtimeTemplate,
+											moduleGraph,
+											chunkGraph,
+											codeGenerationResults
+										},
+										hooks
+									),
+								filenameTemplate,
+								pathOptions: {
+									module,
+									runtime: chunk.runtime,
+									chunkGraph
+								},
+								auxiliary: true,
+								identifier: `webassemblyAsyncModule${chunkGraph.getModuleId(
+									module
+								)}`,
+								hash: chunkGraph.getModuleHash(module, chunk.runtime)
+							});
+						}
+					}
+
+					return result;
+				});
+			}
+		);
+	}
+
+	/**
+	 * Renders the newly generated source from rendering.
+	 * @param {Module} module the rendered module
+	 * @param {WebAssemblyRenderContext} renderContext options object
+	 * @param {CompilationHooks} hooks hooks
+	 * @returns {Source} the newly generated source from rendering
+	 */
+	renderModule(module, renderContext, hooks) {
+		const { codeGenerationResults, chunk } = renderContext;
+		try {
+			const moduleSource = codeGenerationResults.getSource(
+				module,
+				chunk.runtime,
+				"webassembly"
+			);
+			return tryRunOrWebpackError(
+				() =>
+					hooks.renderModuleContent.call(moduleSource, module, renderContext),
+				"AsyncWebAssemblyModulesPlugin.getCompilationHooks().renderModuleContent"
+			);
+		} catch (err) {
+			/** @type {WebpackError} */ (err).module = module;
+			throw err;
+		}
+	}
+}
+
+module.exports = AsyncWebAssemblyModulesPlugin;
Index: frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyParser.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,105 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const t = require("@webassemblyjs/ast");
+const { decode } = require("@webassemblyjs/wasm-parser");
+const Parser = require("../Parser");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+const EnvironmentNotSupportAsyncWarning = require("../errors/EnvironmentNotSupportAsyncWarning");
+
+/** @typedef {import("./AsyncWebAssemblyModulesPlugin").AsyncWasmModuleClass} AsyncWasmModule */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+const WASM_HEADER = Buffer.from([0x00, 0x61, 0x73, 0x6d]);
+
+const decoderOpts = {
+	ignoreCodeSection: true,
+	ignoreDataSection: true,
+
+	// this will avoid having to lookup with identifiers in the ModuleContext
+	ignoreCustomNameSection: true
+};
+
+class WebAssemblyParser extends Parser {
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (!Buffer.isBuffer(source)) {
+			throw new Error("WebAssemblyParser input must be a Buffer");
+		}
+
+		const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
+		buildMeta.exportsType = "namespace";
+		buildMeta.async = true;
+
+		EnvironmentNotSupportAsyncWarning.check(
+			state.module,
+			state.compilation.runtimeTemplate,
+			"asyncWebAssembly"
+		);
+
+		// flag it as async module
+		const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo);
+
+		buildInfo.strict = true;
+
+		if (/** @type {AsyncWasmModule} */ (state.module).phase === "source") {
+			// For source phase, only validate magic header
+			if (source.length < 4 || !source.subarray(0, 4).equals(WASM_HEADER)) {
+				throw new Error(
+					"Source phase imports require valid WebAssembly modules. Invalid magic header (expected \\0asm)."
+				);
+			}
+
+			// Source phase exports the WebAssembly.Module as default
+			state.module.addDependency(
+				new StaticExportsDependency(["default"], false)
+			);
+
+			// Skip full parsing - no exports/imports needed for source phase
+			return state;
+		}
+
+		// parse it
+		const program = decode(source, decoderOpts);
+		const module = program.body[0];
+		/** @type {string[]} */
+		const exports = [];
+
+		t.traverse(module, {
+			ModuleExport({ node }) {
+				exports.push(node.name);
+			},
+
+			ModuleImport({ node }) {
+				const dep = new WebAssemblyImportDependency(
+					node.module,
+					node.name,
+					node.descr,
+					false
+				);
+
+				state.module.addDependency(dep);
+			}
+		});
+
+		state.module.addDependency(new StaticExportsDependency(exports, false));
+
+		return state;
+	}
+}
+
+module.exports = WebAssemblyParser;
Index: frontend/node_modules/webpack/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,142 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Alexander Akait @alexander-akait
+*/
+
+"use strict";
+
+const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const AsyncWasmCompileRuntimeModule = require("../wasm-async/AsyncWasmCompileRuntimeModule");
+const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "UniversalCompileAsyncWasmPlugin";
+
+/**
+ * Enables async WebAssembly loading that works in both browser-like and Node.js
+ * environments by selecting the appropriate binary-loading strategy at runtime.
+ */
+class UniversalCompileAsyncWasmPlugin {
+	/**
+	 * Registers compilation hooks that attach the universal async wasm runtime
+	 * to chunks using `wasmLoading: "universal"`.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalWasmLoading = compilation.outputOptions.wasmLoading;
+			/**
+			 * Determines whether the chunk should use the universal async wasm
+			 * loading backend.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const wasmLoading =
+					options && options.wasmLoading !== undefined
+						? options.wasmLoading
+						: globalWasmLoading;
+				return wasmLoading === "universal";
+			};
+			const generateBeforeStreaming = () =>
+				Template.asString([
+					"if (!useFetch) {",
+					Template.indent(["return fallback();"]),
+					"}"
+				]);
+			/**
+			 * Generates setup code that decides whether the current environment can
+			 * use `fetch` and captures the wasm module URL.
+			 * @param {string} path path
+			 * @returns {string} code
+			 */
+			const generateBeforeLoadBinaryCode = (path) =>
+				Template.asString([
+					"var useFetch = typeof document !== 'undefined' || typeof self !== 'undefined';",
+					`var wasmUrl = ${path};`
+				]);
+			/**
+			 * Generates the runtime expression that fetches the binary in browsers
+			 * or reads it from the filesystem in Node.js.
+			 * @type {(path: string) => string}
+			 */
+			const generateLoadBinaryCode = () =>
+				Template.asString([
+					"(useFetch",
+					Template.indent([
+						`? fetch(new URL(wasmUrl, ${compilation.outputOptions.importMetaName}.url))`
+					]),
+					Template.indent([
+						": Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
+						Template.indent([
+							`readFile(new URL(wasmUrl, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
+							Template.indent([
+								"if (err) return reject(err);",
+								"",
+								"// Fake fetch response",
+								"resolve({",
+								Template.indent(["arrayBuffer() { return buffer; }"]),
+								"});"
+							]),
+							"});"
+						]),
+						"})))"
+					])
+				]);
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.instantiateWasm)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
+						)
+					) {
+						return;
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncWasmLoadingRuntimeModule({
+							generateBeforeLoadBinaryCode,
+							generateLoadBinaryCode,
+							generateBeforeInstantiateStreaming: generateBeforeStreaming,
+							supportsStreaming: true
+						})
+					);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.compileWasm)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
+						)
+					) {
+						return;
+					}
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncWasmCompileRuntimeModule({
+							generateBeforeLoadBinaryCode,
+							generateLoadBinaryCode,
+							generateBeforeCompileStreaming: generateBeforeStreaming,
+							supportsStreaming: true
+						})
+					);
+				});
+		});
+	}
+}
+
+module.exports = UniversalCompileAsyncWasmPlugin;
Index: frontend/node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+
+class UnsupportedWebAssemblyFeatureError extends WebpackError {
+	/**
+	 * Creates an instance of UnsupportedWebAssemblyFeatureError.
+	 * @param {string} message Error message
+	 */
+	constructor(message) {
+		super(message);
+
+		/** @type {string} */
+		this.name = "UnsupportedWebAssemblyFeatureError";
+		this.hideStack = true;
+	}
+}
+
+module.exports = UnsupportedWebAssemblyFeatureError;
Index: frontend/node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,423 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const { compareModulesByIdentifier } = require("../util/comparators");
+const WebAssemblyUtils = require("./WebAssemblyUtils");
+
+/** @typedef {import("@webassemblyjs/ast").Signature} Signature */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+// TODO webpack 6 remove the whole folder
+
+// Get all wasm modules
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Chunk} chunk the chunk
+ * @returns {Module[]} all wasm modules
+ */
+const getAllWasmModules = (moduleGraph, chunkGraph, chunk) => {
+	const wasmModules = chunk.getAllAsyncChunks();
+	/** @type {Module[]} */
+	const array = [];
+	for (const chunk of wasmModules) {
+		for (const m of chunkGraph.getOrderedChunkModulesIterable(
+			chunk,
+			compareModulesByIdentifier
+		)) {
+			if (m.type.startsWith("webassembly")) {
+				array.push(m);
+			}
+		}
+	}
+
+	return array;
+};
+
+/** @typedef {string[]} Declarations */
+
+/**
+ * generates the import object function for a module
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Module} module the module
+ * @param {boolean | undefined} mangle mangle imports
+ * @param {Declarations} declarations array where declarations are pushed to
+ * @param {RuntimeSpec} runtime the runtime
+ * @returns {string} source code
+ */
+const generateImportObject = (
+	chunkGraph,
+	module,
+	mangle,
+	declarations,
+	runtime
+) => {
+	const moduleGraph = chunkGraph.moduleGraph;
+	/** @type {Map<string, ModuleId>} */
+	const waitForInstances = new Map();
+	/** @type {{ module: string, name: string, value: string }[]} */
+	const properties = [];
+	const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies(
+		moduleGraph,
+		module,
+		mangle
+	);
+	for (const usedDep of usedWasmDependencies) {
+		const dep = usedDep.dependency;
+		const importedModule = moduleGraph.getModule(dep);
+		const exportName = dep.name;
+		const usedName =
+			importedModule &&
+			moduleGraph
+				.getExportsInfo(importedModule)
+				.getUsedName(exportName, runtime);
+		const description = dep.description;
+		const direct = dep.onlyDirectImport;
+
+		const module = usedDep.module;
+		const name = usedDep.name;
+
+		if (direct) {
+			const instanceVar = `m${waitForInstances.size}`;
+			waitForInstances.set(
+				instanceVar,
+				/** @type {ModuleId} */
+				(chunkGraph.getModuleId(/** @type {Module} */ (importedModule)))
+			);
+			properties.push({
+				module,
+				name,
+				value: `${instanceVar}[${JSON.stringify(usedName)}]`
+			});
+		} else {
+			const params =
+				/** @type {Signature} */
+				(description.signature).params.map(
+					(param, k) => `p${k}${param.valtype}`
+				);
+
+			const mod = `${RuntimeGlobals.moduleCache}[${JSON.stringify(
+				chunkGraph.getModuleId(/** @type {Module} */ (importedModule))
+			)}]`;
+			const modExports = `${mod}.exports`;
+
+			const cache = `wasmImportedFuncCache${declarations.length}`;
+			declarations.push(`var ${cache};`);
+
+			const modCode =
+				/** @type {Module} */
+				(importedModule).type.startsWith("webassembly")
+					? `${mod} ? ${modExports}[${JSON.stringify(usedName)}] : `
+					: "";
+
+			properties.push({
+				module,
+				name,
+				value: Template.asString([
+					`${modCode}function(${params}) {`,
+					Template.indent([
+						`if(${cache} === undefined) ${cache} = ${modExports};`,
+						`return ${cache}[${JSON.stringify(usedName)}](${params});`
+					]),
+					"}"
+				])
+			});
+		}
+	}
+
+	/** @type {string[]} */
+	let importObject;
+	if (mangle) {
+		importObject = [
+			"return {",
+			Template.indent([
+				properties
+					.map((p) => `${JSON.stringify(p.name)}: ${p.value}`)
+					.join(",\n")
+			]),
+			"};"
+		];
+	} else {
+		/** @type {Map<string, { name: string, value: string }[]>} */
+		const propertiesByModule = new Map();
+		for (const p of properties) {
+			let list = propertiesByModule.get(p.module);
+			if (list === undefined) {
+				propertiesByModule.set(p.module, (list = []));
+			}
+			list.push(p);
+		}
+		importObject = [
+			"return {",
+			Template.indent([
+				Array.from(propertiesByModule, ([module, list]) =>
+					Template.asString([
+						`${JSON.stringify(module)}: {`,
+						Template.indent([
+							list
+								.map((p) => `${JSON.stringify(p.name)}: ${p.value}`)
+								.join(",\n")
+						]),
+						"}"
+					])
+				).join(",\n")
+			]),
+			"};"
+		];
+	}
+
+	const moduleIdStringified = JSON.stringify(chunkGraph.getModuleId(module));
+	if (waitForInstances.size === 1) {
+		const moduleId = [...waitForInstances.values()][0];
+		const promise = `installedWasmModules[${JSON.stringify(moduleId)}]`;
+		const variable = [...waitForInstances.keys()][0];
+		return Template.asString([
+			`${moduleIdStringified}: function() {`,
+			Template.indent([
+				`return promiseResolve().then(function() { return ${promise}; }).then(function(${variable}) {`,
+				Template.indent(importObject),
+				"});"
+			]),
+			"},"
+		]);
+	} else if (waitForInstances.size > 0) {
+		const promises = Array.from(
+			waitForInstances.values(),
+			(id) => `installedWasmModules[${JSON.stringify(id)}]`
+		).join(", ");
+		const variables = Array.from(
+			waitForInstances.keys(),
+			(name, i) => `${name} = array[${i}]`
+		).join(", ");
+		return Template.asString([
+			`${moduleIdStringified}: function() {`,
+			Template.indent([
+				`return promiseResolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`,
+				Template.indent([`var ${variables};`, ...importObject]),
+				"});"
+			]),
+			"},"
+		]);
+	}
+	return Template.asString([
+		`${moduleIdStringified}: function() {`,
+		Template.indent(importObject),
+		"},"
+	]);
+};
+
+/**
+ * @typedef {object} WasmChunkLoadingRuntimeModuleOptions
+ * @property {(path: string) => string} generateLoadBinaryCode
+ * @property {boolean=} supportsStreaming
+ * @property {boolean=} mangleImports
+ * @property {ReadOnlyRuntimeRequirements} runtimeRequirements
+ */
+
+class WasmChunkLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {WasmChunkLoadingRuntimeModuleOptions} options options
+	 */
+	constructor({
+		generateLoadBinaryCode,
+		supportsStreaming,
+		mangleImports,
+		runtimeRequirements
+	}) {
+		super("wasm chunk loading", RuntimeModule.STAGE_ATTACH);
+		this.generateLoadBinaryCode = generateLoadBinaryCode;
+		this.supportsStreaming = supportsStreaming;
+		this.mangleImports = mangleImports;
+		this._runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const withHmr = this._runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const { moduleGraph, outputOptions } = compilation;
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const wasmModules = getAllWasmModules(moduleGraph, chunkGraph, chunk);
+		const { mangleImports } = this;
+		/** @type {Declarations} */
+		const declarations = [];
+		const importObjects = wasmModules.map((module) =>
+			generateImportObject(
+				chunkGraph,
+				module,
+				mangleImports,
+				declarations,
+				chunk.runtime
+			)
+		);
+		const chunkModuleIdMap = chunkGraph.getChunkModuleIdMap(chunk, (m) =>
+			m.type.startsWith("webassembly")
+		);
+		/**
+		 * @param {string} content content
+		 * @returns {string} created import object
+		 */
+		const createImportObject = (content) =>
+			mangleImports
+				? `{ ${JSON.stringify(WebAssemblyUtils.MANGLED_MODULE)}: ${content} }`
+				: content;
+		const wasmModuleSrcPath = compilation.getPath(
+			JSON.stringify(outputOptions.webassemblyModuleFilename),
+			{
+				hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+				hashWithLength: (length) =>
+					`" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
+				module: {
+					id: '" + wasmModuleId + "',
+					hash: `" + ${JSON.stringify(
+						chunkGraph.getChunkModuleRenderedHashMap(chunk, (m) =>
+							m.type.startsWith("webassembly")
+						)
+					)}[chunkId][wasmModuleId] + "`,
+					hashWithLength(length) {
+						return `" + ${JSON.stringify(
+							chunkGraph.getChunkModuleRenderedHashMap(
+								chunk,
+								(m) => m.type.startsWith("webassembly"),
+								length
+							)
+						)}[chunkId][wasmModuleId] + "`;
+					}
+				},
+				runtime: chunk.runtime
+			}
+		);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_wasm`
+			: undefined;
+
+		return Template.asString([
+			"// object to store loaded and loading wasm modules",
+			`var installedWasmModules = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{};`,
+			"",
+			// This function is used to delay reading the installed wasm module promises
+			// by a microtask. Sorting them doesn't help because there are edge cases where
+			// sorting is not possible (modules splitted into different chunks).
+			// So we not even trying and solve this by a microtask delay.
+			"function promiseResolve() { return Promise.resolve(); }",
+			"",
+			Template.asString(declarations),
+			"var wasmImportObjects = {",
+			Template.indent(importObjects),
+			"};",
+			"",
+			`var wasmModuleMap = ${JSON.stringify(
+				chunkModuleIdMap,
+				undefined,
+				"\t"
+			)};`,
+			"",
+			"// object with all WebAssembly.instance exports",
+			`${RuntimeGlobals.wasmInstances} = {};`,
+			"",
+			"// Fetch + compile chunk loading for webassembly",
+			`${fn}.wasm = function(chunkId, promises) {`,
+			Template.indent([
+				"",
+				"var wasmModules = wasmModuleMap[chunkId] || [];",
+				"",
+				"wasmModules.forEach(function(wasmModuleId, idx) {",
+				Template.indent([
+					"var installedWasmModuleData = installedWasmModules[wasmModuleId];",
+					"",
+					'// a Promise means "currently loading" or "already loaded".',
+					"if(installedWasmModuleData)",
+					Template.indent(["promises.push(installedWasmModuleData);"]),
+					"else {",
+					Template.indent([
+						"var importObject = wasmImportObjects[wasmModuleId]();",
+						`var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`,
+						"var promise;",
+						this.supportsStreaming
+							? Template.asString([
+									"if(importObject && typeof importObject.then === 'function' && typeof WebAssembly.compileStreaming === 'function') {",
+									Template.indent([
+										"promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {",
+										Template.indent([
+											`return WebAssembly.instantiate(items[0], ${createImportObject(
+												"items[1]"
+											)});`
+										]),
+										"});"
+									]),
+									"} else if(typeof WebAssembly.instantiateStreaming === 'function') {",
+									Template.indent([
+										`promise = WebAssembly.instantiateStreaming(req, ${createImportObject(
+											"importObject"
+										)});`
+									])
+								])
+							: Template.asString([
+									"if(importObject && typeof importObject.then === 'function') {",
+									Template.indent([
+										"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });",
+										"promise = Promise.all([",
+										Template.indent([
+											"bytesPromise.then(function(bytes) { return WebAssembly.compile(bytes); }),",
+											"importObject"
+										]),
+										"]).then(function(items) {",
+										Template.indent([
+											`return WebAssembly.instantiate(items[0], ${createImportObject(
+												"items[1]"
+											)});`
+										]),
+										"});"
+									])
+								]),
+						"} else {",
+						Template.indent([
+							"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });",
+							"promise = bytesPromise.then(function(bytes) {",
+							Template.indent([
+								`return WebAssembly.instantiate(bytes, ${createImportObject(
+									"importObject"
+								)});`
+							]),
+							"});"
+						]),
+						"}",
+						"promises.push(installedWasmModules[wasmModuleId] = promise.then(function(res) {",
+						Template.indent([
+							`return ${RuntimeGlobals.wasmInstances}[wasmModuleId] = (res.instance || res).exports;`
+						]),
+						"}));"
+					]),
+					"}"
+				]),
+				"});"
+			]),
+			"};"
+		]);
+	}
+}
+
+module.exports = WasmChunkLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,91 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const formatLocation = require("../util/formatLocation");
+const UnsupportedWebAssemblyFeatureError = require("./UnsupportedWebAssemblyFeatureError");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+
+const PLUGIN_NAME = "WasmFinalizeExportsPlugin";
+
+class WasmFinalizeExportsPlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
+			compilation.hooks.finishModules.tap(PLUGIN_NAME, (modules) => {
+				for (const module of modules) {
+					// 1. if a WebAssembly module
+					if (module.type.startsWith("webassembly") === true) {
+						const jsIncompatibleExports =
+							/** @type {BuildMeta} */
+							(module.buildMeta).jsIncompatibleExports;
+
+						if (jsIncompatibleExports === undefined) {
+							continue;
+						}
+
+						for (const connection of compilation.moduleGraph.getIncomingConnections(
+							module
+						)) {
+							// 2. is active and referenced by a non-WebAssembly module
+							if (
+								connection.isTargetActive(undefined) &&
+								/** @type {Module} */
+								(connection.originModule).type.startsWith("webassembly") ===
+									false
+							) {
+								const referencedExports =
+									compilation.getDependencyReferencedExports(
+										/** @type {Dependency} */ (connection.dependency),
+										undefined
+									);
+
+								for (const info of referencedExports) {
+									const names = Array.isArray(info) ? info : info.name;
+									if (names.length === 0) continue;
+									const name = names[0];
+									if (typeof name === "object") continue;
+									// 3. and uses a func with an incompatible JS signature
+									if (
+										Object.prototype.hasOwnProperty.call(
+											jsIncompatibleExports,
+											name
+										)
+									) {
+										// 4. error
+										const error = new UnsupportedWebAssemblyFeatureError(
+											`Export "${name}" with ${jsIncompatibleExports[name]} can only be used for direct wasm to wasm dependencies\n` +
+												`It's used from ${
+													/** @type {Module} */
+													(connection.originModule).readableIdentifier(
+														compilation.requestShortener
+													)
+												} at ${formatLocation(
+													/** @type {Dependency} */ (connection.dependency).loc
+												)}.`
+										);
+										error.module = module;
+										compilation.errors.push(error);
+									}
+								}
+							}
+						}
+					}
+				}
+			});
+		});
+	}
+}
+
+module.exports = WasmFinalizeExportsPlugin;
Index: frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,560 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const t = require("@webassemblyjs/ast");
+const { moduleContextFromModuleAST } = require("@webassemblyjs/ast");
+const { addWithAST, editWithAST } = require("@webassemblyjs/wasm-edit");
+const { decode } = require("@webassemblyjs/wasm-parser");
+const { RawSource } = require("webpack-sources");
+const Generator = require("../Generator");
+const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypeConstants");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyUtils = require("./WebAssemblyUtils");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */
+/** @typedef {import("@webassemblyjs/ast").Instruction} Instruction */
+/** @typedef {import("@webassemblyjs/ast").ModuleImport} ModuleImport */
+/** @typedef {import("@webassemblyjs/ast").ModuleExport} ModuleExport */
+/** @typedef {import("@webassemblyjs/ast").Global} Global */
+/** @typedef {import("@webassemblyjs/ast").AST} AST */
+/** @typedef {import("@webassemblyjs/ast").GlobalType} GlobalType */
+/**
+ * Defines the node path type used by this module.
+ * @template T
+ * @typedef {import("@webassemblyjs/ast").NodePath<T>} NodePath
+ */
+
+/**
+ * Defines the array buffer transform type used by this module.
+ * @typedef {(buf: ArrayBuffer) => ArrayBuffer} ArrayBufferTransform
+ */
+
+/**
+ * Returns composed transform.
+ * @template T
+ * @param {((prev: ArrayBuffer) => ArrayBuffer)[]} fns transforms
+ * @returns {(buf: ArrayBuffer) => ArrayBuffer} composed transform
+ */
+const compose = (...fns) =>
+	fns.reduce(
+		(prevFn, nextFn) => (value) => nextFn(prevFn(value)),
+		(value) => value
+	);
+
+/**
+ * Removes start func.
+ * @param {object} state state
+ * @param {AST} state.ast Module's ast
+ * @returns {ArrayBufferTransform} transform
+ */
+const removeStartFunc = (state) => (bin) =>
+	editWithAST(state.ast, bin, {
+		Start(path) {
+			path.remove();
+		}
+	});
+
+/**
+ * Get imported globals
+ * @param {AST} ast Module's AST
+ * @returns {t.ModuleImport[]} - nodes
+ */
+const getImportedGlobals = (ast) => {
+	/** @type {t.ModuleImport[]} */
+	const importedGlobals = [];
+
+	t.traverse(ast, {
+		ModuleImport({ node }) {
+			if (t.isGlobalType(node.descr)) {
+				importedGlobals.push(node);
+			}
+		}
+	});
+
+	return importedGlobals;
+};
+
+/**
+ * Get the count for imported func
+ * @param {AST} ast Module's AST
+ * @returns {number} - count
+ */
+const getCountImportedFunc = (ast) => {
+	let count = 0;
+
+	t.traverse(ast, {
+		ModuleImport({ node }) {
+			if (t.isFuncImportDescr(node.descr)) {
+				count++;
+			}
+		}
+	});
+
+	return count;
+};
+
+/**
+ * Get next type index
+ * @param {AST} ast Module's AST
+ * @returns {t.Index} - index
+ */
+const getNextTypeIndex = (ast) => {
+	const typeSectionMetadata = t.getSectionMetadata(ast, "type");
+
+	if (typeSectionMetadata === undefined) {
+		return t.indexLiteral(0);
+	}
+
+	return t.indexLiteral(typeSectionMetadata.vectorOfSize.value);
+};
+
+/**
+ * Get next func index
+ * The Func section metadata provide information for implemented funcs
+ * in order to have the correct index we shift the index by number of external
+ * functions.
+ * @param {AST} ast Module's AST
+ * @param {number} countImportedFunc number of imported funcs
+ * @returns {t.Index} - index
+ */
+const getNextFuncIndex = (ast, countImportedFunc) => {
+	const funcSectionMetadata = t.getSectionMetadata(ast, "func");
+
+	if (funcSectionMetadata === undefined) {
+		return t.indexLiteral(0 + countImportedFunc);
+	}
+
+	const vectorOfSize = funcSectionMetadata.vectorOfSize.value;
+
+	return t.indexLiteral(vectorOfSize + countImportedFunc);
+};
+
+/**
+ * Creates an init instruction for a global type
+ * @param {t.GlobalType} globalType the global type
+ * @returns {t.Instruction} init expression
+ */
+const createDefaultInitForGlobal = (globalType) => {
+	if (globalType.valtype[0] === "i") {
+		// create NumberLiteral global initializer
+		return t.objectInstruction("const", globalType.valtype, [
+			t.numberLiteralFromRaw(66)
+		]);
+	} else if (globalType.valtype[0] === "f") {
+		// create FloatLiteral global initializer
+		return t.objectInstruction("const", globalType.valtype, [
+			t.floatLiteral(66, false, false, "66")
+		]);
+	}
+	throw new Error(`unknown type: ${globalType.valtype}`);
+};
+
+/**
+ * Rewrite the import globals:
+ * - removes the ModuleImport instruction
+ * - injects at the same offset a mutable global of the same type
+ *
+ * Since the imported globals are before the other global declarations, our
+ * indices will be preserved.
+ *
+ * Note that globals will become mutable.
+ * @param {object} state transformation state
+ * @param {AST} state.ast Module's ast
+ * @param {t.Instruction[]} state.additionalInitCode list of addition instructions for the init function
+ * @returns {ArrayBufferTransform} transform
+ */
+const rewriteImportedGlobals = (state) => (bin) => {
+	const additionalInitCode = state.additionalInitCode;
+	/** @type {t.Global[]} */
+	const newGlobals = [];
+
+	bin = editWithAST(state.ast, bin, {
+		ModuleImport(path) {
+			if (t.isGlobalType(path.node.descr)) {
+				const globalType =
+					/** @type {GlobalType} */
+					(path.node.descr);
+
+				globalType.mutability = "var";
+
+				const init = [
+					createDefaultInitForGlobal(globalType),
+					t.instruction("end")
+				];
+
+				newGlobals.push(t.global(globalType, init));
+
+				path.remove();
+			}
+		},
+
+		// in order to preserve non-imported global's order we need to re-inject
+		// those as well
+		/**
+		 * Processes the provided path.
+		 * @param {NodePath<Global>} path path
+		 */
+		Global(path) {
+			const { node } = path;
+			const [init] = node.init;
+
+			if (init.id === "get_global") {
+				node.globalType.mutability = "var";
+
+				const initialGlobalIdx = init.args[0];
+
+				node.init = [
+					createDefaultInitForGlobal(node.globalType),
+					t.instruction("end")
+				];
+
+				additionalInitCode.push(
+					/**
+					 * get_global in global initializer only works for imported globals.
+					 * They have the same indices as the init params, so use the
+					 * same index.
+					 */
+					t.instruction("get_local", [initialGlobalIdx]),
+					t.instruction("set_global", [t.indexLiteral(newGlobals.length)])
+				);
+			}
+
+			newGlobals.push(node);
+
+			path.remove();
+		}
+	});
+
+	// Add global declaration instructions
+	return addWithAST(state.ast, bin, newGlobals);
+};
+
+/**
+ * Rewrite the export names
+ * @param {object} state state
+ * @param {AST} state.ast Module's ast
+ * @param {Module} state.module Module
+ * @param {ModuleGraph} state.moduleGraph module graph
+ * @param {Set<string>} state.externalExports Module
+ * @param {RuntimeSpec} state.runtime runtime
+ * @returns {ArrayBufferTransform} transform
+ */
+const rewriteExportNames =
+	({ ast, moduleGraph, module, externalExports, runtime }) =>
+	(bin) =>
+		editWithAST(ast, bin, {
+			/**
+			 * Processes the provided path.
+			 * @param {NodePath<ModuleExport>} path path
+			 */
+			ModuleExport(path) {
+				const isExternal = externalExports.has(path.node.name);
+				if (isExternal) {
+					path.remove();
+					return;
+				}
+				const usedName = moduleGraph
+					.getExportsInfo(module)
+					.getUsedName(path.node.name, runtime);
+				if (!usedName) {
+					path.remove();
+					return;
+				}
+				path.node.name = /** @type {string} */ (usedName);
+			}
+		});
+
+/** @typedef {Map<string, UsedWasmDependency>} Mapping */
+
+/**
+ * Mangle import names and modules
+ * @param {object} state state
+ * @param {AST} state.ast Module's ast
+ * @param {Mapping} state.usedDependencyMap mappings to mangle names
+ * @returns {ArrayBufferTransform} transform
+ */
+const rewriteImports =
+	({ ast, usedDependencyMap }) =>
+	(bin) =>
+		editWithAST(ast, bin, {
+			/**
+			 * Processes the provided path.
+			 * @param {NodePath<ModuleImport>} path path
+			 */
+			ModuleImport(path) {
+				const result = usedDependencyMap.get(
+					`${path.node.module}:${path.node.name}`
+				);
+
+				if (result !== undefined) {
+					path.node.module = result.module;
+					path.node.name = result.name;
+				}
+			}
+		});
+
+/**
+ * Add an init function.
+ *
+ * The init function fills the globals given input arguments.
+ * @param {object} state transformation state
+ * @param {AST} state.ast Module's ast
+ * @param {t.Identifier} state.initFuncId identifier of the init function
+ * @param {t.Index} state.startAtFuncOffset index of the start function
+ * @param {t.ModuleImport[]} state.importedGlobals list of imported globals
+ * @param {t.Instruction[]} state.additionalInitCode list of addition instructions for the init function
+ * @param {t.Index} state.nextFuncIndex index of the next function
+ * @param {t.Index} state.nextTypeIndex index of the next type
+ * @returns {ArrayBufferTransform} transform
+ */
+const addInitFunction =
+	({
+		ast,
+		initFuncId,
+		startAtFuncOffset,
+		importedGlobals,
+		additionalInitCode,
+		nextFuncIndex,
+		nextTypeIndex
+	}) =>
+	(bin) => {
+		const funcParams = importedGlobals.map((importedGlobal) => {
+			// used for debugging
+			const id = t.identifier(
+				`${importedGlobal.module}.${importedGlobal.name}`
+			);
+
+			return t.funcParam(
+				/** @type {string} */ (importedGlobal.descr.valtype),
+				id
+			);
+		});
+
+		/** @type {Instruction[]} */
+		const funcBody = [];
+		for (const [index, _importedGlobal] of importedGlobals.entries()) {
+			const args = [t.indexLiteral(index)];
+			const body = [
+				t.instruction("get_local", args),
+				t.instruction("set_global", args)
+			];
+
+			funcBody.push(...body);
+		}
+
+		if (typeof startAtFuncOffset === "number") {
+			funcBody.push(
+				t.callInstruction(t.numberLiteralFromRaw(startAtFuncOffset))
+			);
+		}
+
+		for (const instr of additionalInitCode) {
+			funcBody.push(instr);
+		}
+
+		funcBody.push(t.instruction("end"));
+
+		/** @type {string[]} */
+		const funcResults = [];
+
+		// Code section
+		const funcSignature = t.signature(funcParams, funcResults);
+		const func = t.func(initFuncId, funcSignature, funcBody);
+
+		// Type section
+		const functype = t.typeInstruction(undefined, funcSignature);
+
+		// Func section
+		const funcindex = t.indexInFuncSection(nextTypeIndex);
+
+		// Export section
+		const moduleExport = t.moduleExport(
+			initFuncId.value,
+			t.moduleExportDescr("Func", nextFuncIndex)
+		);
+
+		return addWithAST(ast, bin, [func, moduleExport, funcindex, functype]);
+	};
+
+/**
+ * Extract mangle mappings from module
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {Module} module current module
+ * @param {boolean=} mangle mangle imports
+ * @returns {Mapping} mappings to mangled names
+ */
+const getUsedDependencyMap = (moduleGraph, module, mangle) => {
+	/** @type {Mapping} */
+	const map = new Map();
+	for (const usedDep of WebAssemblyUtils.getUsedDependencies(
+		moduleGraph,
+		module,
+		mangle
+	)) {
+		const dep = usedDep.dependency;
+		const request = dep.request;
+		const exportName = dep.name;
+		map.set(`${request}:${exportName}`, usedDep);
+	}
+	return map;
+};
+
+/**
+ * Represents the web assembly generator runtime component.
+ * @typedef {object} WebAssemblyGeneratorOptions
+ * @property {boolean=} mangleImports mangle imports
+ */
+
+class WebAssemblyGenerator extends Generator {
+	/**
+	 * Creates an instance of WebAssemblyGenerator.
+	 * @param {WebAssemblyGeneratorOptions} options options
+	 */
+	constructor(options) {
+		super();
+		this.options = options;
+	}
+
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return WEBASSEMBLY_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		const originalSource = module.originalSource();
+		if (!originalSource) {
+			return 0;
+		}
+		return originalSource.size();
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, { moduleGraph, runtime }) {
+		const bin =
+			/** @type {Buffer} */
+			(/** @type {Source} */ (module.originalSource()).source());
+
+		const initFuncId = t.identifier("");
+
+		// parse it
+		const ast = decode(bin, {
+			ignoreDataSection: true,
+			ignoreCodeSection: true,
+			ignoreCustomNameSection: true
+		});
+
+		const moduleContext = moduleContextFromModuleAST(ast.body[0]);
+
+		const importedGlobals = getImportedGlobals(ast);
+		const countImportedFunc = getCountImportedFunc(ast);
+		const startAtFuncOffset = moduleContext.getStart();
+		const nextFuncIndex = getNextFuncIndex(ast, countImportedFunc);
+		const nextTypeIndex = getNextTypeIndex(ast);
+
+		const usedDependencyMap = getUsedDependencyMap(
+			moduleGraph,
+			module,
+			this.options.mangleImports
+		);
+		const externalExports = new Set(
+			module.dependencies
+				.filter((d) => d instanceof WebAssemblyExportImportedDependency)
+				.map((d) => {
+					const wasmDep = /** @type {WebAssemblyExportImportedDependency} */ (
+						d
+					);
+					return wasmDep.exportName;
+				})
+		);
+
+		/** @type {t.Instruction[]} */
+		const additionalInitCode = [];
+
+		const transform = compose(
+			rewriteExportNames({
+				ast,
+				moduleGraph,
+				module,
+				externalExports,
+				runtime
+			}),
+
+			removeStartFunc({ ast }),
+
+			rewriteImportedGlobals({ ast, additionalInitCode }),
+
+			rewriteImports({
+				ast,
+				usedDependencyMap
+			}),
+
+			addInitFunction({
+				ast,
+				initFuncId,
+				importedGlobals,
+				additionalInitCode,
+				startAtFuncOffset,
+				nextFuncIndex,
+				nextTypeIndex
+			})
+		);
+
+		const newBin = transform(/** @type {ArrayBuffer} */ (bin.buffer));
+		const newBuf = Buffer.from(newBin);
+
+		return new RawSource(newBuf);
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		return new RawSource(error.message);
+	}
+
+	/**
+	 * Updates the hash with the data contributed by this instance.
+	 * @param {Hash} hash hash that will be modified
+	 * @param {UpdateHashContext} updateHashContext context for updating hash
+	 */
+	updateHash(hash, updateHashContext) {
+		if (this.options.mangleImports) {
+			hash.update("mangle-imports");
+		}
+	}
+}
+
+module.exports = WebAssemblyGenerator;
Index: frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,115 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const WebpackError = require("../errors/WebpackError");
+
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+
+/**
+ * Gets initial module chains.
+ * @param {Module} module module to get chains from
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {RequestShortener} requestShortener to make readable identifiers
+ * @returns {string[]} all chains to the module
+ */
+const getInitialModuleChains = (
+	module,
+	moduleGraph,
+	chunkGraph,
+	requestShortener
+) => {
+	const queue = [
+		{ head: module, message: module.readableIdentifier(requestShortener) }
+	];
+	/** @type {Set<string>} */
+	const results = new Set();
+	/** @type {Set<string>} */
+	const incompleteResults = new Set();
+	/** @type {Set<Module>} */
+	const visitedModules = new Set();
+
+	for (const chain of queue) {
+		const { head, message } = chain;
+		let final = true;
+		/** @type {Set<Module>} */
+		const alreadyReferencedModules = new Set();
+		for (const connection of moduleGraph.getIncomingConnections(head)) {
+			const newHead = connection.originModule;
+			if (newHead) {
+				if (
+					!chunkGraph.getModuleChunks(newHead).some((c) => c.canBeInitial())
+				) {
+					continue;
+				}
+				final = false;
+				if (alreadyReferencedModules.has(newHead)) continue;
+				alreadyReferencedModules.add(newHead);
+				const moduleName = newHead.readableIdentifier(requestShortener);
+				const detail = connection.explanation
+					? ` (${connection.explanation})`
+					: "";
+				const newMessage = `${moduleName}${detail} --> ${message}`;
+				if (visitedModules.has(newHead)) {
+					incompleteResults.add(`... --> ${newMessage}`);
+					continue;
+				}
+				visitedModules.add(newHead);
+				queue.push({
+					head: newHead,
+					message: newMessage
+				});
+			} else {
+				final = false;
+				const newMessage = connection.explanation
+					? `(${connection.explanation}) --> ${message}`
+					: message;
+				results.add(newMessage);
+			}
+		}
+		if (final) {
+			results.add(message);
+		}
+	}
+	for (const result of incompleteResults) {
+		results.add(result);
+	}
+	return [...results];
+};
+
+class WebAssemblyInInitialChunkError extends WebpackError {
+	/**
+	 * Creates an instance of WebAssemblyInInitialChunkError.
+	 * @param {Module} module WASM module
+	 * @param {ModuleGraph} moduleGraph the module graph
+	 * @param {ChunkGraph} chunkGraph the chunk graph
+	 * @param {RequestShortener} requestShortener request shortener
+	 */
+	constructor(module, moduleGraph, chunkGraph, requestShortener) {
+		const moduleChains = getInitialModuleChains(
+			module,
+			moduleGraph,
+			chunkGraph,
+			requestShortener
+		);
+		const message = `WebAssembly module is included in initial chunk.
+This is not allowed, because WebAssembly download and compilation must happen asynchronous.
+Add an async split point (i. e. import()) somewhere between your entrypoint and the WebAssembly module:
+${moduleChains.map((s) => `* ${s}`).join("\n")}`;
+
+		super(message);
+
+		/** @type {string} */
+		this.name = "WebAssemblyInInitialChunkError";
+		this.hideStack = true;
+		this.module = module;
+	}
+}
+
+module.exports = WebAssemblyInInitialChunkError;
Index: frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,240 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const Generator = require("../Generator");
+const InitFragment = require("../InitFragment");
+const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").SourceType} SourceType */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../NormalModule")} NormalModule */
+
+class WebAssemblyJavascriptGenerator extends Generator {
+	/**
+	 * Returns the source types available for this module.
+	 * @param {NormalModule} module fresh module
+	 * @returns {SourceTypes} available types (do not mutate)
+	 */
+	getTypes(module) {
+		return WEBASSEMBLY_TYPES;
+	}
+
+	/**
+	 * Returns the estimated size for the requested source type.
+	 * @param {NormalModule} module the module
+	 * @param {SourceType=} type source type
+	 * @returns {number} estimate size of the module
+	 */
+	getSize(module, type) {
+		return 95 + module.dependencies.length * 5;
+	}
+
+	/**
+	 * Generates generated code for this runtime module.
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generate(module, generateContext) {
+		const {
+			runtimeTemplate,
+			moduleGraph,
+			chunkGraph,
+			runtimeRequirements,
+			runtime
+		} = generateContext;
+		/** @type {InitFragment<GenerateContext>[]} */
+		const initFragments = [];
+
+		const exportsInfo = moduleGraph.getExportsInfo(module);
+
+		let needExportsCopy = false;
+		/** @typedef {{ dependency: ModuleDependency | undefined, importVar: string, index: number, request: string | undefined, names: Set<string>, reexports: string[] }} ImportData */
+		/** @type {Map<Module, ImportData>} */
+		const importedModules = new Map();
+		/** @type {string[]} */
+		const initParams = [];
+		let index = 0;
+		for (const dep of module.dependencies) {
+			const moduleDep =
+				dep && dep instanceof ModuleDependency ? dep : undefined;
+			const mod = moduleGraph.getModule(dep);
+			if (mod) {
+				let importData = importedModules.get(mod);
+				if (importData === undefined) {
+					importedModules.set(
+						mod,
+						(importData = {
+							dependency: moduleDep,
+							importVar: `m${index}`,
+							index,
+							request: (moduleDep && moduleDep.userRequest) || undefined,
+							names: new Set(),
+							reexports: []
+						})
+					);
+					index++;
+				}
+				if (dep instanceof WebAssemblyImportDependency) {
+					importData.names.add(dep.name);
+					if (dep.description.type === "GlobalType") {
+						const exportName = dep.name;
+						const importedModule = moduleGraph.getModule(dep);
+
+						if (importedModule) {
+							const usedName = moduleGraph
+								.getExportsInfo(importedModule)
+								.getUsedName(exportName, runtime);
+							if (usedName) {
+								initParams.push(
+									runtimeTemplate.exportFromImport({
+										moduleGraph,
+										chunkGraph,
+										module: importedModule,
+										request: dep.request,
+										importVar: importData.importVar,
+										originModule: module,
+										exportName: dep.name,
+										asiSafe: true,
+										isCall: false,
+										callContext: null,
+										defaultInterop: true,
+										initFragments,
+										runtime,
+										runtimeRequirements,
+										dependency: dep
+									})
+								);
+							}
+						}
+					}
+				}
+				if (dep instanceof WebAssemblyExportImportedDependency) {
+					importData.names.add(dep.name);
+					const usedName = moduleGraph
+						.getExportsInfo(module)
+						.getUsedName(dep.exportName, runtime);
+					if (usedName) {
+						runtimeRequirements.add(RuntimeGlobals.exports);
+						const exportProp = `${module.exportsArgument}[${JSON.stringify(
+							usedName
+						)}]`;
+						const defineStatement = Template.asString([
+							`${exportProp} = ${runtimeTemplate.exportFromImport({
+								moduleGraph,
+								module: /** @type {Module} */ (moduleGraph.getModule(dep)),
+								chunkGraph,
+								request: dep.request,
+								importVar: importData.importVar,
+								originModule: module,
+								exportName: dep.name,
+								asiSafe: true,
+								isCall: false,
+								callContext: null,
+								defaultInterop: true,
+								initFragments,
+								runtime,
+								runtimeRequirements,
+								dependency: dep
+							})};`,
+							`if(WebAssembly.Global) ${exportProp} = ` +
+								`new WebAssembly.Global({ value: ${JSON.stringify(
+									dep.valueType
+								)} }, ${exportProp});`
+						]);
+						importData.reexports.push(defineStatement);
+						needExportsCopy = true;
+					}
+				}
+			}
+		}
+		const importsCode = Template.asString(
+			Array.from(
+				importedModules,
+				([module, { importVar, request, reexports, dependency }]) => {
+					const importStatement = runtimeTemplate.importStatement({
+						module,
+						moduleGraph,
+						chunkGraph,
+						request,
+						importVar,
+						originModule: module,
+						runtimeRequirements,
+						dependency
+					});
+					return importStatement[0] + importStatement[1] + reexports.join("\n");
+				}
+			)
+		);
+
+		const copyAllExports =
+			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused &&
+			!needExportsCopy;
+
+		// need these globals
+		runtimeRequirements.add(RuntimeGlobals.module);
+		runtimeRequirements.add(RuntimeGlobals.moduleId);
+		runtimeRequirements.add(RuntimeGlobals.wasmInstances);
+		if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
+			runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
+			runtimeRequirements.add(RuntimeGlobals.exports);
+		}
+		if (!copyAllExports) {
+			runtimeRequirements.add(RuntimeGlobals.exports);
+		}
+
+		// create source
+		const source = new RawSource(
+			[
+				'"use strict";',
+				"// Instantiate WebAssembly module",
+				`var wasmExports = ${RuntimeGlobals.wasmInstances}[${module.moduleArgument}.id];`,
+
+				exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused
+					? `${RuntimeGlobals.makeNamespaceObject}(${module.exportsArgument});`
+					: "",
+
+				// this must be before import for circular dependencies
+				"// export exports from WebAssembly module",
+				copyAllExports
+					? `${module.moduleArgument}.exports = wasmExports;`
+					: "for(var name in wasmExports) " +
+						"if(name) " +
+						`${module.exportsArgument}[name] = wasmExports[name];`,
+				"// exec imports from WebAssembly module (for esm order)",
+				importsCode,
+				"",
+				"// exec wasm module",
+				`wasmExports[""](${initParams.join(", ")})`
+			].join("\n")
+		);
+		return InitFragment.addToSource(source, initFragments, generateContext);
+	}
+
+	/**
+	 * Generates fallback output for the provided error condition.
+	 * @param {Error} error the error
+	 * @param {NormalModule} module module for which the code should be generated
+	 * @param {GenerateContext} generateContext context for generate
+	 * @returns {Source | null} generated code
+	 */
+	generateError(error, module, generateContext) {
+		return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
+	}
+}
+
+module.exports = WebAssemblyJavascriptGenerator;
Index: frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,160 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Generator = require("../Generator");
+const {
+	JAVASCRIPT_TYPE,
+	WEBASSEMBLY_TYPE
+} = require("../ModuleSourceTypeConstants");
+const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+const { compareModulesByFullName } = require("../util/comparators");
+const memoize = require("../util/memoize");
+const WebAssemblyInInitialChunkError = require("./WebAssemblyInInitialChunkError");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+const getWebAssemblyGenerator = memoize(() =>
+	require("./WebAssemblyGenerator")
+);
+const getWebAssemblyJavascriptGenerator = memoize(() =>
+	require("./WebAssemblyJavascriptGenerator")
+);
+const getWebAssemblyParser = memoize(() => require("./WebAssemblyParser"));
+
+const PLUGIN_NAME = "WebAssemblyModulesPlugin";
+
+/**
+ * Options that influence how synchronous WebAssembly modules are transformed
+ * and emitted.
+ * @typedef {object} WebAssemblyModulesPluginOptions
+ * @property {boolean=} mangleImports mangle imports
+ */
+
+/**
+ * Adds parser, generator, manifest, and validation support for synchronous
+ * WebAssembly modules in the compilation pipeline.
+ */
+class WebAssemblyModulesPlugin {
+	/**
+	 * Stores options that affect generated synchronous WebAssembly output.
+	 * @param {WebAssemblyModulesPluginOptions} options options
+	 */
+	constructor(options) {
+		this.options = options;
+	}
+
+	/**
+	 * Registers compilation hooks that parse and generate sync WebAssembly
+	 * modules, emit their binary assets, and report invalid placement in initial
+	 * chunks.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			PLUGIN_NAME,
+			(compilation, { normalModuleFactory }) => {
+				compilation.dependencyFactories.set(
+					WebAssemblyImportDependency,
+					normalModuleFactory
+				);
+
+				compilation.dependencyFactories.set(
+					WebAssemblyExportImportedDependency,
+					normalModuleFactory
+				);
+
+				normalModuleFactory.hooks.createParser
+					.for(WEBASSEMBLY_MODULE_TYPE_SYNC)
+					.tap(PLUGIN_NAME, () => {
+						const WebAssemblyParser = getWebAssemblyParser();
+
+						return new WebAssemblyParser();
+					});
+
+				normalModuleFactory.hooks.createGenerator
+					.for(WEBASSEMBLY_MODULE_TYPE_SYNC)
+					.tap(PLUGIN_NAME, () => {
+						const WebAssemblyJavascriptGenerator =
+							getWebAssemblyJavascriptGenerator();
+						const WebAssemblyGenerator = getWebAssemblyGenerator();
+
+						return Generator.byType({
+							[JAVASCRIPT_TYPE]: new WebAssemblyJavascriptGenerator(),
+							[WEBASSEMBLY_TYPE]: new WebAssemblyGenerator(this.options)
+						});
+					});
+
+				compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
+					const { chunkGraph } = compilation;
+					const { chunk, outputOptions, codeGenerationResults } = options;
+
+					for (const module of chunkGraph.getOrderedChunkModulesIterable(
+						chunk,
+						compareModulesByFullName(compiler)
+					)) {
+						if (module.type === WEBASSEMBLY_MODULE_TYPE_SYNC) {
+							const filenameTemplate = outputOptions.webassemblyModuleFilename;
+
+							result.push({
+								render: () =>
+									codeGenerationResults.getSource(
+										module,
+										chunk.runtime,
+										"webassembly"
+									),
+								filenameTemplate,
+								pathOptions: {
+									module,
+									runtime: chunk.runtime,
+									chunkGraph
+								},
+								auxiliary: true,
+								identifier: `webassemblyModule${chunkGraph.getModuleId(
+									module
+								)}`,
+								hash: chunkGraph.getModuleHash(module, chunk.runtime)
+							});
+						}
+					}
+
+					return result;
+				});
+
+				compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
+					const chunkGraph = compilation.chunkGraph;
+					/** @type {Set<Module>} */
+					const initialWasmModules = new Set();
+					for (const chunk of compilation.chunks) {
+						if (chunk.canBeInitial()) {
+							for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+								if (module.type === WEBASSEMBLY_MODULE_TYPE_SYNC) {
+									initialWasmModules.add(module);
+								}
+							}
+						}
+					}
+					for (const module of initialWasmModules) {
+						compilation.errors.push(
+							new WebAssemblyInInitialChunkError(
+								module,
+								compilation.moduleGraph,
+								compilation.chunkGraph,
+								compilation.requestShortener
+							)
+						);
+					}
+				});
+			}
+		);
+	}
+}
+
+module.exports = WebAssemblyModulesPlugin;
Index: frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,203 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const t = require("@webassemblyjs/ast");
+const { moduleContextFromModuleAST } = require("@webassemblyjs/ast");
+const { decode } = require("@webassemblyjs/wasm-parser");
+const Parser = require("../Parser");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("@webassemblyjs/ast").ModuleImport} ModuleImport */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+const JS_COMPAT_TYPES = new Set(["i32", "i64", "f32", "f64", "externref"]);
+
+/**
+ * Gets js incompatible type.
+ * @param {t.Signature} signature the func signature
+ * @returns {null | string} the type incompatible with js types
+ */
+const getJsIncompatibleType = (signature) => {
+	for (const param of signature.params) {
+		if (!JS_COMPAT_TYPES.has(param.valtype)) {
+			return `${param.valtype} as parameter`;
+		}
+	}
+	for (const type of signature.results) {
+		if (!JS_COMPAT_TYPES.has(type)) return `${type} as result`;
+	}
+	return null;
+};
+
+/**
+ * TODO why are there two different Signature types?
+ * @param {t.FuncSignature} signature the func signature
+ * @returns {null | string} the type incompatible with js types
+ */
+const getJsIncompatibleTypeOfFuncSignature = (signature) => {
+	for (const param of signature.args) {
+		if (!JS_COMPAT_TYPES.has(param)) {
+			return `${param} as parameter`;
+		}
+	}
+	for (const type of signature.result) {
+		if (!JS_COMPAT_TYPES.has(type)) return `${type} as result`;
+	}
+	return null;
+};
+
+const decoderOpts = {
+	ignoreCodeSection: true,
+	ignoreDataSection: true,
+
+	// this will avoid having to lookup with identifiers in the ModuleContext
+	ignoreCustomNameSection: true
+};
+
+class WebAssemblyParser extends Parser {
+	/**
+	 * Parses the provided source and updates the parser state.
+	 * @param {string | Buffer | PreparsedAst} source the source to parse
+	 * @param {ParserState} state the parser state
+	 * @returns {ParserState} the parser state
+	 */
+	parse(source, state) {
+		if (!Buffer.isBuffer(source)) {
+			throw new Error("WebAssemblyParser input must be a Buffer");
+		}
+
+		// flag it as ESM
+		/** @type {BuildInfo} */
+		(state.module.buildInfo).strict = true;
+		/** @type {BuildMeta} */
+		(state.module.buildMeta).exportsType = "namespace";
+
+		// parse it
+		const program = decode(source, decoderOpts);
+		const module = program.body[0];
+
+		const moduleContext = moduleContextFromModuleAST(module);
+
+		// extract imports and exports
+		/** @type {string[]} */
+		const exports = [];
+		const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
+		/** @type {Record<string, string> | undefined} */
+		let jsIncompatibleExports = (buildMeta.jsIncompatibleExports = undefined);
+
+		/** @typedef {ModuleImport | null} ImportNode */
+		/** @type {ImportNode[]} */
+		const importedGlobals = [];
+
+		t.traverse(module, {
+			ModuleExport({ node }) {
+				const descriptor = node.descr;
+
+				if (descriptor.exportType === "Func") {
+					const funcIdx = descriptor.id.value;
+
+					/** @type {t.FuncSignature} */
+					const funcSignature = moduleContext.getFunction(funcIdx);
+
+					const incompatibleType =
+						getJsIncompatibleTypeOfFuncSignature(funcSignature);
+
+					if (incompatibleType) {
+						if (jsIncompatibleExports === undefined) {
+							jsIncompatibleExports =
+								/** @type {BuildMeta} */
+								(state.module.buildMeta).jsIncompatibleExports = {};
+						}
+						jsIncompatibleExports[node.name] = incompatibleType;
+					}
+				}
+
+				exports.push(node.name);
+
+				if (node.descr && node.descr.exportType === "Global") {
+					const refNode = importedGlobals[node.descr.id.value];
+					if (refNode) {
+						const dep = new WebAssemblyExportImportedDependency(
+							node.name,
+							refNode.module,
+							refNode.name,
+							/** @type {string} */
+							(refNode.descr.valtype)
+						);
+
+						state.module.addDependency(dep);
+					}
+				}
+			},
+
+			Global({ node }) {
+				const init = node.init[0];
+
+				/** @type {ImportNode} */
+				let importNode = null;
+
+				if (init.id === "get_global") {
+					const globalIdx = init.args[0].value;
+
+					if (globalIdx < importedGlobals.length) {
+						importNode = importedGlobals[globalIdx];
+					}
+				}
+
+				importedGlobals.push(importNode);
+			},
+
+			ModuleImport({ node }) {
+				/** @type {false | string} */
+				let onlyDirectImport = false;
+
+				if (t.isMemory(node.descr) === true) {
+					onlyDirectImport = "Memory";
+				} else if (t.isTable(node.descr) === true) {
+					onlyDirectImport = "Table";
+				} else if (t.isFuncImportDescr(node.descr) === true) {
+					const incompatibleType = getJsIncompatibleType(
+						/** @type {t.Signature} */
+						(node.descr.signature)
+					);
+					if (incompatibleType) {
+						onlyDirectImport = `Non-JS-compatible Func Signature (${incompatibleType})`;
+					}
+				} else if (t.isGlobalType(node.descr) === true) {
+					const type = /** @type {string} */ (node.descr.valtype);
+					if (!JS_COMPAT_TYPES.has(type)) {
+						onlyDirectImport = `Non-JS-compatible Global Type (${type})`;
+					}
+				}
+
+				const dep = new WebAssemblyImportDependency(
+					node.module,
+					node.name,
+					node.descr,
+					onlyDirectImport
+				);
+
+				state.module.addDependency(dep);
+
+				if (t.isGlobalType(node.descr)) {
+					importedGlobals.push(node);
+				}
+			}
+		});
+
+		state.module.addDependency(new StaticExportsDependency(exports, false));
+
+		return state;
+	}
+}
+
+module.exports = WebAssemblyParser;
Index: frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,68 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Template = require("../Template");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+
+/**
+ * Defines the used wasm dependency type used by this module.
+ * @typedef {object} UsedWasmDependency
+ * @property {WebAssemblyImportDependency} dependency the dependency
+ * @property {string} name the export name
+ * @property {string} module the module name
+ */
+
+const MANGLED_MODULE = "a";
+
+/**
+ * Gets used dependencies.
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {Module} module the module
+ * @param {boolean | undefined} mangle mangle module and export names
+ * @returns {UsedWasmDependency[]} used dependencies and (mangled) name
+ */
+const getUsedDependencies = (moduleGraph, module, mangle) => {
+	/** @type {UsedWasmDependency[]} */
+	const array = [];
+	let importIndex = 0;
+	for (const dep of module.dependencies) {
+		if (dep instanceof WebAssemblyImportDependency) {
+			if (
+				dep.description.type === "GlobalType" ||
+				moduleGraph.getModule(dep) === null
+			) {
+				continue;
+			}
+
+			const exportName = dep.name;
+			// TODO add the following 3 lines when removing of ModuleExport is possible
+			// const importedModule = moduleGraph.getModule(dep);
+			// const usedName = importedModule && moduleGraph.getExportsInfo(importedModule).getUsedName(exportName, runtime);
+			// if (usedName !== false) {
+			if (mangle) {
+				array.push({
+					dependency: dep,
+					name: Template.numberToIdentifier(importIndex++),
+					module: MANGLED_MODULE
+				});
+			} else {
+				array.push({
+					dependency: dep,
+					name: exportName,
+					module: dep.request
+				});
+			}
+		}
+	}
+	return array;
+};
+
+module.exports.MANGLED_MODULE = MANGLED_MODULE;
+module.exports.getUsedDependencies = getUsedDependencies;
Index: frontend/node_modules/webpack/lib/wasm/EnableWasmLoadingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/wasm/EnableWasmLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/wasm/EnableWasmLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,160 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../../declarations/WebpackOptions").WasmLoadingType} WasmLoadingType */
+/** @typedef {import("../Compiler")} Compiler */
+
+/** @typedef {Set<WasmLoadingType>} WasmLoadingTypes */
+
+/** @type {WeakMap<Compiler, Set<WasmLoadingType>>} */
+const enabledTypes = new WeakMap();
+
+/**
+ * Returns the set of wasm loading backends that have already been enabled for
+ * the compiler.
+ * @param {Compiler} compiler compiler instance
+ * @returns {WasmLoadingTypes} enabled types
+ */
+const getEnabledTypes = (compiler) => {
+	let set = enabledTypes.get(compiler);
+	if (set === undefined) {
+		/** @type {WasmLoadingTypes} */
+		set = new Set();
+		enabledTypes.set(compiler, set);
+	}
+	return set;
+};
+
+/**
+ * Validates and enables named wasm loading backends by applying the plugin
+ * implementations that provide their runtime support.
+ */
+class EnableWasmLoadingPlugin {
+	/**
+	 * Stores the wasm loading backend name that should be enabled for the
+	 * compiler.
+	 * @param {WasmLoadingType} type library type that should be available
+	 */
+	constructor(type) {
+		/** @type {WasmLoadingType} */
+		this.type = type;
+	}
+
+	/**
+	 * Marks a custom or built-in wasm loading type as enabled for the compiler
+	 * without applying additional built-in behavior.
+	 * @param {Compiler} compiler the compiler instance
+	 * @param {WasmLoadingType} type type of library
+	 * @returns {void}
+	 */
+	static setEnabled(compiler, type) {
+		getEnabledTypes(compiler).add(type);
+	}
+
+	/**
+	 * Verifies that a wasm loading type has been enabled before code generation
+	 * attempts to use it.
+	 * @param {Compiler} compiler the compiler instance
+	 * @param {WasmLoadingType} type type of library
+	 * @returns {void}
+	 */
+	static checkEnabled(compiler, type) {
+		if (!getEnabledTypes(compiler).has(type)) {
+			throw new Error(
+				`Library type "${type}" is not enabled. ` +
+					"EnableWasmLoadingPlugin need to be used to enable this type of wasm loading. " +
+					'This usually happens through the "output.enabledWasmLoadingTypes" option. ' +
+					'If you are using a function as entry which sets "wasmLoading", you need to add all potential library types to "output.enabledWasmLoadingTypes". ' +
+					`These types are enabled: ${[...getEnabledTypes(compiler)].join(", ")}`
+			);
+		}
+	}
+
+	/**
+	 * Enables the requested wasm loading backend once and applies the
+	 * environment-specific plugins that provide its parser, generator, and
+	 * runtime support.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { type } = this;
+
+		// Only enable once
+		const enabled = getEnabledTypes(compiler);
+		if (enabled.has(type)) return;
+		enabled.add(type);
+
+		if (typeof type === "string") {
+			switch (type) {
+				case "fetch": {
+					if (compiler.options.experiments.syncWebAssembly) {
+						const FetchCompileWasmPlugin = require("../web/FetchCompileWasmPlugin");
+
+						new FetchCompileWasmPlugin({
+							mangleImports: compiler.options.optimization.mangleWasmImports
+						}).apply(compiler);
+					}
+
+					if (compiler.options.experiments.asyncWebAssembly) {
+						const FetchCompileAsyncWasmPlugin = require("../web/FetchCompileAsyncWasmPlugin");
+
+						new FetchCompileAsyncWasmPlugin().apply(compiler);
+					}
+
+					break;
+				}
+				case "async-node": {
+					if (compiler.options.experiments.syncWebAssembly) {
+						const ReadFileCompileWasmPlugin = require("../node/ReadFileCompileWasmPlugin");
+
+						new ReadFileCompileWasmPlugin({
+							mangleImports: compiler.options.optimization.mangleWasmImports,
+							import:
+								compiler.options.output.module &&
+								compiler.options.output.environment.dynamicImport
+						}).apply(compiler);
+					}
+
+					if (compiler.options.experiments.asyncWebAssembly) {
+						const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
+
+						new ReadFileCompileAsyncWasmPlugin({
+							import:
+								compiler.options.output.module &&
+								compiler.options.output.environment.dynamicImport
+						}).apply(compiler);
+					}
+
+					break;
+				}
+				case "universal": {
+					if (compiler.options.experiments.syncWebAssembly) {
+						throw new Error(
+							"Universal wasm loading type is only supported by asynchronous web assembly."
+						);
+					}
+
+					if (compiler.options.experiments.asyncWebAssembly) {
+						const UniversalCompileAsyncWasmPlugin = require("../wasm-async/UniversalCompileAsyncWasmPlugin");
+
+						new UniversalCompileAsyncWasmPlugin().apply(compiler);
+					}
+					break;
+				}
+				default:
+					throw new Error(`Unsupported wasm loading type ${type}.
+Plugins which provide custom wasm loading types must call EnableWasmLoadingPlugin.setEnabled(compiler, type) to disable this error.`);
+			}
+		} else {
+			// TODO support plugin instances here
+			// apply them to the compiler
+		}
+	}
+}
+
+module.exports = EnableWasmLoadingPlugin;
Index: frontend/node_modules/webpack/lib/web/FetchCompileAsyncWasmPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/web/FetchCompileAsyncWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/web/FetchCompileAsyncWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,102 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const AsyncWasmCompileRuntimeModule = require("../wasm-async/AsyncWasmCompileRuntimeModule");
+const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const PLUGIN_NAME = "FetchCompileAsyncWasmPlugin";
+
+/**
+ * Enables asynchronous WebAssembly loading through `fetch` for environments
+ * that can instantiate fetched binaries at runtime.
+ */
+class FetchCompileAsyncWasmPlugin {
+	/**
+	 * Registers compilation hooks that attach the async fetch-based wasm runtime
+	 * to chunks containing async WebAssembly modules.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalWasmLoading = compilation.outputOptions.wasmLoading;
+			/**
+			 * Determines whether the chunk should load async WebAssembly binaries
+			 * through the `fetch` backend.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const wasmLoading =
+					options && options.wasmLoading !== undefined
+						? options.wasmLoading
+						: globalWasmLoading;
+				return wasmLoading === "fetch";
+			};
+			/**
+			 * Generates the runtime expression that downloads the emitted wasm
+			 * binary for an async WebAssembly module.
+			 * @param {string} path path to the wasm file
+			 * @returns {string} code to load the wasm file
+			 */
+			const generateLoadBinaryCode = (path) =>
+				`fetch(${RuntimeGlobals.publicPath} + ${path})`;
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.instantiateWasm)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
+						)
+					) {
+						return;
+					}
+					set.add(RuntimeGlobals.publicPath);
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncWasmLoadingRuntimeModule({
+							generateLoadBinaryCode,
+							supportsStreaming: true
+						})
+					);
+				});
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.compileWasm)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC
+						)
+					) {
+						return;
+					}
+					set.add(RuntimeGlobals.publicPath);
+					compilation.addRuntimeModule(
+						chunk,
+						new AsyncWasmCompileRuntimeModule({
+							generateLoadBinaryCode,
+							supportsStreaming: true
+						})
+					);
+				});
+		});
+	}
+}
+
+module.exports = FetchCompileAsyncWasmPlugin;
Index: frontend/node_modules/webpack/lib/web/FetchCompileWasmPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/web/FetchCompileWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/web/FetchCompileWasmPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,98 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+/**
+ * Options that influence how synchronous WebAssembly modules are emitted for
+ * the fetch-based wasm loading runtime.
+ * @typedef {object} FetchCompileWasmPluginOptions
+ * @property {boolean=} mangleImports mangle imports
+ */
+
+const PLUGIN_NAME = "FetchCompileWasmPlugin";
+
+/**
+ * Enables synchronous WebAssembly chunk loading that fetches `.wasm` files and
+ * compiles them in browser-like environments.
+ */
+class FetchCompileWasmPlugin {
+	/**
+	 * Stores options that affect generated synchronous WebAssembly runtime code.
+	 * @param {FetchCompileWasmPluginOptions=} options options
+	 */
+	constructor(options = {}) {
+		/** @type {FetchCompileWasmPluginOptions} */
+		this.options = options;
+	}
+
+	/**
+	 * Registers compilation hooks that attach the fetch-based synchronous wasm
+	 * runtime module to chunks containing sync WebAssembly modules.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalWasmLoading = compilation.outputOptions.wasmLoading;
+			/**
+			 * Determines whether the chunk should load synchronous WebAssembly
+			 * binaries through the `fetch` backend.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const wasmLoading =
+					options && options.wasmLoading !== undefined
+						? options.wasmLoading
+						: globalWasmLoading;
+				return wasmLoading === "fetch";
+			};
+			/**
+			 * Generates the runtime expression that downloads the emitted wasm
+			 * binary for a module.
+			 * @param {string} path path to the wasm file
+			 * @returns {string} code to load the wasm file
+			 */
+			const generateLoadBinaryCode = (path) =>
+				`fetch(${RuntimeGlobals.publicPath} + ${path})`;
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
+					if (!isEnabledForChunk(chunk)) return;
+					if (
+						!chunkGraph.hasModuleInGraph(
+							chunk,
+							(m) => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC
+						)
+					) {
+						return;
+					}
+					set.add(RuntimeGlobals.moduleCache);
+					set.add(RuntimeGlobals.publicPath);
+					compilation.addRuntimeModule(
+						chunk,
+						new WasmChunkLoadingRuntimeModule({
+							generateLoadBinaryCode,
+							supportsStreaming: true,
+							mangleImports: this.options.mangleImports,
+							runtimeRequirements: set
+						})
+					);
+				});
+		});
+	}
+}
+
+module.exports = FetchCompileWasmPlugin;
Index: frontend/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,111 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const JsonpChunkLoadingRuntimeModule = require("./JsonpChunkLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+
+const PLUGIN_NAME = "JsonpChunkLoadingPlugin";
+
+/**
+ * Enables browser-side JavaScript chunk loading through the JSONP runtime and
+ * adds the supporting runtime requirements for matching chunks.
+ */
+class JsonpChunkLoadingPlugin {
+	/**
+	 * Registers compilation hooks that attach the JSONP chunk-loading runtime
+	 * module and its dependent runtime globals to chunks using `chunkLoading:
+	 * "jsonp"`.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalChunkLoading = compilation.outputOptions.chunkLoading;
+			/**
+			 * Determines whether the chunk resolves JavaScript chunks through the
+			 * JSONP loading backend.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const chunkLoading =
+					options && options.chunkLoading !== undefined
+						? options.chunkLoading
+						: globalChunkLoading;
+				return chunkLoading === "jsonp";
+			};
+			/** @type {WeakSet<Chunk>} */
+			const onceForChunkSet = new WeakSet();
+			/**
+			 * Adds the JSONP runtime module to a chunk once, along with the core
+			 * runtime globals it relies on.
+			 * @param {Chunk} chunk chunk
+			 * @param {RuntimeRequirements} set runtime requirements
+			 */
+			const handler = (chunk, set) => {
+				if (onceForChunkSet.has(chunk)) return;
+				onceForChunkSet.add(chunk);
+				if (!isEnabledForChunk(chunk)) return;
+				set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				set.add(RuntimeGlobals.hasOwnProperty);
+				compilation.addRuntimeModule(
+					chunk,
+					new JsonpChunkLoadingRuntimeModule(set)
+				);
+			};
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.baseURI)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.onChunksLoaded)
+				.tap(PLUGIN_NAME, handler);
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.loadScript);
+					set.add(RuntimeGlobals.getChunkScriptFilename);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.loadScript);
+					set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
+					set.add(RuntimeGlobals.moduleCache);
+					set.add(RuntimeGlobals.hmrModuleData);
+					set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.getUpdateManifestFilename);
+				});
+		});
+	}
+}
+
+module.exports = JsonpChunkLoadingPlugin;
Index: frontend/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,456 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+	generateJavascriptHMR
+} = require("../hmr/JavascriptHotModuleReplacementHelper");
+const chunkHasJs = require("../javascript/JavascriptModulesPlugin").chunkHasJs;
+const { getInitialChunkIds } = require("../javascript/StartupHelpers");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+/**
+ * @typedef {object} JsonpCompilationPluginHooks
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
+ */
+
+/** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {Compilation} compilation the compilation
+	 * @returns {JsonpCompilationPluginHooks} hooks
+	 */
+	static getCompilationHooks(compilation) {
+		if (!(compilation instanceof Compilation)) {
+			throw new TypeError(
+				"The 'compilation' argument must be an instance of Compilation"
+			);
+		}
+		let hooks = compilationHooksMap.get(compilation);
+		if (hooks === undefined) {
+			hooks = {
+				linkPreload: new SyncWaterfallHook(["source", "chunk"]),
+				linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
+			};
+			compilationHooksMap.set(compilation, hooks);
+		}
+		return hooks;
+	}
+
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 */
+	constructor(runtimeRequirements) {
+		super("jsonp chunk loading", RuntimeModule.STAGE_ATTACH);
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this._runtimeRequirements = runtimeRequirements;
+	}
+
+	/**
+	 * @private
+	 * @param {Chunk} chunk chunk
+	 * @returns {string} generated code
+	 */
+	_generateBaseUri(chunk) {
+		const options = chunk.getEntryOptions();
+		if (options && options.baseUri) {
+			return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
+		}
+		return `${RuntimeGlobals.baseURI} = (typeof document !== 'undefined' && document.baseURI) || self.location.href;`;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const {
+			runtimeTemplate,
+			outputOptions: {
+				chunkLoadingGlobal,
+				hotUpdateGlobal,
+				crossOriginLoading,
+				scriptType,
+				charset
+			}
+		} = compilation;
+		const globalObject = runtimeTemplate.globalObject;
+		const { linkPreload, linkPrefetch } =
+			JsonpChunkLoadingRuntimeModule.getCompilationHooks(compilation);
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
+		const withLoading = this._runtimeRequirements.has(
+			RuntimeGlobals.ensureChunkHandlers
+		);
+		const withCallback = this._runtimeRequirements.has(
+			RuntimeGlobals.chunkCallback
+		);
+		const withOnChunkLoad = this._runtimeRequirements.has(
+			RuntimeGlobals.onChunksLoaded
+		);
+		const withHmr = this._runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		const withHmrManifest = this._runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadManifest
+		);
+		const withFetchPriority = this._runtimeRequirements.has(
+			RuntimeGlobals.hasFetchPriority
+		);
+		const chunkLoadingGlobalExpr = `${globalObject}[${JSON.stringify(
+			chunkLoadingGlobal
+		)}]`;
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const withPrefetch =
+			this._runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers) &&
+			chunk.hasChildByOrder(chunkGraph, "prefetch", true, chunkHasJs);
+		const withPreload =
+			this._runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers) &&
+			chunk.hasChildByOrder(chunkGraph, "preload", true, chunkHasJs);
+		const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
+		const hasJsMatcher = compileBooleanMatcher(conditionMap);
+		const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_jsonp`
+			: undefined;
+
+		return Template.asString([
+			withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI",
+			"",
+			"// object to store loaded and loading chunks",
+			"// undefined = chunk not loaded, null = chunk preloaded/prefetched",
+			"// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded",
+			`var installedChunks = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{`,
+			Template.indent(
+				Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(
+					",\n"
+				)
+			),
+			"};",
+			"",
+			withLoading
+				? Template.asString([
+						`${fn}.j = ${runtimeTemplate.basicFunction(
+							`chunkId, promises${withFetchPriority ? ", fetchPriority" : ""}`,
+							hasJsMatcher !== false
+								? Template.indent([
+										"// JSONP chunk loading for javascript",
+										`var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
+										'if(installedChunkData !== 0) { // 0 means "already installed".',
+										Template.indent([
+											"",
+											'// a Promise means "currently loading".',
+											"if(installedChunkData) {",
+											Template.indent([
+												"promises.push(installedChunkData[2]);"
+											]),
+											"} else {",
+											Template.indent([
+												hasJsMatcher === true
+													? "if(true) { // all chunks have JS"
+													: `if(${hasJsMatcher("chunkId")}) {`,
+												Template.indent([
+													"// setup Promise in chunk cache",
+													`var promise = new Promise(${runtimeTemplate.expressionFunction(
+														"installedChunkData = installedChunks[chunkId] = [resolve, reject]",
+														"resolve, reject"
+													)});`,
+													"promises.push(installedChunkData[2] = promise);",
+													"",
+													"// start chunk loading",
+													`var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
+													"// create error before stack unwound to get useful stacktrace later",
+													"var error = new Error();",
+													`var loadingEnded = ${runtimeTemplate.basicFunction(
+														"event",
+														[
+															`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
+															Template.indent([
+																"installedChunkData = installedChunks[chunkId];",
+																"if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
+																"if(installedChunkData) {",
+																Template.indent([
+																	"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
+																	"var realSrc = event && event.target && event.target.src;",
+																	"error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
+																	"error.name = 'ChunkLoadError';",
+																	"error.type = errorType;",
+																	"error.request = realSrc;",
+																	"installedChunkData[1](error);"
+																]),
+																"}"
+															]),
+															"}"
+														]
+													)};`,
+													`${
+														RuntimeGlobals.loadScript
+													}(url, loadingEnded, "chunk-" + chunkId, chunkId${
+														withFetchPriority ? ", fetchPriority" : ""
+													});`
+												]),
+												hasJsMatcher === true
+													? "}"
+													: "} else installedChunks[chunkId] = 0;"
+											]),
+											"}"
+										]),
+										"}"
+									])
+								: Template.indent(["installedChunks[chunkId] = 0;"])
+						)};`
+					])
+				: "// no chunk on demand loading",
+			"",
+			withPrefetch && hasJsMatcher !== false
+				? `${
+						RuntimeGlobals.prefetchChunkHandlers
+					}.j = ${runtimeTemplate.basicFunction("chunkId", [
+						`if((!${
+							RuntimeGlobals.hasOwnProperty
+						}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
+							hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
+						}) {`,
+						Template.indent([
+							"installedChunks[chunkId] = null;",
+							linkPrefetch.call(
+								Template.asString([
+									"var link = document.createElement('link');",
+									charset ? "link.charset = 'utf-8';" : "",
+									crossOriginLoading
+										? `link.crossOrigin = ${JSON.stringify(
+												crossOriginLoading
+											)};`
+										: "",
+									`if (${RuntimeGlobals.scriptNonce}) {`,
+									Template.indent(
+										`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+									),
+									"}",
+									'link.rel = "prefetch";',
+									'link.as = "script";',
+									`link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`
+								]),
+								chunk
+							),
+							"document.head.appendChild(link);"
+						]),
+						"}"
+					])};`
+				: "// no prefetching",
+			"",
+			withPreload && hasJsMatcher !== false
+				? `${
+						RuntimeGlobals.preloadChunkHandlers
+					}.j = ${runtimeTemplate.basicFunction("chunkId", [
+						`if((!${
+							RuntimeGlobals.hasOwnProperty
+						}(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
+							hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
+						}) {`,
+						Template.indent([
+							"installedChunks[chunkId] = null;",
+							linkPreload.call(
+								Template.asString([
+									"var link = document.createElement('link');",
+									scriptType && scriptType !== "module"
+										? `link.type = ${JSON.stringify(scriptType)};`
+										: "",
+									charset ? "link.charset = 'utf-8';" : "",
+									`if (${RuntimeGlobals.scriptNonce}) {`,
+									Template.indent(
+										`link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
+									),
+									"}",
+									scriptType === "module"
+										? 'link.rel = "modulepreload";'
+										: 'link.rel = "preload";',
+									scriptType === "module" ? "" : 'link.as = "script";',
+									`link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
+									crossOriginLoading
+										? crossOriginLoading === "use-credentials"
+											? 'link.crossOrigin = "use-credentials";'
+											: Template.asString([
+													"if (link.href.indexOf(window.location.origin + '/') !== 0) {",
+													Template.indent(
+														`link.crossOrigin = ${JSON.stringify(
+															crossOriginLoading
+														)};`
+													),
+													"}"
+												])
+										: ""
+								]),
+								chunk
+							),
+							"document.head.appendChild(link);"
+						]),
+						"}"
+					])};`
+				: "// no preloaded",
+			"",
+			withHmr
+				? Template.asString([
+						"var currentUpdatedModulesList;",
+						"var waitingUpdateResolves = {};",
+						"function loadUpdateChunk(chunkId, updatedModulesList) {",
+						Template.indent([
+							"currentUpdatedModulesList = updatedModulesList;",
+							`return new Promise(${runtimeTemplate.basicFunction(
+								"resolve, reject",
+								[
+									"waitingUpdateResolves[chunkId] = resolve;",
+									"// start update chunk loading",
+									`var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId);`,
+									"// create error before stack unwound to get useful stacktrace later",
+									"var error = new Error();",
+									`var loadingEnded = ${runtimeTemplate.basicFunction("event", [
+										"if(waitingUpdateResolves[chunkId]) {",
+										Template.indent([
+											"waitingUpdateResolves[chunkId] = undefined",
+											"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
+											"var realSrc = event && event.target && event.target.src;",
+											"error.message = 'Loading hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
+											"error.name = 'ChunkLoadError';",
+											"error.type = errorType;",
+											"error.request = realSrc;",
+											"reject(error);"
+										]),
+										"}"
+									])};`,
+									`${RuntimeGlobals.loadScript}(url, loadingEnded);`
+								]
+							)});`
+						]),
+						"}",
+						"",
+						`${globalObject}[${JSON.stringify(
+							hotUpdateGlobal
+						)}] = ${runtimeTemplate.basicFunction(
+							"chunkId, moreModules, runtime",
+							[
+								"for(var moduleId in moreModules) {",
+								Template.indent([
+									`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
+									Template.indent([
+										"currentUpdate[moduleId] = moreModules[moduleId];",
+										"if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);"
+									]),
+									"}"
+								]),
+								"}",
+								"if(runtime) currentUpdateRuntime.push(runtime);",
+								"if(waitingUpdateResolves[chunkId]) {",
+								Template.indent([
+									"waitingUpdateResolves[chunkId]();",
+									"waitingUpdateResolves[chunkId] = undefined;"
+								]),
+								"}"
+							]
+						)};`,
+						"",
+						generateJavascriptHMR("jsonp")
+					])
+				: "// no HMR",
+			"",
+			withHmrManifest
+				? Template.asString([
+						`${
+							RuntimeGlobals.hmrDownloadManifest
+						} = ${runtimeTemplate.basicFunction("", [
+							'if (typeof fetch === "undefined") throw new Error("No browser support: need fetch API");',
+							`return fetch(${RuntimeGlobals.publicPath} + ${
+								RuntimeGlobals.getUpdateManifestFilename
+							}()).then(${runtimeTemplate.basicFunction("response", [
+								"if(response.status === 404) return; // no update available",
+								'if(!response.ok) throw new Error("Failed to fetch update manifest " + response.statusText);',
+								"return response.json();"
+							])});`
+						])};`
+					])
+				: "// no HMR manifest",
+			"",
+			withOnChunkLoad
+				? `${
+						RuntimeGlobals.onChunksLoaded
+					}.j = ${runtimeTemplate.returningFunction(
+						"installedChunks[chunkId] === 0",
+						"chunkId"
+					)};`
+				: "// no on chunks loaded",
+			"",
+			withCallback || withLoading
+				? Template.asString([
+						"// install a JSONP callback for chunk loading",
+						`var webpackJsonpCallback = ${runtimeTemplate.basicFunction(
+							"parentChunkLoadingFunction, data",
+							[
+								runtimeTemplate.destructureArray(
+									["chunkIds", "moreModules", "runtime"],
+									"data"
+								),
+								'// add "moreModules" to the modules object,',
+								'// then flag all "chunkIds" as loaded and fire callback',
+								"var moduleId, chunkId, i = 0;",
+								`if(chunkIds.some(${runtimeTemplate.returningFunction(
+									"installedChunks[id] !== 0",
+									"id"
+								)})) {`,
+								Template.indent([
+									"for(moduleId in moreModules) {",
+									Template.indent([
+										`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
+										Template.indent(
+											`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
+										),
+										"}"
+									]),
+									"}",
+									`if(runtime) var result = runtime(${RuntimeGlobals.require});`
+								]),
+								"}",
+								"if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);",
+								"for(;i < chunkIds.length; i++) {",
+								Template.indent([
+									"chunkId = chunkIds[i];",
+									`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
+									Template.indent("installedChunks[chunkId][0]();"),
+									"}",
+									"installedChunks[chunkId] = 0;"
+								]),
+								"}",
+								withOnChunkLoad
+									? `return ${RuntimeGlobals.onChunksLoaded}(result);`
+									: ""
+							]
+						)}`,
+						"",
+						`var chunkLoadingGlobal = ${chunkLoadingGlobalExpr} = ${chunkLoadingGlobalExpr} || [];`,
+						"chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));",
+						"chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));"
+					])
+				: "// no jsonp function"
+		]);
+	}
+}
+
+module.exports = JsonpChunkLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/web/JsonpTemplatePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/web/JsonpTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/web/JsonpTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ArrayPushCallbackChunkFormatPlugin = require("../javascript/ArrayPushCallbackChunkFormatPlugin");
+const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
+const JsonpChunkLoadingRuntimeModule = require("./JsonpChunkLoadingRuntimeModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+
+// TODO webpack 6 remove this class
+class JsonpTemplatePlugin {
+	/**
+	 * Returns hooks.
+	 * @deprecated use JsonpChunkLoadingRuntimeModule.getCompilationHooks instead
+	 * @param {Compilation} compilation the compilation
+	 * @returns {JsonpChunkLoadingRuntimeModule.JsonpCompilationPluginHooks} hooks
+	 */
+	static getCompilationHooks(compilation) {
+		return JsonpChunkLoadingRuntimeModule.getCompilationHooks(compilation);
+	}
+
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.options.output.chunkLoading = "jsonp";
+		new ArrayPushCallbackChunkFormatPlugin().apply(compiler);
+		new EnableChunkLoadingPlugin("jsonp").apply(compiler);
+	}
+}
+
+module.exports = JsonpTemplatePlugin;
Index: frontend/node_modules/webpack/lib/webpack.js
===================================================================
--- frontend/node_modules/webpack/lib/webpack.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/webpack.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,269 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const webpackOptionsSchemaCheck = require("../schemas/WebpackOptions.check");
+const webpackOptionsSchema =
+	/** @type {EXPECTED_ANY} */
+	(require("../schemas/WebpackOptions.json"));
+const Compiler = require("./Compiler");
+const MultiCompiler = require("./MultiCompiler");
+const WebpackOptionsApply = require("./WebpackOptionsApply");
+const {
+	applyWebpackOptionsBaseDefaults,
+	applyWebpackOptionsDefaults
+} = require("./config/defaults");
+const {
+	applyWebpackOptionsInterception,
+	getNormalizedWebpackOptions
+} = require("./config/normalization");
+const NodeEnvironmentPlugin = require("./node/NodeEnvironmentPlugin");
+const memoize = require("./util/memoize");
+
+/** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
+/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptionsNormalizedWithDefaults */
+/** @typedef {import("./config/normalization").WebpackOptionsInterception} WebpackOptionsInterception */
+/** @typedef {import("./Compiler").WatchOptions} WatchOptions */
+/** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */
+/** @typedef {import("./MultiCompiler").MultiWebpackOptions} MultiWebpackOptions */
+/** @typedef {import("./MultiStats")} MultiStats */
+/** @typedef {import("./Stats")} Stats */
+
+/** @typedef {(this: Compiler, compiler: Compiler) => void} WebpackPluginFunction */
+/** @typedef {(compiler: Compiler) => void} WebpackPluginInstanceApplyFunction */
+
+const getValidateSchema = memoize(() => require("./validateSchema"));
+
+/**
+ * Defines the callback callback.
+ * @template T
+ * @template [R=void]
+ * @callback Callback
+ * @param {Error | null} err
+ * @param {T=} result
+ * @returns {R}
+ */
+
+/** @typedef {Callback<void>} ErrorCallback */
+
+/**
+ * Creates a multi compiler.
+ * @param {ReadonlyArray<WebpackOptions>} childOptions options array
+ * @param {MultiCompilerOptions} options options
+ * @returns {MultiCompiler} a multi-compiler
+ */
+const createMultiCompiler = (childOptions, options) => {
+	const compilers = childOptions.map((options, index) =>
+		createCompiler(options, index)
+	);
+	const compiler = new MultiCompiler(compilers, options);
+	for (const childCompiler of compilers) {
+		if (childCompiler.options.dependencies) {
+			compiler.setDependencies(
+				childCompiler,
+				childCompiler.options.dependencies
+			);
+		}
+	}
+	return compiler;
+};
+
+/**
+ * Creates a compiler.
+ * @param {WebpackOptions} rawOptions options object
+ * @param {number=} compilerIndex index of compiler
+ * @returns {Compiler} a compiler
+ */
+const createCompiler = (rawOptions, compilerIndex) => {
+	let options = getNormalizedWebpackOptions(rawOptions);
+	applyWebpackOptionsBaseDefaults(options);
+
+	/** @type {WebpackOptionsInterception=} */
+	let interception;
+	({ options, interception } = applyWebpackOptionsInterception(options));
+
+	const compiler = new Compiler(
+		/** @type {string} */ (options.context),
+		options
+	);
+	new NodeEnvironmentPlugin({
+		infrastructureLogging: options.infrastructureLogging
+	}).apply(compiler);
+	if (Array.isArray(options.plugins)) {
+		for (const plugin of options.plugins) {
+			if (typeof plugin === "function") {
+				/** @type {WebpackPluginFunction} */
+				(plugin).call(compiler, compiler);
+			} else if (plugin) {
+				plugin.apply(compiler);
+			}
+		}
+	}
+	const resolvedDefaultOptions = applyWebpackOptionsDefaults(
+		options,
+		compilerIndex
+	);
+	if (resolvedDefaultOptions.platform) {
+		compiler.platform = resolvedDefaultOptions.platform;
+	}
+	if (options.validate) {
+		compiler.hooks.validate.call();
+	}
+	compiler.hooks.environment.call();
+	compiler.hooks.afterEnvironment.call();
+	new WebpackOptionsApply().process(
+		/** @type {WebpackOptionsNormalizedWithDefaults} */
+		(options),
+		compiler,
+		interception
+	);
+	compiler.hooks.initialize.call();
+	return compiler;
+};
+
+/**
+ * Returns array of options.
+ * @template T
+ * @param {T[] | T} options options
+ * @returns {T[]} array of options
+ */
+const asArray = (options) =>
+	Array.isArray(options) ? [...options] : [options];
+
+/**
+ * Checks whether it needs validate.
+ * @param {WebpackOptions | null | undefined} options options
+ * @returns {boolean} true when need to validate, otherwise false
+ */
+const needValidate = (options) => {
+	if (
+		options &&
+		(options.validate === false ||
+			(options.experiments &&
+				options.experiments.futureDefaults === true &&
+				(options.mode === "production" || !options.mode)))
+	) {
+		return false;
+	}
+
+	return true;
+};
+
+/**
+ * Returns the compiler object.
+ * @overload
+ * @param {WebpackOptions} options options object
+ * @param {Callback<Stats>} callback callback
+ * @returns {Compiler | null} the compiler object
+ */
+/**
+ * Returns the compiler object.
+ * @overload
+ * @param {WebpackOptions} options options object
+ * @returns {Compiler} the compiler object
+ */
+/**
+ * Returns the multi compiler object.
+ * @overload
+ * @param {MultiWebpackOptions} options options objects
+ * @param {Callback<MultiStats>} callback callback
+ * @returns {MultiCompiler | null} the multi compiler object
+ */
+/**
+ * Returns the multi compiler object.
+ * @overload
+ * @param {MultiWebpackOptions} options options objects
+ * @returns {MultiCompiler} the multi compiler object
+ */
+/**
+ * Returns compiler or MultiCompiler.
+ * @param {WebpackOptions | MultiWebpackOptions} options options
+ * @param {Callback<Stats> & Callback<MultiStats>=} callback callback
+ * @returns {Compiler | MultiCompiler | null} Compiler or MultiCompiler
+ */
+const webpack = (options, callback) => {
+	const create = () => {
+		const isMultiCompiler = Array.isArray(options);
+
+		if (
+			!asArray(/** @type {WebpackOptions} */ (options)).every((options) =>
+				needValidate(options) ? webpackOptionsSchemaCheck(options) : true
+			)
+		) {
+			getValidateSchema()(
+				webpackOptionsSchema,
+				isMultiCompiler
+					? options.map((options) => (needValidate(options) ? options : {}))
+					: needValidate(options)
+						? options
+						: {}
+			);
+			util.deprecate(
+				() => {},
+				"webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.",
+				"DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID"
+			)();
+		}
+		/** @type {MultiCompiler | Compiler} */
+		let compiler;
+		/** @type {boolean | undefined} */
+		let watch = false;
+		/** @type {WatchOptions | WatchOptions[]} */
+		let watchOptions;
+		if (isMultiCompiler) {
+			/** @type {MultiCompiler} */
+			compiler = createMultiCompiler(
+				options,
+				/** @type {MultiCompilerOptions} */
+				(options)
+			);
+			watch = options.some((options) => options.watch);
+			watchOptions = options.map((options) => options.watchOptions || {});
+		} else {
+			const webpackOptions = /** @type {WebpackOptions} */ (options);
+			/** @type {Compiler} */
+			compiler = createCompiler(webpackOptions);
+			watch = webpackOptions.watch;
+			watchOptions = webpackOptions.watchOptions || {};
+		}
+		return { compiler, watch, watchOptions };
+	};
+	if (callback) {
+		try {
+			const { compiler, watch, watchOptions } = create();
+			if (watch) {
+				compiler.watch(watchOptions, callback);
+			} else {
+				compiler.run((err, stats) => {
+					compiler.close((err2) => {
+						callback(
+							err || err2,
+							/** @type {options extends WebpackOptions ? Stats : MultiStats} */
+							(stats)
+						);
+					});
+				});
+			}
+			return compiler;
+		} catch (err) {
+			process.nextTick(() => callback(/** @type {Error} */ (err)));
+			return null;
+		}
+	} else {
+		const { compiler, watch } = create();
+		if (watch) {
+			util.deprecate(
+				() => {},
+				"A 'callback' argument needs to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback.",
+				"DEP_WEBPACK_WATCH_WITHOUT_CALLBACK"
+			)();
+		}
+		return compiler;
+	}
+};
+
+module.exports = webpack;
Index: frontend/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,119 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const StartupChunkDependenciesPlugin = require("../runtime/StartupChunkDependenciesPlugin");
+const ImportScriptsChunkLoadingRuntimeModule = require("./ImportScriptsChunkLoadingRuntimeModule");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
+
+const PLUGIN_NAME = "ImportScriptsChunkLoadingPlugin";
+
+/**
+ * Enables worker-side chunk loading via `importScripts` and wires in the
+ * runtime helpers needed for startup, loading, and hot updates.
+ */
+class ImportScriptsChunkLoadingPlugin {
+	/**
+	 * Registers compilation hooks that attach the `importScripts` chunk-loading
+	 * runtime and its supporting globals to chunks using that backend.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		new StartupChunkDependenciesPlugin({
+			chunkLoading: "import-scripts",
+			asyncChunkLoading: true
+		}).apply(compiler);
+		compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
+			const globalChunkLoading = compilation.outputOptions.chunkLoading;
+			/**
+			 * Determines whether the chunk resolves additional chunks through the
+			 * worker-side `importScripts` backend.
+			 * @param {Chunk} chunk chunk
+			 * @returns {boolean} true, if wasm loading is enabled for the chunk
+			 */
+			const isEnabledForChunk = (chunk) => {
+				const options = chunk.getEntryOptions();
+				const chunkLoading =
+					options && options.chunkLoading !== undefined
+						? options.chunkLoading
+						: globalChunkLoading;
+				return chunkLoading === "import-scripts";
+			};
+			/** @type {WeakSet<Chunk>} */
+			const onceForChunkSet = new WeakSet();
+			/**
+			 * Adds the `importScripts` chunk-loading runtime module to a chunk once
+			 * and records the globals it depends on.
+			 * @param {Chunk} chunk chunk
+			 * @param {RuntimeRequirements} set runtime requirements
+			 */
+			const handler = (chunk, set) => {
+				if (onceForChunkSet.has(chunk)) return;
+				onceForChunkSet.add(chunk);
+				if (!isEnabledForChunk(chunk)) return;
+				const withCreateScriptUrl = Boolean(
+					compilation.outputOptions.trustedTypes
+				);
+				set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				set.add(RuntimeGlobals.hasOwnProperty);
+				if (withCreateScriptUrl) {
+					set.add(RuntimeGlobals.createScriptUrl);
+				}
+				compilation.addRuntimeModule(
+					chunk,
+					new ImportScriptsChunkLoadingRuntimeModule(set, withCreateScriptUrl)
+				);
+			};
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.baseURI)
+				.tap(PLUGIN_NAME, handler);
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.onChunksLoaded)
+				.tap(PLUGIN_NAME, handler);
+
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.ensureChunkHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.getChunkScriptFilename);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
+					set.add(RuntimeGlobals.moduleCache);
+					set.add(RuntimeGlobals.hmrModuleData);
+					set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+				});
+			compilation.hooks.runtimeRequirementInTree
+				.for(RuntimeGlobals.hmrDownloadManifest)
+				.tap(PLUGIN_NAME, (chunk, set) => {
+					if (!isEnabledForChunk(chunk)) return;
+					set.add(RuntimeGlobals.publicPath);
+					set.add(RuntimeGlobals.getUpdateManifestFilename);
+				});
+		});
+	}
+}
+
+module.exports = ImportScriptsChunkLoadingPlugin;
Index: frontend/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js
===================================================================
--- frontend/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,232 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+	generateJavascriptHMR
+} = require("../hmr/JavascriptHotModuleReplacementHelper");
+const {
+	chunkHasJs,
+	getChunkFilenameTemplate
+} = require("../javascript/JavascriptModulesPlugin");
+const { getInitialChunkIds } = require("../javascript/StartupHelpers");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+
+class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule {
+	/**
+	 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+	 * @param {boolean} withCreateScriptUrl with createScriptUrl support
+	 */
+	constructor(runtimeRequirements, withCreateScriptUrl) {
+		super("importScripts chunk loading", RuntimeModule.STAGE_ATTACH);
+		/** @type {ReadOnlyRuntimeRequirements} */
+		this.runtimeRequirements = runtimeRequirements;
+		/** @type {boolean} */
+		this._withCreateScriptUrl = withCreateScriptUrl;
+	}
+
+	/**
+	 * @private
+	 * @param {Chunk} chunk chunk
+	 * @returns {string} generated code
+	 */
+	_generateBaseUri(chunk) {
+		const options = chunk.getEntryOptions();
+		if (options && options.baseUri) {
+			return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
+		}
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const outputName = compilation.getPath(
+			getChunkFilenameTemplate(chunk, compilation.outputOptions),
+			{
+				chunk,
+				contentHashType: "javascript"
+			}
+		);
+		const rootOutputDir = getUndoPath(
+			outputName,
+			compilation.outputOptions.path,
+			false
+		);
+		return `${RuntimeGlobals.baseURI} = self.location + ${JSON.stringify(
+			rootOutputDir ? `/../${rootOutputDir}` : ""
+		)};`;
+	}
+
+	/**
+	 * Generates runtime code for this runtime module.
+	 * @returns {string | null} runtime code
+	 */
+	generate() {
+		const compilation = /** @type {Compilation} */ (this.compilation);
+		const fn = RuntimeGlobals.ensureChunkHandlers;
+		const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI);
+		const withLoading = this.runtimeRequirements.has(
+			RuntimeGlobals.ensureChunkHandlers
+		);
+		const withCallback = this.runtimeRequirements.has(
+			RuntimeGlobals.chunkCallback
+		);
+		const withHmr = this.runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadUpdateHandlers
+		);
+		const withHmrManifest = this.runtimeRequirements.has(
+			RuntimeGlobals.hmrDownloadManifest
+		);
+		const globalObject = compilation.runtimeTemplate.globalObject;
+		const chunkLoadingGlobalExpr = `${globalObject}[${JSON.stringify(
+			compilation.outputOptions.chunkLoadingGlobal
+		)}]`;
+		const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+		const chunk = /** @type {Chunk} */ (this.chunk);
+		const hasJsMatcher = compileBooleanMatcher(
+			chunkGraph.getChunkConditionMap(chunk, chunkHasJs)
+		);
+		const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
+
+		const stateExpression = withHmr
+			? `${RuntimeGlobals.hmrRuntimeStatePrefix}_importScripts`
+			: undefined;
+		const runtimeTemplate = compilation.runtimeTemplate;
+		const { _withCreateScriptUrl: withCreateScriptUrl } = this;
+
+		return Template.asString([
+			withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI",
+			"",
+			"// object to store loaded chunks",
+			'// "1" means "already loaded"',
+			`var installedChunks = ${
+				stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+			}{`,
+			Template.indent(
+				Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 1`).join(
+					",\n"
+				)
+			),
+			"};",
+			"",
+			withCallback || withLoading
+				? Template.asString([
+						"// importScripts chunk loading",
+						`var installChunk = ${runtimeTemplate.basicFunction("data", [
+							runtimeTemplate.destructureArray(
+								["chunkIds", "moreModules", "runtime"],
+								"data"
+							),
+							"for(var moduleId in moreModules) {",
+							Template.indent([
+								`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
+								Template.indent(
+									`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
+								),
+								"}"
+							]),
+							"}",
+							`if(runtime) runtime(${RuntimeGlobals.require});`,
+							"while(chunkIds.length)",
+							Template.indent("installedChunks[chunkIds.pop()] = 1;"),
+							"parentChunkLoadingFunction(data);"
+						])};`
+					])
+				: "// no chunk install function needed",
+			withCallback || withLoading
+				? Template.asString([
+						withLoading
+							? `${fn}.i = ${runtimeTemplate.basicFunction(
+									"chunkId, promises",
+									hasJsMatcher !== false
+										? [
+												'// "1" is the signal for "already loaded"',
+												"if(!installedChunks[chunkId]) {",
+												Template.indent([
+													hasJsMatcher === true
+														? "if(true) { // all chunks have JS"
+														: `if(${hasJsMatcher("chunkId")}) {`,
+													Template.indent(
+														`importScripts(${
+															withCreateScriptUrl
+																? `${RuntimeGlobals.createScriptUrl}(${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId))`
+																: `${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId)`
+														});`
+													),
+													"}"
+												]),
+												"}"
+											]
+										: "installedChunks[chunkId] = 1;"
+								)};`
+							: "",
+						"",
+						`var chunkLoadingGlobal = ${chunkLoadingGlobalExpr} = ${chunkLoadingGlobalExpr} || [];`,
+						"var parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);",
+						"chunkLoadingGlobal.push = installChunk;"
+					])
+				: "// no chunk loading",
+			"",
+			withHmr
+				? Template.asString([
+						"function loadUpdateChunk(chunkId, updatedModulesList) {",
+						Template.indent([
+							"var success = false;",
+							`${globalObject}[${JSON.stringify(
+								compilation.outputOptions.hotUpdateGlobal
+							)}] = ${runtimeTemplate.basicFunction("_, moreModules, runtime", [
+								"for(var moduleId in moreModules) {",
+								Template.indent([
+									`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
+									Template.indent([
+										"currentUpdate[moduleId] = moreModules[moduleId];",
+										"if(updatedModulesList) updatedModulesList.push(moduleId);"
+									]),
+									"}"
+								]),
+								"}",
+								"if(runtime) currentUpdateRuntime.push(runtime);",
+								"success = true;"
+							])};`,
+							"// start update chunk loading",
+							`importScripts(${
+								withCreateScriptUrl
+									? `${RuntimeGlobals.createScriptUrl}(${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId))`
+									: `${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId)`
+							});`,
+							'if(!success) throw new Error("Loading update chunk failed for unknown reason");'
+						]),
+						"}",
+						"",
+						generateJavascriptHMR("importScripts")
+					])
+				: "// no HMR",
+			"",
+			withHmrManifest
+				? Template.asString([
+						`${
+							RuntimeGlobals.hmrDownloadManifest
+						} = ${runtimeTemplate.basicFunction("", [
+							'if (typeof fetch === "undefined") throw new Error("No browser support: need fetch API");',
+							`return fetch(${RuntimeGlobals.publicPath} + ${
+								RuntimeGlobals.getUpdateManifestFilename
+							}()).then(${runtimeTemplate.basicFunction("response", [
+								"if(response.status === 404) return; // no update available",
+								'if(!response.ok) throw new Error("Failed to fetch update manifest " + response.statusText);',
+								"return response.json();"
+							])});`
+						])};`
+					])
+				: "// no HMR manifest"
+		]);
+	}
+}
+
+module.exports = ImportScriptsChunkLoadingRuntimeModule;
Index: frontend/node_modules/webpack/lib/webworker/WebWorkerTemplatePlugin.js
===================================================================
--- frontend/node_modules/webpack/lib/webworker/WebWorkerTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack/lib/webworker/WebWorkerTemplatePlugin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ArrayPushCallbackChunkFormatPlugin = require("../javascript/ArrayPushCallbackChunkFormatPlugin");
+const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
+
+/** @typedef {import("../Compiler")} Compiler */
+
+class WebWorkerTemplatePlugin {
+	/**
+	 * Applies the plugin by registering its hooks on the compiler.
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.options.output.chunkLoading = "import-scripts";
+		new ArrayPushCallbackChunkFormatPlugin().apply(compiler);
+		new EnableChunkLoadingPlugin("import-scripts").apply(compiler);
+	}
+}
+
+module.exports = WebWorkerTemplatePlugin;
