Index: frontend/node_modules/webpack-dev-middleware/dist/index.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,305 @@
+"use strict";
+
+const {
+  validate
+} = require("schema-utils");
+
+const mime = require("mime-types");
+
+const middleware = require("./middleware");
+
+const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
+
+const setupHooks = require("./utils/setupHooks");
+
+const setupWriteToDisk = require("./utils/setupWriteToDisk");
+
+const setupOutputFileSystem = require("./utils/setupOutputFileSystem");
+
+const ready = require("./utils/ready");
+
+const schema = require("./options.json");
+
+const noop = () => {};
+/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */
+
+/** @typedef {import("webpack").Compiler} Compiler */
+
+/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
+
+/** @typedef {import("webpack").Configuration} Configuration */
+
+/** @typedef {import("webpack").Stats} Stats */
+
+/** @typedef {import("webpack").MultiStats} MultiStats */
+
+/**
+ * @typedef {Object} ExtendedServerResponse
+ * @property {{ webpack?: { devMiddleware?: Context<IncomingMessage, ServerResponse> } }} [locals]
+ */
+
+/** @typedef {import("http").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("http").ServerResponse & ExtendedServerResponse} ServerResponse */
+
+/**
+ * @callback NextFunction
+ * @param {any} [err]
+ * @return {void}
+ */
+
+/**
+ * @typedef {NonNullable<Configuration["watchOptions"]>} WatchOptions
+ */
+
+/**
+ * @typedef {Compiler["watching"]} Watching
+ */
+
+/**
+ * @typedef {ReturnType<Compiler["watch"]>} MultiWatching
+ */
+
+/**
+ * @typedef {Compiler["outputFileSystem"] & { createReadStream?: import("fs").createReadStream, statSync?: import("fs").statSync, lstat?: import("fs").lstat, readFileSync?: import("fs").readFileSync }} OutputFileSystem
+ */
+
+/** @typedef {ReturnType<Compiler["getInfrastructureLogger"]>} Logger */
+
+/**
+ * @callback Callback
+ * @param {Stats | MultiStats} [stats]
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @typedef {Object} Context
+ * @property {boolean} state
+ * @property {Stats | MultiStats | undefined} stats
+ * @property {Callback[]} callbacks
+ * @property {Options<Request, Response>} options
+ * @property {Compiler | MultiCompiler} compiler
+ * @property {Watching | MultiWatching} watching
+ * @property {Logger} logger
+ * @property {OutputFileSystem} outputFileSystem
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @typedef {Record<string, string | number> | Array<{ key: string, value: number | string }> | ((req: Request, res: Response, context: Context<Request, Response>) =>  void | undefined | Record<string, string | number>) | undefined} Headers
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @typedef {Object} Options
+ * @property {{[key: string]: string}} [mimeTypes]
+ * @property {boolean | ((targetPath: string) => boolean)} [writeToDisk]
+ * @property {string} [methods]
+ * @property {Headers<Request, Response>} [headers]
+ * @property {NonNullable<Configuration["output"]>["publicPath"]} [publicPath]
+ * @property {Configuration["stats"]} [stats]
+ * @property {boolean} [serverSideRender]
+ * @property {OutputFileSystem} [outputFileSystem]
+ * @property {boolean | string} [index]
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @callback Middleware
+ * @param {Request} req
+ * @param {Response} res
+ * @param {NextFunction} next
+ * @return {Promise<void>}
+ */
+
+/**
+ * @callback GetFilenameFromUrl
+ * @param {string} url
+ * @returns {string | undefined}
+ */
+
+/**
+ * @callback WaitUntilValid
+ * @param {Callback} callback
+ */
+
+/**
+ * @callback Invalidate
+ * @param {Callback} callback
+ */
+
+/**
+ * @callback Close
+ * @param {(err: Error | null | undefined) => void} callback
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @typedef {Object} AdditionalMethods
+ * @property {GetFilenameFromUrl} getFilenameFromUrl
+ * @property {WaitUntilValid} waitUntilValid
+ * @property {Invalidate} invalidate
+ * @property {Close} close
+ * @property {Context<Request, Response>} context
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @typedef {Middleware<Request, Response> & AdditionalMethods<Request, Response>} API
+ */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {Compiler | MultiCompiler} compiler
+ * @param {Options<Request, Response>} [options]
+ * @returns {API<Request, Response>}
+ */
+
+
+function wdm(compiler, options = {}) {
+  validate(
+  /** @type {Schema} */
+  schema, options, {
+    name: "Dev Middleware",
+    baseDataPath: "options"
+  });
+  const {
+    mimeTypes
+  } = options;
+
+  if (mimeTypes) {
+    const {
+      types
+    } = mime; // mimeTypes from user provided options should take priority
+    // over existing, known types
+    // @ts-ignore
+
+    mime.types = { ...types,
+      ...mimeTypes
+    };
+  }
+  /**
+   * @type {Context<Request, Response>}
+   */
+
+
+  const context = {
+    state: false,
+    // eslint-disable-next-line no-undefined
+    stats: undefined,
+    callbacks: [],
+    options,
+    compiler,
+    // @ts-ignore
+    // eslint-disable-next-line no-undefined
+    watching: undefined,
+    logger: compiler.getInfrastructureLogger("webpack-dev-middleware"),
+    // @ts-ignore
+    // eslint-disable-next-line no-undefined
+    outputFileSystem: undefined
+  };
+  setupHooks(context);
+
+  if (options.writeToDisk) {
+    setupWriteToDisk(context);
+  }
+
+  setupOutputFileSystem(context); // Start watching
+
+  if (
+  /** @type {Compiler} */
+  context.compiler.watching) {
+    context.watching =
+    /** @type {Compiler} */
+    context.compiler.watching;
+  } else {
+    /**
+     * @type {WatchOptions | WatchOptions[]}
+     */
+    let watchOptions;
+    /**
+     * @param {Error | null | undefined} error
+     */
+
+    const errorHandler = error => {
+      if (error) {
+        // TODO: improve that in future
+        // For example - `writeToDisk` can throw an error and right now it is ends watching.
+        // We can improve that and keep watching active, but it is require API on webpack side.
+        // Let's implement that in webpack@5 because it is rare case.
+        context.logger.error(error);
+      }
+    };
+
+    if (Array.isArray(
+    /** @type {MultiCompiler} */
+    context.compiler.compilers)) {
+      watchOptions =
+      /** @type {MultiCompiler} */
+      context.compiler.compilers.map(
+      /**
+       * @param {Compiler} childCompiler
+       * @returns {WatchOptions}
+       */
+      childCompiler => childCompiler.options.watchOptions || {});
+      context.watching =
+      /** @type {MultiWatching} */
+      context.compiler.watch(
+      /** @type {WatchOptions}} */
+      watchOptions, errorHandler);
+    } else {
+      watchOptions =
+      /** @type {Compiler} */
+      context.compiler.options.watchOptions || {};
+      context.watching =
+      /** @type {Watching} */
+      context.compiler.watch(watchOptions, errorHandler);
+    }
+  }
+
+  const instance =
+  /** @type {API<Request, Response>} */
+  middleware(context); // API
+
+  /** @type {API<Request, Response>} */
+
+  instance.getFilenameFromUrl =
+  /**
+   * @param {string} url
+   * @returns {string|undefined}
+   */
+  url => getFilenameFromUrl(context, url);
+  /** @type {API<Request, Response>} */
+
+
+  instance.waitUntilValid = (callback = noop) => {
+    ready(context, callback);
+  };
+  /** @type {API<Request, Response>} */
+
+
+  instance.invalidate = (callback = noop) => {
+    ready(context, callback);
+    context.watching.invalidate();
+  };
+  /** @type {API<Request, Response>} */
+
+
+  instance.close = (callback = noop) => {
+    context.watching.close(callback);
+  };
+  /** @type {API<Request, Response>} */
+
+
+  instance.context = context;
+  return instance;
+}
+
+module.exports = wdm;
Index: frontend/node_modules/webpack-dev-middleware/dist/middleware.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/middleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/middleware.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,249 @@
+"use strict";
+
+const path = require("path");
+
+const mime = require("mime-types");
+
+const parseRange = require("range-parser");
+
+const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
+
+const {
+  getHeaderNames,
+  getHeaderFromRequest,
+  getHeaderFromResponse,
+  setHeaderForResponse,
+  setStatusCode,
+  send,
+  sendError
+} = require("./utils/compatibleAPI");
+
+const ready = require("./utils/ready");
+/** @typedef {import("./index.js").NextFunction} NextFunction */
+
+/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("./index.js").ServerResponse} ServerResponse */
+
+/**
+ * @param {string} type
+ * @param {number} size
+ * @param {import("range-parser").Range} [range]
+ * @returns {string}
+ */
+
+
+function getValueContentRangeHeader(type, size, range) {
+  return `${type} ${range ? `${range.start}-${range.end}` : "*"}/${size}`;
+}
+/**
+ * @param {string | number} title
+ * @param {string} body
+ * @returns {string}
+ */
+
+
+function createHtmlDocument(title, body) {
+  return `${"<!DOCTYPE html>\n" + '<html lang="en">\n' + "<head>\n" + '<meta charset="utf-8">\n' + "<title>"}${title}</title>\n` + `</head>\n` + `<body>\n` + `<pre>${body}</pre>\n` + `</body>\n` + `</html>\n`;
+}
+
+const BYTES_RANGE_REGEXP = /^ *bytes/i;
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("./index.js").Context<Request, Response>} context
+ * @return {import("./index.js").Middleware<Request, Response>}
+ */
+
+function wrapper(context) {
+  return async function middleware(req, res, next) {
+    const acceptedMethods = context.options.methods || ["GET", "HEAD"]; // fixes #282. credit @cexoso. in certain edge situations res.locals is undefined.
+    // eslint-disable-next-line no-param-reassign
+
+    res.locals = res.locals || {};
+
+    if (req.method && !acceptedMethods.includes(req.method)) {
+      await goNext();
+      return;
+    }
+
+    ready(context, processRequest, req);
+
+    async function goNext() {
+      if (!context.options.serverSideRender) {
+        return next();
+      }
+
+      return new Promise(resolve => {
+        ready(context, () => {
+          /** @type {any} */
+          // eslint-disable-next-line no-param-reassign
+          res.locals.webpack = {
+            devMiddleware: context
+          };
+          resolve(next());
+        }, req);
+      });
+    }
+
+    async function processRequest() {
+      /** @type {import("./utils/getFilenameFromUrl").Extra} */
+      const extra = {};
+      const filename = getFilenameFromUrl(context,
+      /** @type {string} */
+      req.url, extra);
+
+      if (!filename) {
+        await goNext();
+        return;
+      }
+
+      if (extra.errorCode) {
+        if (extra.errorCode === 403) {
+          context.logger.error(`Malicious path "${filename}".`);
+        }
+
+        sendError(req, res, extra.errorCode);
+        return;
+      }
+
+      let {
+        headers
+      } = context.options;
+
+      if (typeof headers === "function") {
+        // @ts-ignore
+        headers = headers(req, res, context);
+      }
+      /**
+       * @type {{key: string, value: string | number}[]}
+       */
+
+
+      const allHeaders = [];
+
+      if (typeof headers !== "undefined") {
+        if (!Array.isArray(headers)) {
+          // eslint-disable-next-line guard-for-in
+          for (const name in headers) {
+            // @ts-ignore
+            allHeaders.push({
+              key: name,
+              value: headers[name]
+            });
+          }
+
+          headers = allHeaders;
+        }
+
+        headers.forEach(
+        /**
+         * @param {{key: string, value: any}} header
+         */
+        header => {
+          setHeaderForResponse(res, header.key, header.value);
+        });
+      }
+
+      if (!getHeaderFromResponse(res, "Content-Type")) {
+        // content-type name(like application/javascript; charset=utf-8) or false
+        const contentType = mime.contentType(path.extname(filename)); // Only set content-type header if media type is known
+        // https://tools.ietf.org/html/rfc7231#section-3.1.1.5
+
+        if (contentType) {
+          setHeaderForResponse(res, "Content-Type", contentType);
+        }
+      }
+
+      if (!getHeaderFromResponse(res, "Accept-Ranges")) {
+        setHeaderForResponse(res, "Accept-Ranges", "bytes");
+      }
+
+      const rangeHeader = getHeaderFromRequest(req, "range");
+      let start;
+      let end;
+
+      if (rangeHeader && BYTES_RANGE_REGEXP.test(rangeHeader)) {
+        const size = await new Promise(resolve => {
+          /** @type {import("fs").lstat} */
+          context.outputFileSystem.lstat(filename, (error, stats) => {
+            if (error) {
+              context.logger.error(error);
+              return;
+            }
+
+            resolve(stats.size);
+          });
+        });
+        const parsedRanges = parseRange(size, rangeHeader, {
+          combine: true
+        });
+
+        if (parsedRanges === -1) {
+          const message = "Unsatisfiable range for 'Range' header.";
+          context.logger.error(message);
+          const existingHeaders = getHeaderNames(res);
+
+          for (let i = 0; i < existingHeaders.length; i++) {
+            res.removeHeader(existingHeaders[i]);
+          }
+
+          setStatusCode(res, 416);
+          setHeaderForResponse(res, "Content-Range", getValueContentRangeHeader("bytes", size));
+          setHeaderForResponse(res, "Content-Type", "text/html; charset=utf-8");
+          const document = createHtmlDocument(416, `Error: ${message}`);
+          const byteLength = Buffer.byteLength(document);
+          setHeaderForResponse(res, "Content-Length", Buffer.byteLength(document));
+          send(req, res, document, byteLength);
+          return;
+        } else if (parsedRanges === -2) {
+          context.logger.error("A malformed 'Range' header was provided. A regular response will be sent for this request.");
+        } else if (parsedRanges.length > 1) {
+          context.logger.error("A 'Range' header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.");
+        }
+
+        if (parsedRanges !== -2 && parsedRanges.length === 1) {
+          // Content-Range
+          setStatusCode(res, 206);
+          setHeaderForResponse(res, "Content-Range", getValueContentRangeHeader("bytes", size,
+          /** @type {import("range-parser").Ranges} */
+          parsedRanges[0]));
+          [{
+            start,
+            end
+          }] = parsedRanges;
+        }
+      }
+
+      const isFsSupportsStream = typeof context.outputFileSystem.createReadStream === "function";
+      let bufferOtStream;
+      let byteLength;
+
+      try {
+        if (typeof start !== "undefined" && typeof end !== "undefined" && isFsSupportsStream) {
+          bufferOtStream =
+          /** @type {import("fs").createReadStream} */
+          context.outputFileSystem.createReadStream(filename, {
+            start,
+            end
+          });
+          byteLength = end - start + 1;
+        } else {
+          bufferOtStream =
+          /** @type {import("fs").readFileSync} */
+          context.outputFileSystem.readFileSync(filename);
+          ({
+            byteLength
+          } = bufferOtStream);
+        }
+      } catch (_ignoreError) {
+        await goNext();
+        return;
+      }
+
+      send(req, res, bufferOtStream, byteLength);
+    }
+  };
+}
+
+module.exports = wrapper;
Index: frontend/node_modules/webpack-dev-middleware/dist/options.json
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/options.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/options.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,125 @@
+{
+  "type": "object",
+  "properties": {
+    "mimeTypes": {
+      "description": "Allows a user to register custom mime types or extension mappings.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#mimetypes",
+      "type": "object"
+    },
+    "writeToDisk": {
+      "description": "Allows to write generated files on disk.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#writetodisk",
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "instanceof": "Function"
+        }
+      ]
+    },
+    "methods": {
+      "description": "Allows to pass the list of HTTP request methods accepted by the middleware.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#methods",
+      "type": "array",
+      "items": {
+        "type": "string",
+        "minlength": "1"
+      }
+    },
+    "headers": {
+      "anyOf": [
+        {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "additionalProperties": false,
+            "properties": {
+              "key": {
+                "description": "key of header.",
+                "type": "string"
+              },
+              "value": {
+                "description": "value of header.",
+                "type": "string"
+              }
+            }
+          },
+          "minItems": 1
+        },
+        {
+          "type": "object"
+        },
+        {
+          "instanceof": "Function"
+        }
+      ],
+      "description": "Allows to pass custom HTTP headers on each request",
+      "link": "https://github.com/webpack/webpack-dev-middleware#headers"
+    },
+    "publicPath": {
+      "description": "The `publicPath` specifies the public URL address of the output files when referenced in a browser.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#publicpath",
+      "anyOf": [
+        {
+          "enum": ["auto"]
+        },
+        {
+          "type": "string"
+        },
+        {
+          "instanceof": "Function"
+        }
+      ]
+    },
+    "stats": {
+      "description": "Stats options object or preset name.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#stats",
+      "anyOf": [
+        {
+          "enum": [
+            "none",
+            "summary",
+            "errors-only",
+            "errors-warnings",
+            "minimal",
+            "normal",
+            "detailed",
+            "verbose"
+          ]
+        },
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "object",
+          "additionalProperties": true
+        }
+      ]
+    },
+    "serverSideRender": {
+      "description": "Instructs the module to enable or disable the server-side rendering mode.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#serversiderender",
+      "type": "boolean"
+    },
+    "outputFileSystem": {
+      "description": "Set the default file system which will be used by webpack as primary destination of generated files.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#outputfilesystem",
+      "type": "object"
+    },
+    "index": {
+      "description": "Allows to serve an index of the directory.",
+      "link": "https://github.com/webpack/webpack-dev-middleware#index",
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "string",
+          "minlength": "1"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false
+}
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/compatibleAPI.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/compatibleAPI.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/compatibleAPI.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,292 @@
+"use strict";
+
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+/**
+ * @typedef {Object} ExpectedRequest
+ * @property {(name: string) => string | undefined} get
+ */
+
+/**
+ * @typedef {Object} ExpectedResponse
+ * @property {(name: string) => string | string[] | undefined} get
+ * @property {(name: string, value: number | string | string[]) => void} set
+ * @property {(status: number) => void} status
+ * @property {(data: any) => void} send
+ */
+
+/**
+ * @template {ServerResponse} Response
+ * @param {Response} res
+ * @returns {string[]}
+ */
+function getHeaderNames(res) {
+  if (typeof res.getHeaderNames !== "function") {
+    // @ts-ignore
+    // eslint-disable-next-line no-underscore-dangle
+    return Object.keys(res._headers || {});
+  }
+
+  return res.getHeaderNames();
+}
+/**
+ * @template {IncomingMessage} Request
+ * @param {Request} req
+ * @param {string} name
+ * @returns {string | undefined}
+ */
+
+
+function getHeaderFromRequest(req, name) {
+  // Express API
+  if (typeof
+  /** @type {Request & ExpectedRequest} */
+  req.get === "function") {
+    return (
+      /** @type {Request & ExpectedRequest} */
+      req.get(name)
+    );
+  } // Node.js API
+  // @ts-ignore
+
+
+  return req.headers[name];
+}
+/**
+ * @template {ServerResponse} Response
+ * @param {Response} res
+ * @param {string} name
+ * @returns {number | string | string[] | undefined}
+ */
+
+
+function getHeaderFromResponse(res, name) {
+  // Express API
+  if (typeof
+  /** @type {Response & ExpectedResponse} */
+  res.get === "function") {
+    return (
+      /** @type {Response & ExpectedResponse} */
+      res.get(name)
+    );
+  } // Node.js API
+
+
+  return res.getHeader(name);
+}
+/**
+ * @template {ServerResponse} Response
+ * @param {Response} res
+ * @param {string} name
+ * @param {number | string | string[]} value
+ * @returns {void}
+ */
+
+
+function setHeaderForResponse(res, name, value) {
+  // Express API
+  if (typeof
+  /** @type {Response & ExpectedResponse} */
+  res.set === "function") {
+    /** @type {Response & ExpectedResponse} */
+    res.set(name, typeof value === "number" ? String(value) : value);
+    return;
+  } // Node.js API
+
+
+  res.setHeader(name, value);
+}
+/**
+ * @template {ServerResponse} Response
+ * @param {Response} res
+ * @param {number} code
+ */
+
+
+function setStatusCode(res, code) {
+  if (typeof
+  /** @type {Response & ExpectedResponse} */
+  res.status === "function") {
+    /** @type {Response & ExpectedResponse} */
+    res.status(code);
+    return;
+  } // eslint-disable-next-line no-param-reassign
+
+
+  res.statusCode = code;
+}
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {Request} req
+ * @param {Response} res
+ * @param {string | Buffer | import("fs").ReadStream} bufferOtStream
+ * @param {number} byteLength
+ */
+
+
+function send(req, res, bufferOtStream, byteLength) {
+  if (typeof
+  /** @type {import("fs").ReadStream} */
+  bufferOtStream.pipe === "function") {
+    setHeaderForResponse(res, "Content-Length", byteLength);
+
+    if (req.method === "HEAD") {
+      res.end();
+      return;
+    }
+    /** @type {import("fs").ReadStream} */
+
+
+    bufferOtStream.pipe(res);
+    return;
+  }
+
+  if (typeof
+  /** @type {Response & ExpectedResponse} */
+  res.send === "function") {
+    /** @type {Response & ExpectedResponse} */
+    res.send(bufferOtStream);
+    return;
+  } // Only Node.js API used
+
+
+  res.setHeader("Content-Length", byteLength);
+
+  if (req.method === "HEAD") {
+    res.end();
+  } else {
+    res.end(bufferOtStream);
+  }
+}
+/**
+ * @template {ServerResponse} Response
+ * @param {Response} res
+ */
+
+
+function clearHeadersForResponse(res) {
+  const headers = getHeaderNames(res);
+
+  for (let i = 0; i < headers.length; i++) {
+    res.removeHeader(headers[i]);
+  }
+}
+
+const matchHtmlRegExp = /["'&<>]/;
+/**
+ * @param {string} string raw HTML
+ * @returns {string} escaped HTML
+ */
+
+function escapeHtml(string) {
+  const str = `${string}`;
+  const match = matchHtmlRegExp.exec(str);
+
+  if (!match) {
+    return str;
+  }
+
+  let escape;
+  let html = "";
+  let index = 0;
+  let lastIndex = 0;
+
+  for (({
+    index
+  } = match); index < str.length; index++) {
+    switch (str.charCodeAt(index)) {
+      // "
+      case 34:
+        escape = "&quot;";
+        break;
+      // &
+
+      case 38:
+        escape = "&amp;";
+        break;
+      // '
+
+      case 39:
+        escape = "&#39;";
+        break;
+      // <
+
+      case 60:
+        escape = "&lt;";
+        break;
+      // >
+
+      case 62:
+        escape = "&gt;";
+        break;
+
+      default:
+        // eslint-disable-next-line no-continue
+        continue;
+    }
+
+    if (lastIndex !== index) {
+      html += str.substring(lastIndex, index);
+    }
+
+    lastIndex = index + 1;
+    html += escape;
+  }
+
+  return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
+}
+/** @type {Record<number, string>} */
+
+
+const statuses = {
+  400: "Bad Request",
+  403: "Forbidden",
+  404: "Not Found",
+  416: "Range Not Satisfiable",
+  500: "Internal Server Error"
+};
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {Request} req response
+ * @param {Response} res response
+ * @param {number} status status
+ * @returns {void}
+ */
+
+function sendError(req, res, status) {
+  const content = statuses[status] || String(status);
+  const document = `<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>Error</title>
+</head>
+<body>
+<pre>${escapeHtml(content)}</pre>
+</body>
+</html>`; // Clear existing headers
+
+  clearHeadersForResponse(res); // Send basic response
+
+  setStatusCode(res, status);
+  setHeaderForResponse(res, "Content-Type", "text/html; charset=utf-8");
+  setHeaderForResponse(res, "Content-Security-Policy", "default-src 'none'");
+  setHeaderForResponse(res, "X-Content-Type-Options", "nosniff");
+  const byteLength = Buffer.byteLength(document);
+  setHeaderForResponse(res, "Content-Length", byteLength);
+  res.end(document);
+}
+
+module.exports = {
+  getHeaderNames,
+  getHeaderFromRequest,
+  getHeaderFromResponse,
+  setHeaderForResponse,
+  setStatusCode,
+  send,
+  sendError
+};
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,195 @@
+"use strict";
+
+const path = require("path");
+
+const {
+  parse
+} = require("url");
+
+const querystring = require("querystring");
+
+const getPaths = require("./getPaths");
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+
+const cacheStore = new WeakMap();
+/**
+ * @template T
+ * @param {Function} fn
+ * @param {{ cache?: Map<string, { data: T }> } | undefined} cache
+ * @param {(value: T) => T} callback
+ * @returns {any}
+ */
+// @ts-ignore
+
+const mem = (fn, {
+  cache = new Map()
+} = {}, callback) => {
+  /**
+   * @param {any} arguments_
+   * @return {any}
+   */
+  const memoized = (...arguments_) => {
+    const [key] = arguments_;
+    const cacheItem = cache.get(key);
+
+    if (cacheItem) {
+      return cacheItem.data;
+    }
+
+    let result = fn.apply(void 0, arguments_);
+    result = callback(result);
+    cache.set(key, {
+      data: result
+    });
+    return result;
+  };
+
+  cacheStore.set(memoized, cache);
+  return memoized;
+}; // eslint-disable-next-line no-undefined
+
+
+const memoizedParse = mem(parse, undefined, value => {
+  if (value.pathname) {
+    // eslint-disable-next-line no-param-reassign
+    value.pathname = decode(value.pathname);
+  }
+
+  return value;
+});
+const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
+/**
+ * @typedef {Object} Extra
+ * @property {import("fs").Stats=} stats
+ * @property {number=} errorCode
+ */
+
+/**
+ * decodeURIComponent.
+ *
+ * Allows V8 to only deoptimize this fn instead of all of send().
+ *
+ * @param {string} input
+ * @returns {string}
+ */
+
+function decode(input) {
+  return querystring.unescape(input);
+}
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("../index.js").Context<Request, Response>} context
+ * @param {string} url
+ * @param {Extra=} extra
+ * @returns {string | undefined}
+ */
+
+
+function getFilenameFromUrl(context, url, extra = {}) {
+  const {
+    options
+  } = context;
+  const paths = getPaths(context);
+  /** @type {string | undefined} */
+
+  let foundFilename;
+  /** @type {URL} */
+
+  let urlObject;
+
+  try {
+    // The `url` property of the `request` is contains only  `pathname`, `search` and `hash`
+    urlObject = memoizedParse(url, false, true);
+  } catch (_ignoreError) {
+    return;
+  }
+
+  for (const {
+    publicPath,
+    outputPath
+  } of paths) {
+    /** @type {string | undefined} */
+    let filename;
+    /** @type {URL} */
+
+    let publicPathObject;
+
+    try {
+      publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
+    } catch (_ignoreError) {
+      // eslint-disable-next-line no-continue
+      continue;
+    }
+
+    const {
+      pathname
+    } = urlObject;
+    const {
+      pathname: publicPathPathname
+    } = publicPathObject;
+
+    if (pathname && pathname.startsWith(publicPathPathname)) {
+      // Null byte(s)
+      if (pathname.includes("\0")) {
+        // eslint-disable-next-line no-param-reassign
+        extra.errorCode = 400;
+        return;
+      } // ".." is malicious
+
+
+      if (UP_PATH_REGEXP.test(path.normalize(`./${pathname}`))) {
+        // eslint-disable-next-line no-param-reassign
+        extra.errorCode = 403;
+        return;
+      } // Strip the `pathname` property from the `publicPath` option from the start of requested url
+      // `/complex/foo.js` => `foo.js`
+      // and add outputPath
+      // `foo.js` => `/home/user/my-project/dist/foo.js`
+
+
+      filename = path.join(outputPath, pathname.slice(publicPathPathname.length));
+
+      try {
+        // eslint-disable-next-line no-param-reassign
+        extra.stats =
+        /** @type {import("fs").statSync} */
+        context.outputFileSystem.statSync(filename);
+      } catch (_ignoreError) {
+        // eslint-disable-next-line no-continue
+        continue;
+      }
+
+      if (extra.stats.isFile()) {
+        foundFilename = filename;
+        break;
+      } else if (extra.stats.isDirectory() && (typeof options.index === "undefined" || options.index)) {
+        const indexValue = typeof options.index === "undefined" || typeof options.index === "boolean" ? "index.html" : options.index;
+        filename = path.join(filename, indexValue);
+
+        try {
+          // eslint-disable-next-line no-param-reassign
+          extra.stats =
+          /** @type {import("fs").statSync} */
+          context.outputFileSystem.statSync(filename);
+        } catch (__ignoreError) {
+          // eslint-disable-next-line no-continue
+          continue;
+        }
+
+        if (extra.stats.isFile()) {
+          foundFilename = filename;
+          break;
+        }
+      }
+    }
+  } // eslint-disable-next-line consistent-return
+
+
+  return foundFilename;
+}
+
+module.exports = getFilenameFromUrl;
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/getPaths.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/getPaths.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/getPaths.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,49 @@
+"use strict";
+
+/** @typedef {import("webpack").Compiler} Compiler */
+
+/** @typedef {import("webpack").Stats} Stats */
+
+/** @typedef {import("webpack").MultiStats} MultiStats */
+
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("../index.js").Context<Request, Response>} context
+ */
+function getPaths(context) {
+  const {
+    stats,
+    options
+  } = context;
+  /** @type {Stats[]} */
+
+  const childStats =
+  /** @type {MultiStats} */
+  stats.stats ?
+  /** @type {MultiStats} */
+  stats.stats : [
+  /** @type {Stats} */
+  stats];
+  const publicPaths = [];
+
+  for (const {
+    compilation
+  } of childStats) {
+    // The `output.path` is always present and always absolute
+    const outputPath = compilation.getPath(compilation.outputOptions.path || "");
+    const publicPath = options.publicPath ? compilation.getPath(options.publicPath) : compilation.outputOptions.publicPath ? compilation.getPath(compilation.outputOptions.publicPath) : "";
+    publicPaths.push({
+      outputPath,
+      publicPath
+    });
+  }
+
+  return publicPaths;
+}
+
+module.exports = getPaths;
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/ready.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/ready.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/ready.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+"use strict";
+
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("../index.js").Context<Request, Response>} context
+ * @param {(...args: any[]) => any} callback
+ * @param {Request} [req]
+ * @returns {void}
+ */
+function ready(context, callback, req) {
+  if (context.state) {
+    callback(context.stats);
+    return;
+  }
+
+  const name = req && req.url || callback.name;
+  context.logger.info(`wait until bundle finished${name ? `: ${name}` : ""}`);
+  context.callbacks.push(callback);
+}
+
+module.exports = ready;
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/setupHooks.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/setupHooks.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/setupHooks.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,216 @@
+"use strict";
+
+const webpack = require("webpack");
+
+const {
+  isColorSupported
+} = require("colorette");
+/** @typedef {import("webpack").Configuration} Configuration */
+
+/** @typedef {import("webpack").Compiler} Compiler */
+
+/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
+
+/** @typedef {import("webpack").Stats} Stats */
+
+/** @typedef {import("webpack").MultiStats} MultiStats */
+
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+/** @typedef {Configuration["stats"]} StatsOptions */
+
+/** @typedef {{ children: Configuration["stats"][] }} MultiStatsOptions */
+
+/** @typedef {Exclude<Configuration["stats"], boolean | string | undefined>} NormalizedStatsOptions */
+// TODO remove `color` after dropping webpack v4
+
+/** @typedef {{ children: StatsOptions[], colors?: any }} MultiNormalizedStatsOptions */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("../index.js").Context<Request, Response>} context
+ */
+
+
+function setupHooks(context) {
+  function invalid() {
+    if (context.state) {
+      context.logger.log("Compilation starting...");
+    } // We are now in invalid state
+    // eslint-disable-next-line no-param-reassign
+
+
+    context.state = false; // eslint-disable-next-line no-param-reassign, no-undefined
+
+    context.stats = undefined;
+  } // @ts-ignore
+
+
+  const statsForWebpack4 = webpack.Stats && webpack.Stats.presetToOptions;
+  /**
+   * @param {Configuration["stats"]} statsOptions
+   * @returns {NormalizedStatsOptions}
+   */
+
+  function normalizeStatsOptions(statsOptions) {
+    if (statsForWebpack4) {
+      if (typeof statsOptions === "undefined") {
+        // eslint-disable-next-line no-param-reassign
+        statsOptions = {};
+      } else if (typeof statsOptions === "boolean" || typeof statsOptions === "string") {
+        // @ts-ignore
+        // eslint-disable-next-line no-param-reassign
+        statsOptions = webpack.Stats.presetToOptions(statsOptions);
+      } // @ts-ignore
+
+
+      return statsOptions;
+    }
+
+    if (typeof statsOptions === "undefined") {
+      // eslint-disable-next-line no-param-reassign
+      statsOptions = {
+        preset: "normal"
+      };
+    } else if (typeof statsOptions === "boolean") {
+      // eslint-disable-next-line no-param-reassign
+      statsOptions = statsOptions ? {
+        preset: "normal"
+      } : {
+        preset: "none"
+      };
+    } else if (typeof statsOptions === "string") {
+      // eslint-disable-next-line no-param-reassign
+      statsOptions = {
+        preset: statsOptions
+      };
+    }
+
+    return statsOptions;
+  }
+  /**
+   * @param {Stats | MultiStats} stats
+   */
+
+
+  function done(stats) {
+    // We are now on valid state
+    // eslint-disable-next-line no-param-reassign
+    context.state = true; // eslint-disable-next-line no-param-reassign
+
+    context.stats = stats; // Do the stuff in nextTick, because bundle may be invalidated if a change happened while compiling
+
+    process.nextTick(() => {
+      const {
+        compiler,
+        logger,
+        options,
+        state,
+        callbacks
+      } = context; // Check if still in valid state
+
+      if (!state) {
+        return;
+      }
+
+      logger.log("Compilation finished");
+      const isMultiCompilerMode = Boolean(
+      /** @type {MultiCompiler} */
+      compiler.compilers);
+      /**
+       * @type {StatsOptions | MultiStatsOptions | NormalizedStatsOptions | MultiNormalizedStatsOptions}
+       */
+
+      let statsOptions;
+
+      if (typeof options.stats !== "undefined") {
+        statsOptions = isMultiCompilerMode ? {
+          children:
+          /** @type {MultiCompiler} */
+          compiler.compilers.map(() => options.stats)
+        } : options.stats;
+      } else {
+        statsOptions = isMultiCompilerMode ? {
+          children:
+          /** @type {MultiCompiler} */
+          compiler.compilers.map(child => child.options.stats)
+        } :
+        /** @type {Compiler} */
+        compiler.options.stats;
+      }
+
+      if (isMultiCompilerMode) {
+        /** @type {MultiNormalizedStatsOptions} */
+        statsOptions.children =
+        /** @type {MultiStatsOptions} */
+        statsOptions.children.map(
+        /**
+         * @param {StatsOptions} childStatsOptions
+         * @return {NormalizedStatsOptions}
+         */
+        childStatsOptions => {
+          // eslint-disable-next-line no-param-reassign
+          childStatsOptions = normalizeStatsOptions(childStatsOptions);
+
+          if (typeof childStatsOptions.colors === "undefined") {
+            // eslint-disable-next-line no-param-reassign
+            childStatsOptions.colors = isColorSupported;
+          }
+
+          return childStatsOptions;
+        });
+      } else {
+        /** @type {NormalizedStatsOptions} */
+        statsOptions = normalizeStatsOptions(
+        /** @type {StatsOptions} */
+        statsOptions);
+
+        if (typeof statsOptions.colors === "undefined") {
+          statsOptions.colors = isColorSupported;
+        }
+      } // TODO webpack@4 doesn't support `{ children: [{ colors: true }, { colors: true }] }` for stats
+
+
+      if (
+      /** @type {MultiCompiler} */
+      compiler.compilers && statsForWebpack4) {
+        /** @type {MultiNormalizedStatsOptions} */
+        statsOptions.colors =
+        /** @type {MultiNormalizedStatsOptions} */
+        statsOptions.children.some(
+        /**
+         * @param {StatsOptions} child
+         */
+        // @ts-ignore
+        child => child.colors);
+      }
+
+      const printedStats = stats.toString(statsOptions); // Avoid extra empty line when `stats: 'none'`
+
+      if (printedStats) {
+        // eslint-disable-next-line no-console
+        console.log(printedStats);
+      } // eslint-disable-next-line no-param-reassign
+
+
+      context.callbacks = []; // Execute callback that are delayed
+
+      callbacks.forEach(
+      /**
+       * @param {(...args: any[]) => Stats | MultiStats} callback
+       */
+      callback => {
+        callback(stats);
+      });
+    });
+  }
+
+  context.compiler.hooks.watchRun.tap("webpack-dev-middleware", invalid);
+  context.compiler.hooks.invalid.tap("webpack-dev-middleware", invalid);
+  context.compiler.hooks.done.tap("webpack-dev-middleware", done);
+}
+
+module.exports = setupHooks;
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/setupOutputFileSystem.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/setupOutputFileSystem.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/setupOutputFileSystem.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,58 @@
+"use strict";
+
+const path = require("path");
+
+const memfs = require("memfs");
+/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
+
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("../index.js").Context<Request, Response>} context
+ */
+
+
+function setupOutputFileSystem(context) {
+  let outputFileSystem;
+
+  if (context.options.outputFileSystem) {
+    const {
+      outputFileSystem: outputFileSystemFromOptions
+    } = context.options; // Todo remove when we drop webpack@4 support
+
+    if (typeof outputFileSystemFromOptions.join !== "function") {
+      throw new Error("Invalid options: options.outputFileSystem.join() method is expected");
+    } // Todo remove when we drop webpack@4 support
+    // @ts-ignore
+
+
+    if (typeof outputFileSystemFromOptions.mkdirp !== "function") {
+      throw new Error("Invalid options: options.outputFileSystem.mkdirp() method is expected");
+    }
+
+    outputFileSystem = outputFileSystemFromOptions;
+  } else {
+    outputFileSystem = memfs.createFsFromVolume(new memfs.Volume()); // TODO: remove when we drop webpack@4 support
+    // @ts-ignore
+
+    outputFileSystem.join = path.join.bind(path);
+  }
+
+  const compilers =
+  /** @type {MultiCompiler} */
+  context.compiler.compilers || [context.compiler];
+
+  for (const compiler of compilers) {
+    compiler.outputFileSystem = outputFileSystem;
+  } // @ts-ignore
+  // eslint-disable-next-line no-param-reassign
+
+
+  context.outputFileSystem = outputFileSystem;
+}
+
+module.exports = setupOutputFileSystem;
Index: frontend/node_modules/webpack-dev-middleware/dist/utils/setupWriteToDisk.js
===================================================================
--- frontend/node_modules/webpack-dev-middleware/dist/utils/setupWriteToDisk.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/webpack-dev-middleware/dist/utils/setupWriteToDisk.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,111 @@
+"use strict";
+
+const fs = require("fs");
+
+const path = require("path");
+/** @typedef {import("webpack").Compiler} Compiler */
+
+/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
+
+/** @typedef {import("webpack").Compilation} Compilation */
+
+/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
+
+/** @typedef {import("../index.js").ServerResponse} ServerResponse */
+
+/**
+ * @template {IncomingMessage} Request
+ * @template {ServerResponse} Response
+ * @param {import("../index.js").Context<Request, Response>} context
+ */
+
+
+function setupWriteToDisk(context) {
+  /**
+   * @type {Compiler[]}
+   */
+  const compilers =
+  /** @type {MultiCompiler} */
+  context.compiler.compilers || [context.compiler];
+
+  for (const compiler of compilers) {
+    compiler.hooks.emit.tap("DevMiddleware",
+    /**
+     * @param {Compilation} compilation
+     */
+    compilation => {
+      // @ts-ignore
+      if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) {
+        return;
+      }
+
+      compiler.hooks.assetEmitted.tapAsync("DevMiddleware", (file, info, callback) => {
+        /**
+         * @type {string}
+         */
+        let targetPath;
+        /**
+         * @type {Buffer}
+         */
+
+        let content; // webpack@5
+
+        if (info.compilation) {
+          ({
+            targetPath,
+            content
+          } = info);
+        } else {
+          let targetFile = file;
+          const queryStringIdx = targetFile.indexOf("?");
+
+          if (queryStringIdx >= 0) {
+            targetFile = targetFile.slice(0, queryStringIdx);
+          }
+
+          let {
+            outputPath
+          } = compiler;
+          outputPath = compilation.getPath(outputPath, {}); // @ts-ignore
+
+          content = info;
+          targetPath = path.join(outputPath, targetFile);
+        }
+
+        const {
+          writeToDisk: filter
+        } = context.options;
+        const allowWrite = filter && typeof filter === "function" ? filter(targetPath) : true;
+
+        if (!allowWrite) {
+          return callback();
+        }
+
+        const dir = path.dirname(targetPath);
+        const name = compiler.options.name ? `Child "${compiler.options.name}": ` : "";
+        return fs.mkdir(dir, {
+          recursive: true
+        }, mkdirError => {
+          if (mkdirError) {
+            context.logger.error(`${name}Unable to write "${dir}" directory to disk:\n${mkdirError}`);
+            return callback(mkdirError);
+          }
+
+          return fs.writeFile(targetPath, content, writeFileError => {
+            if (writeFileError) {
+              context.logger.error(`${name}Unable to write "${targetPath}" asset to disk:\n${writeFileError}`);
+              return callback(writeFileError);
+            }
+
+            context.logger.log(`${name}Asset written to disk: "${targetPath}"`);
+            return callback();
+          });
+        });
+      }); // @ts-ignore
+
+      compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true;
+    });
+  }
+}
+
+module.exports = setupWriteToDisk;
