Index: imaps-frontend/node_modules/enhanced-resolve/LICENSE
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/LICENSE	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/LICENSE	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,20 @@
+Copyright JS Foundation and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: imaps-frontend/node_modules/enhanced-resolve/README.md
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/README.md	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/README.md	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,183 @@
+# enhanced-resolve
+
+[![npm][npm]][npm-url]
+[![Build Status][build-status]][build-status-url]
+[![codecov][codecov-badge]][codecov-url]
+[![Install Size][size]][size-url]
+[![GitHub Discussions][discussion]][discussion-url]
+
+Offers an async require.resolve function. It's highly configurable.
+
+## Features
+
+- plugin system
+- provide a custom filesystem
+- sync and async node.js filesystems included
+
+## Getting Started
+
+### Install
+
+```sh
+# npm
+npm install enhanced-resolve
+# or Yarn
+yarn add enhanced-resolve
+```
+
+### Resolve
+
+There is a Node.js API which allows to resolve requests according to the Node.js resolving rules.
+Sync and async APIs are offered. A `create` method allows to create a custom resolve function.
+
+```js
+const resolve = require("enhanced-resolve");
+
+resolve("/some/path/to/folder", "module/dir", (err, result) => {
+	result; // === "/some/path/node_modules/module/dir/index.js"
+});
+
+resolve.sync("/some/path/to/folder", "../../dir");
+// === "/some/path/dir/index.js"
+
+const myResolve = resolve.create({
+	// or resolve.create.sync
+	extensions: [".ts", ".js"]
+	// see more options below
+});
+
+myResolve("/some/path/to/folder", "ts-module", (err, result) => {
+	result; // === "/some/node_modules/ts-module/index.ts"
+});
+```
+
+### Creating a Resolver
+
+The easiest way to create a resolver is to use the `createResolver` function on `ResolveFactory`, along with one of the supplied File System implementations.
+
+```js
+const fs = require("fs");
+const { CachedInputFileSystem, ResolverFactory } = require("enhanced-resolve");
+
+// create a resolver
+const myResolver = ResolverFactory.createResolver({
+	// Typical usage will consume the `fs` + `CachedInputFileSystem`, which wraps Node.js `fs` to add caching.
+	fileSystem: new CachedInputFileSystem(fs, 4000),
+	extensions: [".js", ".json"]
+	/* any other resolver options here. Options/defaults can be seen below */
+});
+
+// resolve a file with the new resolver
+const context = {};
+const lookupStartPath = "/Users/webpack/some/root/dir";
+const request = "./path/to-look-up.js";
+const resolveContext = {};
+myResolver.resolve(context, lookupStartPath, request, resolveContext, (
+	err /*Error*/,
+	filepath /*string*/
+) => {
+	// Do something with the path
+});
+```
+
+#### Resolver Options
+
+| Field            | Default                     | Description                                                                                                                                               |
+|------------------|-----------------------------| --------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| alias            | []                          | A list of module alias configurations or an object which maps key to value                                                                                |
+| aliasFields      | []                          | A list of alias fields in description files                                                                                                               |
+| extensionAlias   | {}                          | An object which maps extension to extension aliases                                                                                                       |
+| cachePredicate   | function() { return true }; | A function which decides whether a request should be cached or not. An object is passed to the function with `path` and `request` properties.             |
+| cacheWithContext | true                        | If unsafe cache is enabled, includes `request.context` in the cache key                                                                                   |
+| conditionNames   | []                          | A list of exports field condition names                                                                                                                   |
+| descriptionFiles | ["package.json"]            | A list of description files to read from                                                                                                                  |
+| enforceExtension | false                       | Enforce that a extension from extensions must be used                                                                                                     |
+| exportsFields    | ["exports"]                 | A list of exports fields in description files                                                                                                             |
+| extensions       | [".js", ".json", ".node"]   | A list of extensions which should be tried for files                                                                                                      |
+| fallback         | []                          | Same as `alias`, but only used if default resolving fails                                                                                                |                                                                                                                                                                                         
+| fileSystem       |                             | The file system which should be used                                                                                                                      |
+| fullySpecified   | false                       | Request passed to resolve is already fully specified and extensions or main files are not resolved for it (they are still resolved for internal requests) |
+| mainFields       | ["main"]                    | A list of main fields in description files                                                                                                                |
+| mainFiles        | ["index"]                   | A list of main files in directories                                                                                                                       |
+| modules          | ["node_modules"]            | A list of directories to resolve modules from, can be absolute path or folder name                                                                        |
+| plugins          | []                          | A list of additional resolve plugins which should be applied                                                                                              |
+| resolver         | undefined                   | A prepared Resolver to which the plugins are attached                                                                                                     |
+| resolveToContext | false                       | Resolve to a context instead of a file                                                                                                                    |
+| preferRelative   | false                       | Prefer to resolve module requests as relative request and fallback to resolving as module                                                                 |
+| preferAbsolute   | false                       | Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots                                                          |
+| restrictions     | []                          | A list of resolve restrictions                                                                                                                            |
+| roots            | []                          | A list of root paths                                                                                                                                      |
+| symlinks         | true                        | Whether to resolve symlinks to their symlinked location                                                                                                   |
+| unsafeCache      | false                       | Use this cache object to unsafely cache the successful requests                                                                                           |
+
+## Plugins
+
+Similar to `webpack`, the core of `enhanced-resolve` functionality is implemented as individual plugins that are executed using [`tapable`](https://github.com/webpack/tapable).
+These plugins can extend the functionality of the library, adding other ways for files/contexts to be resolved.
+
+A plugin should be a `class` (or its ES5 equivalent) with an `apply` method. The `apply` method will receive a `resolver` instance, that can be used to hook in to the event system.
+
+### Plugin Boilerplate
+
+```js
+class MyResolverPlugin {
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("MyResolverPlugin", (request, resolveContext, callback) => {
+				// Any logic you need to create a new `request` can go here
+				resolver.doResolve(target, request, null, resolveContext, callback);
+			});
+	}
+}
+```
+
+Plugins are executed in a pipeline, and register which event they should be executed before/after. In the example above, `source` is the name of the event that starts the pipeline, and `target` is what event this plugin should fire, which is what continues the execution of the pipeline. For an example of how these different plugin events create a chain, see `lib/ResolverFactory.js`, in the `//// pipeline ////` section.
+
+## Escaping
+
+It's allowed to escape `#` as `\0#` to avoid parsing it as fragment.
+
+enhanced-resolve will try to resolve requests containing `#` as path and as fragment, so it will automatically figure out if `./some#thing` means `.../some.js#thing` or `.../some#thing.js`. When a `#` is resolved as path it will be escaped in the result. Here: `.../some\0#thing.js`.
+
+## Tests
+
+```javascript
+yarn test
+```
+
+## Passing options from webpack
+
+If you are using `webpack`, and you want to pass custom options to `enhanced-resolve`, the options are passed from the `resolve` key of your webpack configuration e.g.:
+
+```
+resolve: {
+  extensions: ['.js', '.jsx'],
+  modules: [path.resolve(__dirname, 'src'), 'node_modules'],
+  plugins: [new DirectoryNamedWebpackPlugin()]
+  ...
+},
+```
+
+## License
+
+Copyright (c) 2012-2019 JS Foundation and other contributors
+
+MIT (http://www.opensource.org/licenses/mit-license.php)
+
+[npm]: https://img.shields.io/npm/v/enhanced-resolve.svg
+[npm-url]: https://www.npmjs.com/package/enhanced-resolve
+[build-status]: https://github.com/webpack/enhanced-resolve/actions/workflows/test.yml/badge.svg?branch=master
+[build-status-url]: https://github.com/webpack/enhanced-resolve/actions
+[codecov-badge]: https://codecov.io/gh/webpack/enhanced-resolve/branch/main/graph/badge.svg?token=6B6NxtsZc3
+[codecov-url]: https://codecov.io/gh/webpack/enhanced-resolve
+[size]: https://packagephobia.com/badge?p=enhanced-resolve
+[size-url]: https://packagephobia.com/result?p=enhanced-resolve
+[discussion]: https://img.shields.io/github/discussions/webpack/webpack
+[discussion-url]: https://github.com/webpack/webpack/discussions
Index: imaps-frontend/node_modules/enhanced-resolve/lib/AliasFieldPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/AliasFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/AliasFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,108 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DescriptionFileUtils = require("./DescriptionFileUtils");
+const getInnerRequest = require("./getInnerRequest");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonPrimitive} JsonPrimitive */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class AliasFieldPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | Array<string>} field field
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, field, target) {
+		this.source = source;
+		this.field = field;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("AliasFieldPlugin", (request, resolveContext, callback) => {
+				if (!request.descriptionFileData) return callback();
+				const innerRequest = getInnerRequest(resolver, request);
+				if (!innerRequest) return callback();
+				const fieldData = DescriptionFileUtils.getField(
+					request.descriptionFileData,
+					this.field
+				);
+				if (fieldData === null || typeof fieldData !== "object") {
+					if (resolveContext.log)
+						resolveContext.log(
+							"Field '" +
+								this.field +
+								"' doesn't contain a valid alias configuration"
+						);
+					return callback();
+				}
+				/** @type {JsonPrimitive | undefined} */
+				const data = Object.prototype.hasOwnProperty.call(
+					fieldData,
+					innerRequest
+				)
+					? /** @type {{[Key in string]: JsonPrimitive}} */ (fieldData)[
+							innerRequest
+					  ]
+					: innerRequest.startsWith("./")
+					? /** @type {{[Key in string]: JsonPrimitive}} */ (fieldData)[
+							innerRequest.slice(2)
+					  ]
+					: undefined;
+				if (data === innerRequest) return callback();
+				if (data === undefined) return callback();
+				if (data === false) {
+					/** @type {ResolveRequest} */
+					const ignoreObj = {
+						...request,
+						path: false
+					};
+					if (typeof resolveContext.yield === "function") {
+						resolveContext.yield(ignoreObj);
+						return callback(null, null);
+					}
+					return callback(null, ignoreObj);
+				}
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: /** @type {string} */ (request.descriptionFileRoot),
+					request: /** @type {string} */ (data),
+					fullySpecified: false
+				};
+				resolver.doResolve(
+					target,
+					obj,
+					"aliased from description file " +
+						request.descriptionFilePath +
+						" with mapping '" +
+						innerRequest +
+						"' to '" +
+						/** @type {string} */ (data) +
+						"'",
+					resolveContext,
+					(err, result) => {
+						if (err) return callback(err);
+
+						// Don't allow other aliasing or raw request
+						if (result === undefined) return callback(null, null);
+						callback(null, result);
+					}
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/AliasPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/AliasPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/AliasPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,183 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+const { PathType, getType } = require("./util/path");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+/** @typedef {string | Array<string> | false} Alias */
+/** @typedef {{alias: Alias, name: string, onlyModule?: boolean}} AliasOption */
+
+module.exports = class AliasPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {AliasOption | Array<AliasOption>} options options
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, options, target) {
+		this.source = source;
+		this.options = Array.isArray(options) ? options : [options];
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		/**
+		 * @param {string} maybeAbsolutePath path
+		 * @returns {null|string} absolute path with slash ending
+		 */
+		const getAbsolutePathWithSlashEnding = maybeAbsolutePath => {
+			const type = getType(maybeAbsolutePath);
+			if (type === PathType.AbsolutePosix || type === PathType.AbsoluteWin) {
+				return resolver.join(maybeAbsolutePath, "_").slice(0, -1);
+			}
+			return null;
+		};
+		/**
+		 * @param {string} path path
+		 * @param {string} maybeSubPath sub path
+		 * @returns {boolean} true, if path is sub path
+		 */
+		const isSubPath = (path, maybeSubPath) => {
+			const absolutePath = getAbsolutePathWithSlashEnding(maybeSubPath);
+			if (!absolutePath) return false;
+			return path.startsWith(absolutePath);
+		};
+		resolver
+			.getHook(this.source)
+			.tapAsync("AliasPlugin", (request, resolveContext, callback) => {
+				const innerRequest = request.request || request.path;
+				if (!innerRequest) return callback();
+
+				forEachBail(
+					this.options,
+					(item, callback) => {
+						/** @type {boolean} */
+						let shouldStop = false;
+
+						const matchRequest =
+							innerRequest === item.name ||
+							(!item.onlyModule &&
+								(request.request
+									? innerRequest.startsWith(`${item.name}/`)
+									: isSubPath(innerRequest, item.name)));
+
+						const splitName = item.name.split("*");
+						const matchWildcard = !item.onlyModule && splitName.length === 2;
+
+						if (matchRequest || matchWildcard) {
+							/**
+							 * @param {Alias} alias alias
+							 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
+							 * @returns {void}
+							 */
+							const resolveWithAlias = (alias, callback) => {
+								if (alias === false) {
+									/** @type {ResolveRequest} */
+									const ignoreObj = {
+										...request,
+										path: false
+									};
+									if (typeof resolveContext.yield === "function") {
+										resolveContext.yield(ignoreObj);
+										return callback(null, null);
+									}
+									return callback(null, ignoreObj);
+								}
+
+								let newRequestStr;
+
+								const [prefix, suffix] = splitName;
+								if (
+									matchWildcard &&
+									innerRequest.startsWith(prefix) &&
+									innerRequest.endsWith(suffix)
+								) {
+									const match = innerRequest.slice(
+										prefix.length,
+										innerRequest.length - suffix.length
+									);
+									newRequestStr = item.alias.toString().replace("*", match);
+								}
+
+								if (
+									matchRequest &&
+									innerRequest !== alias &&
+									!innerRequest.startsWith(alias + "/")
+								) {
+									/** @type {string} */
+									const remainingRequest = innerRequest.slice(item.name.length);
+									newRequestStr = alias + remainingRequest;
+								}
+
+								if (newRequestStr !== undefined) {
+									shouldStop = true;
+									/** @type {ResolveRequest} */
+									const obj = {
+										...request,
+										request: newRequestStr,
+										fullySpecified: false
+									};
+									return resolver.doResolve(
+										target,
+										obj,
+										"aliased with mapping '" +
+											item.name +
+											"': '" +
+											alias +
+											"' to '" +
+											newRequestStr +
+											"'",
+										resolveContext,
+										(err, result) => {
+											if (err) return callback(err);
+											if (result) return callback(null, result);
+											return callback();
+										}
+									);
+								}
+								return callback();
+							};
+
+							/**
+							 * @param {null|Error} [err] error
+							 * @param {null|ResolveRequest} [result] result
+							 * @returns {void}
+							 */
+							const stoppingCallback = (err, result) => {
+								if (err) return callback(err);
+
+								if (result) return callback(null, result);
+								// Don't allow other aliasing or raw request
+								if (shouldStop) return callback(null, null);
+								return callback();
+							};
+
+							if (Array.isArray(item.alias)) {
+								return forEachBail(
+									item.alias,
+									resolveWithAlias,
+									stoppingCallback
+								);
+							} else {
+								return resolveWithAlias(item.alias, stoppingCallback);
+							}
+						}
+
+						return callback();
+					},
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/AppendPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/AppendPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/AppendPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,49 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class AppendPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string} appending appending
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, appending, target) {
+		this.source = source;
+		this.appending = appending;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("AppendPlugin", (request, resolveContext, callback) => {
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: request.path + this.appending,
+					relativePath:
+						request.relativePath && request.relativePath + this.appending
+				};
+				resolver.doResolve(
+					target,
+					obj,
+					this.appending,
+					resolveContext,
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,664 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const nextTick = require("process").nextTick;
+
+/** @typedef {import("./Resolver").FileSystem} FileSystem */
+/** @typedef {import("./Resolver").PathLike} PathLike */
+/** @typedef {import("./Resolver").PathOrFileDescriptor} PathOrFileDescriptor */
+/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
+/** @typedef {FileSystem & SyncFileSystem} BaseFileSystem */
+
+/**
+ * @template T
+ * @typedef {import("./Resolver").FileSystemCallback<T>} FileSystemCallback<T>
+ */
+
+/**
+ * @param {string} path path
+ * @returns {string} dirname
+ */
+const dirname = path => {
+	let idx = path.length - 1;
+	while (idx >= 0) {
+		const c = path.charCodeAt(idx);
+		// slash or backslash
+		if (c === 47 || c === 92) break;
+		idx--;
+	}
+	if (idx < 0) return "";
+	return path.slice(0, idx);
+};
+
+/**
+ * @template T
+ * @param {FileSystemCallback<T>[]} callbacks callbacks
+ * @param {Error | null} err error
+ * @param {T} result result
+ */
+const runCallbacks = (callbacks, err, result) => {
+	if (callbacks.length === 1) {
+		callbacks[0](err, result);
+		callbacks.length = 0;
+		return;
+	}
+	let error;
+	for (const callback of callbacks) {
+		try {
+			callback(err, result);
+		} catch (e) {
+			if (!error) error = e;
+		}
+	}
+	callbacks.length = 0;
+	if (error) throw error;
+};
+
+class OperationMergerBackend {
+	/**
+	 * @param {Function | undefined} provider async method in filesystem
+	 * @param {Function | undefined} syncProvider sync method in filesystem
+	 * @param {BaseFileSystem} providerContext call context for the provider methods
+	 */
+	constructor(provider, syncProvider, providerContext) {
+		this._provider = provider;
+		this._syncProvider = syncProvider;
+		this._providerContext = providerContext;
+		this._activeAsyncOperations = new Map();
+
+		this.provide = this._provider
+			? /**
+			   * @param {PathLike | PathOrFileDescriptor} path path
+			   * @param {object | FileSystemCallback<any> | undefined} options options
+			   * @param {FileSystemCallback<any>=} callback callback
+			   * @returns {any} result
+			   */
+			  (path, options, callback) => {
+					if (typeof options === "function") {
+						callback = /** @type {FileSystemCallback<any>} */ (options);
+						options = undefined;
+					}
+					if (
+						typeof path !== "string" &&
+						!Buffer.isBuffer(path) &&
+						!(path instanceof URL) &&
+						typeof path !== "number"
+					) {
+						/** @type {Function} */
+						(callback)(
+							new TypeError("path must be a string, Buffer, URL or number")
+						);
+						return;
+					}
+					if (options) {
+						return /** @type {Function} */ (this._provider).call(
+							this._providerContext,
+							path,
+							options,
+							callback
+						);
+					}
+					let callbacks = this._activeAsyncOperations.get(path);
+					if (callbacks) {
+						callbacks.push(callback);
+						return;
+					}
+					this._activeAsyncOperations.set(path, (callbacks = [callback]));
+					/** @type {Function} */
+					(provider)(
+						path,
+						/**
+						 * @param {Error} err error
+						 * @param {any} result result
+						 */
+						(err, result) => {
+							this._activeAsyncOperations.delete(path);
+							runCallbacks(callbacks, err, result);
+						}
+					);
+			  }
+			: null;
+		this.provideSync = this._syncProvider
+			? /**
+			   * @param {PathLike | PathOrFileDescriptor} path path
+			   * @param {object=} options options
+			   * @returns {any} result
+			   */
+			  (path, options) => {
+					return /** @type {Function} */ (this._syncProvider).call(
+						this._providerContext,
+						path,
+						options
+					);
+			  }
+			: null;
+	}
+
+	purge() {}
+	purgeParent() {}
+}
+
+/*
+
+IDLE:
+	insert data: goto SYNC
+
+SYNC:
+	before provide: run ticks
+	event loop tick: goto ASYNC_ACTIVE
+
+ASYNC:
+	timeout: run tick, goto ASYNC_PASSIVE
+
+ASYNC_PASSIVE:
+	before provide: run ticks
+
+IDLE --[insert data]--> SYNC --[event loop tick]--> ASYNC_ACTIVE --[interval tick]-> ASYNC_PASSIVE
+                                                          ^                             |
+                                                          +---------[insert data]-------+
+*/
+
+const STORAGE_MODE_IDLE = 0;
+const STORAGE_MODE_SYNC = 1;
+const STORAGE_MODE_ASYNC = 2;
+
+/**
+ * @callback Provide
+ * @param {PathLike | PathOrFileDescriptor} path path
+ * @param {any} options options
+ * @param {FileSystemCallback<any>} callback callback
+ * @returns {void}
+ */
+
+class CacheBackend {
+	/**
+	 * @param {number} duration max cache duration of items
+	 * @param {function | undefined} provider async method
+	 * @param {function | undefined} syncProvider sync method
+	 * @param {BaseFileSystem} providerContext call context for the provider methods
+	 */
+	constructor(duration, provider, syncProvider, providerContext) {
+		this._duration = duration;
+		this._provider = provider;
+		this._syncProvider = syncProvider;
+		this._providerContext = providerContext;
+		/** @type {Map<string, FileSystemCallback<any>[]>} */
+		this._activeAsyncOperations = new Map();
+		/** @type {Map<string, { err: Error | null, result?: any, level: Set<string> }>} */
+		this._data = new Map();
+		/** @type {Set<string>[]} */
+		this._levels = [];
+		for (let i = 0; i < 10; i++) this._levels.push(new Set());
+		for (let i = 5000; i < duration; i += 500) this._levels.push(new Set());
+		this._currentLevel = 0;
+		this._tickInterval = Math.floor(duration / this._levels.length);
+		/** @type {STORAGE_MODE_IDLE | STORAGE_MODE_SYNC | STORAGE_MODE_ASYNC} */
+		this._mode = STORAGE_MODE_IDLE;
+
+		/** @type {NodeJS.Timeout | undefined} */
+		this._timeout = undefined;
+		/** @type {number | undefined} */
+		this._nextDecay = undefined;
+
+		// @ts-ignore
+		this.provide = provider ? this.provide.bind(this) : null;
+		// @ts-ignore
+		this.provideSync = syncProvider ? this.provideSync.bind(this) : null;
+	}
+
+	/**
+	 * @param {PathLike | PathOrFileDescriptor} path path
+	 * @param {any} options options
+	 * @param {FileSystemCallback<any>} callback callback
+	 * @returns {void}
+	 */
+	provide(path, options, callback) {
+		if (typeof options === "function") {
+			callback = options;
+			options = undefined;
+		}
+		if (
+			typeof path !== "string" &&
+			!Buffer.isBuffer(path) &&
+			!(path instanceof URL) &&
+			typeof path !== "number"
+		) {
+			callback(new TypeError("path must be a string, Buffer, URL or number"));
+			return;
+		}
+		const strPath = typeof path !== "string" ? path.toString() : path;
+		if (options) {
+			return /** @type {Function} */ (this._provider).call(
+				this._providerContext,
+				path,
+				options,
+				callback
+			);
+		}
+
+		// When in sync mode we can move to async mode
+		if (this._mode === STORAGE_MODE_SYNC) {
+			this._enterAsyncMode();
+		}
+
+		// Check in cache
+		let cacheEntry = this._data.get(strPath);
+		if (cacheEntry !== undefined) {
+			if (cacheEntry.err) return nextTick(callback, cacheEntry.err);
+			return nextTick(callback, null, cacheEntry.result);
+		}
+
+		// Check if there is already the same operation running
+		let callbacks = this._activeAsyncOperations.get(strPath);
+		if (callbacks !== undefined) {
+			callbacks.push(callback);
+			return;
+		}
+		this._activeAsyncOperations.set(strPath, (callbacks = [callback]));
+
+		// Run the operation
+		/** @type {Function} */
+		(this._provider).call(
+			this._providerContext,
+			path,
+			/**
+			 * @param {Error | null} err error
+			 * @param {any} [result] result
+			 */
+			(err, result) => {
+				this._activeAsyncOperations.delete(strPath);
+				this._storeResult(strPath, err, result);
+
+				// Enter async mode if not yet done
+				this._enterAsyncMode();
+
+				runCallbacks(
+					/** @type {FileSystemCallback<any>[]} */ (callbacks),
+					err,
+					result
+				);
+			}
+		);
+	}
+
+	/**
+	 * @param {PathLike | PathOrFileDescriptor} path path
+	 * @param {any} options options
+	 * @returns {any} result
+	 */
+	provideSync(path, options) {
+		if (
+			typeof path !== "string" &&
+			!Buffer.isBuffer(path) &&
+			!(path instanceof URL) &&
+			typeof path !== "number"
+		) {
+			throw new TypeError("path must be a string");
+		}
+		const strPath = typeof path !== "string" ? path.toString() : path;
+		if (options) {
+			return /** @type {Function} */ (this._syncProvider).call(
+				this._providerContext,
+				path,
+				options
+			);
+		}
+
+		// In sync mode we may have to decay some cache items
+		if (this._mode === STORAGE_MODE_SYNC) {
+			this._runDecays();
+		}
+
+		// Check in cache
+		let cacheEntry = this._data.get(strPath);
+		if (cacheEntry !== undefined) {
+			if (cacheEntry.err) throw cacheEntry.err;
+			return cacheEntry.result;
+		}
+
+		// Get all active async operations
+		// This sync operation will also complete them
+		const callbacks = this._activeAsyncOperations.get(strPath);
+		this._activeAsyncOperations.delete(strPath);
+
+		// Run the operation
+		// When in idle mode, we will enter sync mode
+		let result;
+		try {
+			result = /** @type {Function} */ (this._syncProvider).call(
+				this._providerContext,
+				path
+			);
+		} catch (err) {
+			this._storeResult(strPath, /** @type {Error} */ (err), undefined);
+			this._enterSyncModeWhenIdle();
+			if (callbacks) {
+				runCallbacks(callbacks, /** @type {Error} */ (err), undefined);
+			}
+			throw err;
+		}
+		this._storeResult(strPath, null, result);
+		this._enterSyncModeWhenIdle();
+		if (callbacks) {
+			runCallbacks(callbacks, null, result);
+		}
+		return result;
+	}
+
+	/**
+	 * @param {string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set<string | URL | Buffer | number>} [what] what to purge
+	 */
+	purge(what) {
+		if (!what) {
+			if (this._mode !== STORAGE_MODE_IDLE) {
+				this._data.clear();
+				for (const level of this._levels) {
+					level.clear();
+				}
+				this._enterIdleMode();
+			}
+		} else if (
+			typeof what === "string" ||
+			Buffer.isBuffer(what) ||
+			what instanceof URL ||
+			typeof what === "number"
+		) {
+			const strWhat = typeof what !== "string" ? what.toString() : what;
+			for (let [key, data] of this._data) {
+				if (key.startsWith(strWhat)) {
+					this._data.delete(key);
+					data.level.delete(key);
+				}
+			}
+			if (this._data.size === 0) {
+				this._enterIdleMode();
+			}
+		} else {
+			for (let [key, data] of this._data) {
+				for (const item of what) {
+					const strItem = typeof item !== "string" ? item.toString() : item;
+					if (key.startsWith(strItem)) {
+						this._data.delete(key);
+						data.level.delete(key);
+						break;
+					}
+				}
+			}
+			if (this._data.size === 0) {
+				this._enterIdleMode();
+			}
+		}
+	}
+
+	/**
+	 * @param {string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set<string | URL | Buffer | number>} [what] what to purge
+	 */
+	purgeParent(what) {
+		if (!what) {
+			this.purge();
+		} else if (
+			typeof what === "string" ||
+			Buffer.isBuffer(what) ||
+			what instanceof URL ||
+			typeof what === "number"
+		) {
+			const strWhat = typeof what !== "string" ? what.toString() : what;
+			this.purge(dirname(strWhat));
+		} else {
+			const set = new Set();
+			for (const item of what) {
+				const strItem = typeof item !== "string" ? item.toString() : item;
+				set.add(dirname(strItem));
+			}
+			this.purge(set);
+		}
+	}
+
+	/**
+	 * @param {string} path path
+	 * @param {Error | null} err error
+	 * @param {any} result result
+	 */
+	_storeResult(path, err, result) {
+		if (this._data.has(path)) return;
+		const level = this._levels[this._currentLevel];
+		this._data.set(path, { err, result, level });
+		level.add(path);
+	}
+
+	_decayLevel() {
+		const nextLevel = (this._currentLevel + 1) % this._levels.length;
+		const decay = this._levels[nextLevel];
+		this._currentLevel = nextLevel;
+		for (let item of decay) {
+			this._data.delete(item);
+		}
+		decay.clear();
+		if (this._data.size === 0) {
+			this._enterIdleMode();
+		} else {
+			/** @type {number} */
+			(this._nextDecay) += this._tickInterval;
+		}
+	}
+
+	_runDecays() {
+		while (
+			/** @type {number} */ (this._nextDecay) <= Date.now() &&
+			this._mode !== STORAGE_MODE_IDLE
+		) {
+			this._decayLevel();
+		}
+	}
+
+	_enterAsyncMode() {
+		let timeout = 0;
+		switch (this._mode) {
+			case STORAGE_MODE_ASYNC:
+				return;
+			case STORAGE_MODE_IDLE:
+				this._nextDecay = Date.now() + this._tickInterval;
+				timeout = this._tickInterval;
+				break;
+			case STORAGE_MODE_SYNC:
+				this._runDecays();
+				// _runDecays may change the mode
+				if (
+					/** @type {STORAGE_MODE_IDLE | STORAGE_MODE_SYNC | STORAGE_MODE_ASYNC}*/
+					(this._mode) === STORAGE_MODE_IDLE
+				)
+					return;
+				timeout = Math.max(
+					0,
+					/** @type {number} */ (this._nextDecay) - Date.now()
+				);
+				break;
+		}
+		this._mode = STORAGE_MODE_ASYNC;
+		const ref = setTimeout(() => {
+			this._mode = STORAGE_MODE_SYNC;
+			this._runDecays();
+		}, timeout);
+		if (ref.unref) ref.unref();
+		this._timeout = ref;
+	}
+
+	_enterSyncModeWhenIdle() {
+		if (this._mode === STORAGE_MODE_IDLE) {
+			this._mode = STORAGE_MODE_SYNC;
+			this._nextDecay = Date.now() + this._tickInterval;
+		}
+	}
+
+	_enterIdleMode() {
+		this._mode = STORAGE_MODE_IDLE;
+		this._nextDecay = undefined;
+		if (this._timeout) clearTimeout(this._timeout);
+	}
+}
+
+/**
+ * @template {function} Provider
+ * @template {function} AsyncProvider
+ * @template FileSystem
+ * @param {number} duration duration in ms files are cached
+ * @param {Provider | undefined} provider provider
+ * @param {AsyncProvider | undefined} syncProvider sync provider
+ * @param {BaseFileSystem} providerContext provider context
+ * @returns {OperationMergerBackend | CacheBackend} backend
+ */
+const createBackend = (duration, provider, syncProvider, providerContext) => {
+	if (duration > 0) {
+		return new CacheBackend(duration, provider, syncProvider, providerContext);
+	}
+	return new OperationMergerBackend(provider, syncProvider, providerContext);
+};
+
+module.exports = class CachedInputFileSystem {
+	/**
+	 * @param {BaseFileSystem} fileSystem file system
+	 * @param {number} duration duration in ms files are cached
+	 */
+	constructor(fileSystem, duration) {
+		this.fileSystem = fileSystem;
+
+		this._lstatBackend = createBackend(
+			duration,
+			this.fileSystem.lstat,
+			this.fileSystem.lstatSync,
+			this.fileSystem
+		);
+		const lstat = this._lstatBackend.provide;
+		this.lstat = /** @type {FileSystem["lstat"]} */ (lstat);
+		const lstatSync = this._lstatBackend.provideSync;
+		this.lstatSync = /** @type {SyncFileSystem["lstatSync"]} */ (lstatSync);
+
+		this._statBackend = createBackend(
+			duration,
+			this.fileSystem.stat,
+			this.fileSystem.statSync,
+			this.fileSystem
+		);
+		const stat = this._statBackend.provide;
+		this.stat = /** @type {FileSystem["stat"]} */ (stat);
+		const statSync = this._statBackend.provideSync;
+		this.statSync = /** @type {SyncFileSystem["statSync"]} */ (statSync);
+
+		this._readdirBackend = createBackend(
+			duration,
+			this.fileSystem.readdir,
+			this.fileSystem.readdirSync,
+			this.fileSystem
+		);
+		const readdir = this._readdirBackend.provide;
+		this.readdir = /** @type {FileSystem["readdir"]} */ (readdir);
+		const readdirSync = this._readdirBackend.provideSync;
+		this.readdirSync = /** @type {SyncFileSystem["readdirSync"]} */ (
+			readdirSync
+		);
+
+		this._readFileBackend = createBackend(
+			duration,
+			this.fileSystem.readFile,
+			this.fileSystem.readFileSync,
+			this.fileSystem
+		);
+		const readFile = this._readFileBackend.provide;
+		this.readFile = /** @type {FileSystem["readFile"]} */ (readFile);
+		const readFileSync = this._readFileBackend.provideSync;
+		this.readFileSync = /** @type {SyncFileSystem["readFileSync"]} */ (
+			readFileSync
+		);
+
+		this._readJsonBackend = createBackend(
+			duration,
+			// prettier-ignore
+			this.fileSystem.readJson ||
+				(this.readFile &&
+					(
+						/**
+						 * @param {string} path path
+						 * @param {FileSystemCallback<any>} callback
+						 */
+						(path, callback) => {
+							this.readFile(path, (err, buffer) => {
+								if (err) return callback(err);
+								if (!buffer || buffer.length === 0)
+									return callback(new Error("No file content"));
+								let data;
+								try {
+									data = JSON.parse(buffer.toString("utf-8"));
+								} catch (e) {
+									return callback(/** @type {Error} */ (e));
+								}
+								callback(null, data);
+							});
+						})
+				),
+			// prettier-ignore
+			this.fileSystem.readJsonSync ||
+				(this.readFileSync &&
+					(
+						/**
+						 * @param {string} path path
+						 * @returns {any} result
+						 */
+						(path) => {
+							const buffer = this.readFileSync(path);
+							const data = JSON.parse(buffer.toString("utf-8"));
+							return data;
+						}
+				 )),
+			this.fileSystem
+		);
+		const readJson = this._readJsonBackend.provide;
+		this.readJson = /** @type {FileSystem["readJson"]} */ (readJson);
+		const readJsonSync = this._readJsonBackend.provideSync;
+		this.readJsonSync = /** @type {SyncFileSystem["readJsonSync"]} */ (
+			readJsonSync
+		);
+
+		this._readlinkBackend = createBackend(
+			duration,
+			this.fileSystem.readlink,
+			this.fileSystem.readlinkSync,
+			this.fileSystem
+		);
+		const readlink = this._readlinkBackend.provide;
+		this.readlink = /** @type {FileSystem["readlink"]} */ (readlink);
+		const readlinkSync = this._readlinkBackend.provideSync;
+		this.readlinkSync = /** @type {SyncFileSystem["readlinkSync"]} */ (
+			readlinkSync
+		);
+
+		this._realpathBackend = createBackend(
+			duration,
+			this.fileSystem.realpath,
+			this.fileSystem.realpathSync,
+			this.fileSystem
+		);
+		const realpath = this._realpathBackend.provide;
+		this.realpath = /** @type {FileSystem["realpath"]} */ (realpath);
+		const realpathSync = this._realpathBackend.provideSync;
+		this.realpathSync = /** @type {SyncFileSystem["realpathSync"]} */ (
+			realpathSync
+		);
+	}
+
+	/**
+	 * @param {string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set<string | URL | Buffer | number>} [what] what to purge
+	 */
+	purge(what) {
+		this._statBackend.purge(what);
+		this._lstatBackend.purge(what);
+		this._readdirBackend.purgeParent(what);
+		this._readFileBackend.purge(what);
+		this._readlinkBackend.purge(what);
+		this._readJsonBackend.purge(what);
+		this._realpathBackend.purge(what);
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/CloneBasenamePlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/CloneBasenamePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/CloneBasenamePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,53 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const basename = require("./getPaths").basename;
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class CloneBasenamePlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("CloneBasenamePlugin", (request, resolveContext, callback) => {
+				const requestPath = /** @type {string} */ (request.path);
+				const filename = /** @type {string} */ (basename(requestPath));
+				const filePath = resolver.join(requestPath, filename);
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: filePath,
+					relativePath:
+						request.relativePath &&
+						resolver.join(request.relativePath, filename)
+				};
+				resolver.doResolve(
+					target,
+					obj,
+					"using path: " + filePath,
+					resolveContext,
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ConditionalPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ConditionalPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ConditionalPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,59 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class ConditionalPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {Partial<ResolveRequest>} test compare object
+	 * @param {string | null} message log message
+	 * @param {boolean} allowAlternatives when false, do not continue with the current step when "test" matches
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, test, message, allowAlternatives, target) {
+		this.source = source;
+		this.test = test;
+		this.message = message;
+		this.allowAlternatives = allowAlternatives;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		const { test, message, allowAlternatives } = this;
+		const keys = /** @type {(keyof ResolveRequest)[]} */ (Object.keys(test));
+		resolver
+			.getHook(this.source)
+			.tapAsync("ConditionalPlugin", (request, resolveContext, callback) => {
+				for (const prop of keys) {
+					if (request[prop] !== test[prop]) return callback();
+				}
+				resolver.doResolve(
+					target,
+					request,
+					message,
+					resolveContext,
+					allowAlternatives
+						? callback
+						: (err, result) => {
+								if (err) return callback(err);
+
+								// Don't allow other alternatives
+								if (result === undefined) return callback(null, null);
+								callback(null, result);
+						  }
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,98 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DescriptionFileUtils = require("./DescriptionFileUtils");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class DescriptionFilePlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string[]} filenames filenames
+	 * @param {boolean} pathIsFile pathIsFile
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, filenames, pathIsFile, target) {
+		this.source = source;
+		this.filenames = filenames;
+		this.pathIsFile = pathIsFile;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync(
+				"DescriptionFilePlugin",
+				(request, resolveContext, callback) => {
+					const path = request.path;
+					if (!path) return callback();
+					const directory = this.pathIsFile
+						? DescriptionFileUtils.cdUp(path)
+						: path;
+					if (!directory) return callback();
+					DescriptionFileUtils.loadDescriptionFile(
+						resolver,
+						directory,
+						this.filenames,
+						request.descriptionFilePath
+							? {
+									path: request.descriptionFilePath,
+									content: request.descriptionFileData,
+									directory: /** @type {string} */ (request.descriptionFileRoot)
+							  }
+							: undefined,
+						resolveContext,
+						(err, result) => {
+							if (err) return callback(err);
+							if (!result) {
+								if (resolveContext.log)
+									resolveContext.log(
+										`No description file found in ${directory} or above`
+									);
+								return callback();
+							}
+							const relativePath =
+								"." + path.slice(result.directory.length).replace(/\\/g, "/");
+							/** @type {ResolveRequest} */
+							const obj = {
+								...request,
+								descriptionFilePath: result.path,
+								descriptionFileData: result.content,
+								descriptionFileRoot: result.directory,
+								relativePath: relativePath
+							};
+							resolver.doResolve(
+								target,
+								obj,
+								"using description file: " +
+									result.path +
+									" (relative path: " +
+									relativePath +
+									")",
+								resolveContext,
+								(err, result) => {
+									if (err) return callback(err);
+
+									// Don't allow other processing
+									if (result === undefined) return callback(null, null);
+									callback(null, result);
+								}
+							);
+						}
+					);
+				}
+			);
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,201 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonObject} JsonObject */
+/** @typedef {import("./Resolver").JsonValue} JsonValue */
+/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+
+/**
+ * @typedef {Object} DescriptionFileInfo
+ * @property {JsonObject=} content
+ * @property {string} path
+ * @property {string} directory
+ */
+
+/**
+ * @callback ErrorFirstCallback
+ * @param {Error|null=} error
+ * @param {DescriptionFileInfo=} result
+ */
+
+/**
+ * @typedef {Object} Result
+ * @property {string} path path to description file
+ * @property {string} directory directory of description file
+ * @property {JsonObject} content content of description file
+ */
+
+/**
+ * @param {Resolver} resolver resolver
+ * @param {string} directory directory
+ * @param {string[]} filenames filenames
+ * @param {DescriptionFileInfo|undefined} oldInfo oldInfo
+ * @param {ResolveContext} resolveContext resolveContext
+ * @param {ErrorFirstCallback} callback callback
+ */
+function loadDescriptionFile(
+	resolver,
+	directory,
+	filenames,
+	oldInfo,
+	resolveContext,
+	callback
+) {
+	(function findDescriptionFile() {
+		if (oldInfo && oldInfo.directory === directory) {
+			// We already have info for this directory and can reuse it
+			return callback(null, oldInfo);
+		}
+		forEachBail(
+			filenames,
+			/**
+			 * @param {string} filename filename
+			 * @param {(err?: null|Error, result?: null|Result) => void} callback callback
+			 * @returns {void}
+			 */
+			(filename, callback) => {
+				const descriptionFilePath = resolver.join(directory, filename);
+				if (resolver.fileSystem.readJson) {
+					resolver.fileSystem.readJson(descriptionFilePath, (err, content) => {
+						if (err) {
+							if (
+								typeof (/** @type {NodeJS.ErrnoException} */ (err).code) !==
+								"undefined"
+							) {
+								if (resolveContext.missingDependencies) {
+									resolveContext.missingDependencies.add(descriptionFilePath);
+								}
+								return callback();
+							}
+							if (resolveContext.fileDependencies) {
+								resolveContext.fileDependencies.add(descriptionFilePath);
+							}
+							return onJson(err);
+						}
+						if (resolveContext.fileDependencies) {
+							resolveContext.fileDependencies.add(descriptionFilePath);
+						}
+						onJson(null, content);
+					});
+				} else {
+					resolver.fileSystem.readFile(descriptionFilePath, (err, content) => {
+						if (err) {
+							if (resolveContext.missingDependencies) {
+								resolveContext.missingDependencies.add(descriptionFilePath);
+							}
+							return callback();
+						}
+						if (resolveContext.fileDependencies) {
+							resolveContext.fileDependencies.add(descriptionFilePath);
+						}
+
+						/** @type {JsonObject | undefined} */
+						let json;
+
+						if (content) {
+							try {
+								json = JSON.parse(content.toString());
+							} catch (/** @type {unknown} */ e) {
+								return onJson(/** @type {Error} */ (e));
+							}
+						} else {
+							return onJson(new Error("No content in file"));
+						}
+
+						onJson(null, json);
+					});
+				}
+
+				/**
+				 * @param {null|Error} [err] error
+				 * @param {JsonObject} [content] content
+				 * @returns {void}
+				 */
+				function onJson(err, content) {
+					if (err) {
+						if (resolveContext.log)
+							resolveContext.log(
+								descriptionFilePath + " (directory description file): " + err
+							);
+						else
+							err.message =
+								descriptionFilePath + " (directory description file): " + err;
+						return callback(err);
+					}
+					callback(null, {
+						content: /** @type {JsonObject} */ (content),
+						directory,
+						path: descriptionFilePath
+					});
+				}
+			},
+			/**
+			 * @param {null|Error} [err] error
+			 * @param {null|Result} [result] result
+			 * @returns {void}
+			 */
+			(err, result) => {
+				if (err) return callback(err);
+				if (result) {
+					return callback(null, result);
+				} else {
+					const dir = cdUp(directory);
+					if (!dir) {
+						return callback();
+					} else {
+						directory = dir;
+						return findDescriptionFile();
+					}
+				}
+			}
+		);
+	})();
+}
+
+/**
+ * @param {JsonObject} content content
+ * @param {string|string[]} field field
+ * @returns {JsonValue | undefined} field data
+ */
+function getField(content, field) {
+	if (!content) return undefined;
+	if (Array.isArray(field)) {
+		/** @type {JsonValue} */
+		let current = content;
+		for (let j = 0; j < field.length; j++) {
+			if (current === null || typeof current !== "object") {
+				current = null;
+				break;
+			}
+			current = /** @type {JsonObject} */ (current)[field[j]];
+		}
+		return current;
+	} else {
+		return content[field];
+	}
+}
+
+/**
+ * @param {string} directory directory
+ * @returns {string|null} parent directory or null
+ */
+function cdUp(directory) {
+	if (directory === "/") return null;
+	const i = directory.lastIndexOf("/"),
+		j = directory.lastIndexOf("\\");
+	const p = i < 0 ? j : j < 0 ? i : i < j ? j : i;
+	if (p < 0) return null;
+	return directory.slice(0, p || 1);
+}
+
+exports.loadDescriptionFile = loadDescriptionFile;
+exports.getField = getField;
+exports.cdUp = cdUp;
Index: imaps-frontend/node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,63 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class DirectoryExistsPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync(
+				"DirectoryExistsPlugin",
+				(request, resolveContext, callback) => {
+					const fs = resolver.fileSystem;
+					const directory = request.path;
+					if (!directory) return callback();
+					fs.stat(directory, (err, stat) => {
+						if (err || !stat) {
+							if (resolveContext.missingDependencies)
+								resolveContext.missingDependencies.add(directory);
+							if (resolveContext.log)
+								resolveContext.log(directory + " doesn't exist");
+							return callback();
+						}
+						if (!stat.isDirectory()) {
+							if (resolveContext.missingDependencies)
+								resolveContext.missingDependencies.add(directory);
+							if (resolveContext.log)
+								resolveContext.log(directory + " is not a directory");
+							return callback();
+						}
+						if (resolveContext.fileDependencies)
+							resolveContext.fileDependencies.add(directory);
+						resolver.doResolve(
+							target,
+							request,
+							`existing directory ${directory}`,
+							resolveContext,
+							callback
+						);
+					});
+				}
+			);
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,200 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const DescriptionFileUtils = require("./DescriptionFileUtils");
+const forEachBail = require("./forEachBail");
+const { processExportsField } = require("./util/entrypoints");
+const { parseIdentifier } = require("./util/identifier");
+const {
+	invalidSegmentRegEx,
+	deprecatedInvalidSegmentRegEx
+} = require("./util/path");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonObject} JsonObject */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+/** @typedef {import("./util/entrypoints").ExportsField} ExportsField */
+/** @typedef {import("./util/entrypoints").FieldProcessor} FieldProcessor */
+
+module.exports = class ExportsFieldPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {Set<string>} conditionNames condition names
+	 * @param {string | string[]} fieldNamePath name path
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, conditionNames, fieldNamePath, target) {
+		this.source = source;
+		this.target = target;
+		this.conditionNames = conditionNames;
+		this.fieldName = fieldNamePath;
+		/** @type {WeakMap<JsonObject, FieldProcessor>} */
+		this.fieldProcessorCache = new WeakMap();
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("ExportsFieldPlugin", (request, resolveContext, callback) => {
+				// When there is no description file, abort
+				if (!request.descriptionFilePath) return callback();
+				if (
+					// When the description file is inherited from parent, abort
+					// (There is no description file inside of this package)
+					request.relativePath !== "." ||
+					request.request === undefined
+				)
+					return callback();
+
+				const remainingRequest =
+					request.query || request.fragment
+						? (request.request === "." ? "./" : request.request) +
+						  request.query +
+						  request.fragment
+						: request.request;
+				const exportsField =
+					/** @type {ExportsField|null|undefined} */
+					(
+						DescriptionFileUtils.getField(
+							/** @type {JsonObject} */ (request.descriptionFileData),
+							this.fieldName
+						)
+					);
+				if (!exportsField) return callback();
+
+				if (request.directory) {
+					return callback(
+						new Error(
+							`Resolving to directories is not possible with the exports field (request was ${remainingRequest}/)`
+						)
+					);
+				}
+
+				/** @type {string[]} */
+				let paths;
+				/** @type {string | null} */
+				let usedField;
+
+				try {
+					// We attach the cache to the description file instead of the exportsField value
+					// because we use a WeakMap and the exportsField could be a string too.
+					// Description file is always an object when exports field can be accessed.
+					let fieldProcessor = this.fieldProcessorCache.get(
+						/** @type {JsonObject} */ (request.descriptionFileData)
+					);
+					if (fieldProcessor === undefined) {
+						fieldProcessor = processExportsField(exportsField);
+						this.fieldProcessorCache.set(
+							/** @type {JsonObject} */ (request.descriptionFileData),
+							fieldProcessor
+						);
+					}
+					[paths, usedField] = fieldProcessor(
+						remainingRequest,
+						this.conditionNames
+					);
+				} catch (/** @type {unknown} */ err) {
+					if (resolveContext.log) {
+						resolveContext.log(
+							`Exports field in ${request.descriptionFilePath} can't be processed: ${err}`
+						);
+					}
+					return callback(/** @type {Error} */ (err));
+				}
+
+				if (paths.length === 0) {
+					return callback(
+						new Error(
+							`Package path ${remainingRequest} is not exported from package ${request.descriptionFileRoot} (see exports field in ${request.descriptionFilePath})`
+						)
+					);
+				}
+
+				forEachBail(
+					paths,
+					/**
+					 * @param {string} p path
+					 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
+					 * @param {number} i index
+					 * @returns {void}
+					 */
+					(p, callback, i) => {
+						const parsedIdentifier = parseIdentifier(p);
+
+						if (!parsedIdentifier) return callback();
+
+						const [relativePath, query, fragment] = parsedIdentifier;
+
+						if (relativePath.length === 0 || !relativePath.startsWith("./")) {
+							if (paths.length === i) {
+								return callback(
+									new Error(
+										`Invalid "exports" target "${p}" defined for "${usedField}" in the package config ${request.descriptionFilePath}, targets must start with "./"`
+									)
+								);
+							}
+
+							return callback();
+						}
+
+						if (
+							invalidSegmentRegEx.exec(relativePath.slice(2)) !== null &&
+							deprecatedInvalidSegmentRegEx.test(relativePath.slice(2)) !== null
+						) {
+							if (paths.length === i) {
+								return callback(
+									new Error(
+										`Invalid "exports" target "${p}" defined for "${usedField}" in the package config ${request.descriptionFilePath}, targets must start with "./"`
+									)
+								);
+							}
+
+							return callback();
+						}
+
+						/** @type {ResolveRequest} */
+						const obj = {
+							...request,
+							request: undefined,
+							path: resolver.join(
+								/** @type {string} */ (request.descriptionFileRoot),
+								relativePath
+							),
+							relativePath,
+							query,
+							fragment
+						};
+
+						resolver.doResolve(
+							target,
+							obj,
+							"using exports field: " + p,
+							resolveContext,
+							(err, result) => {
+								if (err) return callback(err);
+								// Don't allow to continue - https://github.com/webpack/enhanced-resolve/issues/400
+								if (result === undefined) return callback(null, null);
+								callback(null, result);
+							}
+						);
+					},
+					/**
+					 * @param {null|Error} [err] error
+					 * @param {null|ResolveRequest} [result] result
+					 * @returns {void}
+					 */
+					(err, result) => callback(err, result || null)
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ExtensionAliasPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ExtensionAliasPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ExtensionAliasPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,101 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+/** @typedef {{ alias: string|string[], extension: string }} ExtensionAliasOption */
+
+module.exports = class ExtensionAliasPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {ExtensionAliasOption} options options
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, options, target) {
+		this.source = source;
+		this.options = options;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		const { extension, alias } = this.options;
+		resolver
+			.getHook(this.source)
+			.tapAsync("ExtensionAliasPlugin", (request, resolveContext, callback) => {
+				const requestPath = request.request;
+				if (!requestPath || !requestPath.endsWith(extension)) return callback();
+				const isAliasString = typeof alias === "string";
+				/**
+				 * @param {string} alias extension alias
+				 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
+				 * @param {number} [index] index
+				 * @returns {void}
+				 */
+				const resolve = (alias, callback, index) => {
+					const newRequest = `${requestPath.slice(
+						0,
+						-extension.length
+					)}${alias}`;
+
+					return resolver.doResolve(
+						target,
+						{
+							...request,
+							request: newRequest,
+							fullySpecified: true
+						},
+						`aliased from extension alias with mapping '${extension}' to '${alias}'`,
+						resolveContext,
+						(err, result) => {
+							// Throw error if we are on the last alias (for multiple aliases) and it failed, always throw if we are not an array or we have only one alias
+							if (!isAliasString && index) {
+								if (index !== this.options.alias.length) {
+									if (resolveContext.log) {
+										resolveContext.log(
+											`Failed to alias from extension alias with mapping '${extension}' to '${alias}' for '${newRequest}': ${err}`
+										);
+									}
+
+									return callback(null, result);
+								}
+
+								return callback(err, result);
+							} else {
+								callback(err, result);
+							}
+						}
+					);
+				};
+				/**
+				 * @param {null|Error} [err] error
+				 * @param {null|ResolveRequest} [result] result
+				 * @returns {void}
+				 */
+				const stoppingCallback = (err, result) => {
+					if (err) return callback(err);
+					if (result) return callback(null, result);
+					// Don't allow other aliasing or raw request
+					return callback(null, null);
+				};
+				if (isAliasString) {
+					resolve(alias, stoppingCallback);
+				} else if (alias.length > 1) {
+					forEachBail(alias, resolve, stoppingCallback);
+				} else {
+					resolve(alias[0], stoppingCallback);
+				}
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/FileExistsPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/FileExistsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/FileExistsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,58 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class FileExistsPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		const fs = resolver.fileSystem;
+		resolver
+			.getHook(this.source)
+			.tapAsync("FileExistsPlugin", (request, resolveContext, callback) => {
+				const file = request.path;
+				if (!file) return callback();
+				fs.stat(file, (err, stat) => {
+					if (err || !stat) {
+						if (resolveContext.missingDependencies)
+							resolveContext.missingDependencies.add(file);
+						if (resolveContext.log) resolveContext.log(file + " doesn't exist");
+						return callback();
+					}
+					if (!stat.isFile()) {
+						if (resolveContext.missingDependencies)
+							resolveContext.missingDependencies.add(file);
+						if (resolveContext.log) resolveContext.log(file + " is not a file");
+						return callback();
+					}
+					if (resolveContext.fileDependencies)
+						resolveContext.fileDependencies.add(file);
+					resolver.doResolve(
+						target,
+						request,
+						"existing file: " + file,
+						resolveContext,
+						callback
+					);
+				});
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,223 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const DescriptionFileUtils = require("./DescriptionFileUtils");
+const forEachBail = require("./forEachBail");
+const { processImportsField } = require("./util/entrypoints");
+const { parseIdentifier } = require("./util/identifier");
+const {
+	invalidSegmentRegEx,
+	deprecatedInvalidSegmentRegEx
+} = require("./util/path");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonObject} JsonObject */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+/** @typedef {import("./util/entrypoints").FieldProcessor} FieldProcessor */
+/** @typedef {import("./util/entrypoints").ImportsField} ImportsField */
+
+const dotCode = ".".charCodeAt(0);
+
+module.exports = class ImportsFieldPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {Set<string>} conditionNames condition names
+	 * @param {string | string[]} fieldNamePath name path
+	 * @param {string | ResolveStepHook} targetFile target file
+	 * @param {string | ResolveStepHook} targetPackage target package
+	 */
+	constructor(
+		source,
+		conditionNames,
+		fieldNamePath,
+		targetFile,
+		targetPackage
+	) {
+		this.source = source;
+		this.targetFile = targetFile;
+		this.targetPackage = targetPackage;
+		this.conditionNames = conditionNames;
+		this.fieldName = fieldNamePath;
+		/** @type {WeakMap<JsonObject, FieldProcessor>} */
+		this.fieldProcessorCache = new WeakMap();
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const targetFile = resolver.ensureHook(this.targetFile);
+		const targetPackage = resolver.ensureHook(this.targetPackage);
+
+		resolver
+			.getHook(this.source)
+			.tapAsync("ImportsFieldPlugin", (request, resolveContext, callback) => {
+				// When there is no description file, abort
+				if (!request.descriptionFilePath || request.request === undefined) {
+					return callback();
+				}
+
+				const remainingRequest =
+					request.request + request.query + request.fragment;
+				const importsField =
+					/** @type {ImportsField|null|undefined} */
+					(
+						DescriptionFileUtils.getField(
+							/** @type {JsonObject} */ (request.descriptionFileData),
+							this.fieldName
+						)
+					);
+				if (!importsField) return callback();
+
+				if (request.directory) {
+					return callback(
+						new Error(
+							`Resolving to directories is not possible with the imports field (request was ${remainingRequest}/)`
+						)
+					);
+				}
+
+				/** @type {string[]} */
+				let paths;
+				/** @type {string | null} */
+				let usedField;
+
+				try {
+					// We attach the cache to the description file instead of the importsField value
+					// because we use a WeakMap and the importsField could be a string too.
+					// Description file is always an object when exports field can be accessed.
+					let fieldProcessor = this.fieldProcessorCache.get(
+						/** @type {JsonObject} */ (request.descriptionFileData)
+					);
+					if (fieldProcessor === undefined) {
+						fieldProcessor = processImportsField(importsField);
+						this.fieldProcessorCache.set(
+							/** @type {JsonObject} */ (request.descriptionFileData),
+							fieldProcessor
+						);
+					}
+					[paths, usedField] = fieldProcessor(
+						remainingRequest,
+						this.conditionNames
+					);
+				} catch (/** @type {unknown} */ err) {
+					if (resolveContext.log) {
+						resolveContext.log(
+							`Imports field in ${request.descriptionFilePath} can't be processed: ${err}`
+						);
+					}
+					return callback(/** @type {Error} */ (err));
+				}
+
+				if (paths.length === 0) {
+					return callback(
+						new Error(
+							`Package import ${remainingRequest} is not imported from package ${request.descriptionFileRoot} (see imports field in ${request.descriptionFilePath})`
+						)
+					);
+				}
+
+				forEachBail(
+					paths,
+					/**
+					 * @param {string} p path
+					 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
+					 * @param {number} i index
+					 * @returns {void}
+					 */
+					(p, callback, i) => {
+						const parsedIdentifier = parseIdentifier(p);
+
+						if (!parsedIdentifier) return callback();
+
+						const [path_, query, fragment] = parsedIdentifier;
+
+						switch (path_.charCodeAt(0)) {
+							// should be relative
+							case dotCode: {
+								if (
+									invalidSegmentRegEx.exec(path_.slice(2)) !== null &&
+									deprecatedInvalidSegmentRegEx.test(path_.slice(2)) !== null
+								) {
+									if (paths.length === i) {
+										return callback(
+											new Error(
+												`Invalid "imports" target "${p}" defined for "${usedField}" in the package config ${request.descriptionFilePath}, targets must start with "./"`
+											)
+										);
+									}
+
+									return callback();
+								}
+
+								/** @type {ResolveRequest} */
+								const obj = {
+									...request,
+									request: undefined,
+									path: resolver.join(
+										/** @type {string} */ (request.descriptionFileRoot),
+										path_
+									),
+									relativePath: path_,
+									query,
+									fragment
+								};
+
+								resolver.doResolve(
+									targetFile,
+									obj,
+									"using imports field: " + p,
+									resolveContext,
+									(err, result) => {
+										if (err) return callback(err);
+										// Don't allow to continue - https://github.com/webpack/enhanced-resolve/issues/400
+										if (result === undefined) return callback(null, null);
+										callback(null, result);
+									}
+								);
+								break;
+							}
+
+							// package resolving
+							default: {
+								/** @type {ResolveRequest} */
+								const obj = {
+									...request,
+									request: path_,
+									relativePath: path_,
+									fullySpecified: true,
+									query,
+									fragment
+								};
+
+								resolver.doResolve(
+									targetPackage,
+									obj,
+									"using imports field: " + p,
+									resolveContext,
+									(err, result) => {
+										if (err) return callback(err);
+										// Don't allow to continue - https://github.com/webpack/enhanced-resolve/issues/400
+										if (result === undefined) return callback(null, null);
+										callback(null, result);
+									}
+								);
+							}
+						}
+					},
+					/**
+					 * @param {null|Error} [err] error
+					 * @param {null|ResolveRequest} [result] result
+					 * @returns {void}
+					 */
+					(err, result) => callback(err, result || null)
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/JoinRequestPartPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/JoinRequestPartPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/JoinRequestPartPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,75 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+const namespaceStartCharCode = "@".charCodeAt(0);
+
+module.exports = class JoinRequestPartPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync(
+				"JoinRequestPartPlugin",
+				(request, resolveContext, callback) => {
+					const req = request.request || "";
+					let i = req.indexOf("/", 3);
+
+					if (i >= 0 && req.charCodeAt(2) === namespaceStartCharCode) {
+						i = req.indexOf("/", i + 1);
+					}
+
+					/** @type {string} */
+					let moduleName;
+					/** @type {string} */
+					let remainingRequest;
+					/** @type {boolean} */
+					let fullySpecified;
+					if (i < 0) {
+						moduleName = req;
+						remainingRequest = ".";
+						fullySpecified = false;
+					} else {
+						moduleName = req.slice(0, i);
+						remainingRequest = "." + req.slice(i);
+						fullySpecified = /** @type {boolean} */ (request.fullySpecified);
+					}
+					/** @type {ResolveRequest} */
+					const obj = {
+						...request,
+						path: resolver.join(
+							/** @type {string} */
+							(request.path),
+							moduleName
+						),
+						relativePath:
+							request.relativePath &&
+							resolver.join(request.relativePath, moduleName),
+						request: remainingRequest,
+						fullySpecified
+					};
+					resolver.doResolve(target, obj, null, resolveContext, callback);
+				}
+			);
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/JoinRequestPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/JoinRequestPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/JoinRequestPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,45 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class JoinRequestPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("JoinRequestPlugin", (request, resolveContext, callback) => {
+				const requestPath = /** @type {string} */ (request.path);
+				const requestRequest = /** @type {string} */ (request.request);
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: resolver.join(requestPath, requestRequest),
+					relativePath:
+						request.relativePath &&
+						resolver.join(request.relativePath, requestRequest),
+					request: undefined
+				};
+				resolver.doResolve(target, obj, null, resolveContext, callback);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/LogInfoPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/LogInfoPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/LogInfoPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,54 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class LogInfoPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 */
+	constructor(source) {
+		this.source = source;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const source = this.source;
+		resolver
+			.getHook(this.source)
+			.tapAsync("LogInfoPlugin", (request, resolveContext, callback) => {
+				if (!resolveContext.log) return callback();
+				const log = resolveContext.log;
+				const prefix = "[" + source + "] ";
+				if (request.path)
+					log(prefix + "Resolving in directory: " + request.path);
+				if (request.request)
+					log(prefix + "Resolving request: " + request.request);
+				if (request.module) log(prefix + "Request is an module request.");
+				if (request.directory) log(prefix + "Request is a directory request.");
+				if (request.query)
+					log(prefix + "Resolving request query: " + request.query);
+				if (request.fragment)
+					log(prefix + "Resolving request fragment: " + request.fragment);
+				if (request.descriptionFilePath)
+					log(
+						prefix + "Has description data from " + request.descriptionFilePath
+					);
+				if (request.relativePath)
+					log(
+						prefix +
+							"Relative path from description file is: " +
+							request.relativePath
+					);
+				callback();
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/MainFieldPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/MainFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/MainFieldPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,90 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const path = require("path");
+const DescriptionFileUtils = require("./DescriptionFileUtils");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonObject} JsonObject */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+/** @typedef {{name: string|Array<string>, forceRelative: boolean}} MainFieldOptions */
+
+const alreadyTriedMainField = Symbol("alreadyTriedMainField");
+
+module.exports = class MainFieldPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {MainFieldOptions} options options
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, options, target) {
+		this.source = source;
+		this.options = options;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("MainFieldPlugin", (request, resolveContext, callback) => {
+				if (
+					request.path !== request.descriptionFileRoot ||
+					/** @type {ResolveRequest & { [alreadyTriedMainField]?: string }} */
+					(request)[alreadyTriedMainField] === request.descriptionFilePath ||
+					!request.descriptionFilePath
+				)
+					return callback();
+				const filename = path.basename(request.descriptionFilePath);
+				let mainModule =
+					/** @type {string|null|undefined} */
+					(
+						DescriptionFileUtils.getField(
+							/** @type {JsonObject} */ (request.descriptionFileData),
+							this.options.name
+						)
+					);
+
+				if (
+					!mainModule ||
+					typeof mainModule !== "string" ||
+					mainModule === "." ||
+					mainModule === "./"
+				) {
+					return callback();
+				}
+				if (this.options.forceRelative && !/^\.\.?\//.test(mainModule))
+					mainModule = "./" + mainModule;
+				/** @type {ResolveRequest & { [alreadyTriedMainField]?: string }} */
+				const obj = {
+					...request,
+					request: mainModule,
+					module: false,
+					directory: mainModule.endsWith("/"),
+					[alreadyTriedMainField]: request.descriptionFilePath
+				};
+				return resolver.doResolve(
+					target,
+					obj,
+					"use " +
+						mainModule +
+						" from " +
+						this.options.name +
+						" in " +
+						filename,
+					resolveContext,
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInHierachicDirectoriesPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInHierachicDirectoriesPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInHierachicDirectoriesPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,9 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+// TODO remove in next major
+module.exports = require("./ModulesInHierarchicalDirectoriesPlugin");
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInHierarchicalDirectoriesPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInHierarchicalDirectoriesPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInHierarchicalDirectoriesPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,87 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+const getPaths = require("./getPaths");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class ModulesInHierarchicalDirectoriesPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | Array<string>} directories directories
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, directories, target) {
+		this.source = source;
+		this.directories = /** @type {Array<string>} */ ([]).concat(directories);
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync(
+				"ModulesInHierarchicalDirectoriesPlugin",
+				(request, resolveContext, callback) => {
+					const fs = resolver.fileSystem;
+					const addrs = getPaths(/** @type {string} */ (request.path))
+						.paths.map(p => {
+							return this.directories.map(d => resolver.join(p, d));
+						})
+						.reduce((array, p) => {
+							array.push.apply(array, p);
+							return array;
+						}, []);
+					forEachBail(
+						addrs,
+						/**
+						 * @param {string} addr addr
+						 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
+						 * @returns {void}
+						 */
+						(addr, callback) => {
+							fs.stat(addr, (err, stat) => {
+								if (!err && stat && stat.isDirectory()) {
+									/** @type {ResolveRequest} */
+									const obj = {
+										...request,
+										path: addr,
+										request: "./" + request.request,
+										module: false
+									};
+									const message = "looking for modules in " + addr;
+									return resolver.doResolve(
+										target,
+										obj,
+										message,
+										resolveContext,
+										callback
+									);
+								}
+								if (resolveContext.log)
+									resolveContext.log(
+										addr + " doesn't exist or is not a directory"
+									);
+								if (resolveContext.missingDependencies)
+									resolveContext.missingDependencies.add(addr);
+								return callback();
+							});
+						},
+						callback
+					);
+				}
+			);
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,49 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class ModulesInRootPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string} path path
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, path, target) {
+		this.source = source;
+		this.path = path;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("ModulesInRootPlugin", (request, resolveContext, callback) => {
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: this.path,
+					request: "./" + request.request,
+					module: false
+				};
+				resolver.doResolve(
+					target,
+					obj,
+					"looking for modules in " + this.path,
+					resolveContext,
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/NextPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/NextPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/NextPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,33 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class NextPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("NextPlugin", (request, resolveContext, callback) => {
+				resolver.doResolve(target, request, null, resolveContext, callback);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ParsePlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ParsePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ParsePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,76 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class ParsePlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {Partial<ResolveRequest>} requestOptions request options
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, requestOptions, target) {
+		this.source = source;
+		this.requestOptions = requestOptions;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("ParsePlugin", (request, resolveContext, callback) => {
+				const parsed = resolver.parse(/** @type {string} */ (request.request));
+				/** @type {ResolveRequest} */
+				const obj = { ...request, ...parsed, ...this.requestOptions };
+				if (request.query && !parsed.query) {
+					obj.query = request.query;
+				}
+				if (request.fragment && !parsed.fragment) {
+					obj.fragment = request.fragment;
+				}
+				if (parsed && resolveContext.log) {
+					if (parsed.module) resolveContext.log("Parsed request is a module");
+					if (parsed.directory)
+						resolveContext.log("Parsed request is a directory");
+				}
+				// There is an edge-case where a request with # can be a path or a fragment -> try both
+				if (obj.request && !obj.query && obj.fragment) {
+					const directory = obj.fragment.endsWith("/");
+					/** @type {ResolveRequest} */
+					const alternative = {
+						...obj,
+						directory,
+						request:
+							obj.request +
+							(obj.directory ? "/" : "") +
+							(directory ? obj.fragment.slice(0, -1) : obj.fragment),
+						fragment: ""
+					};
+					resolver.doResolve(
+						target,
+						alternative,
+						null,
+						resolveContext,
+						(err, result) => {
+							if (err) return callback(err);
+							if (result) return callback(null, result);
+							resolver.doResolve(target, obj, null, resolveContext, callback);
+						}
+					);
+					return;
+				}
+				resolver.doResolve(target, obj, null, resolveContext, callback);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/PnpPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/PnpPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/PnpPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,133 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Maël Nison @arcanis
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/**
+ * @typedef {Object} PnpApiImpl
+ * @property {function(string, string, object): string | null} resolveToUnqualified
+ */
+
+module.exports = class PnpPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {PnpApiImpl} pnpApi pnpApi
+	 * @param {string | ResolveStepHook} target target
+	 * @param {string | ResolveStepHook} alternateTarget alternateTarget
+	 */
+	constructor(source, pnpApi, target, alternateTarget) {
+		this.source = source;
+		this.pnpApi = pnpApi;
+		this.target = target;
+		this.alternateTarget = alternateTarget;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		/** @type {ResolveStepHook} */
+		const target = resolver.ensureHook(this.target);
+		const alternateTarget = resolver.ensureHook(this.alternateTarget);
+		resolver
+			.getHook(this.source)
+			.tapAsync("PnpPlugin", (request, resolveContext, callback) => {
+				const req = request.request;
+				if (!req) return callback();
+
+				// The trailing slash indicates to PnP that this value is a folder rather than a file
+				const issuer = `${request.path}/`;
+
+				const packageMatch = /^(@[^/]+\/)?[^/]+/.exec(req);
+				if (!packageMatch) return callback();
+
+				const packageName = packageMatch[0];
+				const innerRequest = `.${req.slice(packageName.length)}`;
+
+				/** @type {string|undefined|null} */
+				let resolution;
+				/** @type {string|undefined|null} */
+				let apiResolution;
+				try {
+					resolution = this.pnpApi.resolveToUnqualified(packageName, issuer, {
+						considerBuiltins: false
+					});
+
+					if (resolution === null) {
+						// This is either not a PnP managed issuer or it's a Node builtin
+						// Try to continue resolving with our alternatives
+						resolver.doResolve(
+							alternateTarget,
+							request,
+							"issuer is not managed by a pnpapi",
+							resolveContext,
+							(err, result) => {
+								if (err) return callback(err);
+								if (result) return callback(null, result);
+								// Skip alternatives
+								return callback(null, null);
+							}
+						);
+						return;
+					}
+
+					if (resolveContext.fileDependencies) {
+						apiResolution = this.pnpApi.resolveToUnqualified("pnpapi", issuer, {
+							considerBuiltins: false
+						});
+					}
+				} catch (/** @type {unknown} */ error) {
+					if (
+						/** @type {Error & { code: string }} */
+						(error).code === "MODULE_NOT_FOUND" &&
+						/** @type {Error & { pnpCode: string }} */
+						(error).pnpCode === "UNDECLARED_DEPENDENCY"
+					) {
+						// This is not a PnP managed dependency.
+						// Try to continue resolving with our alternatives
+						if (resolveContext.log) {
+							resolveContext.log(`request is not managed by the pnpapi`);
+							for (const line of /** @type {Error} */ (error).message
+								.split("\n")
+								.filter(Boolean))
+								resolveContext.log(`  ${line}`);
+						}
+						return callback();
+					}
+					return callback(/** @type {Error} */ (error));
+				}
+
+				if (resolution === packageName) return callback();
+
+				if (apiResolution && resolveContext.fileDependencies) {
+					resolveContext.fileDependencies.add(apiResolution);
+				}
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: resolution,
+					request: innerRequest,
+					ignoreSymlinks: true,
+					fullySpecified: request.fullySpecified && innerRequest !== "."
+				};
+				resolver.doResolve(
+					target,
+					obj,
+					`resolved by pnp to ${resolution}`,
+					resolveContext,
+					(err, result) => {
+						if (err) return callback(err);
+						if (result) return callback(null, result);
+						// Skip alternatives
+						return callback(null, null);
+					}
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/Resolver.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/Resolver.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/Resolver.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,800 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } = require("tapable");
+const createInnerContext = require("./createInnerContext");
+const { parseIdentifier } = require("./util/identifier");
+const {
+	normalize,
+	cachedJoin: join,
+	getType,
+	PathType
+} = require("./util/path");
+
+/** @typedef {import("./ResolverFactory").ResolveOptions} ResolveOptions */
+
+/** @typedef {Error & { details?: string }} ErrorWithDetail */
+
+/** @typedef {(err: ErrorWithDetail | null, res?: string | false, req?: ResolveRequest) => void} ResolveCallback */
+
+/**
+ * @typedef {Object} PossibleFileSystemError
+ * @property {string=} code
+ * @property {number=} errno
+ * @property {string=} path
+ * @property {string=} syscall
+ */
+
+/**
+ * @template T
+ * @callback FileSystemCallback
+ * @param {PossibleFileSystemError & Error | null} err
+ * @param {T=} result
+ */
+
+/**
+ * @typedef {string | Buffer | URL} PathLike
+ */
+
+/**
+ * @typedef {PathLike | number} PathOrFileDescriptor
+ */
+
+/**
+ * @typedef {Object} ObjectEncodingOptions
+ * @property {BufferEncoding | null | undefined} [encoding]
+ */
+
+/** @typedef {function(NodeJS.ErrnoException | null, string=): void} StringCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Buffer=): void} BufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, (string | Buffer)=): void} StringOrBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IStats=): void} StatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IBigIntStats=): void} BigIntStatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, (IStats | IBigIntStats)=): void} StatsOrBigIntStatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | Error | null, JsonObject=): void} ReadJsonCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, string[]=): void} ReaddirStringCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Buffer[]=): void} ReaddirBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, (string[] | Buffer[])=): void} ReaddirStringOrBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Dirent[]=): void} ReaddirDirentCallback */
+
+/**
+ * @template T
+ * @typedef {Object} IStatsBase
+ * @property {() => boolean} isFile
+ * @property {() => boolean} isDirectory
+ * @property {() => boolean} isBlockDevice
+ * @property {() => boolean} isCharacterDevice
+ * @property {() => boolean} isSymbolicLink
+ * @property {() => boolean} isFIFO
+ * @property {() => boolean} isSocket
+ * @property {T} dev
+ * @property {T} ino
+ * @property {T} mode
+ * @property {T} nlink
+ * @property {T} uid
+ * @property {T} gid
+ * @property {T} rdev
+ * @property {T} size
+ * @property {T} blksize
+ * @property {T} blocks
+ * @property {T} atimeMs
+ * @property {T} mtimeMs
+ * @property {T} ctimeMs
+ * @property {T} birthtimeMs
+ * @property {Date} atime
+ * @property {Date} mtime
+ * @property {Date} ctime
+ * @property {Date} birthtime
+ */
+
+/**
+ * @typedef {IStatsBase<number>} IStats
+ */
+
+/**
+ * @typedef {IStatsBase<bigint> & { atimeNs: bigint, mtimeNs: bigint, ctimeNs: bigint, birthtimeNs: bigint  }} IBigIntStats
+ */
+
+/**
+ * @typedef {Object} Dirent
+ * @property {() => boolean} isFile
+ * @property {() => boolean} isDirectory
+ * @property {() => boolean} isBlockDevice
+ * @property {() => boolean} isCharacterDevice
+ * @property {() => boolean} isSymbolicLink
+ * @property {() => boolean} isFIFO
+ * @property {() => boolean} isSocket
+ * @property {string} name
+ * @property {string} path
+ */
+
+/**
+ * @typedef {Object} StatOptions
+ * @property {(boolean | undefined)=} bigint
+ */
+
+/**
+ * @typedef {Object} StatSyncOptions
+ * @property {(boolean | undefined)=} bigint
+ * @property {(boolean | undefined)=} throwIfNoEntry
+ */
+
+/**
+ * @typedef {{
+ * (path: PathOrFileDescriptor, options: ({ encoding?: null | undefined, flag?: string | undefined } & import("events").Abortable) | undefined | null, callback: BufferCallback): void;
+ * (path: PathOrFileDescriptor, options: ({ encoding: BufferEncoding, flag?: string | undefined } & import("events").Abortable) | BufferEncoding, callback: StringCallback): void;
+ * (path: PathOrFileDescriptor, options: (ObjectEncodingOptions & { flag?: string | undefined } & import("events").Abortable) | BufferEncoding | undefined | null, callback: StringOrBufferCallback): void;
+ * (path: PathOrFileDescriptor, callback: BufferCallback): void;
+ * }} ReadFile
+ */
+
+/**
+ * @typedef {ObjectEncodingOptions | BufferEncoding | undefined | null} EncodingOption
+ */
+
+/**
+ * @typedef {'buffer'| { encoding: 'buffer' }} BufferEncodingOption
+ */
+
+/**
+ * @typedef {{
+ * (path: PathOrFileDescriptor, options?: { encoding?: null | undefined, flag?: string | undefined } | null): Buffer;
+ * (path: PathOrFileDescriptor, options: { encoding: BufferEncoding, flag?: string | undefined } | BufferEncoding): string;
+ * (path: PathOrFileDescriptor, options?: (ObjectEncodingOptions & { flag?: string | undefined }) | BufferEncoding | null): string | Buffer;
+ * }} ReadFileSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | undefined | null, callback: ReaddirStringCallback): void;
+ * (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer', callback: ReaddirBufferCallback): void;
+ * (path: PathLike, callback: ReaddirStringCallback): void;
+ * (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: ReaddirStringOrBufferCallback): void;
+ * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: ReaddirDirentCallback): void;
+ * }} Readdir
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | null): string[];
+ * (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer'): Buffer[];
+ * (path: PathLike, options?: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | null): string[] | Buffer[];
+ * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }): Dirent[];
+ * }} ReaddirSync
+
+ /**
+ * @typedef {function(PathOrFileDescriptor, ReadJsonCallback): void} ReadJson
+ */
+
+/**
+ * @typedef {function(PathOrFileDescriptor): JsonObject} ReadJsonSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options: EncodingOption, callback: StringCallback): void;
+ * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void;
+ * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void;
+ * (path: PathLike, callback: StringCallback): void;
+ * }} Readlink
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: EncodingOption): string;
+ * (path: PathLike, options: BufferEncodingOption): Buffer;
+ * (path: PathLike, options?: EncodingOption): string | Buffer;
+ * }} ReadlinkSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, callback: StatsCallback): void;
+ * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void;
+ * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void;
+ * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void;
+ * }} LStat
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: undefined): IStats;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+ * (path: PathLike,  options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats;
+ * (path: PathLike,  options?: StatSyncOptions): IStats | IBigIntStats | undefined;
+ * }} LStatSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, callback: StatsCallback): void;
+ * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void;
+ * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void;
+ * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void;
+ * }} Stat
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: undefined): IStats;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+ * (path: PathLike,  options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats;
+ * (path: PathLike,  options?: StatSyncOptions): IStats | IBigIntStats | undefined;
+ * }} StatSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options: EncodingOption, callback: StringCallback): void;
+ * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void;
+ * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void;
+ * (path: PathLike, callback: StringCallback): void;
+ * }} RealPath
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: EncodingOption): string;
+ * (path: PathLike, options: BufferEncodingOption): Buffer;
+ * (path: PathLike, options?: EncodingOption): string | Buffer;
+ * }} RealPathSync
+ */
+
+/**
+ * @typedef {Object} FileSystem
+ * @property {ReadFile} readFile
+ * @property {Readdir} readdir
+ * @property {ReadJson=} readJson
+ * @property {Readlink} readlink
+ * @property {LStat=} lstat
+ * @property {Stat} stat
+ * @property {RealPath=} realpath
+ */
+
+/**
+ * @typedef {Object} SyncFileSystem
+ * @property {ReadFileSync} readFileSync
+ * @property {ReaddirSync} readdirSync
+ * @property {ReadJsonSync=} readJsonSync
+ * @property {ReadlinkSync} readlinkSync
+ * @property {LStatSync=} lstatSync
+ * @property {StatSync} statSync
+ * @property {RealPathSync=} realpathSync
+ */
+
+/**
+ * @typedef {Object} ParsedIdentifier
+ * @property {string} request
+ * @property {string} query
+ * @property {string} fragment
+ * @property {boolean} directory
+ * @property {boolean} module
+ * @property {boolean} file
+ * @property {boolean} internal
+ */
+
+/** @typedef {string | number | boolean | null} JsonPrimitive */
+/** @typedef {JsonValue[]} JsonArray */
+/** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */
+/** @typedef {{[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined}} JsonObject */
+
+/**
+ * @typedef {Object} BaseResolveRequest
+ * @property {string | false} path
+ * @property {object=} context
+ * @property {string=} descriptionFilePath
+ * @property {string=} descriptionFileRoot
+ * @property {JsonObject=} descriptionFileData
+ * @property {string=} relativePath
+ * @property {boolean=} ignoreSymlinks
+ * @property {boolean=} fullySpecified
+ * @property {string=} __innerRequest
+ * @property {string=} __innerRequest_request
+ * @property {string=} __innerRequest_relativePath
+ */
+
+/** @typedef {BaseResolveRequest & Partial<ParsedIdentifier>} ResolveRequest */
+
+/**
+ * String with special formatting
+ * @typedef {string} StackEntry
+ */
+
+/**
+ * @template T
+ * @typedef {{ add: (item: T) => void }} WriteOnlySet
+ */
+
+/** @typedef {(function (ResolveRequest): void)} ResolveContextYield */
+
+/**
+ * Resolve context
+ * @typedef {Object} ResolveContext
+ * @property {WriteOnlySet<string>=} contextDependencies
+ * @property {WriteOnlySet<string>=} fileDependencies files that was found on file system
+ * @property {WriteOnlySet<string>=} missingDependencies dependencies that was not found on file system
+ * @property {Set<StackEntry>=} stack set of hooks' calls. For instance, `resolve → parsedResolve → describedResolve`,
+ * @property {(function(string): void)=} log log function
+ * @property {ResolveContextYield=} yield yield result, if provided plugins can return several results
+ */
+
+/** @typedef {AsyncSeriesBailHook<[ResolveRequest, ResolveContext], ResolveRequest | null>} ResolveStepHook */
+
+/**
+ * @typedef {Object} KnownHooks
+ * @property {SyncHook<[ResolveStepHook, ResolveRequest], void>} resolveStep
+ * @property {SyncHook<[ResolveRequest, Error]>} noResolve
+ * @property {ResolveStepHook} resolve
+ * @property {AsyncSeriesHook<[ResolveRequest, ResolveContext]>} result
+ */
+
+/**
+ * @typedef {{[key: string]: ResolveStepHook}} EnsuredHooks
+ */
+
+/**
+ * @param {string} str input string
+ * @returns {string} in camel case
+ */
+function toCamelCase(str) {
+	return str.replace(/-([a-z])/g, str => str.slice(1).toUpperCase());
+}
+
+class Resolver {
+	/**
+	 * @param {ResolveStepHook} hook hook
+	 * @param {ResolveRequest} request request
+	 * @returns {StackEntry} stack entry
+	 */
+	static createStackEntry(hook, request) {
+		return (
+			hook.name +
+			": (" +
+			request.path +
+			") " +
+			(request.request || "") +
+			(request.query || "") +
+			(request.fragment || "") +
+			(request.directory ? " directory" : "") +
+			(request.module ? " module" : "")
+		);
+	}
+
+	/**
+	 * @param {FileSystem} fileSystem a filesystem
+	 * @param {ResolveOptions} options options
+	 */
+	constructor(fileSystem, options) {
+		this.fileSystem = fileSystem;
+		this.options = options;
+		/** @type {KnownHooks} */
+		this.hooks = {
+			resolveStep: new SyncHook(["hook", "request"], "resolveStep"),
+			noResolve: new SyncHook(["request", "error"], "noResolve"),
+			resolve: new AsyncSeriesBailHook(
+				["request", "resolveContext"],
+				"resolve"
+			),
+			result: new AsyncSeriesHook(["result", "resolveContext"], "result")
+		};
+	}
+
+	/**
+	 * @param {string | ResolveStepHook} name hook name or hook itself
+	 * @returns {ResolveStepHook} the hook
+	 */
+	ensureHook(name) {
+		if (typeof name !== "string") {
+			return name;
+		}
+		name = toCamelCase(name);
+		if (/^before/.test(name)) {
+			return /** @type {ResolveStepHook} */ (
+				this.ensureHook(name[6].toLowerCase() + name.slice(7)).withOptions({
+					stage: -10
+				})
+			);
+		}
+		if (/^after/.test(name)) {
+			return /** @type {ResolveStepHook} */ (
+				this.ensureHook(name[5].toLowerCase() + name.slice(6)).withOptions({
+					stage: 10
+				})
+			);
+		}
+		/** @type {ResolveStepHook} */
+		const hook = /** @type {KnownHooks & EnsuredHooks} */ (this.hooks)[name];
+		if (!hook) {
+			/** @type {KnownHooks & EnsuredHooks} */
+			(this.hooks)[name] = new AsyncSeriesBailHook(
+				["request", "resolveContext"],
+				name
+			);
+
+			return /** @type {KnownHooks & EnsuredHooks} */ (this.hooks)[name];
+		}
+		return hook;
+	}
+
+	/**
+	 * @param {string | ResolveStepHook} name hook name or hook itself
+	 * @returns {ResolveStepHook} the hook
+	 */
+	getHook(name) {
+		if (typeof name !== "string") {
+			return name;
+		}
+		name = toCamelCase(name);
+		if (/^before/.test(name)) {
+			return /** @type {ResolveStepHook} */ (
+				this.getHook(name[6].toLowerCase() + name.slice(7)).withOptions({
+					stage: -10
+				})
+			);
+		}
+		if (/^after/.test(name)) {
+			return /** @type {ResolveStepHook} */ (
+				this.getHook(name[5].toLowerCase() + name.slice(6)).withOptions({
+					stage: 10
+				})
+			);
+		}
+		/** @type {ResolveStepHook} */
+		const hook = /** @type {KnownHooks & EnsuredHooks} */ (this.hooks)[name];
+		if (!hook) {
+			throw new Error(`Hook ${name} doesn't exist`);
+		}
+		return hook;
+	}
+
+	/**
+	 * @param {object} context context information object
+	 * @param {string} path context path
+	 * @param {string} request request string
+	 * @returns {string | false} result
+	 */
+	resolveSync(context, path, request) {
+		/** @type {Error | null | undefined} */
+		let err = undefined;
+		/** @type {string | false | undefined} */
+		let result = undefined;
+		let sync = false;
+		this.resolve(context, path, request, {}, (e, r) => {
+			err = e;
+			result = r;
+			sync = true;
+		});
+		if (!sync) {
+			throw new Error(
+				"Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!"
+			);
+		}
+		if (err) throw err;
+		if (result === undefined) throw new Error("No result");
+		return result;
+	}
+
+	/**
+	 * @param {object} context context information object
+	 * @param {string} path context path
+	 * @param {string} request request string
+	 * @param {ResolveContext} resolveContext resolve context
+	 * @param {ResolveCallback} callback callback function
+	 * @returns {void}
+	 */
+	resolve(context, path, request, resolveContext, callback) {
+		if (!context || typeof context !== "object")
+			return callback(new Error("context argument is not an object"));
+		if (typeof path !== "string")
+			return callback(new Error("path argument is not a string"));
+		if (typeof request !== "string")
+			return callback(new Error("request argument is not a string"));
+		if (!resolveContext)
+			return callback(new Error("resolveContext argument is not set"));
+
+		/** @type {ResolveRequest} */
+		const obj = {
+			context: context,
+			path: path,
+			request: request
+		};
+
+		/** @type {ResolveContextYield | undefined} */
+		let yield_;
+		let yieldCalled = false;
+		/** @type {ResolveContextYield | undefined} */
+		let finishYield;
+		if (typeof resolveContext.yield === "function") {
+			const old = resolveContext.yield;
+			/**
+			 * @param {ResolveRequest} obj object
+			 */
+			yield_ = obj => {
+				old(obj);
+				yieldCalled = true;
+			};
+			/**
+			 * @param {ResolveRequest} result result
+			 * @returns {void}
+			 */
+			finishYield = result => {
+				if (result) {
+					/** @type {ResolveContextYield} */ (yield_)(result);
+				}
+				callback(null);
+			};
+		}
+
+		const message = `resolve '${request}' in '${path}'`;
+
+		/**
+		 * @param {ResolveRequest} result result
+		 * @returns {void}
+		 */
+		const finishResolved = result => {
+			return callback(
+				null,
+				result.path === false
+					? false
+					: `${result.path.replace(/#/g, "\0#")}${
+							result.query ? result.query.replace(/#/g, "\0#") : ""
+					  }${result.fragment || ""}`,
+				result
+			);
+		};
+
+		/**
+		 * @param {string[]} log logs
+		 * @returns {void}
+		 */
+		const finishWithoutResolve = log => {
+			/**
+			 * @type {ErrorWithDetail}
+			 */
+			const error = new Error("Can't " + message);
+			error.details = log.join("\n");
+			this.hooks.noResolve.call(obj, error);
+			return callback(error);
+		};
+
+		if (resolveContext.log) {
+			// We need log anyway to capture it in case of an error
+			const parentLog = resolveContext.log;
+			/** @type {string[]} */
+			const log = [];
+			return this.doResolve(
+				this.hooks.resolve,
+				obj,
+				message,
+				{
+					log: msg => {
+						parentLog(msg);
+						log.push(msg);
+					},
+					yield: yield_,
+					fileDependencies: resolveContext.fileDependencies,
+					contextDependencies: resolveContext.contextDependencies,
+					missingDependencies: resolveContext.missingDependencies,
+					stack: resolveContext.stack
+				},
+				(err, result) => {
+					if (err) return callback(err);
+
+					if (yieldCalled || (result && yield_)) {
+						return /** @type {ResolveContextYield} */ (finishYield)(
+							/** @type {ResolveRequest} */ (result)
+						);
+					}
+
+					if (result) return finishResolved(result);
+
+					return finishWithoutResolve(log);
+				}
+			);
+		} else {
+			// Try to resolve assuming there is no error
+			// We don't log stuff in this case
+			return this.doResolve(
+				this.hooks.resolve,
+				obj,
+				message,
+				{
+					log: undefined,
+					yield: yield_,
+					fileDependencies: resolveContext.fileDependencies,
+					contextDependencies: resolveContext.contextDependencies,
+					missingDependencies: resolveContext.missingDependencies,
+					stack: resolveContext.stack
+				},
+				(err, result) => {
+					if (err) return callback(err);
+
+					if (yieldCalled || (result && yield_)) {
+						return /** @type {ResolveContextYield} */ (finishYield)(
+							/** @type {ResolveRequest} */ (result)
+						);
+					}
+
+					if (result) return finishResolved(result);
+
+					// log is missing for the error details
+					// so we redo the resolving for the log info
+					// this is more expensive to the success case
+					// is assumed by default
+					/** @type {string[]} */
+					const log = [];
+
+					return this.doResolve(
+						this.hooks.resolve,
+						obj,
+						message,
+						{
+							log: msg => log.push(msg),
+							yield: yield_,
+							stack: resolveContext.stack
+						},
+						(err, result) => {
+							if (err) return callback(err);
+
+							// In a case that there is a race condition and yield will be called
+							if (yieldCalled || (result && yield_)) {
+								return /** @type {ResolveContextYield} */ (finishYield)(
+									/** @type {ResolveRequest} */ (result)
+								);
+							}
+
+							return finishWithoutResolve(log);
+						}
+					);
+				}
+			);
+		}
+	}
+
+	/**
+	 * @param {ResolveStepHook} hook hook
+	 * @param {ResolveRequest} request request
+	 * @param {null|string} message string
+	 * @param {ResolveContext} resolveContext resolver context
+	 * @param {(err?: null|Error, result?: ResolveRequest) => void} callback callback
+	 * @returns {void}
+	 */
+	doResolve(hook, request, message, resolveContext, callback) {
+		const stackEntry = Resolver.createStackEntry(hook, request);
+
+		/** @type {Set<string> | undefined} */
+		let newStack;
+		if (resolveContext.stack) {
+			newStack = new Set(resolveContext.stack);
+			if (resolveContext.stack.has(stackEntry)) {
+				/**
+				 * Prevent recursion
+				 * @type {Error & {recursion?: boolean}}
+				 */
+				const recursionError = new Error(
+					"Recursion in resolving\nStack:\n  " +
+						Array.from(newStack).join("\n  ")
+				);
+				recursionError.recursion = true;
+				if (resolveContext.log)
+					resolveContext.log("abort resolving because of recursion");
+				return callback(recursionError);
+			}
+			newStack.add(stackEntry);
+		} else {
+			// creating a set with new Set([item])
+			// allocates a new array that has to be garbage collected
+			// this is an EXTREMELY hot path, so let's avoid it
+			newStack = new Set();
+			newStack.add(stackEntry);
+		}
+		this.hooks.resolveStep.call(hook, request);
+
+		if (hook.isUsed()) {
+			const innerContext = createInnerContext(
+				{
+					log: resolveContext.log,
+					yield: resolveContext.yield,
+					fileDependencies: resolveContext.fileDependencies,
+					contextDependencies: resolveContext.contextDependencies,
+					missingDependencies: resolveContext.missingDependencies,
+					stack: newStack
+				},
+				message
+			);
+			return hook.callAsync(request, innerContext, (err, result) => {
+				if (err) return callback(err);
+				if (result) return callback(null, result);
+				callback();
+			});
+		} else {
+			callback();
+		}
+	}
+
+	/**
+	 * @param {string} identifier identifier
+	 * @returns {ParsedIdentifier} parsed identifier
+	 */
+	parse(identifier) {
+		const part = {
+			request: "",
+			query: "",
+			fragment: "",
+			module: false,
+			directory: false,
+			file: false,
+			internal: false
+		};
+
+		const parsedIdentifier = parseIdentifier(identifier);
+
+		if (!parsedIdentifier) return part;
+
+		[part.request, part.query, part.fragment] = parsedIdentifier;
+
+		if (part.request.length > 0) {
+			part.internal = this.isPrivate(identifier);
+			part.module = this.isModule(part.request);
+			part.directory = this.isDirectory(part.request);
+			if (part.directory) {
+				part.request = part.request.slice(0, -1);
+			}
+		}
+
+		return part;
+	}
+
+	/**
+	 * @param {string} path path
+	 * @returns {boolean} true, if the path is a module
+	 */
+	isModule(path) {
+		return getType(path) === PathType.Normal;
+	}
+
+	/**
+	 * @param {string} path path
+	 * @returns {boolean} true, if the path is private
+	 */
+	isPrivate(path) {
+		return getType(path) === PathType.Internal;
+	}
+
+	/**
+	 * @param {string} path a path
+	 * @returns {boolean} true, if the path is a directory path
+	 */
+	isDirectory(path) {
+		return path.endsWith("/");
+	}
+
+	/**
+	 * @param {string} path path
+	 * @param {string} request request
+	 * @returns {string} joined path
+	 */
+	join(path, request) {
+		return join(path, request);
+	}
+
+	/**
+	 * @param {string} path path
+	 * @returns {string} normalized path
+	 */
+	normalize(path) {
+		return normalize(path);
+	}
+}
+
+module.exports = Resolver;
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ResolverFactory.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ResolverFactory.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ResolverFactory.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,728 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const versions = require("process").versions;
+const Resolver = require("./Resolver");
+const { getType, PathType } = require("./util/path");
+
+const SyncAsyncFileSystemDecorator = require("./SyncAsyncFileSystemDecorator");
+
+const AliasFieldPlugin = require("./AliasFieldPlugin");
+const AliasPlugin = require("./AliasPlugin");
+const AppendPlugin = require("./AppendPlugin");
+const ConditionalPlugin = require("./ConditionalPlugin");
+const DescriptionFilePlugin = require("./DescriptionFilePlugin");
+const DirectoryExistsPlugin = require("./DirectoryExistsPlugin");
+const ExportsFieldPlugin = require("./ExportsFieldPlugin");
+const ExtensionAliasPlugin = require("./ExtensionAliasPlugin");
+const FileExistsPlugin = require("./FileExistsPlugin");
+const ImportsFieldPlugin = require("./ImportsFieldPlugin");
+const JoinRequestPartPlugin = require("./JoinRequestPartPlugin");
+const JoinRequestPlugin = require("./JoinRequestPlugin");
+const MainFieldPlugin = require("./MainFieldPlugin");
+const ModulesInHierarchicalDirectoriesPlugin = require("./ModulesInHierarchicalDirectoriesPlugin");
+const ModulesInRootPlugin = require("./ModulesInRootPlugin");
+const NextPlugin = require("./NextPlugin");
+const ParsePlugin = require("./ParsePlugin");
+const PnpPlugin = require("./PnpPlugin");
+const RestrictionsPlugin = require("./RestrictionsPlugin");
+const ResultPlugin = require("./ResultPlugin");
+const RootsPlugin = require("./RootsPlugin");
+const SelfReferencePlugin = require("./SelfReferencePlugin");
+const SymlinkPlugin = require("./SymlinkPlugin");
+const TryNextPlugin = require("./TryNextPlugin");
+const UnsafeCachePlugin = require("./UnsafeCachePlugin");
+const UseFilePlugin = require("./UseFilePlugin");
+
+/** @typedef {import("./AliasPlugin").AliasOption} AliasOptionEntry */
+/** @typedef {import("./ExtensionAliasPlugin").ExtensionAliasOption} ExtensionAliasOption */
+/** @typedef {import("./PnpPlugin").PnpApiImpl} PnpApi */
+/** @typedef {import("./Resolver").EnsuredHooks} EnsuredHooks */
+/** @typedef {import("./Resolver").FileSystem} FileSystem */
+/** @typedef {import("./Resolver").KnownHooks} KnownHooks */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
+
+/** @typedef {string|string[]|false} AliasOptionNewRequest */
+/** @typedef {{[k: string]: AliasOptionNewRequest}} AliasOptions */
+/** @typedef {{[k: string]: string|string[] }} ExtensionAliasOptions */
+/** @typedef {false | 0 | "" | null | undefined} Falsy */
+/** @typedef {{apply: function(Resolver): void} | (function(this: Resolver, Resolver): void) | Falsy} Plugin */
+
+/**
+ * @typedef {Object} UserResolveOptions
+ * @property {(AliasOptions | AliasOptionEntry[])=} alias A list of module alias configurations or an object which maps key to value
+ * @property {(AliasOptions | AliasOptionEntry[])=} fallback A list of module alias configurations or an object which maps key to value, applied only after modules option
+ * @property {ExtensionAliasOptions=} extensionAlias An object which maps extension to extension aliases
+ * @property {(string | string[])[]=} aliasFields A list of alias fields in description files
+ * @property {(function(ResolveRequest): boolean)=} cachePredicate A function which decides whether a request should be cached or not. An object is passed with at least `path` and `request` properties.
+ * @property {boolean=} cacheWithContext Whether or not the unsafeCache should include request context as part of the cache key.
+ * @property {string[]=} descriptionFiles A list of description files to read from
+ * @property {string[]=} conditionNames A list of exports field condition names.
+ * @property {boolean=} enforceExtension Enforce that a extension from extensions must be used
+ * @property {(string | string[])[]=} exportsFields A list of exports fields in description files
+ * @property {(string | string[])[]=} importsFields A list of imports fields in description files
+ * @property {string[]=} extensions A list of extensions which should be tried for files
+ * @property {FileSystem} fileSystem The file system which should be used
+ * @property {(object | boolean)=} unsafeCache Use this cache object to unsafely cache the successful requests
+ * @property {boolean=} symlinks Resolve symlinks to their symlinked location
+ * @property {Resolver=} resolver A prepared Resolver to which the plugins are attached
+ * @property {string[] | string=} modules A list of directories to resolve modules from, can be absolute path or folder name
+ * @property {(string | string[] | {name: string | string[], forceRelative: boolean})[]=} mainFields A list of main fields in description files
+ * @property {string[]=} mainFiles  A list of main files in directories
+ * @property {Plugin[]=} plugins A list of additional resolve plugins which should be applied
+ * @property {PnpApi | null=} pnpApi A PnP API that should be used - null is "never", undefined is "auto"
+ * @property {string[]=} roots A list of root paths
+ * @property {boolean=} fullySpecified The request is already fully specified and no extensions or directories are resolved for it
+ * @property {boolean=} resolveToContext Resolve to a context instead of a file
+ * @property {(string|RegExp)[]=} restrictions A list of resolve restrictions
+ * @property {boolean=} useSyncFileSystemCalls Use only the sync constraints of the file system calls
+ * @property {boolean=} preferRelative Prefer to resolve module requests as relative requests before falling back to modules
+ * @property {boolean=} preferAbsolute Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots
+ */
+
+/**
+ * @typedef {Object} ResolveOptions
+ * @property {AliasOptionEntry[]} alias
+ * @property {AliasOptionEntry[]} fallback
+ * @property {Set<string | string[]>} aliasFields
+ * @property {ExtensionAliasOption[]} extensionAlias
+ * @property {(function(ResolveRequest): boolean)} cachePredicate
+ * @property {boolean} cacheWithContext
+ * @property {Set<string>} conditionNames A list of exports field condition names.
+ * @property {string[]} descriptionFiles
+ * @property {boolean} enforceExtension
+ * @property {Set<string | string[]>} exportsFields
+ * @property {Set<string | string[]>} importsFields
+ * @property {Set<string>} extensions
+ * @property {FileSystem} fileSystem
+ * @property {object | false} unsafeCache
+ * @property {boolean} symlinks
+ * @property {Resolver=} resolver
+ * @property {Array<string | string[]>} modules
+ * @property {{name: string[], forceRelative: boolean}[]} mainFields
+ * @property {Set<string>} mainFiles
+ * @property {Plugin[]} plugins
+ * @property {PnpApi | null} pnpApi
+ * @property {Set<string>} roots
+ * @property {boolean} fullySpecified
+ * @property {boolean} resolveToContext
+ * @property {Set<string|RegExp>} restrictions
+ * @property {boolean} preferRelative
+ * @property {boolean} preferAbsolute
+ */
+
+/**
+ * @param {PnpApi | null=} option option
+ * @returns {PnpApi | null} processed option
+ */
+function processPnpApiOption(option) {
+	if (
+		option === undefined &&
+		/** @type {NodeJS.ProcessVersions & {pnp: string}} */ versions.pnp
+	) {
+		const _findPnpApi =
+			/** @type {function(string): PnpApi | null}} */
+			(
+				// @ts-ignore
+				require("module").findPnpApi
+			);
+
+		if (_findPnpApi) {
+			return {
+				resolveToUnqualified(request, issuer, opts) {
+					const pnpapi = _findPnpApi(issuer);
+
+					if (!pnpapi) {
+						// Issuer isn't managed by PnP
+						return null;
+					}
+
+					return pnpapi.resolveToUnqualified(request, issuer, opts);
+				}
+			};
+		}
+	}
+
+	return option || null;
+}
+
+/**
+ * @param {AliasOptions | AliasOptionEntry[] | undefined} alias alias
+ * @returns {AliasOptionEntry[]} normalized aliases
+ */
+function normalizeAlias(alias) {
+	return typeof alias === "object" && !Array.isArray(alias) && alias !== null
+		? Object.keys(alias).map(key => {
+				/** @type {AliasOptionEntry} */
+				const obj = { name: key, onlyModule: false, alias: alias[key] };
+
+				if (/\$$/.test(key)) {
+					obj.onlyModule = true;
+					obj.name = key.slice(0, -1);
+				}
+
+				return obj;
+		  })
+		: /** @type {Array<AliasOptionEntry>} */ (alias) || [];
+}
+
+/**
+ * @param {UserResolveOptions} options input options
+ * @returns {ResolveOptions} output options
+ */
+function createOptions(options) {
+	const mainFieldsSet = new Set(options.mainFields || ["main"]);
+	/** @type {ResolveOptions["mainFields"]} */
+	const mainFields = [];
+
+	for (const item of mainFieldsSet) {
+		if (typeof item === "string") {
+			mainFields.push({
+				name: [item],
+				forceRelative: true
+			});
+		} else if (Array.isArray(item)) {
+			mainFields.push({
+				name: item,
+				forceRelative: true
+			});
+		} else {
+			mainFields.push({
+				name: Array.isArray(item.name) ? item.name : [item.name],
+				forceRelative: item.forceRelative
+			});
+		}
+	}
+
+	return {
+		alias: normalizeAlias(options.alias),
+		fallback: normalizeAlias(options.fallback),
+		aliasFields: new Set(options.aliasFields),
+		cachePredicate:
+			options.cachePredicate ||
+			function () {
+				return true;
+			},
+		cacheWithContext:
+			typeof options.cacheWithContext !== "undefined"
+				? options.cacheWithContext
+				: true,
+		exportsFields: new Set(options.exportsFields || ["exports"]),
+		importsFields: new Set(options.importsFields || ["imports"]),
+		conditionNames: new Set(options.conditionNames),
+		descriptionFiles: Array.from(
+			new Set(options.descriptionFiles || ["package.json"])
+		),
+		enforceExtension:
+			options.enforceExtension === undefined
+				? options.extensions && options.extensions.includes("")
+					? true
+					: false
+				: options.enforceExtension,
+		extensions: new Set(options.extensions || [".js", ".json", ".node"]),
+		extensionAlias: options.extensionAlias
+			? Object.keys(options.extensionAlias).map(k => ({
+					extension: k,
+					alias: /** @type {ExtensionAliasOptions} */ (options.extensionAlias)[
+						k
+					]
+			  }))
+			: [],
+		fileSystem: options.useSyncFileSystemCalls
+			? new SyncAsyncFileSystemDecorator(
+					/** @type {SyncFileSystem} */ (
+						/** @type {unknown} */ (options.fileSystem)
+					)
+			  )
+			: options.fileSystem,
+		unsafeCache:
+			options.unsafeCache && typeof options.unsafeCache !== "object"
+				? {}
+				: options.unsafeCache || false,
+		symlinks: typeof options.symlinks !== "undefined" ? options.symlinks : true,
+		resolver: options.resolver,
+		modules: mergeFilteredToArray(
+			Array.isArray(options.modules)
+				? options.modules
+				: options.modules
+				? [options.modules]
+				: ["node_modules"],
+			item => {
+				const type = getType(item);
+				return type === PathType.Normal || type === PathType.Relative;
+			}
+		),
+		mainFields,
+		mainFiles: new Set(options.mainFiles || ["index"]),
+		plugins: options.plugins || [],
+		pnpApi: processPnpApiOption(options.pnpApi),
+		roots: new Set(options.roots || undefined),
+		fullySpecified: options.fullySpecified || false,
+		resolveToContext: options.resolveToContext || false,
+		preferRelative: options.preferRelative || false,
+		preferAbsolute: options.preferAbsolute || false,
+		restrictions: new Set(options.restrictions)
+	};
+}
+
+/**
+ * @param {UserResolveOptions} options resolve options
+ * @returns {Resolver} created resolver
+ */
+exports.createResolver = function (options) {
+	const normalizedOptions = createOptions(options);
+
+	const {
+		alias,
+		fallback,
+		aliasFields,
+		cachePredicate,
+		cacheWithContext,
+		conditionNames,
+		descriptionFiles,
+		enforceExtension,
+		exportsFields,
+		extensionAlias,
+		importsFields,
+		extensions,
+		fileSystem,
+		fullySpecified,
+		mainFields,
+		mainFiles,
+		modules,
+		plugins: userPlugins,
+		pnpApi,
+		resolveToContext,
+		preferRelative,
+		preferAbsolute,
+		symlinks,
+		unsafeCache,
+		resolver: customResolver,
+		restrictions,
+		roots
+	} = normalizedOptions;
+
+	const plugins = userPlugins.slice();
+
+	const resolver = customResolver
+		? customResolver
+		: new Resolver(fileSystem, normalizedOptions);
+
+	//// pipeline ////
+
+	resolver.ensureHook("resolve");
+	resolver.ensureHook("internalResolve");
+	resolver.ensureHook("newInternalResolve");
+	resolver.ensureHook("parsedResolve");
+	resolver.ensureHook("describedResolve");
+	resolver.ensureHook("rawResolve");
+	resolver.ensureHook("normalResolve");
+	resolver.ensureHook("internal");
+	resolver.ensureHook("rawModule");
+	resolver.ensureHook("alternateRawModule");
+	resolver.ensureHook("module");
+	resolver.ensureHook("resolveAsModule");
+	resolver.ensureHook("undescribedResolveInPackage");
+	resolver.ensureHook("resolveInPackage");
+	resolver.ensureHook("resolveInExistingDirectory");
+	resolver.ensureHook("relative");
+	resolver.ensureHook("describedRelative");
+	resolver.ensureHook("directory");
+	resolver.ensureHook("undescribedExistingDirectory");
+	resolver.ensureHook("existingDirectory");
+	resolver.ensureHook("undescribedRawFile");
+	resolver.ensureHook("rawFile");
+	resolver.ensureHook("file");
+	resolver.ensureHook("finalFile");
+	resolver.ensureHook("existingFile");
+	resolver.ensureHook("resolved");
+
+	// TODO remove in next major
+	// cspell:word Interal
+	// Backward-compat
+	// @ts-ignore
+	resolver.hooks.newInteralResolve = resolver.hooks.newInternalResolve;
+
+	// resolve
+	for (const { source, resolveOptions } of [
+		{ source: "resolve", resolveOptions: { fullySpecified } },
+		{ source: "internal-resolve", resolveOptions: { fullySpecified: false } }
+	]) {
+		if (unsafeCache) {
+			plugins.push(
+				new UnsafeCachePlugin(
+					source,
+					cachePredicate,
+					/** @type {import("./UnsafeCachePlugin").Cache} */ (unsafeCache),
+					cacheWithContext,
+					`new-${source}`
+				)
+			);
+			plugins.push(
+				new ParsePlugin(`new-${source}`, resolveOptions, "parsed-resolve")
+			);
+		} else {
+			plugins.push(new ParsePlugin(source, resolveOptions, "parsed-resolve"));
+		}
+	}
+
+	// parsed-resolve
+	plugins.push(
+		new DescriptionFilePlugin(
+			"parsed-resolve",
+			descriptionFiles,
+			false,
+			"described-resolve"
+		)
+	);
+	plugins.push(new NextPlugin("after-parsed-resolve", "described-resolve"));
+
+	// described-resolve
+	plugins.push(new NextPlugin("described-resolve", "raw-resolve"));
+	if (fallback.length > 0) {
+		plugins.push(
+			new AliasPlugin("described-resolve", fallback, "internal-resolve")
+		);
+	}
+
+	// raw-resolve
+	if (alias.length > 0) {
+		plugins.push(new AliasPlugin("raw-resolve", alias, "internal-resolve"));
+	}
+	aliasFields.forEach(item => {
+		plugins.push(new AliasFieldPlugin("raw-resolve", item, "internal-resolve"));
+	});
+	extensionAlias.forEach(item =>
+		plugins.push(
+			new ExtensionAliasPlugin("raw-resolve", item, "normal-resolve")
+		)
+	);
+	plugins.push(new NextPlugin("raw-resolve", "normal-resolve"));
+
+	// normal-resolve
+	if (preferRelative) {
+		plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
+	}
+	plugins.push(
+		new ConditionalPlugin(
+			"after-normal-resolve",
+			{ module: true },
+			"resolve as module",
+			false,
+			"raw-module"
+		)
+	);
+	plugins.push(
+		new ConditionalPlugin(
+			"after-normal-resolve",
+			{ internal: true },
+			"resolve as internal import",
+			false,
+			"internal"
+		)
+	);
+	if (preferAbsolute) {
+		plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
+	}
+	if (roots.size > 0) {
+		plugins.push(new RootsPlugin("after-normal-resolve", roots, "relative"));
+	}
+	if (!preferRelative && !preferAbsolute) {
+		plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
+	}
+
+	// internal
+	importsFields.forEach(importsField => {
+		plugins.push(
+			new ImportsFieldPlugin(
+				"internal",
+				conditionNames,
+				importsField,
+				"relative",
+				"internal-resolve"
+			)
+		);
+	});
+
+	// raw-module
+	exportsFields.forEach(exportsField => {
+		plugins.push(
+			new SelfReferencePlugin("raw-module", exportsField, "resolve-as-module")
+		);
+	});
+	modules.forEach(item => {
+		if (Array.isArray(item)) {
+			if (item.includes("node_modules") && pnpApi) {
+				plugins.push(
+					new ModulesInHierarchicalDirectoriesPlugin(
+						"raw-module",
+						item.filter(i => i !== "node_modules"),
+						"module"
+					)
+				);
+				plugins.push(
+					new PnpPlugin(
+						"raw-module",
+						pnpApi,
+						"undescribed-resolve-in-package",
+						"alternate-raw-module"
+					)
+				);
+
+				plugins.push(
+					new ModulesInHierarchicalDirectoriesPlugin(
+						"alternate-raw-module",
+						["node_modules"],
+						"module"
+					)
+				);
+			} else {
+				plugins.push(
+					new ModulesInHierarchicalDirectoriesPlugin(
+						"raw-module",
+						item,
+						"module"
+					)
+				);
+			}
+		} else {
+			plugins.push(new ModulesInRootPlugin("raw-module", item, "module"));
+		}
+	});
+
+	// module
+	plugins.push(new JoinRequestPartPlugin("module", "resolve-as-module"));
+
+	// resolve-as-module
+	if (!resolveToContext) {
+		plugins.push(
+			new ConditionalPlugin(
+				"resolve-as-module",
+				{ directory: false, request: "." },
+				"single file module",
+				true,
+				"undescribed-raw-file"
+			)
+		);
+	}
+	plugins.push(
+		new DirectoryExistsPlugin(
+			"resolve-as-module",
+			"undescribed-resolve-in-package"
+		)
+	);
+
+	// undescribed-resolve-in-package
+	plugins.push(
+		new DescriptionFilePlugin(
+			"undescribed-resolve-in-package",
+			descriptionFiles,
+			false,
+			"resolve-in-package"
+		)
+	);
+	plugins.push(
+		new NextPlugin("after-undescribed-resolve-in-package", "resolve-in-package")
+	);
+
+	// resolve-in-package
+	exportsFields.forEach(exportsField => {
+		plugins.push(
+			new ExportsFieldPlugin(
+				"resolve-in-package",
+				conditionNames,
+				exportsField,
+				"relative"
+			)
+		);
+	});
+	plugins.push(
+		new NextPlugin("resolve-in-package", "resolve-in-existing-directory")
+	);
+
+	// resolve-in-existing-directory
+	plugins.push(
+		new JoinRequestPlugin("resolve-in-existing-directory", "relative")
+	);
+
+	// relative
+	plugins.push(
+		new DescriptionFilePlugin(
+			"relative",
+			descriptionFiles,
+			true,
+			"described-relative"
+		)
+	);
+	plugins.push(new NextPlugin("after-relative", "described-relative"));
+
+	// described-relative
+	if (resolveToContext) {
+		plugins.push(new NextPlugin("described-relative", "directory"));
+	} else {
+		plugins.push(
+			new ConditionalPlugin(
+				"described-relative",
+				{ directory: false },
+				null,
+				true,
+				"raw-file"
+			)
+		);
+		plugins.push(
+			new ConditionalPlugin(
+				"described-relative",
+				{ fullySpecified: false },
+				"as directory",
+				true,
+				"directory"
+			)
+		);
+	}
+
+	// directory
+	plugins.push(
+		new DirectoryExistsPlugin("directory", "undescribed-existing-directory")
+	);
+
+	if (resolveToContext) {
+		// undescribed-existing-directory
+		plugins.push(new NextPlugin("undescribed-existing-directory", "resolved"));
+	} else {
+		// undescribed-existing-directory
+		plugins.push(
+			new DescriptionFilePlugin(
+				"undescribed-existing-directory",
+				descriptionFiles,
+				false,
+				"existing-directory"
+			)
+		);
+		mainFiles.forEach(item => {
+			plugins.push(
+				new UseFilePlugin(
+					"undescribed-existing-directory",
+					item,
+					"undescribed-raw-file"
+				)
+			);
+		});
+
+		// described-existing-directory
+		mainFields.forEach(item => {
+			plugins.push(
+				new MainFieldPlugin(
+					"existing-directory",
+					item,
+					"resolve-in-existing-directory"
+				)
+			);
+		});
+		mainFiles.forEach(item => {
+			plugins.push(
+				new UseFilePlugin("existing-directory", item, "undescribed-raw-file")
+			);
+		});
+
+		// undescribed-raw-file
+		plugins.push(
+			new DescriptionFilePlugin(
+				"undescribed-raw-file",
+				descriptionFiles,
+				true,
+				"raw-file"
+			)
+		);
+		plugins.push(new NextPlugin("after-undescribed-raw-file", "raw-file"));
+
+		// raw-file
+		plugins.push(
+			new ConditionalPlugin(
+				"raw-file",
+				{ fullySpecified: true },
+				null,
+				false,
+				"file"
+			)
+		);
+		if (!enforceExtension) {
+			plugins.push(new TryNextPlugin("raw-file", "no extension", "file"));
+		}
+		extensions.forEach(item => {
+			plugins.push(new AppendPlugin("raw-file", item, "file"));
+		});
+
+		// file
+		if (alias.length > 0)
+			plugins.push(new AliasPlugin("file", alias, "internal-resolve"));
+		aliasFields.forEach(item => {
+			plugins.push(new AliasFieldPlugin("file", item, "internal-resolve"));
+		});
+		plugins.push(new NextPlugin("file", "final-file"));
+
+		// final-file
+		plugins.push(new FileExistsPlugin("final-file", "existing-file"));
+
+		// existing-file
+		if (symlinks)
+			plugins.push(new SymlinkPlugin("existing-file", "existing-file"));
+		plugins.push(new NextPlugin("existing-file", "resolved"));
+	}
+
+	const resolved =
+		/** @type {KnownHooks & EnsuredHooks} */
+		(resolver.hooks).resolved;
+
+	// resolved
+	if (restrictions.size > 0) {
+		plugins.push(new RestrictionsPlugin(resolved, restrictions));
+	}
+
+	plugins.push(new ResultPlugin(resolved));
+
+	//// RESOLVER ////
+
+	for (const plugin of plugins) {
+		if (typeof plugin === "function") {
+			/** @type {function(this: Resolver, Resolver): void} */
+			(plugin).call(resolver, resolver);
+		} else if (plugin) {
+			plugin.apply(resolver);
+		}
+	}
+
+	return resolver;
+};
+
+/**
+ * Merging filtered elements
+ * @param {string[]} array source array
+ * @param {function(string): boolean} filter predicate
+ * @returns {Array<string | string[]>} merge result
+ */
+function mergeFilteredToArray(array, filter) {
+	/** @type {Array<string | string[]>} */
+	const result = [];
+	const set = new Set(array);
+
+	for (const item of set) {
+		if (filter(item)) {
+			const lastElement =
+				result.length > 0 ? result[result.length - 1] : undefined;
+			if (Array.isArray(lastElement)) {
+				lastElement.push(item);
+			} else {
+				result.push([item]);
+			}
+		} else {
+			result.push(item);
+		}
+	}
+
+	return result;
+}
Index: imaps-frontend/node_modules/enhanced-resolve/lib/RestrictionsPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/RestrictionsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/RestrictionsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,70 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+const slashCode = "/".charCodeAt(0);
+const backslashCode = "\\".charCodeAt(0);
+
+/**
+ * @param {string} path path
+ * @param {string} parent parent path
+ * @returns {boolean} true, if path is inside of parent
+ */
+const isInside = (path, parent) => {
+	if (!path.startsWith(parent)) return false;
+	if (path.length === parent.length) return true;
+	const charCode = path.charCodeAt(parent.length);
+	return charCode === slashCode || charCode === backslashCode;
+};
+
+module.exports = class RestrictionsPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {Set<string | RegExp>} restrictions restrictions
+	 */
+	constructor(source, restrictions) {
+		this.source = source;
+		this.restrictions = restrictions;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		resolver
+			.getHook(this.source)
+			.tapAsync("RestrictionsPlugin", (request, resolveContext, callback) => {
+				if (typeof request.path === "string") {
+					const path = request.path;
+					for (const rule of this.restrictions) {
+						if (typeof rule === "string") {
+							if (!isInside(path, rule)) {
+								if (resolveContext.log) {
+									resolveContext.log(
+										`${path} is not inside of the restriction ${rule}`
+									);
+								}
+								return callback(null, null);
+							}
+						} else if (!rule.test(path)) {
+							if (resolveContext.log) {
+								resolveContext.log(
+									`${path} doesn't match the restriction ${rule}`
+								);
+							}
+							return callback(null, null);
+						}
+					}
+				}
+
+				callback();
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/ResultPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/ResultPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/ResultPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,42 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class ResultPlugin {
+	/**
+	 * @param {ResolveStepHook} source source
+	 */
+	constructor(source) {
+		this.source = source;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		this.source.tapAsync(
+			"ResultPlugin",
+			(request, resolverContext, callback) => {
+				const obj = { ...request };
+				if (resolverContext.log)
+					resolverContext.log("reporting result " + obj.path);
+				resolver.hooks.result.callAsync(obj, resolverContext, err => {
+					if (err) return callback(err);
+					if (typeof resolverContext.yield === "function") {
+						resolverContext.yield(obj);
+						callback(null, null);
+					} else {
+						callback(null, obj);
+					}
+				});
+			}
+		);
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/RootsPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/RootsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/RootsPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,69 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+class RootsPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source hook
+	 * @param {Set<string>} roots roots
+	 * @param {string | ResolveStepHook} target target hook
+	 */
+	constructor(source, roots, target) {
+		this.roots = Array.from(roots);
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+
+		resolver
+			.getHook(this.source)
+			.tapAsync("RootsPlugin", (request, resolveContext, callback) => {
+				const req = request.request;
+				if (!req) return callback();
+				if (!req.startsWith("/")) return callback();
+
+				forEachBail(
+					this.roots,
+					/**
+					 * @param {string} root root
+					 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
+					 * @returns {void}
+					 */
+					(root, callback) => {
+						const path = resolver.join(root, req.slice(1));
+						/** @type {ResolveRequest} */
+						const obj = {
+							...request,
+							path,
+							relativePath: request.relativePath && path
+						};
+						resolver.doResolve(
+							target,
+							obj,
+							`root path ${root}`,
+							resolveContext,
+							callback
+						);
+					},
+					callback
+				);
+			});
+	}
+}
+
+module.exports = RootsPlugin;
Index: imaps-frontend/node_modules/enhanced-resolve/lib/SelfReferencePlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/SelfReferencePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/SelfReferencePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,82 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const DescriptionFileUtils = require("./DescriptionFileUtils");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonObject} JsonObject */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+const slashCode = "/".charCodeAt(0);
+
+module.exports = class SelfReferencePlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | string[]} fieldNamePath name path
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, fieldNamePath, target) {
+		this.source = source;
+		this.target = target;
+		this.fieldName = fieldNamePath;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("SelfReferencePlugin", (request, resolveContext, callback) => {
+				if (!request.descriptionFilePath) return callback();
+
+				const req = request.request;
+				if (!req) return callback();
+
+				// Feature is only enabled when an exports field is present
+				const exportsField = DescriptionFileUtils.getField(
+					/** @type {JsonObject} */ (request.descriptionFileData),
+					this.fieldName
+				);
+				if (!exportsField) return callback();
+
+				const name = DescriptionFileUtils.getField(
+					/** @type {JsonObject} */ (request.descriptionFileData),
+					"name"
+				);
+				if (typeof name !== "string") return callback();
+
+				if (
+					req.startsWith(name) &&
+					(req.length === name.length ||
+						req.charCodeAt(name.length) === slashCode)
+				) {
+					const remainingRequest = `.${req.slice(name.length)}`;
+					/** @type {ResolveRequest} */
+					const obj = {
+						...request,
+						request: remainingRequest,
+						path: /** @type {string} */ (request.descriptionFileRoot),
+						relativePath: "."
+					};
+
+					resolver.doResolve(
+						target,
+						obj,
+						"self reference",
+						resolveContext,
+						callback
+					);
+				} else {
+					return callback();
+				}
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/SymlinkPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/SymlinkPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/SymlinkPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,100 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+const getPaths = require("./getPaths");
+const { getType, PathType } = require("./util/path");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class SymlinkPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, target) {
+		this.source = source;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		const fs = resolver.fileSystem;
+		resolver
+			.getHook(this.source)
+			.tapAsync("SymlinkPlugin", (request, resolveContext, callback) => {
+				if (request.ignoreSymlinks) return callback();
+				const pathsResult = getPaths(/** @type {string} */ (request.path));
+				const pathSegments = pathsResult.segments;
+				const paths = pathsResult.paths;
+
+				let containsSymlink = false;
+				let idx = -1;
+				forEachBail(
+					paths,
+					/**
+					 * @param {string} path path
+					 * @param {(err?: null|Error, result?: null|number) => void} callback callback
+					 * @returns {void}
+					 */
+					(path, callback) => {
+						idx++;
+						if (resolveContext.fileDependencies)
+							resolveContext.fileDependencies.add(path);
+						fs.readlink(path, (err, result) => {
+							if (!err && result) {
+								pathSegments[idx] = /** @type {string} */ (result);
+								containsSymlink = true;
+								// Shortcut when absolute symlink found
+								const resultType = getType(result.toString());
+								if (
+									resultType === PathType.AbsoluteWin ||
+									resultType === PathType.AbsolutePosix
+								) {
+									return callback(null, idx);
+								}
+							}
+							callback();
+						});
+					},
+					/**
+					 * @param {null|Error} [err] error
+					 * @param {null|number} [idx] result
+					 * @returns {void}
+					 */
+					(err, idx) => {
+						if (!containsSymlink) return callback();
+						const resultSegments =
+							typeof idx === "number"
+								? pathSegments.slice(0, idx + 1)
+								: pathSegments.slice();
+						const result = resultSegments.reduceRight((a, b) => {
+							return resolver.join(a, b);
+						});
+						/** @type {ResolveRequest} */
+						const obj = {
+							...request,
+							path: result
+						};
+						resolver.doResolve(
+							target,
+							obj,
+							"resolved symlink to " + result,
+							resolveContext,
+							callback
+						);
+					}
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,220 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver").FileSystem} FileSystem */
+/** @typedef {import("./Resolver").ReaddirStringCallback} ReaddirStringCallback */
+/** @typedef {import("./Resolver").StringCallback} StringCallback */
+/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
+
+/**
+ * @param {SyncFileSystem} fs file system implementation
+ * @constructor
+ */
+function SyncAsyncFileSystemDecorator(fs) {
+	this.fs = fs;
+
+	this.lstat = undefined;
+	this.lstatSync = undefined;
+	const lstatSync = fs.lstatSync;
+	if (lstatSync) {
+		this.lstat =
+			/** @type {FileSystem["lstat"]} */
+			(
+				(arg, options, callback) => {
+					let result;
+					try {
+						result = /** @type {Function | undefined} */ (callback)
+							? lstatSync.call(fs, arg, options)
+							: lstatSync.call(fs, arg);
+					} catch (e) {
+						return (callback || options)(
+							/** @type {NodeJS.ErrnoException | null} */ (e)
+						);
+					}
+
+					(callback || options)(null, /** @type {any} */ (result));
+				}
+			);
+		this.lstatSync =
+			/** @type {SyncFileSystem["lstatSync"]} */
+			((arg, options) => lstatSync.call(fs, arg, options));
+	}
+
+	this.stat =
+		/** @type {FileSystem["stat"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.statSync(arg, options)
+						: fs.statSync(arg);
+				} catch (e) {
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
+				}
+
+				(callback || options)(null, /** @type {any} */ (result));
+			}
+		);
+	this.statSync =
+		/** @type {SyncFileSystem["statSync"]} */
+		((arg, options) => fs.statSync(arg, options));
+
+	this.readdir =
+		/** @type {FileSystem["readdir"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.readdirSync(
+								arg,
+								/** @type {Exclude<Parameters<FileSystem["readdir"]>[1], ReaddirStringCallback>} */
+								(options)
+						  )
+						: fs.readdirSync(arg);
+				} catch (e) {
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
+				}
+
+				(callback || options)(null, /** @type {any} */ (result));
+			}
+		);
+	this.readdirSync =
+		/** @type {SyncFileSystem["readdirSync"]} */
+		(
+			(arg, options) =>
+				fs.readdirSync(
+					arg,
+					/** @type {Parameters<SyncFileSystem["readdirSync"]>[1]} */ (options)
+				)
+		);
+
+	this.readFile =
+		/** @type {FileSystem["readFile"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.readFileSync(arg, options)
+						: fs.readFileSync(arg);
+				} catch (e) {
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
+				}
+
+				(callback || options)(null, /** @type {any} */ (result));
+			}
+		);
+	this.readFileSync =
+		/** @type {SyncFileSystem["readFileSync"]} */
+		((arg, options) => fs.readFileSync(arg, options));
+
+	this.readlink =
+		/** @type {FileSystem["readlink"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.readlinkSync(
+								arg,
+								/** @type {Exclude<Parameters<FileSystem["readlink"]>[1], StringCallback>} */
+								(options)
+						  )
+						: fs.readlinkSync(arg);
+				} catch (e) {
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
+				}
+
+				(callback || options)(null, /** @type {any} */ (result));
+			}
+		);
+	this.readlinkSync =
+		/** @type {SyncFileSystem["readlinkSync"]} */
+		(
+			(arg, options) =>
+				fs.readlinkSync(
+					arg,
+					/** @type {Parameters<SyncFileSystem["readlinkSync"]>[1]} */ (options)
+				)
+		);
+
+	this.readJson = undefined;
+	this.readJsonSync = undefined;
+	const readJsonSync = fs.readJsonSync;
+	if (readJsonSync) {
+		this.readJson =
+			/** @type {FileSystem["readJson"]} */
+			(
+				(arg, callback) => {
+					let result;
+					try {
+						result = readJsonSync.call(fs, arg);
+					} catch (e) {
+						return callback(
+							/** @type {NodeJS.ErrnoException | Error | null} */ (e)
+						);
+					}
+
+					callback(null, result);
+				}
+			);
+		this.readJsonSync =
+			/** @type {SyncFileSystem["readJsonSync"]} */
+			(arg => readJsonSync.call(fs, arg));
+	}
+
+	this.realpath = undefined;
+	this.realpathSync = undefined;
+	const realpathSync = fs.realpathSync;
+	if (realpathSync) {
+		this.realpath =
+			/** @type {FileSystem["realpath"]} */
+			(
+				(arg, options, callback) => {
+					let result;
+					try {
+						result = /** @type {Function | undefined} */ (callback)
+							? realpathSync.call(
+									fs,
+									arg,
+									/** @type {Exclude<Parameters<NonNullable<FileSystem["realpath"]>>[1], StringCallback>} */
+									(options)
+							  )
+							: realpathSync.call(fs, arg);
+					} catch (e) {
+						return (callback || options)(
+							/** @type {NodeJS.ErrnoException | null} */ (e)
+						);
+					}
+
+					(callback || options)(null, /** @type {any} */ (result));
+				}
+			);
+		this.realpathSync =
+			/** @type {SyncFileSystem["realpathSync"]} */
+			(
+				(arg, options) =>
+					realpathSync.call(
+						fs,
+						arg,
+						/** @type {Parameters<NonNullable<SyncFileSystem["realpathSync"]>>[1]} */
+						(options)
+					)
+			);
+	}
+}
+module.exports = SyncAsyncFileSystemDecorator;
Index: imaps-frontend/node_modules/enhanced-resolve/lib/TryNextPlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/TryNextPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/TryNextPlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,41 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class TryNextPlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string} message message
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, message, target) {
+		this.source = source;
+		this.message = message;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("TryNextPlugin", (request, resolveContext, callback) => {
+				resolver.doResolve(
+					target,
+					request,
+					this.message,
+					resolveContext,
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,112 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+/** @typedef {import("./Resolver").ResolveContextYield} ResolveContextYield */
+/** @typedef {{[k: string]: ResolveRequest | ResolveRequest[] | undefined}} Cache */
+
+/**
+ * @param {string} type type of cache
+ * @param {ResolveRequest} request request
+ * @param {boolean} withContext cache with context?
+ * @returns {string} cache id
+ */
+function getCacheId(type, request, withContext) {
+	return JSON.stringify({
+		type,
+		context: withContext ? request.context : "",
+		path: request.path,
+		query: request.query,
+		fragment: request.fragment,
+		request: request.request
+	});
+}
+
+module.exports = class UnsafeCachePlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {function(ResolveRequest): boolean} filterPredicate filterPredicate
+	 * @param {Cache} cache cache
+	 * @param {boolean} withContext withContext
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, filterPredicate, cache, withContext, target) {
+		this.source = source;
+		this.filterPredicate = filterPredicate;
+		this.withContext = withContext;
+		this.cache = cache;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("UnsafeCachePlugin", (request, resolveContext, callback) => {
+				if (!this.filterPredicate(request)) return callback();
+				const isYield = typeof resolveContext.yield === "function";
+				const cacheId = getCacheId(
+					isYield ? "yield" : "default",
+					request,
+					this.withContext
+				);
+				const cacheEntry = this.cache[cacheId];
+				if (cacheEntry) {
+					if (isYield) {
+						const yield_ = /** @type {Function} */ (resolveContext.yield);
+						if (Array.isArray(cacheEntry)) {
+							for (const result of cacheEntry) yield_(result);
+						} else {
+							yield_(cacheEntry);
+						}
+						return callback(null, null);
+					}
+					return callback(null, /** @type {ResolveRequest} */ (cacheEntry));
+				}
+
+				/** @type {ResolveContextYield|undefined} */
+				let yieldFn;
+				/** @type {ResolveContextYield|undefined} */
+				let yield_;
+				/** @type {ResolveRequest[]} */
+				const yieldResult = [];
+				if (isYield) {
+					yieldFn = resolveContext.yield;
+					yield_ = result => {
+						yieldResult.push(result);
+					};
+				}
+
+				resolver.doResolve(
+					target,
+					request,
+					null,
+					yield_ ? { ...resolveContext, yield: yield_ } : resolveContext,
+					(err, result) => {
+						if (err) return callback(err);
+						if (isYield) {
+							if (result) yieldResult.push(result);
+							for (const result of yieldResult) {
+								/** @type {ResolveContextYield} */
+								(yieldFn)(result);
+							}
+							this.cache[cacheId] = yieldResult;
+							return callback(null, null);
+						}
+						if (result) return callback(null, (this.cache[cacheId] = result));
+						callback();
+					}
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/UseFilePlugin.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/UseFilePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/UseFilePlugin.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,55 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
+
+module.exports = class UseFilePlugin {
+	/**
+	 * @param {string | ResolveStepHook} source source
+	 * @param {string} filename filename
+	 * @param {string | ResolveStepHook} target target
+	 */
+	constructor(source, filename, target) {
+		this.source = source;
+		this.filename = filename;
+		this.target = target;
+	}
+
+	/**
+	 * @param {Resolver} resolver the resolver
+	 * @returns {void}
+	 */
+	apply(resolver) {
+		const target = resolver.ensureHook(this.target);
+		resolver
+			.getHook(this.source)
+			.tapAsync("UseFilePlugin", (request, resolveContext, callback) => {
+				const filePath = resolver.join(
+					/** @type {string} */ (request.path),
+					this.filename
+				);
+
+				/** @type {ResolveRequest} */
+				const obj = {
+					...request,
+					path: filePath,
+					relativePath:
+						request.relativePath &&
+						resolver.join(request.relativePath, this.filename)
+				};
+				resolver.doResolve(
+					target,
+					obj,
+					"using path: " + filePath,
+					resolveContext,
+					callback
+				);
+			});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/createInnerContext.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/createInnerContext.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/createInnerContext.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,46 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
+
+/**
+ * @param {ResolveContext} options options for inner context
+ * @param {null|string} message message to log
+ * @returns {ResolveContext} inner context
+ */
+module.exports = function createInnerContext(options, message) {
+	let messageReported = false;
+	let innerLog = undefined;
+	if (options.log) {
+		if (message) {
+			/**
+			 * @param {string} msg message
+			 */
+			innerLog = msg => {
+				if (!messageReported) {
+					/** @type {(function(string): void)} */
+					(options.log)(message);
+					messageReported = true;
+				}
+
+				/** @type {(function(string): void)} */
+				(options.log)("  " + msg);
+			};
+		} else {
+			innerLog = options.log;
+		}
+	}
+
+	return {
+		log: innerLog,
+		yield: options.yield,
+		fileDependencies: options.fileDependencies,
+		contextDependencies: options.contextDependencies,
+		missingDependencies: options.missingDependencies,
+		stack: options.stack
+	};
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/forEachBail.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/forEachBail.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/forEachBail.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,50 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+
+/**
+ * @template T
+ * @template Z
+ * @callback Iterator
+ * @param {T} item item
+ * @param {(err?: null|Error, result?: null|Z) => void} callback callback
+ * @param {number} i index
+ * @returns {void}
+ */
+
+/**
+ * @template T
+ * @template Z
+ * @param {T[]} array array
+ * @param {Iterator<T, Z>} iterator iterator
+ * @param {(err?: null|Error, result?: null|Z, i?: number) => void} callback callback after all items are iterated
+ * @returns {void}
+ */
+module.exports = function forEachBail(array, iterator, callback) {
+	if (array.length === 0) return callback();
+
+	let i = 0;
+	const next = () => {
+		/** @type {boolean|undefined} */
+		let loop = undefined;
+		iterator(
+			array[i++],
+			(err, result) => {
+				if (err || result !== undefined || i >= array.length) {
+					return callback(err, result, i);
+				}
+				if (loop === false) while (next());
+				loop = true;
+			},
+			i
+		);
+		if (!loop) loop = false;
+		return loop;
+	};
+	while (next());
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/getInnerRequest.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/getInnerRequest.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/getInnerRequest.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,36 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+
+/**
+ * @param {Resolver} resolver resolver
+ * @param {ResolveRequest} request string
+ * @returns {string} inner request
+ */
+module.exports = function getInnerRequest(resolver, request) {
+	if (
+		typeof request.__innerRequest === "string" &&
+		request.__innerRequest_request === request.request &&
+		request.__innerRequest_relativePath === request.relativePath
+	)
+		return request.__innerRequest;
+	/** @type {string|undefined} */
+	let innerRequest;
+	if (request.request) {
+		innerRequest = request.request;
+		if (/^\.\.?(?:\/|$)/.test(innerRequest) && request.relativePath) {
+			innerRequest = resolver.join(request.relativePath, innerRequest);
+		}
+	} else {
+		innerRequest = request.relativePath;
+	}
+	request.__innerRequest_request = request.request;
+	request.__innerRequest_relativePath = request.relativePath;
+	return (request.__innerRequest = /** @type {string} */ (innerRequest));
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/getPaths.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/getPaths.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/getPaths.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,45 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * @param {string} path path
+ * @returns {{paths: string[], segments: string[]}}} paths and segments
+ */
+module.exports = function getPaths(path) {
+	if (path === "/") return { paths: ["/"], segments: [""] };
+	const parts = path.split(/(.*?[\\/]+)/);
+	const paths = [path];
+	const segments = [parts[parts.length - 1]];
+	let part = parts[parts.length - 1];
+	path = path.substring(0, path.length - part.length - 1);
+	for (let i = parts.length - 2; i > 2; i -= 2) {
+		paths.push(path);
+		part = parts[i];
+		path = path.substring(0, path.length - part.length) || "/";
+		segments.push(part.slice(0, -1));
+	}
+	part = parts[1];
+	segments.push(part);
+	paths.push(part);
+	return {
+		paths: paths,
+		segments: segments
+	};
+};
+
+/**
+ * @param {string} path path
+ * @returns {string|null} basename or null
+ */
+module.exports.basename = function basename(path) {
+	const i = path.lastIndexOf("/"),
+		j = path.lastIndexOf("\\");
+	const p = i < 0 ? j : j < 0 ? i : i < j ? j : i;
+	if (p < 0) return null;
+	const s = path.slice(p + 1);
+	return s;
+};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/index.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/index.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/index.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,203 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const fs = require("graceful-fs");
+const CachedInputFileSystem = require("./CachedInputFileSystem");
+const ResolverFactory = require("./ResolverFactory");
+
+/** @typedef {import("./PnpPlugin").PnpApiImpl} PnpApi */
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").FileSystem} FileSystem */
+/** @typedef {import("./Resolver").ResolveCallback} ResolveCallback */
+/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+/** @typedef {import("./ResolverFactory").Plugin} Plugin */
+/** @typedef {import("./ResolverFactory").UserResolveOptions} ResolveOptions */
+/** @typedef {{
+ * (context: object, path: string, request: string, resolveContext: ResolveContext, callback: ResolveCallback): void;
+ * (context: object, path: string, request: string, callback: ResolveCallback): void;
+ * (path: string, request: string, resolveContext: ResolveContext, callback: ResolveCallback): void;
+ * (path: string, request: string, callback: ResolveCallback): void;
+ * }} ResolveFunctionAsync
+ */
+/** @typedef {{
+ * (context: object, path: string, request: string): string|false;
+ * (path: string, request: string): string|false;
+ * }} ResolveFunction
+ */
+
+const nodeFileSystem = new CachedInputFileSystem(fs, 4000);
+
+const nodeContext = {
+	environments: ["node+es3+es5+process+native"]
+};
+
+const asyncResolver = ResolverFactory.createResolver({
+	conditionNames: ["node"],
+	extensions: [".js", ".json", ".node"],
+	fileSystem: nodeFileSystem
+});
+
+/**
+ * @type {ResolveFunctionAsync}
+ */
+const resolve =
+	/**
+	 * @param {object|string} context
+	 * @param {string} path
+	 * @param {string|ResolveContext|ResolveCallback} request
+	 * @param {ResolveContext|ResolveCallback=} resolveContext
+	 * @param {ResolveCallback=} callback
+	 */
+	(context, path, request, resolveContext, callback) => {
+		if (typeof context === "string") {
+			callback = /** @type {ResolveCallback} */ (resolveContext);
+			resolveContext = /** @type {ResolveContext} */ (request);
+			request = path;
+			path = context;
+			context = nodeContext;
+		}
+		if (typeof callback !== "function") {
+			callback = /** @type {ResolveCallback} */ (resolveContext);
+		}
+		asyncResolver.resolve(
+			context,
+			path,
+			/** @type {string} */ (request),
+			/** @type {ResolveContext} */ (resolveContext),
+			/** @type {ResolveCallback} */ (callback)
+		);
+	};
+
+const syncResolver = ResolverFactory.createResolver({
+	conditionNames: ["node"],
+	extensions: [".js", ".json", ".node"],
+	useSyncFileSystemCalls: true,
+	fileSystem: nodeFileSystem
+});
+
+/**
+ * @type {ResolveFunction}
+ */
+const resolveSync =
+	/**
+	 * @param {object|string} context
+	 * @param {string} path
+	 * @param {string=} request
+	 */
+	(context, path, request) => {
+		if (typeof context === "string") {
+			request = path;
+			path = context;
+			context = nodeContext;
+		}
+		return syncResolver.resolveSync(
+			context,
+			path,
+			/** @type {string} */ (request)
+		);
+	};
+
+/** @typedef {Omit<ResolveOptions, "fileSystem"> & Partial<Pick<ResolveOptions, "fileSystem">>} ResolveOptionsOptionalFS */
+
+/**
+ * @param {ResolveOptionsOptionalFS} options Resolver options
+ * @returns {ResolveFunctionAsync} Resolver function
+ */
+function create(options) {
+	const resolver = ResolverFactory.createResolver({
+		fileSystem: nodeFileSystem,
+		...options
+	});
+	/**
+	 * @param {object|string} context Custom context
+	 * @param {string} path Base path
+	 * @param {string|ResolveContext|ResolveCallback} request String to resolve
+	 * @param {ResolveContext|ResolveCallback=} resolveContext Resolve context
+	 * @param {ResolveCallback=} callback Result callback
+	 */
+	return function (context, path, request, resolveContext, callback) {
+		if (typeof context === "string") {
+			callback = /** @type {ResolveCallback} */ (resolveContext);
+			resolveContext = /** @type {ResolveContext} */ (request);
+			request = path;
+			path = context;
+			context = nodeContext;
+		}
+		if (typeof callback !== "function") {
+			callback = /** @type {ResolveCallback} */ (resolveContext);
+		}
+		resolver.resolve(
+			context,
+			path,
+			/** @type {string} */ (request),
+			/** @type {ResolveContext} */ (resolveContext),
+			callback
+		);
+	};
+}
+
+/**
+ * @param {ResolveOptionsOptionalFS} options Resolver options
+ * @returns {ResolveFunction} Resolver function
+ */
+function createSync(options) {
+	const resolver = ResolverFactory.createResolver({
+		useSyncFileSystemCalls: true,
+		fileSystem: nodeFileSystem,
+		...options
+	});
+	/**
+	 * @param {object|string} context custom context
+	 * @param {string} path base path
+	 * @param {string=} request request to resolve
+	 * @returns {string|false} Resolved path or false
+	 */
+	return function (context, path, request) {
+		if (typeof context === "string") {
+			request = path;
+			path = context;
+			context = nodeContext;
+		}
+		return resolver.resolveSync(context, path, /** @type {string} */ (request));
+	};
+}
+
+/**
+ * @template A
+ * @template B
+ * @param {A} obj input a
+ * @param {B} exports input b
+ * @returns {A & B} merged
+ */
+const mergeExports = (obj, exports) => {
+	const descriptors = Object.getOwnPropertyDescriptors(exports);
+	Object.defineProperties(obj, descriptors);
+	return /** @type {A & B} */ (Object.freeze(obj));
+};
+
+module.exports = mergeExports(resolve, {
+	get sync() {
+		return resolveSync;
+	},
+	create: mergeExports(create, {
+		get sync() {
+			return createSync;
+		}
+	}),
+	ResolverFactory,
+	CachedInputFileSystem,
+	get CloneBasenamePlugin() {
+		return require("./CloneBasenamePlugin");
+	},
+	get LogInfoPlugin() {
+		return require("./LogInfoPlugin");
+	},
+	get forEachBail() {
+		return require("./forEachBail");
+	}
+});
Index: imaps-frontend/node_modules/enhanced-resolve/lib/util/entrypoints.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/util/entrypoints.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/util/entrypoints.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,573 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+/** @typedef {string|(string|ConditionalMapping)[]} DirectMapping */
+/** @typedef {{[k: string]: MappingValue}} ConditionalMapping */
+/** @typedef {ConditionalMapping|DirectMapping|null} MappingValue */
+/** @typedef {Record<string, MappingValue>|ConditionalMapping|DirectMapping} ExportsField */
+/** @typedef {Record<string, MappingValue>} ImportsField */
+
+/**
+ * Processing exports/imports field
+ * @callback FieldProcessor
+ * @param {string} request request
+ * @param {Set<string>} conditionNames condition names
+ * @returns {[string[], string | null]} resolved paths with used field
+ */
+
+/*
+Example exports field:
+{
+  ".": "./main.js",
+  "./feature": {
+    "browser": "./feature-browser.js",
+    "default": "./feature.js"
+  }
+}
+Terminology:
+
+Enhanced-resolve name keys ("." and "./feature") as exports field keys.
+
+If value is string or string[], mapping is called as a direct mapping
+and value called as a direct export.
+
+If value is key-value object, mapping is called as a conditional mapping
+and value called as a conditional export.
+
+Key in conditional mapping is called condition name.
+
+Conditional mapping nested in another conditional mapping is called nested mapping.
+
+----------
+
+Example imports field:
+{
+  "#a": "./main.js",
+  "#moment": {
+    "browser": "./moment/index.js",
+    "default": "moment"
+  },
+  "#moment/": {
+    "browser": "./moment/",
+    "default": "moment/"
+  }
+}
+Terminology:
+
+Enhanced-resolve name keys ("#a" and "#moment/", "#moment") as imports field keys.
+
+If value is string or string[], mapping is called as a direct mapping
+and value called as a direct export.
+
+If value is key-value object, mapping is called as a conditional mapping
+and value called as a conditional export.
+
+Key in conditional mapping is called condition name.
+
+Conditional mapping nested in another conditional mapping is called nested mapping.
+
+*/
+
+const { parseIdentifier } = require("./identifier");
+const slashCode = "/".charCodeAt(0);
+const dotCode = ".".charCodeAt(0);
+const hashCode = "#".charCodeAt(0);
+const patternRegEx = /\*/g;
+
+/**
+ * @param {ExportsField} exportsField the exports field
+ * @returns {FieldProcessor} process callback
+ */
+module.exports.processExportsField = function processExportsField(
+	exportsField
+) {
+	return createFieldProcessor(
+		buildExportsField(exportsField),
+		request => (request.length === 0 ? "." : "./" + request),
+		assertExportsFieldRequest,
+		assertExportTarget
+	);
+};
+
+/**
+ * @param {ImportsField} importsField the exports field
+ * @returns {FieldProcessor} process callback
+ */
+module.exports.processImportsField = function processImportsField(
+	importsField
+) {
+	return createFieldProcessor(
+		importsField,
+		request => "#" + request,
+		assertImportsFieldRequest,
+		assertImportTarget
+	);
+};
+
+/**
+ * @param {ExportsField | ImportsField} field root
+ * @param {(s: string) => string} normalizeRequest Normalize request, for `imports` field it adds `#`, for `exports` field it adds `.` or `./`
+ * @param {(s: string) => string} assertRequest assertRequest
+ * @param {(s: string, f: boolean) => void} assertTarget assertTarget
+ * @returns {FieldProcessor} field processor
+ */
+function createFieldProcessor(
+	field,
+	normalizeRequest,
+	assertRequest,
+	assertTarget
+) {
+	return function fieldProcessor(request, conditionNames) {
+		request = assertRequest(request);
+
+		const match = findMatch(normalizeRequest(request), field);
+
+		if (match === null) return [[], null];
+
+		const [mapping, remainingRequest, isSubpathMapping, isPattern, usedField] =
+			match;
+
+		/** @type {DirectMapping|null} */
+		let direct = null;
+
+		if (isConditionalMapping(mapping)) {
+			direct = conditionalMapping(
+				/** @type {ConditionalMapping} */ (mapping),
+				conditionNames
+			);
+
+			// matching not found
+			if (direct === null) return [[], null];
+		} else {
+			direct = /** @type {DirectMapping} */ (mapping);
+		}
+
+		return [
+			directMapping(
+				remainingRequest,
+				isPattern,
+				isSubpathMapping,
+				direct,
+				conditionNames,
+				assertTarget
+			),
+			usedField
+		];
+	};
+}
+
+/**
+ * @param {string} request request
+ * @returns {string} updated request
+ */
+function assertExportsFieldRequest(request) {
+	if (request.charCodeAt(0) !== dotCode) {
+		throw new Error('Request should be relative path and start with "."');
+	}
+	if (request.length === 1) return "";
+	if (request.charCodeAt(1) !== slashCode) {
+		throw new Error('Request should be relative path and start with "./"');
+	}
+	if (request.charCodeAt(request.length - 1) === slashCode) {
+		throw new Error("Only requesting file allowed");
+	}
+
+	return request.slice(2);
+}
+
+/**
+ * @param {string} request request
+ * @returns {string} updated request
+ */
+function assertImportsFieldRequest(request) {
+	if (request.charCodeAt(0) !== hashCode) {
+		throw new Error('Request should start with "#"');
+	}
+	if (request.length === 1) {
+		throw new Error("Request should have at least 2 characters");
+	}
+	if (request.charCodeAt(1) === slashCode) {
+		throw new Error('Request should not start with "#/"');
+	}
+	if (request.charCodeAt(request.length - 1) === slashCode) {
+		throw new Error("Only requesting file allowed");
+	}
+
+	return request.slice(1);
+}
+
+/**
+ * @param {string} exp export target
+ * @param {boolean} expectFolder is folder expected
+ */
+function assertExportTarget(exp, expectFolder) {
+	const parsedIdentifier = parseIdentifier(exp);
+
+	if (!parsedIdentifier) {
+		return;
+	}
+
+	const [relativePath] = parsedIdentifier;
+	const isFolder =
+		relativePath.charCodeAt(relativePath.length - 1) === slashCode;
+
+	if (isFolder !== expectFolder) {
+		throw new Error(
+			expectFolder
+				? `Expecting folder to folder mapping. ${JSON.stringify(
+						exp
+				  )} should end with "/"`
+				: `Expecting file to file mapping. ${JSON.stringify(
+						exp
+				  )} should not end with "/"`
+		);
+	}
+}
+
+/**
+ * @param {string} imp import target
+ * @param {boolean} expectFolder is folder expected
+ */
+function assertImportTarget(imp, expectFolder) {
+	const parsedIdentifier = parseIdentifier(imp);
+
+	if (!parsedIdentifier) {
+		return;
+	}
+
+	const [relativePath] = parsedIdentifier;
+	const isFolder =
+		relativePath.charCodeAt(relativePath.length - 1) === slashCode;
+
+	if (isFolder !== expectFolder) {
+		throw new Error(
+			expectFolder
+				? `Expecting folder to folder mapping. ${JSON.stringify(
+						imp
+				  )} should end with "/"`
+				: `Expecting file to file mapping. ${JSON.stringify(
+						imp
+				  )} should not end with "/"`
+		);
+	}
+}
+
+/**
+ * @param {string} a first string
+ * @param {string} b second string
+ * @returns {number} compare result
+ */
+function patternKeyCompare(a, b) {
+	const aPatternIndex = a.indexOf("*");
+	const bPatternIndex = b.indexOf("*");
+	const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1;
+	const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1;
+
+	if (baseLenA > baseLenB) return -1;
+	if (baseLenB > baseLenA) return 1;
+	if (aPatternIndex === -1) return 1;
+	if (bPatternIndex === -1) return -1;
+	if (a.length > b.length) return -1;
+	if (b.length > a.length) return 1;
+
+	return 0;
+}
+
+/**
+ * Trying to match request to field
+ * @param {string} request request
+ * @param {ExportsField | ImportsField} field exports or import field
+ * @returns {[MappingValue, string, boolean, boolean, string]|null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
+ */
+function findMatch(request, field) {
+	if (
+		Object.prototype.hasOwnProperty.call(field, request) &&
+		!request.includes("*") &&
+		!request.endsWith("/")
+	) {
+		const target = /** @type {{[k: string]: MappingValue}} */ (field)[request];
+
+		return [target, "", false, false, request];
+	}
+
+	/** @type {string} */
+	let bestMatch = "";
+	/** @type {string|undefined} */
+	let bestMatchSubpath;
+
+	const keys = Object.getOwnPropertyNames(field);
+
+	for (let i = 0; i < keys.length; i++) {
+		const key = keys[i];
+		const patternIndex = key.indexOf("*");
+
+		if (patternIndex !== -1 && request.startsWith(key.slice(0, patternIndex))) {
+			const patternTrailer = key.slice(patternIndex + 1);
+
+			if (
+				request.length >= key.length &&
+				request.endsWith(patternTrailer) &&
+				patternKeyCompare(bestMatch, key) === 1 &&
+				key.lastIndexOf("*") === patternIndex
+			) {
+				bestMatch = key;
+				bestMatchSubpath = request.slice(
+					patternIndex,
+					request.length - patternTrailer.length
+				);
+			}
+		}
+		// For legacy `./foo/`
+		else if (
+			key[key.length - 1] === "/" &&
+			request.startsWith(key) &&
+			patternKeyCompare(bestMatch, key) === 1
+		) {
+			bestMatch = key;
+			bestMatchSubpath = request.slice(key.length);
+		}
+	}
+
+	if (bestMatch === "") return null;
+
+	const target = /** @type {{[k: string]: MappingValue}} */ (field)[bestMatch];
+	const isSubpathMapping = bestMatch.endsWith("/");
+	const isPattern = bestMatch.includes("*");
+
+	return [
+		target,
+		/** @type {string} */ (bestMatchSubpath),
+		isSubpathMapping,
+		isPattern,
+		bestMatch
+	];
+}
+
+/**
+ * @param {ConditionalMapping|DirectMapping|null} mapping mapping
+ * @returns {boolean} is conditional mapping
+ */
+function isConditionalMapping(mapping) {
+	return (
+		mapping !== null && typeof mapping === "object" && !Array.isArray(mapping)
+	);
+}
+
+/**
+ * @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
+ * @param {boolean} isPattern true, if mapping is a pattern (contains "*")
+ * @param {boolean} isSubpathMapping true, for subpath mappings
+ * @param {DirectMapping|null} mappingTarget direct export
+ * @param {Set<string>} conditionNames condition names
+ * @param {(d: string, f: boolean) => void} assert asserting direct value
+ * @returns {string[]} mapping result
+ */
+function directMapping(
+	remainingRequest,
+	isPattern,
+	isSubpathMapping,
+	mappingTarget,
+	conditionNames,
+	assert
+) {
+	if (mappingTarget === null) return [];
+
+	if (typeof mappingTarget === "string") {
+		return [
+			targetMapping(
+				remainingRequest,
+				isPattern,
+				isSubpathMapping,
+				mappingTarget,
+				assert
+			)
+		];
+	}
+
+	/** @type {string[]} */
+	const targets = [];
+
+	for (const exp of mappingTarget) {
+		if (typeof exp === "string") {
+			targets.push(
+				targetMapping(
+					remainingRequest,
+					isPattern,
+					isSubpathMapping,
+					exp,
+					assert
+				)
+			);
+			continue;
+		}
+
+		const mapping = conditionalMapping(exp, conditionNames);
+		if (!mapping) continue;
+		const innerExports = directMapping(
+			remainingRequest,
+			isPattern,
+			isSubpathMapping,
+			mapping,
+			conditionNames,
+			assert
+		);
+		for (const innerExport of innerExports) {
+			targets.push(innerExport);
+		}
+	}
+
+	return targets;
+}
+
+/**
+ * @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
+ * @param {boolean} isPattern true, if mapping is a pattern (contains "*")
+ * @param {boolean} isSubpathMapping true, for subpath mappings
+ * @param {string} mappingTarget direct export
+ * @param {(d: string, f: boolean) => void} assert asserting direct value
+ * @returns {string} mapping result
+ */
+function targetMapping(
+	remainingRequest,
+	isPattern,
+	isSubpathMapping,
+	mappingTarget,
+	assert
+) {
+	if (remainingRequest === undefined) {
+		assert(mappingTarget, false);
+
+		return mappingTarget;
+	}
+
+	if (isSubpathMapping) {
+		assert(mappingTarget, true);
+
+		return mappingTarget + remainingRequest;
+	}
+
+	assert(mappingTarget, false);
+
+	let result = mappingTarget;
+
+	if (isPattern) {
+		result = result.replace(
+			patternRegEx,
+			remainingRequest.replace(/\$/g, "$$")
+		);
+	}
+
+	return result;
+}
+
+/**
+ * @param {ConditionalMapping} conditionalMapping_ conditional mapping
+ * @param {Set<string>} conditionNames condition names
+ * @returns {DirectMapping|null} direct mapping if found
+ */
+function conditionalMapping(conditionalMapping_, conditionNames) {
+	/** @type {[ConditionalMapping, string[], number][]} */
+	let lookup = [[conditionalMapping_, Object.keys(conditionalMapping_), 0]];
+
+	loop: while (lookup.length > 0) {
+		const [mapping, conditions, j] = lookup[lookup.length - 1];
+
+		for (let i = j; i < conditions.length; i++) {
+			const condition = conditions[i];
+
+			if (condition === "default") {
+				const innerMapping = mapping[condition];
+				// is nested
+				if (isConditionalMapping(innerMapping)) {
+					const conditionalMapping = /** @type {ConditionalMapping} */ (
+						innerMapping
+					);
+					lookup[lookup.length - 1][2] = i + 1;
+					lookup.push([conditionalMapping, Object.keys(conditionalMapping), 0]);
+					continue loop;
+				}
+
+				return /** @type {DirectMapping} */ (innerMapping);
+			}
+
+			if (conditionNames.has(condition)) {
+				const innerMapping = mapping[condition];
+				// is nested
+				if (isConditionalMapping(innerMapping)) {
+					const conditionalMapping = /** @type {ConditionalMapping} */ (
+						innerMapping
+					);
+					lookup[lookup.length - 1][2] = i + 1;
+					lookup.push([conditionalMapping, Object.keys(conditionalMapping), 0]);
+					continue loop;
+				}
+
+				return /** @type {DirectMapping} */ (innerMapping);
+			}
+		}
+
+		lookup.pop();
+	}
+
+	return null;
+}
+
+/**
+ * @param {ExportsField} field exports field
+ * @returns {ExportsField} normalized exports field
+ */
+function buildExportsField(field) {
+	// handle syntax sugar, if exports field is direct mapping for "."
+	if (typeof field === "string" || Array.isArray(field)) {
+		return { ".": field };
+	}
+
+	const keys = Object.keys(field);
+
+	for (let i = 0; i < keys.length; i++) {
+		const key = keys[i];
+
+		if (key.charCodeAt(0) !== dotCode) {
+			// handle syntax sugar, if exports field is conditional mapping for "."
+			if (i === 0) {
+				while (i < keys.length) {
+					const charCode = keys[i].charCodeAt(0);
+					if (charCode === dotCode || charCode === slashCode) {
+						throw new Error(
+							`Exports field key should be relative path and start with "." (key: ${JSON.stringify(
+								key
+							)})`
+						);
+					}
+					i++;
+				}
+
+				return { ".": field };
+			}
+
+			throw new Error(
+				`Exports field key should be relative path and start with "." (key: ${JSON.stringify(
+					key
+				)})`
+			);
+		}
+
+		if (key.length === 1) {
+			continue;
+		}
+
+		if (key.charCodeAt(1) !== slashCode) {
+			throw new Error(
+				`Exports field key should be relative path and start with "./" (key: ${JSON.stringify(
+					key
+				)})`
+			);
+		}
+	}
+
+	return field;
+}
Index: imaps-frontend/node_modules/enhanced-resolve/lib/util/identifier.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/util/identifier.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/util/identifier.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,27 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const PATH_QUERY_FRAGMENT_REGEXP =
+	/^(#?(?:\0.|[^?#\0])*)(\?(?:\0.|[^#\0])*)?(#.*)?$/;
+
+/**
+ * @param {string} identifier identifier
+ * @returns {[string, string, string]|null} parsed identifier
+ */
+function parseIdentifier(identifier) {
+	const match = PATH_QUERY_FRAGMENT_REGEXP.exec(identifier);
+
+	if (!match) return null;
+
+	return [
+		match[1].replace(/\0(.)/g, "$1"),
+		match[2] ? match[2].replace(/\0(.)/g, "$1") : "",
+		match[3] || ""
+	];
+}
+
+module.exports.parseIdentifier = parseIdentifier;
Index: imaps-frontend/node_modules/enhanced-resolve/lib/util/module-browser.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/util/module-browser.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/util/module-browser.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,8 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+module.exports = {};
Index: imaps-frontend/node_modules/enhanced-resolve/lib/util/path.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/util/path.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/util/path.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,203 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const path = require("path");
+
+const CHAR_HASH = "#".charCodeAt(0);
+const CHAR_SLASH = "/".charCodeAt(0);
+const CHAR_BACKSLASH = "\\".charCodeAt(0);
+const CHAR_A = "A".charCodeAt(0);
+const CHAR_Z = "Z".charCodeAt(0);
+const CHAR_LOWER_A = "a".charCodeAt(0);
+const CHAR_LOWER_Z = "z".charCodeAt(0);
+const CHAR_DOT = ".".charCodeAt(0);
+const CHAR_COLON = ":".charCodeAt(0);
+
+const posixNormalize = path.posix.normalize;
+const winNormalize = path.win32.normalize;
+
+/**
+ * @enum {number}
+ */
+const PathType = Object.freeze({
+	Empty: 0,
+	Normal: 1,
+	Relative: 2,
+	AbsoluteWin: 3,
+	AbsolutePosix: 4,
+	Internal: 5
+});
+exports.PathType = PathType;
+
+const invalidSegmentRegEx =
+	/(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))?(\\|\/|$)/i;
+exports.invalidSegmentRegEx = invalidSegmentRegEx;
+
+const deprecatedInvalidSegmentRegEx =
+	/(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i;
+exports.deprecatedInvalidSegmentRegEx = deprecatedInvalidSegmentRegEx;
+
+/**
+ * @param {string} p a path
+ * @returns {PathType} type of path
+ */
+const getType = p => {
+	switch (p.length) {
+		case 0:
+			return PathType.Empty;
+		case 1: {
+			const c0 = p.charCodeAt(0);
+			switch (c0) {
+				case CHAR_DOT:
+					return PathType.Relative;
+				case CHAR_SLASH:
+					return PathType.AbsolutePosix;
+				case CHAR_HASH:
+					return PathType.Internal;
+			}
+			return PathType.Normal;
+		}
+		case 2: {
+			const c0 = p.charCodeAt(0);
+			switch (c0) {
+				case CHAR_DOT: {
+					const c1 = p.charCodeAt(1);
+					switch (c1) {
+						case CHAR_DOT:
+						case CHAR_SLASH:
+							return PathType.Relative;
+					}
+					return PathType.Normal;
+				}
+				case CHAR_SLASH:
+					return PathType.AbsolutePosix;
+				case CHAR_HASH:
+					return PathType.Internal;
+			}
+			const c1 = p.charCodeAt(1);
+			if (c1 === CHAR_COLON) {
+				if (
+					(c0 >= CHAR_A && c0 <= CHAR_Z) ||
+					(c0 >= CHAR_LOWER_A && c0 <= CHAR_LOWER_Z)
+				) {
+					return PathType.AbsoluteWin;
+				}
+			}
+			return PathType.Normal;
+		}
+	}
+	const c0 = p.charCodeAt(0);
+	switch (c0) {
+		case CHAR_DOT: {
+			const c1 = p.charCodeAt(1);
+			switch (c1) {
+				case CHAR_SLASH:
+					return PathType.Relative;
+				case CHAR_DOT: {
+					const c2 = p.charCodeAt(2);
+					if (c2 === CHAR_SLASH) return PathType.Relative;
+					return PathType.Normal;
+				}
+			}
+			return PathType.Normal;
+		}
+		case CHAR_SLASH:
+			return PathType.AbsolutePosix;
+		case CHAR_HASH:
+			return PathType.Internal;
+	}
+	const c1 = p.charCodeAt(1);
+	if (c1 === CHAR_COLON) {
+		const c2 = p.charCodeAt(2);
+		if (
+			(c2 === CHAR_BACKSLASH || c2 === CHAR_SLASH) &&
+			((c0 >= CHAR_A && c0 <= CHAR_Z) ||
+				(c0 >= CHAR_LOWER_A && c0 <= CHAR_LOWER_Z))
+		) {
+			return PathType.AbsoluteWin;
+		}
+	}
+	return PathType.Normal;
+};
+exports.getType = getType;
+
+/**
+ * @param {string} p a path
+ * @returns {string} the normalized path
+ */
+const normalize = p => {
+	switch (getType(p)) {
+		case PathType.Empty:
+			return p;
+		case PathType.AbsoluteWin:
+			return winNormalize(p);
+		case PathType.Relative: {
+			const r = posixNormalize(p);
+			return getType(r) === PathType.Relative ? r : `./${r}`;
+		}
+	}
+	return posixNormalize(p);
+};
+exports.normalize = normalize;
+
+/**
+ * @param {string} rootPath the root path
+ * @param {string | undefined} request the request path
+ * @returns {string} the joined path
+ */
+const join = (rootPath, request) => {
+	if (!request) return normalize(rootPath);
+	const requestType = getType(request);
+	switch (requestType) {
+		case PathType.AbsolutePosix:
+			return posixNormalize(request);
+		case PathType.AbsoluteWin:
+			return winNormalize(request);
+	}
+	switch (getType(rootPath)) {
+		case PathType.Normal:
+		case PathType.Relative:
+		case PathType.AbsolutePosix:
+			return posixNormalize(`${rootPath}/${request}`);
+		case PathType.AbsoluteWin:
+			return winNormalize(`${rootPath}\\${request}`);
+	}
+	switch (requestType) {
+		case PathType.Empty:
+			return rootPath;
+		case PathType.Relative: {
+			const r = posixNormalize(rootPath);
+			return getType(r) === PathType.Relative ? r : `./${r}`;
+		}
+	}
+	return posixNormalize(rootPath);
+};
+exports.join = join;
+
+/** @type {Map<string, Map<string, string | undefined>>} */
+const joinCache = new Map();
+
+/**
+ * @param {string} rootPath the root path
+ * @param {string} request the request path
+ * @returns {string} the joined path
+ */
+const cachedJoin = (rootPath, request) => {
+	/** @type {string | undefined} */
+	let cacheEntry;
+	let cache = joinCache.get(rootPath);
+	if (cache === undefined) {
+		joinCache.set(rootPath, (cache = new Map()));
+	} else {
+		cacheEntry = cache.get(request);
+		if (cacheEntry !== undefined) return cacheEntry;
+	}
+	cacheEntry = join(rootPath, request);
+	cache.set(request, cacheEntry);
+	return cacheEntry;
+};
+exports.cachedJoin = cachedJoin;
Index: imaps-frontend/node_modules/enhanced-resolve/lib/util/process-browser.js
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/lib/util/process-browser.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/lib/util/process-browser.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,22 @@
+/*
+	MIT License http://www.opensource.org/licenses/mit-license.php
+	Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+module.exports = {
+	/**
+	 * @type {Record<string, string>}
+	 */
+	versions: {},
+	/**
+	 * @param {function} fn function
+	 */
+	nextTick(fn) {
+		const args = Array.prototype.slice.call(arguments, 1);
+		Promise.resolve().then(function () {
+			fn.apply(null, args);
+		});
+	}
+};
Index: imaps-frontend/node_modules/enhanced-resolve/package.json
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/package.json	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/package.json	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,72 @@
+{
+  "name": "enhanced-resolve",
+  "version": "5.18.0",
+  "author": "Tobias Koppers @sokra",
+  "description": "Offers a async require.resolve function. It's highly configurable.",
+  "files": [
+    "lib",
+    "types.d.ts",
+    "LICENSE"
+  ],
+  "browser": {
+    "process": "./lib/util/process-browser.js",
+    "module": "./lib/util/module-browser.js"
+  },
+  "dependencies": {
+    "graceful-fs": "^4.2.4",
+    "tapable": "^2.2.0"
+  },
+  "license": "MIT",
+  "devDependencies": {
+    "@types/graceful-fs": "^4.1.6",
+    "@types/jest": "^27.5.1",
+    "@types/node": "20.9.5",
+    "cspell": "4.2.8",
+    "eslint": "^7.9.0",
+    "eslint-config-prettier": "^6.11.0",
+    "eslint-plugin-jsdoc": "^30.5.1",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-prettier": "^3.1.4",
+    "husky": "^6.0.0",
+    "jest": "^27.5.1",
+    "lint-staged": "^10.4.0",
+    "memfs": "^3.2.0",
+    "prettier": "^2.1.2",
+    "tooling": "webpack/tooling#v1.23.1",
+    "typescript": "^5.3.3"
+  },
+  "engines": {
+    "node": ">=10.13.0"
+  },
+  "main": "lib/index.js",
+  "types": "types.d.ts",
+  "homepage": "http://github.com/webpack/enhanced-resolve",
+  "scripts": {
+    "lint": "yarn run code-lint && yarn run type-lint && yarn typings-test && yarn run special-lint && yarn run spelling",
+    "fix": "yarn run code-lint-fix && yarn run special-lint-fix",
+    "code-lint": "eslint --cache lib test",
+    "code-lint-fix": "eslint --cache lib test --fix",
+    "type-lint": "tsc",
+    "typings-test": "tsc -p tsconfig.types.test.json",
+    "type-report": "rimraf coverage && yarn cover:types && yarn cover:report && open-cli coverage/lcov-report/index.html",
+    "special-lint": "node node_modules/tooling/lockfile-lint && node node_modules/tooling/inherit-types && node node_modules/tooling/format-file-header && node node_modules/tooling/generate-types",
+    "special-lint-fix": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/format-file-header --write && node node_modules/tooling/generate-types --write",
+    "pretty": "prettier --loglevel warn --write \"lib/**/*.{js,json}\" \"test/*.js\"",
+    "pretest": "yarn lint",
+    "spelling": "cspell \"**\"",
+    "test:only": "node_modules/.bin/jest",
+    "test:watch": "yarn test:only -- --watch",
+    "test:coverage": "yarn test:only -- --collectCoverageFrom=\"lib/**/*.js\" --coverage",
+    "test": "yarn test:coverage",
+    "precover": "yarn lint",
+    "prepare": "husky install"
+  },
+  "lint-staged": {
+    "*": "cspell --no-must-find-files",
+    "*.js": "eslint --cache"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/webpack/enhanced-resolve.git"
+  }
+}
Index: imaps-frontend/node_modules/enhanced-resolve/types.d.ts
===================================================================
--- imaps-frontend/node_modules/enhanced-resolve/types.d.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/enhanced-resolve/types.d.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,1135 @@
+/*
+ * This file was automatically generated.
+ * DO NOT MODIFY BY HAND.
+ * Run `yarn special-lint-fix` to update
+ */
+
+import { Buffer } from "buffer";
+import { AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } from "tapable";
+import { URL as URL_Import } from "url";
+
+declare interface Abortable {
+	/**
+	 * When provided the corresponding `AbortController` can be used to cancel an asynchronous action.
+	 */
+	signal?: AbortSignal;
+}
+type Alias = string | false | string[];
+declare interface AliasOption {
+	alias: Alias;
+	name: string;
+	onlyModule?: boolean;
+}
+type AliasOptionNewRequest = string | false | string[];
+declare interface AliasOptions {
+	[index: string]: AliasOptionNewRequest;
+}
+type BaseFileSystem = FileSystem & SyncFileSystem;
+declare interface BaseResolveRequest {
+	path: string | false;
+	context?: object;
+	descriptionFilePath?: string;
+	descriptionFileRoot?: string;
+	descriptionFileData?: JsonObject;
+	relativePath?: string;
+	ignoreSymlinks?: boolean;
+	fullySpecified?: boolean;
+	__innerRequest?: string;
+	__innerRequest_request?: string;
+	__innerRequest_relativePath?: string;
+}
+type BufferEncoding =
+	| "ascii"
+	| "utf8"
+	| "utf-8"
+	| "utf16le"
+	| "utf-16le"
+	| "ucs2"
+	| "ucs-2"
+	| "base64"
+	| "base64url"
+	| "latin1"
+	| "binary"
+	| "hex";
+type BufferEncodingOption = "buffer" | { encoding: "buffer" };
+declare class CachedInputFileSystem {
+	constructor(fileSystem: BaseFileSystem, duration: number);
+	fileSystem: BaseFileSystem;
+	lstat?: LStat;
+	lstatSync?: LStatSync;
+	stat: Stat;
+	statSync: StatSync;
+	readdir: Readdir;
+	readdirSync: ReaddirSync;
+	readFile: ReadFile;
+	readFileSync: ReadFileSync;
+	readJson?: (
+		arg0: PathOrFileDescriptor,
+		arg1: (
+			arg0: null | Error | NodeJS.ErrnoException,
+			arg1?: JsonObject
+		) => void
+	) => void;
+	readJsonSync?: (arg0: PathOrFileDescriptor) => JsonObject;
+	readlink: Readlink;
+	readlinkSync: ReadlinkSync;
+	realpath?: RealPath;
+	realpathSync?: RealPathSync;
+	purge(
+		what?:
+			| string
+			| number
+			| Buffer
+			| URL_url
+			| (string | number | Buffer | URL_url)[]
+			| Set<string | number | Buffer | URL_url>
+	): void;
+}
+declare class CloneBasenamePlugin {
+	constructor(
+		source:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >,
+		target:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >
+	);
+	source:
+		| string
+		| AsyncSeriesBailHook<
+				[ResolveRequest, ResolveContext],
+				null | ResolveRequest
+		  >;
+	target:
+		| string
+		| AsyncSeriesBailHook<
+				[ResolveRequest, ResolveContext],
+				null | ResolveRequest
+		  >;
+	apply(resolver: Resolver): void;
+}
+declare interface Dirent {
+	isFile: () => boolean;
+	isDirectory: () => boolean;
+	isBlockDevice: () => boolean;
+	isCharacterDevice: () => boolean;
+	isSymbolicLink: () => boolean;
+	isFIFO: () => boolean;
+	isSocket: () => boolean;
+	name: string;
+	path: string;
+}
+type EncodingOption =
+	| undefined
+	| null
+	| "ascii"
+	| "utf8"
+	| "utf-8"
+	| "utf16le"
+	| "utf-16le"
+	| "ucs2"
+	| "ucs-2"
+	| "base64"
+	| "base64url"
+	| "latin1"
+	| "binary"
+	| "hex"
+	| ObjectEncodingOptions;
+type ErrorWithDetail = Error & { details?: string };
+declare interface ExtensionAliasOption {
+	alias: string | string[];
+	extension: string;
+}
+declare interface ExtensionAliasOptions {
+	[index: string]: string | string[];
+}
+declare interface FileSystem {
+	readFile: ReadFile;
+	readdir: Readdir;
+	readJson?: (
+		arg0: PathOrFileDescriptor,
+		arg1: (
+			arg0: null | Error | NodeJS.ErrnoException,
+			arg1?: JsonObject
+		) => void
+	) => void;
+	readlink: Readlink;
+	lstat?: LStat;
+	stat: Stat;
+	realpath?: RealPath;
+}
+type IBigIntStats = IStatsBase<bigint> & {
+	atimeNs: bigint;
+	mtimeNs: bigint;
+	ctimeNs: bigint;
+	birthtimeNs: bigint;
+};
+declare interface IStats {
+	isFile: () => boolean;
+	isDirectory: () => boolean;
+	isBlockDevice: () => boolean;
+	isCharacterDevice: () => boolean;
+	isSymbolicLink: () => boolean;
+	isFIFO: () => boolean;
+	isSocket: () => boolean;
+	dev: number;
+	ino: number;
+	mode: number;
+	nlink: number;
+	uid: number;
+	gid: number;
+	rdev: number;
+	size: number;
+	blksize: number;
+	blocks: number;
+	atimeMs: number;
+	mtimeMs: number;
+	ctimeMs: number;
+	birthtimeMs: number;
+	atime: Date;
+	mtime: Date;
+	ctime: Date;
+	birthtime: Date;
+}
+declare interface IStatsBase<T> {
+	isFile: () => boolean;
+	isDirectory: () => boolean;
+	isBlockDevice: () => boolean;
+	isCharacterDevice: () => boolean;
+	isSymbolicLink: () => boolean;
+	isFIFO: () => boolean;
+	isSocket: () => boolean;
+	dev: T;
+	ino: T;
+	mode: T;
+	nlink: T;
+	uid: T;
+	gid: T;
+	rdev: T;
+	size: T;
+	blksize: T;
+	blocks: T;
+	atimeMs: T;
+	mtimeMs: T;
+	ctimeMs: T;
+	birthtimeMs: T;
+	atime: Date;
+	mtime: Date;
+	ctime: Date;
+	birthtime: Date;
+}
+declare interface Iterator<T, Z> {
+	(
+		item: T,
+		callback: (err?: null | Error, result?: null | Z) => void,
+		i: number
+	): void;
+}
+type JsonObject = { [index: string]: JsonValue } & {
+	[index: string]:
+		| undefined
+		| null
+		| string
+		| number
+		| boolean
+		| JsonObject
+		| JsonValue[];
+};
+type JsonValue = null | string | number | boolean | JsonObject | JsonValue[];
+declare interface KnownHooks {
+	resolveStep: SyncHook<
+		[
+			AsyncSeriesBailHook<
+				[ResolveRequest, ResolveContext],
+				null | ResolveRequest
+			>,
+			ResolveRequest
+		]
+	>;
+	noResolve: SyncHook<[ResolveRequest, Error]>;
+	resolve: AsyncSeriesBailHook<
+		[ResolveRequest, ResolveContext],
+		null | ResolveRequest
+	>;
+	result: AsyncSeriesHook<[ResolveRequest, ResolveContext]>;
+}
+declare interface LStat {
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | (StatOptions & { bigint?: false }),
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: StatOptions & { bigint: true },
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IBigIntStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | StatOptions,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: IStats | IBigIntStats
+		) => void
+	): void;
+}
+declare interface LStatSync {
+	(path: PathLike, options?: undefined): IStats;
+	(
+		path: PathLike,
+		options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false }
+	): undefined | IStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: true; throwIfNoEntry: false }
+	): undefined | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats;
+	(path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false }
+	): IStats | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions):
+		| undefined
+		| IStats
+		| IBigIntStats;
+}
+declare class LogInfoPlugin {
+	constructor(
+		source:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >
+	);
+	source:
+		| string
+		| AsyncSeriesBailHook<
+				[ResolveRequest, ResolveContext],
+				null | ResolveRequest
+		  >;
+	apply(resolver: Resolver): void;
+}
+declare interface ObjectEncodingOptions {
+	encoding?:
+		| null
+		| "ascii"
+		| "utf8"
+		| "utf-8"
+		| "utf16le"
+		| "utf-16le"
+		| "ucs2"
+		| "ucs-2"
+		| "base64"
+		| "base64url"
+		| "latin1"
+		| "binary"
+		| "hex";
+}
+declare interface ParsedIdentifier {
+	request: string;
+	query: string;
+	fragment: string;
+	directory: boolean;
+	module: boolean;
+	file: boolean;
+	internal: boolean;
+}
+type PathLike = string | Buffer | URL_url;
+type PathOrFileDescriptor = string | number | Buffer | URL_url;
+type Plugin =
+	| undefined
+	| null
+	| false
+	| ""
+	| 0
+	| { apply: (arg0: Resolver) => void }
+	| ((this: Resolver, arg1: Resolver) => void);
+declare interface PnpApi {
+	resolveToUnqualified: (
+		arg0: string,
+		arg1: string,
+		arg2: object
+	) => null | string;
+}
+declare interface ReadFile {
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| undefined
+			| null
+			| ({ encoding?: null; flag?: string } & Abortable),
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| ({ encoding: BufferEncoding; flag?: string } & Abortable)
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex",
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| undefined
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & { flag?: string } & Abortable),
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string | Buffer
+		) => void
+	): void;
+	(
+		path: PathOrFileDescriptor,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+}
+declare interface ReadFileSync {
+	(
+		path: PathOrFileDescriptor,
+		options?: null | { encoding?: null; flag?: string }
+	): Buffer;
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| { encoding: BufferEncoding; flag?: string }
+	): string;
+	(
+		path: PathOrFileDescriptor,
+		options?:
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & { flag?: string })
+	): string | Buffer;
+}
+declare interface Readdir {
+	(
+		path: PathLike,
+		options:
+			| undefined
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| {
+					encoding:
+						| null
+						| "ascii"
+						| "utf8"
+						| "utf-8"
+						| "utf16le"
+						| "utf-16le"
+						| "ucs2"
+						| "ucs-2"
+						| "base64"
+						| "base64url"
+						| "latin1"
+						| "binary"
+						| "hex";
+					withFileTypes?: false;
+					recursive?: boolean;
+			  },
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string[]) => void
+	): void;
+	(
+		path: PathLike,
+		options:
+			| { encoding: "buffer"; withFileTypes?: false; recursive?: boolean }
+			| "buffer",
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer[]) => void
+	): void;
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string[]) => void
+	): void;
+	(
+		path: PathLike,
+		options:
+			| undefined
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & {
+					withFileTypes?: false;
+					recursive?: boolean;
+			  }),
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string[] | Buffer[]
+		) => void
+	): void;
+	(
+		path: PathLike,
+		options: ObjectEncodingOptions & {
+			withFileTypes: true;
+			recursive?: boolean;
+		},
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Dirent[]) => void
+	): void;
+}
+declare interface ReaddirSync {
+	(
+		path: PathLike,
+		options?:
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| {
+					encoding:
+						| null
+						| "ascii"
+						| "utf8"
+						| "utf-8"
+						| "utf16le"
+						| "utf-16le"
+						| "ucs2"
+						| "ucs-2"
+						| "base64"
+						| "base64url"
+						| "latin1"
+						| "binary"
+						| "hex";
+					withFileTypes?: false;
+					recursive?: boolean;
+			  }
+	): string[];
+	(
+		path: PathLike,
+		options:
+			| "buffer"
+			| { encoding: "buffer"; withFileTypes?: false; recursive?: boolean }
+	): Buffer[];
+	(
+		path: PathLike,
+		options?:
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean })
+	): string[] | Buffer[];
+	(
+		path: PathLike,
+		options: ObjectEncodingOptions & {
+			withFileTypes: true;
+			recursive?: boolean;
+		}
+	): Dirent[];
+}
+declare interface Readlink {
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+	(
+		path: PathLike,
+		options: BufferEncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string | Buffer
+		) => void
+	): void;
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+}
+declare interface ReadlinkSync {
+	(path: PathLike, options?: EncodingOption): string;
+	(path: PathLike, options: BufferEncodingOption): Buffer;
+	(path: PathLike, options?: EncodingOption): string | Buffer;
+}
+declare interface RealPath {
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+	(
+		path: PathLike,
+		options: BufferEncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string | Buffer
+		) => void
+	): void;
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+}
+declare interface RealPathSync {
+	(path: PathLike, options?: EncodingOption): string;
+	(path: PathLike, options: BufferEncodingOption): Buffer;
+	(path: PathLike, options?: EncodingOption): string | Buffer;
+}
+declare interface ResolveContext {
+	contextDependencies?: WriteOnlySet<string>;
+
+	/**
+	 * files that was found on file system
+	 */
+	fileDependencies?: WriteOnlySet<string>;
+
+	/**
+	 * dependencies that was not found on file system
+	 */
+	missingDependencies?: WriteOnlySet<string>;
+
+	/**
+	 * set of hooks' calls. For instance, `resolve → parsedResolve → describedResolve`,
+	 */
+	stack?: Set<string>;
+
+	/**
+	 * log function
+	 */
+	log?: (arg0: string) => void;
+
+	/**
+	 * yield result, if provided plugins can return several results
+	 */
+	yield?: (arg0: ResolveRequest) => void;
+}
+declare interface ResolveFunction {
+	(context: object, path: string, request: string): string | false;
+	(path: string, request: string): string | false;
+}
+declare interface ResolveFunctionAsync {
+	(
+		context: object,
+		path: string,
+		request: string,
+		resolveContext: ResolveContext,
+		callback: (
+			err: null | ErrorWithDetail,
+			res?: string | false,
+			req?: ResolveRequest
+		) => void
+	): void;
+	(
+		context: object,
+		path: string,
+		request: string,
+		callback: (
+			err: null | ErrorWithDetail,
+			res?: string | false,
+			req?: ResolveRequest
+		) => void
+	): void;
+	(
+		path: string,
+		request: string,
+		resolveContext: ResolveContext,
+		callback: (
+			err: null | ErrorWithDetail,
+			res?: string | false,
+			req?: ResolveRequest
+		) => void
+	): void;
+	(
+		path: string,
+		request: string,
+		callback: (
+			err: null | ErrorWithDetail,
+			res?: string | false,
+			req?: ResolveRequest
+		) => void
+	): void;
+}
+type ResolveOptionsOptionalFS = Omit<
+	ResolveOptionsResolverFactoryObject_2,
+	"fileSystem"
+> &
+	Partial<Pick<ResolveOptionsResolverFactoryObject_2, "fileSystem">>;
+declare interface ResolveOptionsResolverFactoryObject_1 {
+	alias: AliasOption[];
+	fallback: AliasOption[];
+	aliasFields: Set<string | string[]>;
+	extensionAlias: ExtensionAliasOption[];
+	cachePredicate: (arg0: ResolveRequest) => boolean;
+	cacheWithContext: boolean;
+
+	/**
+	 * A list of exports field condition names.
+	 */
+	conditionNames: Set<string>;
+	descriptionFiles: string[];
+	enforceExtension: boolean;
+	exportsFields: Set<string | string[]>;
+	importsFields: Set<string | string[]>;
+	extensions: Set<string>;
+	fileSystem: FileSystem;
+	unsafeCache: false | object;
+	symlinks: boolean;
+	resolver?: Resolver;
+	modules: (string | string[])[];
+	mainFields: { name: string[]; forceRelative: boolean }[];
+	mainFiles: Set<string>;
+	plugins: Plugin[];
+	pnpApi: null | PnpApi;
+	roots: Set<string>;
+	fullySpecified: boolean;
+	resolveToContext: boolean;
+	restrictions: Set<string | RegExp>;
+	preferRelative: boolean;
+	preferAbsolute: boolean;
+}
+declare interface ResolveOptionsResolverFactoryObject_2 {
+	/**
+	 * A list of module alias configurations or an object which maps key to value
+	 */
+	alias?: AliasOptions | AliasOption[];
+
+	/**
+	 * A list of module alias configurations or an object which maps key to value, applied only after modules option
+	 */
+	fallback?: AliasOptions | AliasOption[];
+
+	/**
+	 * An object which maps extension to extension aliases
+	 */
+	extensionAlias?: ExtensionAliasOptions;
+
+	/**
+	 * A list of alias fields in description files
+	 */
+	aliasFields?: (string | string[])[];
+
+	/**
+	 * A function which decides whether a request should be cached or not. An object is passed with at least `path` and `request` properties.
+	 */
+	cachePredicate?: (arg0: ResolveRequest) => boolean;
+
+	/**
+	 * Whether or not the unsafeCache should include request context as part of the cache key.
+	 */
+	cacheWithContext?: boolean;
+
+	/**
+	 * A list of description files to read from
+	 */
+	descriptionFiles?: string[];
+
+	/**
+	 * A list of exports field condition names.
+	 */
+	conditionNames?: string[];
+
+	/**
+	 * Enforce that a extension from extensions must be used
+	 */
+	enforceExtension?: boolean;
+
+	/**
+	 * A list of exports fields in description files
+	 */
+	exportsFields?: (string | string[])[];
+
+	/**
+	 * A list of imports fields in description files
+	 */
+	importsFields?: (string | string[])[];
+
+	/**
+	 * A list of extensions which should be tried for files
+	 */
+	extensions?: string[];
+
+	/**
+	 * The file system which should be used
+	 */
+	fileSystem: FileSystem;
+
+	/**
+	 * Use this cache object to unsafely cache the successful requests
+	 */
+	unsafeCache?: boolean | object;
+
+	/**
+	 * Resolve symlinks to their symlinked location
+	 */
+	symlinks?: boolean;
+
+	/**
+	 * A prepared Resolver to which the plugins are attached
+	 */
+	resolver?: Resolver;
+
+	/**
+	 * A list of directories to resolve modules from, can be absolute path or folder name
+	 */
+	modules?: string | string[];
+
+	/**
+	 * A list of main fields in description files
+	 */
+	mainFields?: (
+		| string
+		| string[]
+		| { name: string | string[]; forceRelative: boolean }
+	)[];
+
+	/**
+	 * A list of main files in directories
+	 */
+	mainFiles?: string[];
+
+	/**
+	 * A list of additional resolve plugins which should be applied
+	 */
+	plugins?: Plugin[];
+
+	/**
+	 * A PnP API that should be used - null is "never", undefined is "auto"
+	 */
+	pnpApi?: null | PnpApi;
+
+	/**
+	 * A list of root paths
+	 */
+	roots?: string[];
+
+	/**
+	 * The request is already fully specified and no extensions or directories are resolved for it
+	 */
+	fullySpecified?: boolean;
+
+	/**
+	 * Resolve to a context instead of a file
+	 */
+	resolveToContext?: boolean;
+
+	/**
+	 * A list of resolve restrictions
+	 */
+	restrictions?: (string | RegExp)[];
+
+	/**
+	 * Use only the sync constraints of the file system calls
+	 */
+	useSyncFileSystemCalls?: boolean;
+
+	/**
+	 * Prefer to resolve module requests as relative requests before falling back to modules
+	 */
+	preferRelative?: boolean;
+
+	/**
+	 * Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots
+	 */
+	preferAbsolute?: boolean;
+}
+type ResolveRequest = BaseResolveRequest & Partial<ParsedIdentifier>;
+declare abstract class Resolver {
+	fileSystem: FileSystem;
+	options: ResolveOptionsResolverFactoryObject_1;
+	hooks: KnownHooks;
+	ensureHook(
+		name:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >
+	): AsyncSeriesBailHook<
+		[ResolveRequest, ResolveContext],
+		null | ResolveRequest
+	>;
+	getHook(
+		name:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >
+	): AsyncSeriesBailHook<
+		[ResolveRequest, ResolveContext],
+		null | ResolveRequest
+	>;
+	resolveSync(context: object, path: string, request: string): string | false;
+	resolve(
+		context: object,
+		path: string,
+		request: string,
+		resolveContext: ResolveContext,
+		callback: (
+			err: null | ErrorWithDetail,
+			res?: string | false,
+			req?: ResolveRequest
+		) => void
+	): void;
+	doResolve(
+		hook: AsyncSeriesBailHook<
+			[ResolveRequest, ResolveContext],
+			null | ResolveRequest
+		>,
+		request: ResolveRequest,
+		message: null | string,
+		resolveContext: ResolveContext,
+		callback: (err?: null | Error, result?: ResolveRequest) => void
+	): void;
+	parse(identifier: string): ParsedIdentifier;
+	isModule(path: string): boolean;
+	isPrivate(path: string): boolean;
+	isDirectory(path: string): boolean;
+	join(path: string, request: string): string;
+	normalize(path: string): string;
+}
+declare interface Stat {
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | (StatOptions & { bigint?: false }),
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: StatOptions & { bigint: true },
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IBigIntStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | StatOptions,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: IStats | IBigIntStats
+		) => void
+	): void;
+}
+declare interface StatOptions {
+	bigint?: boolean;
+}
+declare interface StatSync {
+	(path: PathLike, options?: undefined): IStats;
+	(
+		path: PathLike,
+		options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false }
+	): undefined | IStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: true; throwIfNoEntry: false }
+	): undefined | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats;
+	(path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false }
+	): IStats | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions):
+		| undefined
+		| IStats
+		| IBigIntStats;
+}
+declare interface StatSyncOptions {
+	bigint?: boolean;
+	throwIfNoEntry?: boolean;
+}
+declare interface SyncFileSystem {
+	readFileSync: ReadFileSync;
+	readdirSync: ReaddirSync;
+	readJsonSync?: (arg0: PathOrFileDescriptor) => JsonObject;
+	readlinkSync: ReadlinkSync;
+	lstatSync?: LStatSync;
+	statSync: StatSync;
+	realpathSync?: RealPathSync;
+}
+
+/**
+ * `URL` class is a global reference for `require('url').URL`
+ * https://nodejs.org/api/url.html#the-whatwg-url-api
+ */
+declare interface URL_url extends URL_Import {}
+declare interface WriteOnlySet<T> {
+	add: (item: T) => void;
+}
+declare function exports(
+	context: object,
+	path: string,
+	request: string,
+	resolveContext: ResolveContext,
+	callback: (
+		err: null | ErrorWithDetail,
+		res?: string | false,
+		req?: ResolveRequest
+	) => void
+): void;
+declare function exports(
+	context: object,
+	path: string,
+	request: string,
+	callback: (
+		err: null | ErrorWithDetail,
+		res?: string | false,
+		req?: ResolveRequest
+	) => void
+): void;
+declare function exports(
+	path: string,
+	request: string,
+	resolveContext: ResolveContext,
+	callback: (
+		err: null | ErrorWithDetail,
+		res?: string | false,
+		req?: ResolveRequest
+	) => void
+): void;
+declare function exports(
+	path: string,
+	request: string,
+	callback: (
+		err: null | ErrorWithDetail,
+		res?: string | false,
+		req?: ResolveRequest
+	) => void
+): void;
+declare namespace exports {
+	export const sync: ResolveFunction;
+	export function create(
+		options: ResolveOptionsOptionalFS
+	): ResolveFunctionAsync;
+	export namespace create {
+		export const sync: (options: ResolveOptionsOptionalFS) => ResolveFunction;
+	}
+	export namespace ResolverFactory {
+		export let createResolver: (
+			options: ResolveOptionsResolverFactoryObject_2
+		) => Resolver;
+	}
+	export const forEachBail: <T, Z>(
+		array: T[],
+		iterator: Iterator<T, Z>,
+		callback: (err?: null | Error, result?: null | Z, i?: number) => void
+	) => void;
+	export type ResolveCallback = (
+		err: null | ErrorWithDetail,
+		res?: string | false,
+		req?: ResolveRequest
+	) => void;
+	export {
+		CachedInputFileSystem,
+		CloneBasenamePlugin,
+		LogInfoPlugin,
+		ResolveOptionsOptionalFS,
+		PnpApi,
+		Resolver,
+		FileSystem,
+		ResolveContext,
+		ResolveRequest,
+		Plugin,
+		ResolveOptionsResolverFactoryObject_2 as ResolveOptions,
+		ResolveFunctionAsync,
+		ResolveFunction
+	};
+}
+
+export = exports;
