Index: imaps-frontend/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/AggressiveMergingPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,98 @@
+/*
+	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 */
+
+/**
+ * @typedef {object} AggressiveMergingPluginOptions
+ * @property {number=} minSizeReduce minimal size reduction to trigger merging
+ */
+
+class 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/"
+			);
+		}
+		this.options = options || {};
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const options = this.options;
+		const minSizeReduce = options.minSizeReduce || 1.5;
+
+		compiler.hooks.thisCompilation.tap(
+			"AggressiveMergingPlugin",
+			compilation => {
+				compilation.hooks.optimizeChunks.tap(
+					{
+						name: "AggressiveMergingPlugin",
+						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: imaps-frontend/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/AggressiveSplittingPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,348 @@
+/*
+	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 {
+	compareModulesByIdentifier,
+	compareChunks
+} = require("../util/comparators");
+const createSchemaValidation = require("../util/create-schema-validation");
+const identifierUtils = require("../util/identifier");
+
+/** @typedef {import("../../declarations/plugins/optimize/AggressiveSplittingPlugin").AggressiveSplittingPluginOptions} AggressiveSplittingPluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+
+const validate = createSchemaValidation(
+	require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.check.js"),
+	() =>
+		require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.json"),
+	{
+		name: "Aggressive Splitting Plugin",
+		baseDataPath: "options"
+	}
+);
+
+/**
+ * @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);
+};
+
+/**
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Chunk} chunk the chunk
+ * @returns {function(Module): boolean} filter for entry module
+ */
+const isNotAEntryModule = (chunkGraph, chunk) => module =>
+	!chunkGraph.isEntryModuleInChunk(module, chunk);
+
+/** @type {WeakSet<Chunk>} */
+const recordedChunks = new WeakSet();
+
+class AggressiveSplittingPlugin {
+	/**
+	 * @param {AggressiveSplittingPluginOptions=} options options object
+	 */
+	constructor(options = {}) {
+		validate(options);
+
+		this.options = options;
+		if (typeof this.options.minSize !== "number") {
+			this.options.minSize = 30 * 1024;
+		}
+		if (typeof this.options.maxSize !== "number") {
+			this.options.maxSize = 50 * 1024;
+		}
+		if (typeof this.options.chunkOverhead !== "number") {
+			this.options.chunkOverhead = 0;
+		}
+		if (typeof this.options.entryChunkMultiplicator !== "number") {
+			this.options.entryChunkMultiplicator = 1;
+		}
+	}
+
+	/**
+	 * @param {Chunk} chunk the chunk to test
+	 * @returns {boolean} true if the chunk was recorded
+	 */
+	static wasChunkRecorded(chunk) {
+		return recordedChunks.has(chunk);
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap(
+			"AggressiveSplittingPlugin",
+			compilation => {
+				let needAdditionalSeal = false;
+				/** @typedef {{ id?: NonNullable<Chunk["id"]>, hash?: NonNullable<Chunk["hash"]>, modules: Module[], size: number }} SplitData */
+				/** @type {SplitData[]} */
+				let newSplits;
+				/** @type {Set<Chunk>} */
+				let fromAggressiveSplittingSet;
+				/** @type {Map<Chunk, SplitData>} */
+				let chunkSplitDataMap;
+				compilation.hooks.optimize.tap("AggressiveSplittingPlugin", () => {
+					newSplits = [];
+					fromAggressiveSplittingSet = new Set();
+					chunkSplitDataMap = new Map();
+				});
+				compilation.hooks.optimizeChunks.tap(
+					{
+						name: "AggressiveSplittingPlugin",
+						stage: STAGE_ADVANCED
+					},
+					chunks => {
+						const chunkGraph = compilation.chunkGraph;
+						// Precompute stuff
+						const nameToModuleMap = new Map();
+						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
+						const usedIds = new Set();
+						for (const chunk of chunks) {
+							usedIds.add(chunk.id);
+						}
+
+						const recordedSplits =
+							(compilation.records && compilation.records.aggressiveSplits) ||
+							[];
+						const usedSplits = newSplits
+							? recordedSplits.concat(newSplits)
+							: recordedSplits;
+
+						const minSize = /** @type {number} */ (this.options.minSize);
+						const maxSize = /** @type {number} */ (this.options.maxSize);
+
+						/**
+						 * @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 =>
+								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(
+									Array.from(selectedChunks)[0]
+								) === selectedModules.length
+							) {
+								const chunk = Array.from(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 = /** @type {TODO} */ (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 = Array.from(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));
+								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 => moduleToNameMap.get(m))
+										.sort(),
+									size: selectedModulesSize
+								};
+
+								if (applySplit(splitData)) {
+									newSplits = (newSplits || []).concat(splitData);
+									changed = true;
+								}
+							}
+						}
+						if (changed) return true;
+					}
+				);
+				compilation.hooks.recordHash.tap(
+					"AggressiveSplittingPlugin",
+					records => {
+						// 4. save made splittings to records
+						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 = Array.from(allSplits);
+
+							needAdditionalSeal = false;
+						}
+					}
+				);
+				compilation.hooks.needAdditionalSeal.tap(
+					"AggressiveSplittingPlugin",
+					() => {
+						if (needAdditionalSeal) {
+							needAdditionalSeal = false;
+							return true;
+						}
+					}
+				);
+			}
+		);
+	}
+}
+module.exports = AggressiveSplittingPlugin;
Index: imaps-frontend/node_modules/webpack/lib/optimize/ConcatenatedModule.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/ConcatenatedModule.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/ConcatenatedModule.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,1904 @@
+/*
+	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 { UsageState } = require("../ExportsInfo");
+const Module = require("../Module");
+const { JS_TYPES } = require("../ModuleSourceTypesConstants");
+const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
+const JavascriptParser = require("../javascript/JavascriptParser");
+const { equals } = require("../util/ArrayHelpers");
+const LazySet = require("../util/LazySet");
+const { concatComparators } = require("../util/comparators");
+const {
+	RESERVED_NAMES,
+	findNewName,
+	addScopeSymbols,
+	getAllReferences,
+	getPathInAst,
+	getUsedNamesInScopeInfo
+} = require("../util/concatenate");
+const createHash = require("../util/createHash");
+const { makePathsRelative } = require("../util/identifier");
+const makeSerializable = require("../util/makeSerializable");
+const propertyAccess = require("../util/propertyAccess");
+const { propertyName } = require("../util/propertyName");
+const {
+	filterRuntime,
+	intersectRuntime,
+	mergeRuntimeCondition,
+	mergeRuntimeConditionNonFalse,
+	runtimeConditionToString,
+	subtractRuntimeCondition
+} = require("../util/runtime");
+
+/** @typedef {import("eslint-scope").Reference} Reference */
+/** @typedef {import("eslint-scope").Scope} Scope */
+/** @typedef {import("eslint-scope").Variable} Variable */
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
+/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").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("../ModuleParseError")} ModuleParseError */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../WebpackError")} WebpackError */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
+/** @typedef {import("../javascript/JavascriptParser").Program} Program */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {typeof import("../util/Hash")} HashConstructor */
+/** @typedef {import("../util/concatenate").UsedNames} UsedNames */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @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 = /** @type {any} */ (Referencer);
+if (!ReferencerClass.prototype.PropertyDefinition) {
+	ReferencerClass.prototype.PropertyDefinition =
+		ReferencerClass.prototype.Property;
+}
+
+/**
+ * @typedef {object} ReexportInfo
+ * @property {Module} module
+ * @property {string[]} export
+ */
+
+/** @typedef {RawBinding | SymbolBinding} Binding */
+
+/**
+ * @typedef {object} RawBinding
+ * @property {ModuleInfo} info
+ * @property {string} rawName
+ * @property {string=} comment
+ * @property {string[]} ids
+ * @property {string[]} exportName
+ */
+
+/**
+ * @typedef {object} SymbolBinding
+ * @property {ConcatenatedModuleInfo} info
+ * @property {string} name
+ * @property {string=} comment
+ * @property {string[]} ids
+ * @property {string[]} exportName
+ */
+
+/** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo } ModuleInfo */
+/** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo | ReferenceToModuleInfo } ModuleInfoOrReference */
+
+/**
+ * @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 {Map<string, string> | undefined} exportMap
+ * @property {Map<string, string> | undefined} rawExportMap
+ * @property {string=} namespaceExportSymbol
+ * @property {string | undefined} namespaceObjectName
+ * @property {boolean} interopNamespaceObjectUsed
+ * @property {string | undefined} interopNamespaceObjectName
+ * @property {boolean} interopNamespaceObject2Used
+ * @property {string | undefined} interopNamespaceObject2Name
+ * @property {boolean} interopDefaultAccessUsed
+ * @property {string | undefined} interopDefaultAccessName
+ */
+
+/**
+ * @typedef {object} ExternalModuleInfo
+ * @property {"external"} type
+ * @property {Module} module
+ * @property {RuntimeSpec | boolean} runtimeCondition
+ * @property {number} index
+ * @property {string | undefined} name
+ * @property {boolean} interopNamespaceObjectUsed
+ * @property {string | undefined} interopNamespaceObjectName
+ * @property {boolean} interopNamespaceObject2Used
+ * @property {string | undefined} interopNamespaceObject2Name
+ * @property {boolean} interopDefaultAccessUsed
+ * @property {string | undefined} interopDefaultAccessName
+ */
+
+/**
+ * @typedef {object} ReferenceToModuleInfo
+ * @property {"reference"} type
+ * @property {RuntimeSpec | boolean} runtimeCondition
+ * @property {ModuleInfo} target
+ */
+
+/**
+ * @template T
+ * @param {string} property property
+ * @param {function(T[keyof T], 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 {object} ConcatenationEntry
+ * @property {"concatenated" | "external"} type
+ * @property {Module} module
+ * @property {RuntimeSpec | boolean} runtimeCondition
+ */
+
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ModuleInfo} info module info
+ * @param {string[]} exportName exportName
+ * @param {Map<Module, ModuleInfo>} moduleToInfoMap moduleToInfoMap
+ * @param {RuntimeSpec} runtime for which runtime
+ * @param {RequestShortener} requestShortener the request shortener
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated
+ * @param {boolean} asCall asCall
+ * @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,
+	strictHarmonyModule,
+	asiSafe,
+	alreadyVisited = new Set()
+) => {
+	const exportsType = info.module.getExportsType(
+		moduleGraph,
+		strictHarmonyModule
+	);
+	if (exportName.length === 0) {
+		switch (exportsType) {
+			case "default-only":
+				info.interopNamespaceObject2Used = true;
+				return {
+					info,
+					rawName: /** @type {string} */ (info.interopNamespaceObject2Name),
+					ids: exportName,
+					exportName
+				};
+			case "default-with-named":
+				info.interopNamespaceObjectUsed = true;
+				return {
+					info,
+					rawName: /** @type {string} */ (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);
+						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
+					};
+				}
+				break;
+			}
+			case "dynamic":
+				switch (exportName[0]) {
+					case "default": {
+						exportName = exportName.slice(1);
+						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":
+				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 {string[]} */ (
+					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,
+					/** @type {BuildMeta} */
+					(info.module.buildMeta).strictHarmonyModule,
+					asiSafe,
+					alreadyVisited
+				);
+			}
+			if (info.namespaceExportSymbol) {
+				const usedName = /** @type {string[]} */ (
+					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 {string[]} */ (
+				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: info.name + comment, ids: used, exportName };
+		}
+	}
+};
+
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ModuleInfo} info module info
+ * @param {string[]} exportName exportName
+ * @param {Map<Module, ModuleInfo>} moduleToInfoMap moduleToInfoMap
+ * @param {RuntimeSpec} runtime for which runtime
+ * @param {RequestShortener} requestShortener the request shortener
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated
+ * @param {boolean} asCall asCall
+ * @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,
+	callContext,
+	strictHarmonyModule,
+	asiSafe
+) => {
+	const binding = getFinalBinding(
+		moduleGraph,
+		info,
+		exportName,
+		moduleToInfoMap,
+		runtime,
+		requestShortener,
+		runtimeTemplate,
+		neededNamespaceObjects,
+		asCall,
+		strictHarmonyModule,
+		asiSafe
+	);
+	{
+		const { ids, comment } = binding;
+		let reference;
+		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<[Record<string, string>], boolean | void>} exportsDefinitions
+ */
+
+/** @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 {object=} associatedObjectForCache object for caching
+	 * @param {string | HashConstructor=} hashFunction hash function to use
+	 * @returns {ConcatenatedModule} the module
+	 */
+	static create(
+		rootModule,
+		modules,
+		runtime,
+		compilation,
+		associatedObjectForCache,
+		hashFunction = "md4"
+	) {
+		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 = {
+				exportsDefinitions: new SyncBailHook(["definitions"])
+			};
+			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 | undefined} */
+		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 {SourceTypes} types available (do not mutate)
+	 */
+	getSourceTypes() {
+		return JS_TYPES;
+	}
+
+	get modules() {
+		return Array.from(this._modules);
+	}
+
+	/**
+	 * @returns {string} a unique identifier of the module
+	 */
+	identifier() {
+		return this._identifier;
+	}
+
+	/**
+	 * @param {RequestShortener} requestShortener the request shortener
+	 * @returns {string} a user readable identifier of the module
+	 */
+	readableIdentifier(requestShortener) {
+		return `${this.rootModule.readableIdentifier(
+			requestShortener
+		)} + ${this._modules.size - 1} modules`;
+	}
+
+	/**
+	 * @param {LibIdentOptions} options options
+	 * @returns {string | null} an identifier for library inclusion
+	 */
+	libIdent(options) {
+		return this.rootModule.libIdent(options);
+	}
+
+	/**
+	 * @returns {string | null} absolute path which should be used for condition matching (usually the resource path)
+	 */
+	nameForCondition() {
+		return this.rootModule.nameForCondition();
+	}
+
+	/**
+	 * @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);
+	}
+
+	/**
+	 * @param {WebpackOptions} options webpack options
+	 * @param {Compilation} compilation the compilation
+	 * @param {ResolverWithOptions} resolver the resolver
+	 * @param {InputFileSystem} fs the file system
+	 * @param {function(WebpackError=): void} callback callback function
+	 * @returns {void}
+	 */
+	build(options, compilation, resolver, fs, callback) {
+		const { rootModule } = this;
+		const { moduleArgument, exportsArgument } =
+			/** @type {BuildInfo} */
+			(rootModule.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 =>
+					!(dep instanceof HarmonyImportDependency) ||
+					!this._modules.has(
+						/** @type {Module} */ (compilation.moduleGraph.getModule(dep))
+					)
+			)) {
+				this.dependencies.push(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 } =
+				/** @type {BuildInfo} */ (m.buildInfo);
+
+			// populate topLevelDeclarations
+			if (topLevelDeclarations) {
+				const topLevelDeclarations = this.buildInfo.topLevelDeclarations;
+				if (topLevelDeclarations !== undefined) {
+					for (const decl of topLevelDeclarations) {
+						topLevelDeclarations.add(decl);
+					}
+				}
+			} else {
+				this.buildInfo.topLevelDeclarations = undefined;
+			}
+
+			// populate assets
+			if (assets) {
+				if (this.buildInfo.assets === undefined) {
+					this.buildInfo.assets = Object.create(null);
+				}
+				Object.assign(
+					/** @type {NonNullable<BuildInfo["assets"]>} */
+					(
+						/** @type {BuildInfo} */
+						(this.buildInfo).assets
+					),
+					assets
+				);
+			}
+			if (assetsInfo) {
+				if (this.buildInfo.assetsInfo === undefined) {
+					this.buildInfo.assetsInfo = new Map();
+				}
+				for (const [key, value] of assetsInfo) {
+					this.buildInfo.assetsInfo.set(key, value);
+				}
+			}
+		}
+		callback();
+	}
+
+	/**
+	 * @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, RuntimeSpec | true>} */
+		const existingEntries = new Map();
+
+		/**
+		 * @param {Module} module a module
+		 * @returns {Iterable<{ connection: ModuleGraphConnection, runtimeCondition: RuntimeSpec | true }>} imported modules in order
+		 */
+		const getConcatenatedImports = module => {
+			const connections = Array.from(
+				moduleGraph.getOutgoingConnections(module)
+			);
+			if (module === rootModule) {
+				for (const c of moduleGraph.getOutgoingConnections(this))
+					connections.push(c);
+			}
+			/**
+			 * @type {Array<{ connection: ModuleGraphConnection, sourceOrder: number, rangeStart: number }>}
+			 */
+			const references = connections
+				.filter(connection => {
+					if (!(connection.dependency instanceof HarmonyImportDependency))
+						return false;
+					return (
+						connection &&
+						connection.resolvedOriginModule === module &&
+						connection.module &&
+						connection.isTargetActive(runtime)
+					);
+				})
+				.map(connection => {
+					const dep = /** @type {HarmonyImportDependency} */ (
+						connection.dependency
+					);
+					return {
+						connection,
+						sourceOrder: dep.sourceOrder,
+						rangeStart: dep.range && dep.range[0]
+					};
+				});
+			/**
+			 * 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 }>} */
+			const referencesMap = new Map();
+			for (const { connection } of references) {
+				const runtimeCondition = filterRuntime(runtime, r =>
+					connection.isTargetActive(r)
+				);
+				if (runtimeCondition === false) continue;
+				const module = connection.module;
+				const entry = referencesMap.get(module);
+				if (entry === undefined) {
+					referencesMap.set(module, { connection, runtimeCondition });
+					continue;
+				}
+				entry.runtimeCondition = mergeRuntimeConditionNonFalse(
+					entry.runtimeCondition,
+					runtimeCondition,
+					runtime
+				);
+			}
+			return referencesMap.values();
+		};
+
+		/**
+		 * @param {ModuleGraphConnection} connection graph connection
+		 * @param {RuntimeSpec | true} runtimeCondition runtime condition
+		 * @returns {void}
+		 */
+		const enterModule = (connection, runtimeCondition) => {
+			const module = connection.module;
+			if (!module) return;
+			const existingEntry = existingEntries.get(module);
+			if (existingEntry === true) {
+				return;
+			}
+			if (modulesSet.has(module)) {
+				existingEntries.set(module, 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.`
+					);
+				}
+				const imports = getConcatenatedImports(module);
+				for (const { connection, runtimeCondition } of imports)
+					enterModule(connection, runtimeCondition);
+				list.push({
+					type: "concatenated",
+					module: connection.module,
+					runtimeCondition
+				});
+			} else {
+				if (existingEntry !== undefined) {
+					const reducedRuntimeCondition = subtractRuntimeCondition(
+						runtimeCondition,
+						existingEntry,
+						runtime
+					);
+					if (reducedRuntimeCondition === false) return;
+					runtimeCondition = reducedRuntimeCondition;
+					existingEntries.set(
+						connection.module,
+						mergeRuntimeConditionNonFalse(
+							existingEntry,
+							runtimeCondition,
+							runtime
+						)
+					);
+				} else {
+					existingEntries.set(connection.module, runtimeCondition);
+				}
+				if (list.length > 0) {
+					const lastItem = list[list.length - 1];
+					if (
+						lastItem.type === "external" &&
+						lastItem.module === connection.module
+					) {
+						lastItem.runtimeCondition = mergeRuntimeCondition(
+							lastItem.runtimeCondition,
+							runtimeCondition,
+							runtime
+						);
+						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
+				});
+			}
+		};
+
+		existingEntries.set(rootModule, true);
+		const imports = getConcatenatedImports(rootModule);
+		for (const { connection, runtimeCondition } of imports)
+			enterModule(connection, runtimeCondition);
+		list.push({
+			type: "concatenated",
+			module: rootModule,
+			runtimeCondition: 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 {object=} associatedObjectForCache object for caching
+	 * @param {string | HashConstructor=} hashFunction hash function to use
+	 * @returns {string} the identifier
+	 */
+	static _createIdentifier(
+		rootModule,
+		modules,
+		associatedObjectForCache,
+		hashFunction = "md4"
+	) {
+		const cachedMakePathsRelative = makePathsRelative.bindContextCache(
+			/** @type {string} */ (rootModule.context),
+			associatedObjectForCache
+		);
+		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")}`;
+	}
+
+	/**
+	 * @param {LazySet<string>} fileDependencies set where file dependencies are added to
+	 * @param {LazySet<string>} contextDependencies set where context dependencies are added to
+	 * @param {LazySet<string>} missingDependencies set where missing dependencies are added to
+	 * @param {LazySet<string>} buildDependencies set where build dependencies are added to
+	 */
+	addCacheDependencies(
+		fileDependencies,
+		contextDependencies,
+		missingDependencies,
+		buildDependencies
+	) {
+		for (const module of this._modules) {
+			module.addCacheDependencies(
+				fileDependencies,
+				contextDependencies,
+				missingDependencies,
+				buildDependencies
+			);
+		}
+	}
+
+	/**
+	 * @param {CodeGenerationContext} context context for code generation
+	 * @returns {CodeGenerationResult} result
+	 */
+	codeGeneration({
+		dependencyTemplates,
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime: generationRuntime,
+		codeGenerationResults
+	}) {
+		/** @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 {Set<ConcatenatedModuleInfo>} */
+		const neededNamespaceObjects = new Set();
+
+		// 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,
+				/** @type {CodeGenerationResults} */
+				(codeGenerationResults)
+			);
+		}
+
+		// List of all used names to avoid conflicts
+		const allUsedNames = new Set(RESERVED_NAMES);
+		// Updated Top level declarations are created by renaming
+		const topLevelDeclarations = new Set();
+
+		// List of additional names in scope for module references
+		/** @type {Map<string, { usedNames: UsedNames, alreadyCheckedScopes: Set<TODO> }>} */
+		const usedNamesInScopeInfo = new Map();
+		/**
+		 * @param {string} module module identifier
+		 * @param {string} id export id
+		 * @returns {{ usedNames: UsedNames, alreadyCheckedScopes: Set<TODO> }} info
+		 */
+
+		// Set of already checked scopes
+		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
+				const superClassCache = new WeakMap();
+				/**
+				 * @param {Scope} scope scope
+				 * @returns {TODO} result
+				 */
+				const getSuperClassExpressions = scope => {
+					const cacheEntry = superClassCache.get(scope);
+					if (cacheEntry !== undefined) return cacheEntry;
+					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: 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,
+								/** @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);
+						}
+					}
+				}
+			}
+		}
+
+		// 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 { usedNames, alreadyCheckedScopes } = getUsedNamesInScopeInfo(
+							usedNamesInScopeInfo,
+							info.module.identifier(),
+							name
+						);
+						if (allUsedNames.has(name) || usedNames.has(name)) {
+							const references = getAllReferences(variable);
+							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);
+							const source = /** @type {ReplaceSource} */ (info.source);
+							const allIdentifiers = new Set(
+								references.map(r => r.identifier).concat(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);
+						}
+					}
+					let namespaceObjectName;
+					if (info.namespaceExportSymbol) {
+						namespaceObjectName = info.internalNames.get(
+							info.namespaceExportSymbol
+						);
+					} else {
+						namespaceObjectName = findNewName(
+							"namespaceObject",
+							allUsedNames,
+							namespaceObjectUsedNames,
+							info.module.readableIdentifier(requestShortener)
+						);
+						allUsedNames.add(namespaceObjectName);
+					}
+					info.namespaceObjectName =
+						/** @type {string} */
+						(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);
+					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"
+			) {
+				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);
+				for (const reference of globalScope.through) {
+					const name = reference.identifier.name;
+					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 finalName = getFinalName(
+							moduleGraph,
+							referencedInfo,
+							match.ids,
+							moduleToInfoMap,
+							runtime,
+							requestShortener,
+							runtimeTemplate,
+							neededNamespaceObjects,
+							match.call,
+							!match.directImport,
+							/** @type {BuildMeta} */
+							(info.module.buildMeta).strictHarmonyModule,
+							match.asiSafe
+						);
+						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, function(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,
+						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;
+		if (
+			moduleGraph.getExportsInfo(this).otherExportsInfo.getUsed(runtime) !==
+			UsageState.Unused
+		) {
+			shouldAddHarmonyFlag = true;
+		}
+
+		// define exports
+		if (exportsMap.size > 0) {
+			const { exportsDefinitions } = ConcatenatedModule.getCompilationHooks(
+				/** @type {Compilation} */ (this.compilation)
+			);
+
+			const definitions = [];
+			for (const [key, value] of exportsMap) {
+				definitions.push(
+					`\n  ${propertyName(key)}: ${runtimeTemplate.returningFunction(
+						value(requestShortener)
+					)}`
+				);
+			}
+			const shouldSkipRenderDefinitions =
+				exportsDefinitions.call(exportsFinalName);
+
+			if (!shouldSkipRenderDefinitions) {
+				runtimeRequirements.add(RuntimeGlobals.exports);
+				runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
+
+				if (shouldAddHarmonyFlag) {
+					result.add("// ESM COMPAT FLAG\n");
+					result.add(
+						runtimeTemplate.defineEsModuleFlagStatement({
+							exportsArgument: this.exportsArgument,
+							runtimeRequirements
+						})
+					);
+				}
+
+				result.add("\n// EXPORTS\n");
+				result.add(
+					`${RuntimeGlobals.definePropertyGetters}(${
+						this.exportsArgument
+					}, {${definitions.join(",")}\n});\n`
+				);
+			} else {
+				/** @type {BuildMeta} */
+				(this.buildMeta).exportsFinalName = exportsFinalName;
+			}
+		}
+
+		// list unused exports
+		if (unusedExports.size > 0) {
+			result.add(
+				`\n// UNUSED EXPORTS: ${joinIterableWithComma(unusedExports)}\n`
+			);
+		}
+
+		// generate namespace objects
+		const namespaceObjectSources = new Map();
+		for (const info of neededNamespaceObjects) {
+			if (info.namespaceExportSymbol) continue;
+			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,
+						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);
+			}
+		}
+
+		const chunkInitFragments = [];
+
+		// evaluate modules in order
+		for (const rawInfo of modulesWithInfo) {
+			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": {
+					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`);
+					}
+					result.add(
+						`var ${info.name} = ${RuntimeGlobals.require}(${JSON.stringify(
+							chunkGraph.getModuleId(info.module)
+						)});`
+					);
+					name = info.name;
+					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}");
+			}
+		}
+
+		const data = new Map();
+		if (chunkInitFragments.length > 0)
+			data.set("chunkInitFragments", chunkInitFragments);
+		data.set("topLevelDeclarations", topLevelDeclarations);
+
+		/** @type {CodeGenerationResult} */
+		const resultEntry = {
+			sources: new Map([["javascript", new CachedSource(result)]]),
+			data,
+			runtimeRequirements
+		};
+
+		return resultEntry;
+	}
+
+	/**
+	 * @param {Map<Module, ModuleInfo>} 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 {CodeGenerationResults} codeGenerationResults codeGenerationResults
+	 */
+	_analyseModule(
+		modulesMap,
+		info,
+		dependencyTemplates,
+		runtimeTemplate,
+		moduleGraph,
+		chunkGraph,
+		runtime,
+		codeGenerationResults
+	) {
+		if (info.type === "concatenated") {
+			const m = info.module;
+			try {
+				// Create a concatenation scope to track and capture information
+				const concatenationScope = new ConcatenationScope(modulesMap, info);
+
+				// TODO cache codeGeneration results
+				const codeGenResult = m.codeGeneration({
+					dependencyTemplates,
+					runtimeTemplate,
+					moduleGraph,
+					chunkGraph,
+					runtime,
+					concatenationScope,
+					codeGenerationResults,
+					sourceTypes: JS_TYPES
+				});
+				const source = /** @type {Source} */ (
+					codeGenResult.sources.get("javascript")
+				);
+				const data = codeGenResult.data;
+				const chunkInitFragments = data && data.get("chunkInitFragments");
+				const code = source.source().toString();
+				let ast;
+				try {
+					ast = JavascriptParser._parse(code, {
+						sourceType: "module"
+					});
+				} catch (_err) {
+					const err = /** @type {TODO} */ (_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;
+			} 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[], Map<Module, ModuleInfo>]} module info items
+	 */
+	_getModulesWithInfo(moduleGraph, runtime) {
+		const orderedConcatenationList = this._createConcatenationList(
+			this.rootModule,
+			this._modules,
+			runtime,
+			moduleGraph
+		);
+		/** @type {Map<Module, ModuleInfo>} */
+		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
+						};
+						break;
+					case "external":
+						item = {
+							type: "external",
+							module: info.module,
+							runtimeCondition: info.runtimeCondition,
+							index,
+							name: undefined,
+							interopNamespaceObjectUsed: false,
+							interopNamespaceObjectName: undefined,
+							interopNamespaceObject2Used: false,
+							interopNamespaceObject2Name: undefined,
+							interopDefaultAccessUsed: false,
+							interopDefaultAccessName: undefined
+						};
+						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,
+				target: item
+			};
+			return ref;
+		});
+		return [list, map];
+	}
+
+	/**
+	 * @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: imaps-frontend/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/EnsureChunkConditionsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,88 @@
+/*
+	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 */
+
+class EnsureChunkConditionsPlugin {
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			"EnsureChunkConditionsPlugin",
+			compilation => {
+				/**
+				 * @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: "EnsureChunkConditionsPlugin",
+						stage: STAGE_BASIC
+					},
+					handler
+				);
+			}
+		);
+	}
+}
+module.exports = EnsureChunkConditionsPlugin;
Index: imaps-frontend/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/FlagIncludedChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,130 @@
+/*
+	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 */
+
+class FlagIncludedChunksPlugin {
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap("FlagIncludedChunksPlugin", compilation => {
+			compilation.hooks.optimizeChunkIds.tap(
+				"FlagIncludedChunksPlugin",
+				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);
+					const modulos = Array.from(
+						{ length: 31 },
+						(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;
+						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: imaps-frontend/node_modules/webpack/lib/optimize/InnerGraph.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/InnerGraph.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/InnerGraph.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,351 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+
+/** @typedef {import("estree").Node} AnyNode */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/** @typedef {Map<TopLevelSymbol | null, Set<string | TopLevelSymbol> | true | undefined>} InnerGraph */
+/** @typedef {function(boolean | Set<string> | undefined): void} UsageCallback */
+
+/**
+ * @typedef {object} StateObject
+ * @property {InnerGraph} innerGraph
+ * @property {TopLevelSymbol=} currentTopLevelSymbol
+ * @property {Map<TopLevelSymbol, Set<UsageCallback>>} usageCallbackMap
+ */
+
+/** @typedef {false|StateObject} State */
+
+/** @type {WeakMap<ParserState, State>} */
+const parserStateMap = new WeakMap();
+const topLevelSymbolTag = Symbol("top level symbol");
+
+/**
+ * @param {ParserState} parserState parser state
+ * @returns {State | undefined} state
+ */
+function getState(parserState) {
+	return parserStateMap.get(parserState);
+}
+
+/**
+ * @param {ParserState} parserState parser state
+ * @returns {void}
+ */
+module.exports.bailout = parserState => {
+	parserStateMap.set(parserState, false);
+};
+
+/**
+ * @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()
+	});
+};
+
+/**
+ * @param {ParserState} parserState parser state
+ * @returns {boolean} true, when enabled
+ */
+module.exports.isEnabled = parserState => {
+	const state = parserStateMap.get(parserState);
+	return Boolean(state);
+};
+
+/**
+ * @param {ParserState} state parser state
+ * @param {TopLevelSymbol | null} symbol the symbol, or null for all symbols
+ * @param {string | TopLevelSymbol | true} 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);
+		}
+	}
+};
+
+/**
+ * @param {JavascriptParser} parser the parser
+ * @param {string} name name of variable
+ * @param {string | TopLevelSymbol | true} 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);
+	}
+};
+
+/**
+ * @param {ParserState} state parser state
+ * @returns {void}
+ */
+module.exports.inferDependencyUsage = state => {
+	const innerGraphState = getState(state);
+
+	if (!innerGraphState) {
+		return;
+	}
+
+	const { innerGraph, usageCallbackMap } = innerGraphState;
+	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 {Set<string|TopLevelSymbol> | true} */
+			let newSet = new Set();
+			let isTerminal = true;
+			const value = innerGraph.get(key);
+			let alreadyProcessed = processed.get(key);
+			if (alreadyProcessed === undefined) {
+				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);
+		}
+	}
+};
+
+/**
+ * @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) {
+				callbacks = new Set();
+				usageCallbackMap.set(currentTopLevelSymbol, callbacks);
+			}
+
+			callbacks.add(onUsageCallback);
+		} else {
+			onUsageCallback(true);
+		}
+	} else {
+		onUsageCallback(undefined);
+	}
+};
+
+/**
+ * @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;
+	}
+};
+
+/**
+ * @param {ParserState} state parser state
+ * @returns {TopLevelSymbol|void} usage data
+ */
+module.exports.getTopLevelSymbol = state => {
+	const innerGraphState = getState(state);
+
+	if (innerGraphState) {
+		return innerGraphState.currentTopLevelSymbol;
+	}
+};
+
+/**
+ * @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 fn = new TopLevelSymbol(name);
+	parser.tagVariable(name, topLevelSymbolTag, fn);
+	return fn;
+};
+
+/**
+ * @param {Dependency} dependency the dependency
+ * @param {Set<string> | boolean} 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;
+};
+
+/**
+ * @param {Dependency} dependency the dependency
+ * @param {Set<string> | boolean | undefined} usedByExports usedByExports info
+ * @param {ModuleGraph} moduleGraph moduleGraph
+ * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} 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;
+};
+
+class TopLevelSymbol {
+	/**
+	 * @param {string} name name of the variable
+	 */
+	constructor(name) {
+		this.name = name;
+	}
+}
+
+module.exports.TopLevelSymbol = TopLevelSymbol;
+module.exports.topLevelSymbolTag = topLevelSymbolTag;
Index: imaps-frontend/node_modules/webpack/lib/optimize/InnerGraphPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/InnerGraphPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/InnerGraphPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,450 @@
+/*
+	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 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").Node} Node */
+/** @typedef {import("estree").VariableDeclarator} VariableDeclaratorNode */
+/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+/** @typedef {import("./InnerGraph").InnerGraph} InnerGraph */
+/** @typedef {import("./InnerGraph").TopLevelSymbol} TopLevelSymbol */
+
+const { topLevelSymbolTag } = InnerGraph;
+
+const PLUGIN_NAME = "InnerGraphPlugin";
+
+class InnerGraphPlugin {
+	/**
+	 * Apply the plugin
+	 * @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()
+				);
+
+				/**
+				 * @param {JavascriptParser} parser the parser
+				 * @param {JavascriptParserOptions} parserOptions options
+				 * @returns {void}
+				 */
+				const handler = (parser, parserOptions) => {
+					/**
+					 * @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);
+					});
+
+					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, TopLevelSymbol>} */
+					const statementWithTopLevelSymbol = new WeakMap();
+					/** @type {WeakMap<Node, Node>} */
+					const statementPurePart = new WeakMap();
+
+					/** @type {WeakMap<ClassExpression | ClassDeclaration, TopLevelSymbol>} */
+					const classWithTopLevelSymbol = new WeakMap();
+
+					/** @type {WeakMap<VariableDeclaratorNode, TopLevelSymbol>} */
+					const declWithTopLevelSymbol = new WeakMap();
+					/** @type {WeakSet<VariableDeclaratorNode>} */
+					const 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 fn =
+								/** @type {TopLevelSymbol} */
+								(InnerGraph.tagTopLevelSymbol(parser, name));
+							statementWithTopLevelSymbol.set(statement, fn);
+							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 fn = /** @type {TopLevelSymbol} */ (
+									InnerGraph.tagTopLevelSymbol(parser, name)
+								);
+								classWithTopLevelSymbol.set(statement, fn);
+								return true;
+							}
+							if (statement.type === "ExportDefaultDeclaration") {
+								const name = "*default*";
+								const fn =
+									/** @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),
+										fn
+									);
+								} else if (
+									parser.isPure(
+										/** @type {Expression} */
+										(decl),
+										/** @type {Range} */
+										(statement.range)[0]
+									)
+								) {
+									statementWithTopLevelSymbol.set(statement, fn);
+									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 (
+							parser.scope.topLevelScope === true &&
+							decl.init &&
+							decl.id.type === "Identifier"
+						) {
+							const name = decl.id.name;
+							if (
+								decl.init.type === "ClassExpression" &&
+								parser.isPure(
+									decl.init,
+									/** @type {Range} */ (decl.id.range)[1]
+								)
+							) {
+								const fn =
+									/** @type {TopLevelSymbol} */
+									(InnerGraph.tagTopLevelSymbol(parser, name));
+								classWithTopLevelSymbol.set(decl.init, fn);
+							} else if (
+								parser.isPure(
+									decl.init,
+									/** @type {Range} */ (decl.id.range)[1]
+								)
+							) {
+								const fn =
+									/** @type {TopLevelSymbol} */
+									(InnerGraph.tagTopLevelSymbol(parser, name));
+								declWithTopLevelSymbol.set(decl, fn);
+								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 fn = statementWithTopLevelSymbol.get(statement);
+							if (fn) {
+								InnerGraph.setTopLevelSymbol(parser.state, fn);
+								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 fn = classWithTopLevelSymbol.get(statement);
+								if (
+									fn &&
+									parser.isPure(
+										expr,
+										statement.id
+											? /** @type {Range} */ (statement.id.range)[1]
+											: /** @type {Range} */ (statement.range)[0]
+									)
+								) {
+									InnerGraph.setTopLevelSymbol(parser.state, fn);
+									onUsageSuper(expr);
+								}
+							}
+						}
+					);
+
+					parser.hooks.classBodyElement.tap(
+						PLUGIN_NAME,
+						(element, classDefinition) => {
+							if (!InnerGraph.isEnabled(parser.state)) return;
+							if (parser.scope.topLevelScope === true) {
+								const fn = classWithTopLevelSymbol.get(classDefinition);
+								if (fn) {
+									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 fn = classWithTopLevelSymbol.get(classDefinition);
+								if (fn) {
+									if (
+										!element.static ||
+										parser.isPure(
+											expression,
+											element.key
+												? /** @type {Range} */ (element.key.range)[1]
+												: /** @type {Range} */ (element.range)[0]
+										)
+									) {
+										InnerGraph.setTopLevelSymbol(parser.state, fn);
+										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 fn = declWithTopLevelSymbol.get(decl);
+
+						if (fn) {
+							InnerGraph.setTopLevelSymbol(parser.state, fn);
+							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(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: imaps-frontend/node_modules/webpack/lib/optimize/LimitChunkCountPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/LimitChunkCountPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/LimitChunkCountPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,277 @@
+/*
+	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");
+const createSchemaValidation = require("../util/create-schema-validation");
+
+/** @typedef {import("../../declarations/plugins/optimize/LimitChunkCountPlugin").LimitChunkCountPluginOptions} LimitChunkCountPluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const validate = createSchemaValidation(
+	require("../../schemas/plugins/optimize/LimitChunkCountPlugin.check.js"),
+	() => require("../../schemas/plugins/optimize/LimitChunkCountPlugin.json"),
+	{
+		name: "Limit Chunk Count Plugin",
+		baseDataPath: "options"
+	}
+);
+
+/**
+ * @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
+ */
+
+/**
+ * @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);
+	}
+};
+
+class LimitChunkCountPlugin {
+	/**
+	 * @param {LimitChunkCountPluginOptions=} options options object
+	 */
+	constructor(options) {
+		validate(options);
+		this.options = /** @type {LimitChunkCountPluginOptions} */ (options);
+	}
+
+	/**
+	 * @param {Compiler} compiler the webpack compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const options = this.options;
+		compiler.hooks.compilation.tap("LimitChunkCountPlugin", compilation => {
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: "LimitChunkCountPlugin",
+					stage: STAGE_ADVANCED
+				},
+				chunks => {
+					const chunkGraph = compilation.chunkGraph;
+					const maxChunks = 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);
+					const orderedChunks = Array.from(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
+					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
+						/**
+						 * @param {ChunkCombination} c combination
+						 * @returns {number} integrated size
+						 */
+						c => c.integratedSize,
+						(a, b) => a - b,
+						// Layer 3: ordered by position difference in orderedChunk (-> to be deterministic)
+						/**
+						 * @param {ChunkCombination} c combination
+						 * @returns {number} position difference
+						 */
+						c => c.bIdx - c.aIdx,
+						(a, b) => a - b,
+						// Layer 4: ordered by position in orderedChunk (-> to be deterministic)
+						(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,
+								options
+							);
+
+							const aSize = chunkGraph.getChunkSize(a, options);
+							const bSize = chunkGraph.getChunkSize(b, options);
+							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,
+										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,
+										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: imaps-frontend/node_modules/webpack/lib/optimize/MangleExportsPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/MangleExportsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/MangleExportsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,182 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { UsageState } = require("../ExportsInfo");
+const {
+	numberToIdentifier,
+	NUMBER_OF_IDENTIFIER_START_CHARS,
+	NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS
+} = 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 */
+
+/**
+ * @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
+const comparator = compareSelect(e => e.name, compareStringsNumeric);
+/**
+ * @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;
+	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-zA-Z0-9_$]/.test(name)) ||
+				// Don't rename 2 char exports in deterministic mode
+				(deterministic &&
+					name.length === 2 &&
+					/^[a-zA-Z_$][a-zA-Z0-9_$]|^[1-9][0-9]/.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 {
+		const usedExports = [];
+		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) {
+				let name;
+				do {
+					name = numberToIdentifier(i++);
+				} while (usedNames.has(name));
+				exportInfo.setUsedName(name);
+			}
+		}
+	}
+};
+
+class MangleExportsPlugin {
+	/**
+	 * @param {boolean} deterministic use deterministic names
+	 */
+	constructor(deterministic) {
+		this._deterministic = deterministic;
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _deterministic: deterministic } = this;
+		compiler.hooks.compilation.tap("MangleExportsPlugin", compilation => {
+			const moduleGraph = compilation.moduleGraph;
+			compilation.hooks.optimizeCodeGeneration.tap(
+				"MangleExportsPlugin",
+				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: imaps-frontend/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/MergeDuplicateChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,135 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_BASIC } = require("../OptimizationStages");
+const createSchemaValidation = require("../util/create-schema-validation");
+const { runtimeEqual } = require("../util/runtime");
+
+/** @typedef {import("../../declarations/plugins/optimize/MergeDuplicateChunksPlugin").MergeDuplicateChunksPluginOptions} MergeDuplicateChunksPluginOptions */
+/** @typedef {import("../Compiler")} Compiler */
+
+const validate = createSchemaValidation(
+	require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js"),
+	() =>
+		require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.json"),
+	{
+		name: "Merge Duplicate Chunks Plugin",
+		baseDataPath: "options"
+	}
+);
+
+class MergeDuplicateChunksPlugin {
+	/**
+	 * @param {MergeDuplicateChunksPluginOptions} options options object
+	 */
+	constructor(options = { stage: STAGE_BASIC }) {
+		validate(options);
+		this.options = options;
+	}
+
+	/**
+	 * @param {Compiler} compiler the compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap(
+			"MergeDuplicateChunksPlugin",
+			compilation => {
+				compilation.hooks.optimizeChunks.tap(
+					{
+						name: "MergeDuplicateChunksPlugin",
+						stage: this.options.stage
+					},
+					chunks => {
+						const { chunkGraph, moduleGraph } = compilation;
+
+						// remember already tested chunks for performance
+						const notDuplicates = new Set();
+
+						// for each chunk
+						for (const chunk of chunks) {
+							// track a Set of all chunk that could be duplicates
+							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: imaps-frontend/node_modules/webpack/lib/optimize/MinChunkSizePlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/MinChunkSizePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/MinChunkSizePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,113 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_ADVANCED } = require("../OptimizationStages");
+const createSchemaValidation = require("../util/create-schema-validation");
+
+/** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+const validate = createSchemaValidation(
+	require("../../schemas/plugins/optimize/MinChunkSizePlugin.check.js"),
+	() => require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"),
+	{
+		name: "Min Chunk Size Plugin",
+		baseDataPath: "options"
+	}
+);
+
+class MinChunkSizePlugin {
+	/**
+	 * @param {MinChunkSizePluginOptions} options options object
+	 */
+	constructor(options) {
+		validate(options);
+		this.options = options;
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const options = this.options;
+		const minChunkSize = options.minChunkSize;
+		compiler.hooks.compilation.tap("MinChunkSizePlugin", compilation => {
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: "MinChunkSizePlugin",
+					stage: STAGE_ADVANCED
+				},
+				chunks => {
+					const chunkGraph = compilation.chunkGraph;
+					const equalOptions = {
+						chunkOverhead: 1,
+						entryChunkMultiplicator: 1
+					};
+
+					const chunkSizesMap = new Map();
+					/** @type {[Chunk, Chunk][]} */
+					const combinations = [];
+					/** @type {Chunk[]} */
+					const smallChunks = [];
+					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) < 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, options));
+						visitedChunks.push(a);
+					}
+
+					const sortedSizeFilteredExtendedPairCombinations = combinations
+						.map(pair => {
+							// extend combination pairs with size and integrated size
+							const a = chunkSizesMap.get(pair[0]);
+							const b = chunkSizesMap.get(pair[1]);
+							const ab = chunkGraph.getIntegratedChunksSize(
+								pair[0],
+								pair[1],
+								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: imaps-frontend/node_modules/webpack/lib/optimize/MinMaxSizeWarning.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/MinMaxSizeWarning.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/MinMaxSizeWarning.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,35 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const SizeFormatHelpers = require("../SizeFormatHelpers");
+const WebpackError = require("../WebpackError");
+
+class MinMaxSizeWarning extends WebpackError {
+	/**
+	 * @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 (${SizeFormatHelpers.formatSize(minSize)}) is ` +
+				`bigger than maxSize (${SizeFormatHelpers.formatSize(maxSize)}).\n` +
+				"This seem to be a invalid optimization.splitChunks configuration."
+		);
+	}
+}
+
+module.exports = MinMaxSizeWarning;
Index: imaps-frontend/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,932 @@
+/*
+	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 ModuleGraph = require("../ModuleGraph");
+const { STAGE_DEFAULT } = require("../OptimizationStages");
+const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
+const { compareModulesByIdentifier } = require("../util/comparators");
+const {
+	intersectRuntime,
+	mergeRuntimeOwned,
+	filterRuntime,
+	runtimeToString,
+	mergeRuntime
+} = require("../util/runtime");
+const ConcatenatedModule = require("./ConcatenatedModule");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+/**
+ * @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
+ */
+
+/**
+ * @param {string} msg message
+ * @returns {string} formatted message
+ */
+const formatBailoutReason = msg => `ModuleConcatenation bailout: ${msg}`;
+
+class ModuleConcatenationPlugin {
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const { _backCompat: backCompat } = compiler;
+		compiler.hooks.compilation.tap("ModuleConcatenationPlugin", 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();
+
+			/**
+			 * @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)
+					);
+			};
+
+			/**
+			 * @param {Module} module the module
+			 * @param {string | ((requestShortener: RequestShortener) => string)} reason the reason
+			 */
+			const setInnerBailoutReason = (module, reason) => {
+				bailoutReasonMap.set(module, 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;
+			};
+
+			/**
+			 * @param {Module} module the module
+			 * @param {Module | function(RequestShortener): string} 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: "ModuleConcatenationPlugin",
+					stage: STAGE_DEFAULT
+				},
+				(allChunks, modules, callback) => {
+					const logger = compilation.getLogger(
+						"webpack.ModuleConcatenationPlugin"
+					);
+					const { chunkGraph, moduleGraph } = compilation;
+					const relevantModules = [];
+					const possibleInners = new Set();
+					const context = {
+						chunkGraph,
+						moduleGraph
+					};
+					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;
+						}
+
+						// Module must not be an entry point
+						if (chunkGraph.isEntryModule(module)) {
+							setInnerBailoutReason(module, "Module is an entry point");
+							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");
+					const concatConfigurations = [];
+					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;
+
+						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
+						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) {
+							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");
+					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
+							ConcatenatedModule.getCompilationHooks(compilation);
+							const newModule = ConcatenatedModule.create(
+								rootModule,
+								modules,
+								concatConfiguration.runtime,
+								compilation,
+								compiler.root,
+								compilation.outputOptions.hashFunction
+							);
+
+							const build = () => {
+								newModule.build(
+									compiler.options,
+									compilation,
+									/** @type {TODO} */
+									(null),
+									/** @type {TODO} */
+									(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 instanceof HarmonyImportDependency &&
+													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) {
+												chunkGraph.disconnectChunkAndModule(chunk, m);
+											} else {
+												const newSourceTypes = new Set(sourceTypes);
+												newSourceTypes.delete("javascript");
+												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 instanceof HarmonyImportDependency &&
+										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));
+						}
+					);
+				}
+			);
+		});
+	}
+
+	/**
+	 * @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;
+		const set = new Set();
+		for (const dep of module.dependencies) {
+			// Get reference info only for harmony Dependencies
+			if (!(dep instanceof HarmonyImportDependency)) 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;
+	}
+
+	/**
+	 * @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, Module | function(RequestShortener): string>} 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 | Module | function(RequestShortener): string} 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 = Array.from(
+			chunkGraph.getModuleChunksIterable(config.rootModule)
+		).filter(chunk => !chunkGraph.isModuleInChunk(module, chunk));
+		if (missingChunks.length > 0) {
+			/**
+			 * @param {RequestShortener} requestShortener request shortener
+			 * @returns {string} problem description
+			 */
+			const problem = requestShortener => {
+				const missingChunksList = Array.from(
+					new Set(missingChunks.map(chunk => chunk.name || "unnamed chunk(s)"))
+				).sort();
+				const chunks = Array.from(
+					new Set(
+						Array.from(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) {
+				/**
+				 * @param {RequestShortener} requestShortener request shortener
+				 * @returns {string} problem description
+				 */
+				const problem = requestShortener => {
+					const importingExplanations = new Set(
+						activeNonModulesConnections.map(c => c.explanation).filter(Boolean)
+					);
+					const explanations = Array.from(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, readonly 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
+				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 = Array.from(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) {
+			/**
+			 * @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, readonly ModuleGraph.ModuleGraphConnection[]>} */
+		const nonHarmonyConnections = new Map();
+		for (const [originModule, connections] of incomingConnectionsFromModules) {
+			const selected = connections.filter(
+				connection =>
+					!connection.dependency ||
+					!(connection.dependency instanceof HarmonyImportDependency)
+			);
+			if (selected.length > 0)
+				nonHarmonyConnections.set(originModule, connections);
+		}
+		if (nonHarmonyConnections.size > 0) {
+			/**
+			 * @param {RequestShortener} requestShortener request shortener
+			 * @returns {string} problem description
+			 */
+			const problem = requestShortener => {
+				const names = Array.from(nonHarmonyConnections)
+					.map(
+						([originModule, connections]) =>
+							`${originModule.readableIdentifier(
+								requestShortener
+							)} (referenced with ${Array.from(
+								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) {
+				/**
+				 * @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;
+			}
+		}
+
+		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;
+	}
+}
+
+class ConcatConfiguration {
+	/**
+	 * @param {Module} rootModule the root module
+	 * @param {RuntimeSpec} runtime the runtime
+	 */
+	constructor(rootModule, runtime) {
+		this.rootModule = rootModule;
+		this.runtime = runtime;
+		/** @type {Set<Module>} */
+		this.modules = new Set();
+		this.modules.add(rootModule);
+		/** @type {Map<Module, Module | function(RequestShortener): string>} */
+		this.warnings = new Map();
+	}
+
+	/**
+	 * @param {Module} module the module
+	 */
+	add(module) {
+		this.modules.add(module);
+	}
+
+	/**
+	 * @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;
+	}
+
+	/**
+	 * @param {Module} module the module
+	 * @param {Module | function(RequestShortener): string} problem the problem
+	 */
+	addWarning(module, problem) {
+		this.warnings.set(module, problem);
+	}
+
+	/**
+	 * @returns {Map<Module, Module | function(RequestShortener): string>} warnings
+	 */
+	getWarningsSorted() {
+		return new Map(
+			Array.from(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 {Set<Module>} modules as set
+	 */
+	getModules() {
+		return this.modules;
+	}
+
+	snapshot() {
+		return this.modules.size;
+	}
+
+	/**
+	 * @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: imaps-frontend/node_modules/webpack/lib/optimize/RealContentHashPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/RealContentHashPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/RealContentHashPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,464 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncBailHook } = require("tapable");
+const { RawSource, CachedSource, CompatSource } = require("webpack-sources");
+const Compilation = require("../Compilation");
+const WebpackError = require("../WebpackError");
+const { compareSelect, compareStrings } = require("../util/comparators");
+const createHash = require("../util/createHash");
+
+/** @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 */
+
+const EMPTY_SET = new Set();
+
+/**
+ * @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);
+	}
+};
+
+/**
+ * @template T
+ * @param {T[]} input list
+ * @param {function(T): Buffer} fn map function
+ * @returns {Buffer[]} buffers without duplicates
+ */
+const mapAndDeduplicateBuffers = (input, fn) => {
+	// Buffer.equals compares size first so this should be efficient enough
+	// If it becomes a performance problem we can use a map and group by size
+	// instead of looping over all assets.
+	const result = [];
+	outer: for (const value of input) {
+		const buf = fn(value);
+		for (const other of result) {
+			if (buf.equals(other)) continue outer;
+		}
+		result.push(buf);
+	}
+	return result;
+};
+
+/**
+ * Escapes regular expression metacharacters
+ * @param {string} str String to quote
+ * @returns {string} Escaped string
+ */
+const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
+
+const cachedSourceMap = new WeakMap();
+
+/**
+ * @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>} OwnHashes */
+/** @typedef {Set<string>} ReferencedHashes */
+/** @typedef {Set<string>} Hashes */
+
+/**
+ * @typedef {object} AssetInfoForRealContentHash
+ * @property {string} name
+ * @property {AssetInfo} info
+ * @property {Source} source
+ * @property {RawSource | undefined} newSource
+ * @property {RawSource | undefined} newSourceWithoutOwn
+ * @property {string} content
+ * @property {OwnHashes | undefined} ownHashes
+ * @property {Promise<void> | undefined} contentComputePromise
+ * @property {Promise<void> | undefined} contentComputeWithoutOwnPromise
+ * @property {ReferencedHashes | undefined} referencedHashes
+ * @property {Hashes} hashes
+ */
+
+/**
+ * @typedef {object} CompilationHooks
+ * @property {SyncBailHook<[Buffer[], string], string | void>} updateHash
+ */
+
+/** @type {WeakMap<Compilation, CompilationHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class RealContentHashPlugin {
+	/**
+	 * @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;
+	}
+
+	/**
+	 * @param {object} options options object
+	 * @param {string | Hash} options.hashFunction the hash function to use
+	 * @param {string} options.hashDigest the hash digest to use
+	 */
+	constructor({ hashFunction, hashDigest }) {
+		this._hashFunction = hashFunction;
+		this._hashDigest = hashDigest;
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap("RealContentHashPlugin", compilation => {
+			const cacheAnalyse = compilation.getCache(
+				"RealContentHashPlugin|analyse"
+			);
+			const cacheGenerate = compilation.getCache(
+				"RealContentHashPlugin|generate"
+			);
+			const hooks = RealContentHashPlugin.getCompilationHooks(compilation);
+			compilation.hooks.processAssets.tapPromise(
+				{
+					name: "RealContentHashPlugin",
+					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),
+								Array.from(hashes).join("|")
+							);
+							[asset.referencedHashes, asset.ownHashes] =
+								await cacheAnalyse.providePromise(name, etag, () => {
+									const referencedHashes = new Set();
+									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];
+								});
+						})
+					);
+					/**
+					 * @param {string} hash the hash
+					 * @returns {undefined | ReferencedHashes} the referenced hashes
+					 */
+					const getDependencies = hash => {
+						const assets = hashToAssets.get(hash);
+						if (!assets) {
+							const referencingAssets = assetsWithInfo.filter(asset =>
+								/** @type {ReferencedHashes} */ (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;
+						}
+						const hashes = new Set();
+						for (const { referencedHashes, ownHashes } of assets) {
+							if (!(/** @type {OwnHashes} */ (ownHashes).has(hash))) {
+								for (const hash of /** @type {OwnHashes} */ (ownHashes)) {
+									hashes.add(hash);
+								}
+							}
+							for (const hash of /** @type {ReferencedHashes} */ (
+								referencedHashes
+							)) {
+								hashes.add(hash);
+							}
+						}
+						return hashes;
+					};
+					/**
+					 * @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
+						)})`;
+					};
+					const hashesInOrder = new Set();
+					for (const hash of hashToAssets.keys()) {
+						/**
+						 * @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());
+					}
+					const hashToNewHash = new Map();
+					/**
+					 * @param {AssetInfoForRealContentHash} asset asset info
+					 * @returns {Etag} etag
+					 */
+					const getEtag = asset =>
+						cacheGenerate.mergeEtags(
+							cacheGenerate.getLazyHashedEtag(asset.source),
+							Array.from(
+								/** @type {ReferencedHashes} */ (asset.referencedHashes),
+								hash => hashToNewHash.get(hash)
+							).join("|")
+						);
+					/**
+					 * @param {AssetInfoForRealContentHash} asset asset info
+					 * @returns {Promise<void>}
+					 */
+					const computeNewContent = asset => {
+						if (asset.contentComputePromise) return asset.contentComputePromise;
+						return (asset.contentComputePromise = (async () => {
+							if (
+								/** @type {OwnHashes} */ (asset.ownHashes).size > 0 ||
+								Array.from(
+									/** @type {ReferencedHashes} */
+									(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 =>
+											hashToNewHash.get(hash)
+										);
+										return new RawSource(newContent);
+									}
+								);
+							}
+						})());
+					};
+					/**
+					 * @param {AssetInfoForRealContentHash} asset asset info
+					 * @returns {Promise<void>}
+					 */
+					const computeNewContentWithoutOwn = asset => {
+						if (asset.contentComputeWithoutOwnPromise)
+							return asset.contentComputeWithoutOwnPromise;
+						return (asset.contentComputeWithoutOwnPromise = (async () => {
+							if (
+								/** @type {OwnHashes} */ (asset.ownHashes).size > 0 ||
+								Array.from(
+									/** @type {ReferencedHashes} */
+									(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 {OwnHashes} */ (asset.ownHashes).has(hash)
+												) {
+													return "";
+												}
+												return hashToNewHash.get(hash);
+											}
+										);
+										return new RawSource(newContent);
+									}
+								);
+							}
+						})());
+					};
+					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 {OwnHashes} */ (asset.ownHashes).has(oldHash)
+									? computeNewContentWithoutOwn(asset)
+									: computeNewContent(asset)
+							)
+						);
+						const assetsContent = mapAndDeduplicateBuffers(assets, asset => {
+							if (/** @type {OwnHashes} */ (asset.ownHashes).has(oldHash)) {
+								return asset.newSourceWithoutOwn
+									? asset.newSourceWithoutOwn.buffer()
+									: asset.source.buffer();
+							}
+							return asset.newSource
+								? asset.newSource.buffer()
+								: asset.source.buffer();
+						});
+						let newHash = hooks.updateHash.call(assetsContent, oldHash);
+						if (!newHash) {
+							const hash = createHash(this._hashFunction);
+							if (compilation.outputOptions.hashSalt) {
+								hash.update(compilation.outputOptions.hashSalt);
+							}
+							for (const content of assetsContent) {
+								hash.update(content);
+							}
+							const digest = hash.digest(this._hashDigest);
+							newHash = /** @type {string} */ (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 =>
+								hashToNewHash.get(hash)
+							);
+
+							const infoUpdate = {};
+							const hash = asset.info.contenthash;
+							infoUpdate.contenthash = Array.isArray(hash)
+								? hash.map(hash => hashToNewHash.get(hash))
+								: 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: imaps-frontend/node_modules/webpack/lib/optimize/RemoveEmptyChunksPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/RemoveEmptyChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/RemoveEmptyChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,57 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { STAGE_BASIC, STAGE_ADVANCED } = require("../OptimizationStages");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compiler")} Compiler */
+
+class RemoveEmptyChunksPlugin {
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap("RemoveEmptyChunksPlugin", compilation => {
+			/**
+			 * @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);
+					}
+				}
+			};
+
+			// TODO do it once
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: "RemoveEmptyChunksPlugin",
+					stage: STAGE_BASIC
+				},
+				handler
+			);
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: "RemoveEmptyChunksPlugin",
+					stage: STAGE_ADVANCED
+				},
+				handler
+			);
+		});
+	}
+}
+module.exports = RemoveEmptyChunksPlugin;
Index: imaps-frontend/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,204 @@
+/*
+	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>} 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;
+	}
+}
+
+class RemoveParentModulesPlugin {
+	/**
+	 * @param {Compiler} compiler the compiler
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.compilation.tap("RemoveParentModulesPlugin", compilation => {
+			/**
+			 * @param {Iterable<Chunk>} chunks the chunks
+			 * @param {ChunkGroup[]} chunkGroups the chunk groups
+			 */
+			const handler = (chunks, chunkGroups) => {
+				const chunkGraph = compilation.chunkGraph;
+				const queue = new Set();
+				const availableModulesMap = new WeakMap();
+
+				let nextModuleMask = ONE_BIGINT;
+				const maskByModule = new WeakMap();
+				/** @type {Module[]} */
+				const ordinalModules = [];
+
+				/**
+				 * Gets or creates a unique mask for a module
+				 * @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
+				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);
+				}
+
+				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 | 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(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: "RemoveParentModulesPlugin",
+					stage: STAGE_BASIC
+				},
+				handler
+			);
+		});
+	}
+}
+module.exports = RemoveParentModulesPlugin;
Index: imaps-frontend/node_modules/webpack/lib/optimize/RuntimeChunkPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/RuntimeChunkPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/RuntimeChunkPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,57 @@
+/*
+	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 */
+/** @typedef {import("../Entrypoint")} Entrypoint */
+
+class RuntimeChunkPlugin {
+	/**
+	 * @param {{ name?: (entrypoint: { name: string }) => string }} options options
+	 */
+	constructor(options) {
+		this.options = {
+			/**
+			 * @param {Entrypoint} entrypoint entrypoint name
+			 * @returns {string} runtime chunk name
+			 */
+			name: entrypoint => `runtime~${entrypoint.name}`,
+			...options
+		};
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		compiler.hooks.thisCompilation.tap("RuntimeChunkPlugin", compilation => {
+			compilation.hooks.addEntry.tap(
+				"RuntimeChunkPlugin",
+				(_, { 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 =
+							/** @type {string | ((entrypoint: { name: string }) => string)} */
+							(this.options.name);
+						if (typeof name === "function") {
+							name = name({ name: entryName });
+						}
+						data.options.runtime = name;
+					}
+				}
+			);
+		});
+	}
+}
+
+module.exports = RuntimeChunkPlugin;
Index: imaps-frontend/node_modules/webpack/lib/optimize/SideEffectsFlagPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/SideEffectsFlagPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/SideEffectsFlagPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,396 @@
+/*
+	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_ESM,
+	JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("../ModuleTypeConstants");
+const { STAGE_DEFAULT } = require("../OptimizationStages");
+const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
+const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
+const formatLocation = require("../formatLocation");
+
+/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */
+/** @typedef {import("estree").Statement} Statement */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../NormalModuleFactory").ModuleSettings} ModuleSettings */
+/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("../javascript/JavascriptParser").Range} Range */
+
+/**
+ * @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 {object} ReexportInfo
+ * @property {Map<string, ExportInModule[]>} static
+ * @property {Map<Module, Set<string>>} dynamic
+ */
+
+/** @typedef {Map<string, RegExp>} CacheItem */
+
+/** @type {WeakMap<any, CacheItem>} */
+const globToRegexpCache = new WeakMap();
+
+/**
+ * @param {string} glob the pattern
+ * @param {Map<string, RegExp>} 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;
+};
+
+const PLUGIN_NAME = "SideEffectsFlagPlugin";
+
+class SideEffectsFlagPlugin {
+	/**
+	 * @param {boolean} analyseSource analyse source code for side effects
+	 */
+	constructor(analyseSource = true) {
+		this._analyseSource = analyseSource;
+	}
+
+	/**
+	 * Apply the plugin
+	 * @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,
+								sideEffects,
+								/** @type {CacheItem} */ (cache)
+							);
+							module.factoryMeta.sideEffectFree = !hasSideEffects;
+						}
+					}
+
+					return module;
+				});
+				normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module, data) => {
+					const settings = /** @type {ModuleSettings} */ (data.settings);
+					if (typeof settings.sideEffects === "boolean") {
+						if (module.factoryMeta === undefined) {
+							module.factoryMeta = {};
+						}
+						module.factoryMeta.sideEffectFree = !settings.sideEffects;
+					}
+					return module;
+				});
+				if (this._analyseSource) {
+					/**
+					 * @param {JavascriptParser} parser the parser
+					 * @returns {void}
+					 */
+					const parserHandler = parser => {
+						/** @type {undefined | Statement | ModuleDeclaration} */
+						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(
+												/** @type {TODO} */
+												(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)
+											)}`
+									);
+							}
+						});
+					};
+					for (const key of [
+						JAVASCRIPT_MODULE_TYPE_AUTO,
+						JAVASCRIPT_MODULE_TYPE_ESM,
+						JAVASCRIPT_MODULE_TYPE_DYNAMIC
+					]) {
+						normalModuleFactory.hooks.parser
+							.for(key)
+							.tap(PLUGIN_NAME, parserHandler);
+					}
+				}
+				compilation.hooks.optimizeDependencies.tap(
+					{
+						name: PLUGIN_NAME,
+						stage: STAGE_DEFAULT
+					},
+					modules => {
+						const logger = compilation.getLogger(
+							"webpack.SideEffectsFlagPlugin"
+						);
+
+						logger.time("update dependencies");
+
+						const optimizedModules = new Set();
+
+						/**
+						 * @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;
+									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 }) => {
+													moduleGraph.updateModule(dep, newModule);
+													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.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);
+						}
+						logger.timeEnd("update dependencies");
+					}
+				);
+			}
+		);
+	}
+
+	/**
+	 * @param {string} moduleName the module name
+	 * @param {undefined | boolean | string | string[]} flagValue the flag value
+	 * @param {Map<string, RegExp>} 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: imaps-frontend/node_modules/webpack/lib/optimize/SplitChunksPlugin.js
===================================================================
--- imaps-frontend/node_modules/webpack/lib/optimize/SplitChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/webpack/lib/optimize/SplitChunksPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,1767 @@
+/*
+	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("../WebpackError");
+const { requestToId } = require("../ids/IdHelpers");
+const { isSubset } = require("../util/SetHelpers");
+const SortableSet = require("../util/SortableSet");
+const {
+	compareModulesByIdentifier,
+	compareIterables
+} = 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").OptimizationSplitChunksGetCacheGroups} OptimizationSplitChunksGetCacheGroups */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */
+/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksSizes} OptimizationSplitChunksSizes */
+/** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */
+/** @typedef {import("../util/deterministicGrouping").GroupedItems<Module>} DeterministicGroupingGroupedItemsForModule */
+/** @typedef {import("../util/deterministicGrouping").Options<Module>} DeterministicGroupingOptionsForModule */
+
+/** @typedef {Record<string, number>} SplitChunksSizes */
+
+/**
+ * @callback ChunkFilterFunction
+ * @param {Chunk} chunk
+ * @returns {boolean | undefined}
+ */
+
+/**
+ * @callback CombineSizeFunction
+ * @param {number} a
+ * @param {number} b
+ * @returns {number}
+ */
+
+/**
+ * @typedef {object} CacheGroupSource
+ * @property {string=} key
+ * @property {number=} priority
+ * @property {GetName=} getName
+ * @property {ChunkFilterFunction=} chunksFilter
+ * @property {boolean=} enforce
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} minSizeReduction
+ * @property {SplitChunksSizes} minRemainingSize
+ * @property {SplitChunksSizes} enforceSizeThreshold
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {number=} minChunks
+ * @property {number=} maxAsyncRequests
+ * @property {number=} maxInitialRequests
+ * @property {TemplatePath=} filename
+ * @property {string=} idHint
+ * @property {string=} automaticNameDelimiter
+ * @property {boolean=} reuseExistingChunk
+ * @property {boolean=} usedExports
+ */
+
+/**
+ * @typedef {object} CacheGroup
+ * @property {string} key
+ * @property {number=} priority
+ * @property {GetName=} getName
+ * @property {ChunkFilterFunction=} chunksFilter
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} minSizeReduction
+ * @property {SplitChunksSizes} minRemainingSize
+ * @property {SplitChunksSizes} enforceSizeThreshold
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {number=} minChunks
+ * @property {number=} maxAsyncRequests
+ * @property {number=} maxInitialRequests
+ * @property {TemplatePath=} 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
+ */
+
+/**
+ * @typedef {object} FallbackCacheGroup
+ * @property {ChunkFilterFunction} chunksFilter
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {string} automaticNameDelimiter
+ */
+
+/**
+ * @typedef {object} CacheGroupsContext
+ * @property {ModuleGraph} moduleGraph
+ * @property {ChunkGraph} chunkGraph
+ */
+
+/**
+ * @callback GetCacheGroups
+ * @param {Module} module
+ * @param {CacheGroupsContext} context
+ * @returns {CacheGroupSource[]}
+ */
+
+/**
+ * @callback GetName
+ * @param {Module=} module
+ * @param {Chunk[]=} chunks
+ * @param {string=} key
+ * @returns {string=}
+ */
+
+/**
+ * @typedef {object} SplitChunksOptions
+ * @property {ChunkFilterFunction} chunksFilter
+ * @property {string[]} defaultSizeTypes
+ * @property {SplitChunksSizes} minSize
+ * @property {SplitChunksSizes} minSizeReduction
+ * @property {SplitChunksSizes} minRemainingSize
+ * @property {SplitChunksSizes} enforceSizeThreshold
+ * @property {SplitChunksSizes} maxInitialSize
+ * @property {SplitChunksSizes} maxAsyncSize
+ * @property {number} minChunks
+ * @property {number} maxAsyncRequests
+ * @property {number} maxInitialRequests
+ * @property {boolean} hidePathInfo
+ * @property {TemplatePath} filename
+ * @property {string} automaticNameDelimiter
+ * @property {GetCacheGroups} getCacheGroups
+ * @property {GetName} getName
+ * @property {boolean} usedExports
+ * @property {FallbackCacheGroup} fallbackCacheGroup
+ */
+
+/**
+ * @typedef {object} ChunksInfoItem
+ * @property {SortableSet<Module>} modules
+ * @property {CacheGroup} cacheGroup
+ * @property {number} cacheGroupIndex
+ * @property {string} name
+ * @property {Record<string, number>} sizes
+ * @property {Set<Chunk>} chunks
+ * @property {Set<Chunk>} reusableChunks
+ * @property {Set<bigint | Chunk>} chunksKeys
+ */
+
+const defaultGetName = /** @type {GetName} */ (() => {});
+
+const deterministicGroupingForModules =
+	/** @type {function(DeterministicGroupingOptionsForModule): DeterministicGroupingGroupedItemsForModule[]} */
+	(deterministicGrouping);
+
+/** @type {WeakMap<Module, string>} */
+const getKeyCache = new WeakMap();
+
+/**
+ * @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);
+};
+
+/**
+ * @param {Chunk} chunk the chunk
+ * @returns {number} 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;
+};
+
+/**
+ * @template {object} T
+ * @template {object} R
+ * @param {T} obj obj an object
+ * @param {function(T[keyof T], keyof T): T[keyof T]} fn fn
+ * @returns {T} result
+ */
+const mapObject = (obj, fn) => {
+	const newObj = Object.create(null);
+	for (const key of Object.keys(obj)) {
+		newObj[key] = fn(
+			obj[/** @type {keyof T} */ (key)],
+			/** @type {keyof T} */
+			(key)
+		);
+	}
+	return newObj;
+};
+
+/**
+ * @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);
+
+/**
+ * @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);
+};
+
+/**
+ * @param {Chunk} chunk the chunk
+ * @returns {boolean} true, if the chunk is an entry chunk
+ */
+const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial();
+/**
+ * @param {Chunk} chunk the chunk
+ * @returns {boolean} true, if the chunk is an async chunk
+ */
+const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial();
+/**
+ * @param {Chunk} chunk the chunk
+ * @returns {boolean} always true
+ */
+const ALL_CHUNK_FILTER = chunk => true;
+
+/**
+ * @param {OptimizationSplitChunksSizes | undefined} value the sizes
+ * @param {string[]} defaultSizeTypes the default size types
+ * @returns {SplitChunksSizes} normalized representation
+ */
+const normalizeSizes = (value, defaultSizeTypes) => {
+	if (typeof value === "number") {
+		/** @type {Record<string, number>} */
+		const o = {};
+		for (const sizeType of defaultSizeTypes) o[sizeType] = value;
+		return o;
+	} else if (typeof value === "object" && value !== null) {
+		return { ...value };
+	}
+	return {};
+};
+
+/**
+ * @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;
+};
+
+/**
+ * @param {SplitChunksSizes} sizes the sizes
+ * @returns {boolean} true, if there are sizes > 0
+ */
+const hasNonZeroSizes = sizes => {
+	for (const key of Object.keys(sizes)) {
+		if (sizes[key] > 0) return true;
+	}
+	return false;
+};
+
+/**
+ * @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 = new Set(Object.keys(a));
+	const bKeys = 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;
+};
+
+/**
+ * @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 Object.keys(minSize)) {
+		const size = sizes[key];
+		if (size === undefined || size === 0) continue;
+		if (size < minSize[key]) return false;
+	}
+	return true;
+};
+
+/**
+ * @param {SplitChunksSizes} sizes the sizes
+ * @param {SplitChunksSizes} minSizeReduction the min sizes
+ * @param {number} 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 Object.keys(minSizeReduction)) {
+		const size = sizes[key];
+		if (size === undefined || size === 0) continue;
+		if (size * chunkCount < minSizeReduction[key]) return false;
+	}
+	return true;
+};
+
+/**
+ * @param {SplitChunksSizes} sizes the sizes
+ * @param {SplitChunksSizes} minSize the min sizes
+ * @returns {undefined | string[]} list of size types that are below min size
+ */
+const getViolatingMinSizes = (sizes, minSize) => {
+	let list;
+	for (const key of 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;
+};
+
+/**
+ * @param {SplitChunksSizes} sizes the sizes
+ * @returns {number} the total size
+ */
+const totalSize = sizes => {
+	let size = 0;
+	for (const key of Object.keys(sizes)) {
+		size += sizes[key];
+	}
+	return size;
+};
+
+/**
+ * @param {false|string|Function|undefined} name the chunk name
+ * @returns {GetName | 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 {GetName} */ (name);
+	}
+};
+
+/**
+ * @param {OptimizationSplitChunksCacheGroup["chunks"]} chunks the chunk filter option
+ * @returns {ChunkFilterFunction} 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;
+	}
+};
+
+/**
+ * @param {GetCacheGroups | Record<string, false|string|RegExp|OptimizationSplitChunksGetCacheGroups|OptimizationSplitChunksCacheGroup>} cacheGroups the cache group options
+ * @param {string[]} 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 {(function(Module, CacheGroupsContext, 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") {
+				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);
+					}
+				});
+			}
+		}
+		/**
+		 * @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;
+};
+
+/**
+ * @param {undefined|boolean|string|RegExp|Function} 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);
+	}
+	if (test instanceof RegExp) {
+		const name = module.nameForCondition();
+		return name && test.test(name);
+	}
+	return false;
+};
+
+/**
+ * @param {undefined|string|RegExp|Function} 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;
+};
+
+/**
+ * @param {undefined|string|RegExp|Function} 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);
+	}
+	if (test instanceof RegExp) {
+		const layer = module.layer;
+		return test.test(layer);
+	}
+	return false;
+};
+
+/**
+ * @param {OptimizationSplitChunksCacheGroup} options the group options
+ * @param {string} key key of cache group
+ * @param {string[]} 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
+	};
+};
+
+module.exports = class 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: 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 ? normalizeName(options.name) : defaultGetName,
+			automaticNameDelimiter: options.automaticNameDelimiter,
+			usedExports: options.usedExports,
+			fallbackCacheGroup: {
+				chunksFilter: 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();
+	}
+
+	/**
+	 * @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
+		);
+		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;
+	}
+
+	/**
+	 * Apply the plugin
+	 * @param {Compiler} compiler the compiler instance
+	 * @returns {void}
+	 */
+	apply(compiler) {
+		const cachedMakePathsRelative = makePathsRelative.bindContextCache(
+			compiler.context,
+			compiler.root
+		);
+		compiler.hooks.thisCompilation.tap("SplitChunksPlugin", compilation => {
+			const logger = compilation.getLogger("webpack.SplitChunksPlugin");
+			let alreadyOptimized = false;
+			compilation.hooks.unseal.tap("SplitChunksPlugin", () => {
+				alreadyOptimized = false;
+			});
+			compilation.hooks.optimizeChunks.tap(
+				{
+					name: "SplitChunksPlugin",
+					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 = index << ONE;
+					}
+					/**
+					 * @param {Iterable<Chunk>} 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 =
+							chunkIndexMap.get(first) | chunkIndexMap.get(result.value);
+						while (!(result = iterator.next()).done) {
+							const raw = chunkIndexMap.get(result.value);
+							key = key ^ raw;
+						}
+						return 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 chunkIndexMap.get(key).toString(16);
+					};
+
+					const getChunkSetsInGraph = memoize(() => {
+						/** @type {Map<bigint, Set<Chunk>>} */
+						const chunkSetsInGraph = new Map();
+						/** @type {Set<Chunk>} */
+						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 };
+					});
+
+					/**
+					 * @param {Module} module the module
+					 * @returns {Iterable<Chunk[]>} groups of chunks with equal exports
+					 */
+					const groupChunksByExports = module => {
+						const exportsInfo = moduleGraph.getExportsInfo(module);
+						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();
+
+					const getExportsChunkSetsInGraph = memoize(() => {
+						/** @type {Map<bigint, Set<Chunk>>} */
+						const chunkSetsInGraph = new Map();
+						/** @type {Set<Chunk>} */
+						const singleChunkSets = new Set();
+						for (const module of compilation.modules) {
+							const groupedChunks = Array.from(groupChunksByExports(module));
+							groupedByExportsMap.set(module, groupedChunks);
+							for (const chunks of groupedChunks) {
+								if (chunks.length === 1) {
+									singleChunkSets.add(chunks[0]);
+								} else {
+									const chunksKey = /** @type {bigint} */ (getKey(chunks));
+									if (!chunkSetsInGraph.has(chunksKey)) {
+										chunkSetsInGraph.set(chunksKey, new Set(chunks));
+									}
+								}
+							}
+						}
+						return { chunkSetsInGraph, singleChunkSets };
+					});
+
+					// group these set of chunks by count
+					// to allow to check less sets via isSubset
+					// (only smaller sets can be subset)
+					/**
+					 * @param {IterableIterator<Set<Chunk>>} chunkSets set of sets of chunks
+					 * @returns {Map<number, Array<Set<Chunk>>>} map of sets of chunks by count
+					 */
+					const groupChunkSetsByCount = chunkSets => {
+						/** @type {Map<number, Array<Set<Chunk>>>} */
+						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()
+						)
+					);
+
+					// Create a list of possible combinations
+					const createGetCombinations = (
+						chunkSets,
+						singleChunkSets,
+						chunkSetsByCount
+					) => {
+						/** @type {Map<bigint | Chunk, (Set<Chunk> | Chunk)[]>} */
+						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 = chunkSets.get(key);
+							/** @type {(Set<Chunk> | Chunk)[]} */
+							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()
+						);
+					});
+					const getCombinations = key => getCombinationsFactory()(key);
+
+					const getExportsCombinationsFactory = memoize(() => {
+						const { chunkSetsInGraph, singleChunkSets } =
+							getExportsChunkSetsInGraph();
+						return createGetCombinations(
+							chunkSetsInGraph,
+							singleChunkSets,
+							getExportsChunkSetsByCount()
+						);
+					});
+					const getExportsCombinations = key =>
+						getExportsCombinationsFactory()(key);
+
+					/**
+					 * @typedef {object} SelectedChunksResult
+					 * @property {Chunk[]} chunks the list of chunks
+					 * @property {bigint | Chunk} key a key of the list
+					 */
+
+					/** @type {WeakMap<Set<Chunk> | Chunk, WeakMap<ChunkFilterFunction, SelectedChunksResult>>} */
+					const selectedChunksCacheByChunksSet = new WeakMap();
+
+					/**
+					 * get list and key by applying the filter function to the list
+					 * It is cached for performance reasons
+					 * @param {Set<Chunk> | Chunk} chunks list of chunks
+					 * @param {ChunkFilterFunction} chunkFilter filter function for chunks
+					 * @returns {SelectedChunksResult} list and key
+					 */
+					const getSelectedChunks = (chunks, chunkFilter) => {
+						let entry = selectedChunksCacheByChunksSet.get(chunks);
+						if (entry === undefined) {
+							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();
+
+					/**
+					 * @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 {string} */
+							(cacheGroup.getName(module, selectedChunks, cacheGroup.key));
+						// Check if the name is ok
+						const existingChunk = 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(
+												"SplitChunksPlugin\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 = /** @type {ChunksInfoItem} */ (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<Set<Chunk> | 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 {ChunkFilterFunction} */ (cacheGroup.chunksFilter)
+									);
+
+								addModuleToChunksInfoMap(
+									cacheGroup,
+									cacheGroupIndex,
+									selectedChunks,
+									selectedChunksKey,
+									module
+								);
+							}
+							cacheGroupIndex++;
+						}
+					}
+
+					logger.timeEnd("modules");
+
+					logger.time("queue");
+
+					/**
+					 * @param {ChunksInfoItem} info entry
+					 * @param {string[]} 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);
+								}
+							}
+						}
+					};
+
+					/**
+					 * @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);
+						}
+					}
+
+					/**
+					 * @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
+						let bestEntryKey;
+						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 {Chunk["name"] | 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);
+
+						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 = /** @type {number} */ (
+									chunk.isOnlyInitial()
+										? item.cacheGroup.maxInitialRequests
+										: chunk.canBeInitial()
+											? Math.min(
+													/** @type {number} */
+													(item.cacheGroup.maxInitialRequests),
+													/** @type {number} */
+													(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 (
+								/** @type {number} */ (usedChunks.size) >=
+								/** @type {number} */ (item.cacheGroup.minChunks)
+							) {
+								const chunksArr = Array.from(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;
+							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.concat(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 Array.from(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 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) {
+								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(
+									/** @type {Chunk["name"]} */ (name)
+								);
+								chunk.split(newPart);
+								newPart.chunkReason = chunk.chunkReason;
+								// 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 = /** @type {Chunk["name"]} */ (name);
+							}
+						}
+					}
+					logger.timeEnd("maxSize");
+				}
+			);
+		});
+	}
+};
