Index: imaps-frontend/node_modules/readdirp/LICENSE
===================================================================
--- imaps-frontend/node_modules/readdirp/LICENSE	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/LICENSE	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com)
+
+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/readdirp/README.md
===================================================================
--- imaps-frontend/node_modules/readdirp/README.md	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/README.md	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,121 @@
+# readdirp [![Weekly downloads](https://img.shields.io/npm/dw/readdirp.svg)](https://github.com/paulmillr/readdirp)
+
+Recursive version of [fs.readdir](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback). Exposes a **stream API** and a **promise API**.
+
+Supports both ESM and common.js.
+
+```sh
+npm install readdirp
+```
+
+```javascript
+// Use streams to achieve small RAM & CPU footprint.
+// 1) Streams example with for-await.
+import readdirp from 'readdirp';
+for await (const entry of readdirp('.')) {
+  const {path} = entry;
+  console.log(`${JSON.stringify({path})}`);
+}
+
+// 2) Streams example, non for-await.
+// Print out all JS files along with their size within the current folder & subfolders.
+import readdirp from 'readdirp';
+readdirp('.', {alwaysStat: true, fileFilter: (f) => f.basename.endsWith('.js')})
+  .on('data', (entry) => {
+    const {path, stats: {size}} = entry;
+    console.log(`${JSON.stringify({path, size})}`);
+  })
+  // Optionally call stream.destroy() in `warn()` in order to abort and cause 'close' to be emitted
+  .on('warn', error => console.error('non-fatal error', error))
+  .on('error', error => console.error('fatal error', error))
+  .on('end', () => console.log('done'));
+
+// 3) Promise example. More RAM and CPU than streams / for-await.
+import { readdirpPromise } from 'readdirp';
+const files = await readdirpPromise('.');
+console.log(files.map(file => file.path));
+
+// Other options.
+import readdirp from 'readdirp';
+readdirp('test', {
+  fileFilter: (f) => f.basename.endsWith('.js'),
+  directoryFilter: (d) => d.basename !== '.git',
+  // directoryFilter: (di) => di.basename.length === 9
+  type: 'files_directories',
+  depth: 1
+});
+```
+
+## API
+
+`const stream = readdirp(root[, options])` — **Stream API**
+
+- Reads given root recursively and returns a `stream` of [entry infos](#entryinfo)
+- Optionally can be used like `for await (const entry of stream)` with node.js 10+ (`asyncIterator`).
+- `on('data', (entry) => {})` [entry info](#entryinfo) for every file / dir.
+- `on('warn', (error) => {})` non-fatal `Error` that prevents a file / dir from being processed. Example: inaccessible to the user.
+- `on('error', (error) => {})` fatal `Error` which also ends the stream. Example: illegal options where passed.
+- `on('end')` — we are done. Called when all entries were found and no more will be emitted.
+- `on('close')` — stream is destroyed via `stream.destroy()`.
+  Could be useful if you want to manually abort even on a non fatal error.
+  At that point the stream is no longer `readable` and no more entries, warning or errors are emitted
+- To learn more about streams, consult the very detailed [nodejs streams documentation](https://nodejs.org/api/stream.html)
+  or the [stream-handbook](https://github.com/substack/stream-handbook)
+
+`const entries = await readdirp.promise(root[, options])` — **Promise API**. Returns a list of [entry infos](#entryinfo).
+
+First argument is awalys `root`, path in which to start reading and recursing into subdirectories.
+
+### options
+
+- `fileFilter`: filter to include or exclude files
+    - **Function**: a function that takes an entry info as a parameter and returns true to include or false to exclude the entry
+- `directoryFilter`: filter to include/exclude directories found and to recurse into. Directories that do not pass a filter will not be recursed into.
+- `depth: 5`: depth at which to stop recursing even if more subdirectories are found
+- `type: 'files'`: determines if data events on the stream should be emitted for `'files'` (default), `'directories'`, `'files_directories'`, or `'all'`. Setting to `'all'` will also include entries for other types of file descriptors like character devices, unix sockets and named pipes.
+- `alwaysStat: false`: always return `stats` property for every file. Default is `false`, readdirp will return `Dirent` entries. Setting it to `true` can double readdir execution time - use it only when you need file `size`, `mtime` etc. Cannot be enabled on node <10.10.0.
+- `lstat: false`: include symlink entries in the stream along with files. When `true`, `fs.lstat` would be used instead of `fs.stat`
+
+### `EntryInfo`
+
+Has the following properties:
+
+- `path: 'assets/javascripts/react.js'`: path to the file/directory (relative to given root)
+- `fullPath: '/Users/dev/projects/app/assets/javascripts/react.js'`: full path to the file/directory found
+- `basename: 'react.js'`: name of the file/directory
+- `dirent: fs.Dirent`: built-in [dir entry object](https://nodejs.org/api/fs.html#fs_class_fs_dirent) - only with `alwaysStat: false`
+- `stats: fs.Stats`: built in [stat object](https://nodejs.org/api/fs.html#fs_class_fs_stats) - only with `alwaysStat: true`
+
+## Changelog
+
+- 4.0 (Aug 25, 2024) rewritten in typescript, producing hybrid common.js / esm module.
+    - Remove glob support and all dependencies
+    - Make sure you're using `let {readdirp} = require('readdirp')` in common.js
+- 3.5 (Oct 13, 2020) disallows recursive directory-based symlinks.
+  Before, it could have entered infinite loop.
+- 3.4 (Mar 19, 2020) adds support for directory-based symlinks.
+- 3.3 (Dec 6, 2019) stabilizes RAM consumption and enables perf management with `highWaterMark` option. Fixes race conditions related to `for-await` looping.
+- 3.2 (Oct 14, 2019) improves performance by 250% and makes streams implementation more idiomatic.
+- 3.1 (Jul 7, 2019) brings `bigint` support to `stat` output on Windows. This is backwards-incompatible for some cases. Be careful. It you use it incorrectly, you'll see "TypeError: Cannot mix BigInt and other types, use explicit conversions".
+- 3.0 brings huge performance improvements and stream backpressure support.
+- Upgrading 2.x to 3.x:
+    - Signature changed from `readdirp(options)` to `readdirp(root, options)`
+    - Replaced callback API with promise API.
+    - Renamed `entryType` option to `type`
+    - Renamed `entryType: 'both'` to `'files_directories'`
+    - `EntryInfo`
+        - Renamed `stat` to `stats`
+            - Emitted only when `alwaysStat: true`
+            - `dirent` is emitted instead of `stats` by default with `alwaysStat: false`
+        - Renamed `name` to `basename`
+        - Removed `parentDir` and `fullParentDir` properties
+- Supported node.js versions:
+    - 4.x: node 14+
+    - 3.x: node 8+
+    - 2.x: node 0.6+
+
+## License
+
+Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (<https://paulmillr.com>)
+
+MIT License, see [LICENSE](LICENSE) file.
Index: imaps-frontend/node_modules/readdirp/esm/index.d.ts
===================================================================
--- imaps-frontend/node_modules/readdirp/esm/index.d.ts	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/esm/index.d.ts	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,67 @@
+import type { Stats, Dirent } from 'fs';
+import { Readable } from 'stream';
+export type Path = string;
+export interface EntryInfo {
+    path: string;
+    fullPath: string;
+    stats?: Stats;
+    dirent?: Dirent;
+    basename: string;
+}
+export type PathOrDirent = Dirent | Path;
+export type Tester = (path: EntryInfo) => boolean;
+export type Predicate = string[] | string | Tester;
+declare function defaultOptions(): {
+    root: string;
+    fileFilter: (_path: EntryInfo) => boolean;
+    directoryFilter: (_path: EntryInfo) => boolean;
+    type: string;
+    lstat: boolean;
+    depth: number;
+    alwaysStat: boolean;
+    highWaterMark: number;
+};
+export type ReaddirpOptions = ReturnType<typeof defaultOptions>;
+export interface DirEntry {
+    files: PathOrDirent[];
+    depth: number;
+    path: Path;
+}
+export declare class ReaddirpStream extends Readable {
+    parents: any[];
+    reading: boolean;
+    parent?: DirEntry;
+    _stat: Function;
+    _maxDepth: number;
+    _wantsDir: boolean;
+    _wantsFile: boolean;
+    _wantsEverything: boolean;
+    _root: Path;
+    _isDirent: boolean;
+    _statsProp: 'dirent' | 'stats';
+    _rdOptions: {
+        encoding: 'utf8';
+        withFileTypes: boolean;
+    };
+    _fileFilter: Tester;
+    _directoryFilter: Tester;
+    constructor(options?: Partial<ReaddirpOptions>);
+    _read(batch: number): Promise<void>;
+    _exploreDir(path: Path, depth: number): Promise<{
+        files: string[] | undefined;
+        depth: number;
+        path: string;
+    }>;
+    _formatEntry(dirent: PathOrDirent, path: Path): Promise<EntryInfo | undefined>;
+    _onError(err: Error): void;
+    _getEntryType(entry: EntryInfo): Promise<void | "" | "file" | "directory">;
+    _includeAsFile(entry: EntryInfo): boolean | undefined;
+}
+/**
+ * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
+ * @param root Root directory
+ * @param options Options to specify root (start directory), filters and recursion depth
+ */
+export declare const readdirp: (root: Path, options?: Partial<ReaddirpOptions>) => ReaddirpStream;
+export declare const readdirpPromise: (root: Path, options?: Partial<ReaddirpOptions>) => Promise<string[]>;
+export default readdirp;
Index: imaps-frontend/node_modules/readdirp/esm/index.js
===================================================================
--- imaps-frontend/node_modules/readdirp/esm/index.js	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/esm/index.js	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,238 @@
+import { stat, lstat, readdir, realpath } from 'fs/promises';
+import { Readable } from 'stream';
+import { resolve as pathResolve, relative as pathRelative, join as pathJoin, sep as pathSep, } from 'path';
+function defaultOptions() {
+    return {
+        root: '.',
+        fileFilter: (_path) => true,
+        directoryFilter: (_path) => true,
+        type: FILE_TYPE,
+        lstat: false,
+        depth: 2147483648,
+        alwaysStat: false,
+        highWaterMark: 4096,
+    };
+}
+const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR';
+const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]);
+const FILE_TYPE = 'files';
+const DIR_TYPE = 'directories';
+const FILE_DIR_TYPE = 'files_directories';
+const EVERYTHING_TYPE = 'all';
+const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];
+const DIR_TYPES = new Set([DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]);
+const FILE_TYPES = new Set([FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]);
+const isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code);
+const wantBigintFsStats = process.platform === 'win32';
+const emptyFn = (_path) => true;
+const normalizeFilter = (filter) => {
+    if (filter === undefined)
+        return emptyFn;
+    if (typeof filter === 'function')
+        return filter;
+    if (typeof filter === 'string') {
+        const fl = filter.trim();
+        return (entry) => entry.basename === fl;
+    }
+    if (Array.isArray(filter)) {
+        const trItems = filter.map((item) => item.trim());
+        return (entry) => trItems.some((f) => entry.basename === f);
+    }
+    return emptyFn;
+};
+export class ReaddirpStream extends Readable {
+    constructor(options = {}) {
+        super({
+            objectMode: true,
+            autoDestroy: true,
+            highWaterMark: options.highWaterMark,
+        });
+        const opts = { ...defaultOptions(), ...options };
+        const { root, type } = opts;
+        this._fileFilter = normalizeFilter(opts.fileFilter);
+        this._directoryFilter = normalizeFilter(opts.directoryFilter);
+        const statMethod = opts.lstat ? lstat : stat;
+        // Use bigint stats if it's windows and stat() supports options (node 10+).
+        if (wantBigintFsStats) {
+            this._stat = (path) => statMethod(path, { bigint: true });
+        }
+        else {
+            this._stat = statMethod;
+        }
+        this._maxDepth = opts.depth;
+        this._wantsDir = DIR_TYPES.has(type);
+        this._wantsFile = FILE_TYPES.has(type);
+        this._wantsEverything = type === EVERYTHING_TYPE;
+        this._root = pathResolve(root);
+        this._isDirent = !opts.alwaysStat;
+        this._statsProp = this._isDirent ? 'dirent' : 'stats';
+        this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };
+        // Launch stream with one parent, the root dir.
+        this.parents = [this._exploreDir(root, 1)];
+        this.reading = false;
+        this.parent = undefined;
+    }
+    async _read(batch) {
+        if (this.reading)
+            return;
+        this.reading = true;
+        try {
+            while (!this.destroyed && batch > 0) {
+                const par = this.parent;
+                const fil = par && par.files;
+                if (fil && fil.length > 0) {
+                    const { path, depth } = par;
+                    const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path));
+                    const awaited = await Promise.all(slice);
+                    for (const entry of awaited) {
+                        if (!entry) {
+                            batch--;
+                            return;
+                        }
+                        if (this.destroyed)
+                            return;
+                        const entryType = await this._getEntryType(entry);
+                        if (entryType === 'directory' && this._directoryFilter(entry)) {
+                            if (depth <= this._maxDepth) {
+                                this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
+                            }
+                            if (this._wantsDir) {
+                                this.push(entry);
+                                batch--;
+                            }
+                        }
+                        else if ((entryType === 'file' || this._includeAsFile(entry)) &&
+                            this._fileFilter(entry)) {
+                            if (this._wantsFile) {
+                                this.push(entry);
+                                batch--;
+                            }
+                        }
+                    }
+                }
+                else {
+                    const parent = this.parents.pop();
+                    if (!parent) {
+                        this.push(null);
+                        break;
+                    }
+                    this.parent = await parent;
+                    if (this.destroyed)
+                        return;
+                }
+            }
+        }
+        catch (error) {
+            this.destroy(error);
+        }
+        finally {
+            this.reading = false;
+        }
+    }
+    async _exploreDir(path, depth) {
+        let files;
+        try {
+            files = await readdir(path, this._rdOptions);
+        }
+        catch (error) {
+            this._onError(error);
+        }
+        return { files, depth, path };
+    }
+    async _formatEntry(dirent, path) {
+        let entry;
+        const basename = this._isDirent ? dirent.name : dirent;
+        try {
+            const fullPath = pathResolve(pathJoin(path, basename));
+            entry = { path: pathRelative(this._root, fullPath), fullPath, basename };
+            entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
+        }
+        catch (err) {
+            this._onError(err);
+            return;
+        }
+        return entry;
+    }
+    _onError(err) {
+        if (isNormalFlowError(err) && !this.destroyed) {
+            this.emit('warn', err);
+        }
+        else {
+            this.destroy(err);
+        }
+    }
+    async _getEntryType(entry) {
+        // entry may be undefined, because a warning or an error were emitted
+        // and the statsProp is undefined
+        if (!entry && this._statsProp in entry) {
+            return '';
+        }
+        const stats = entry[this._statsProp];
+        if (stats.isFile())
+            return 'file';
+        if (stats.isDirectory())
+            return 'directory';
+        if (stats && stats.isSymbolicLink()) {
+            const full = entry.fullPath;
+            try {
+                const entryRealPath = await realpath(full);
+                const entryRealPathStats = await lstat(entryRealPath);
+                if (entryRealPathStats.isFile()) {
+                    return 'file';
+                }
+                if (entryRealPathStats.isDirectory()) {
+                    const len = entryRealPath.length;
+                    if (full.startsWith(entryRealPath) && full.substr(len, 1) === pathSep) {
+                        const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
+                        // @ts-ignore
+                        recursiveError.code = RECURSIVE_ERROR_CODE;
+                        return this._onError(recursiveError);
+                    }
+                    return 'directory';
+                }
+            }
+            catch (error) {
+                this._onError(error);
+                return '';
+            }
+        }
+    }
+    _includeAsFile(entry) {
+        const stats = entry && entry[this._statsProp];
+        return stats && this._wantsEverything && !stats.isDirectory();
+    }
+}
+/**
+ * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
+ * @param root Root directory
+ * @param options Options to specify root (start directory), filters and recursion depth
+ */
+export const readdirp = (root, options = {}) => {
+    // @ts-ignore
+    let type = options.entryType || options.type;
+    if (type === 'both')
+        type = FILE_DIR_TYPE; // backwards-compatibility
+    if (type)
+        options.type = type;
+    if (!root) {
+        throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
+    }
+    else if (typeof root !== 'string') {
+        throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
+    }
+    else if (type && !ALL_TYPES.includes(type)) {
+        throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
+    }
+    options.root = root;
+    return new ReaddirpStream(options);
+};
+export const readdirpPromise = (root, options = {}) => {
+    return new Promise((resolve, reject) => {
+        const files = [];
+        readdirp(root, options)
+            .on('data', (entry) => files.push(entry))
+            .on('end', () => resolve(files))
+            .on('error', (error) => reject(error));
+    });
+};
+export default readdirp;
Index: imaps-frontend/node_modules/readdirp/esm/package.json
===================================================================
--- imaps-frontend/node_modules/readdirp/esm/package.json	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/esm/package.json	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,1 @@
+{ "type": "module", "sideEffects": false }
Index: imaps-frontend/node_modules/readdirp/index.d.ts
===================================================================
--- imaps-frontend/node_modules/readdirp/index.d.ts	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/index.d.ts	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,67 @@
+import type { Stats, Dirent } from 'fs';
+import { Readable } from 'stream';
+export type Path = string;
+export interface EntryInfo {
+    path: string;
+    fullPath: string;
+    stats?: Stats;
+    dirent?: Dirent;
+    basename: string;
+}
+export type PathOrDirent = Dirent | Path;
+export type Tester = (path: EntryInfo) => boolean;
+export type Predicate = string[] | string | Tester;
+declare function defaultOptions(): {
+    root: string;
+    fileFilter: (_path: EntryInfo) => boolean;
+    directoryFilter: (_path: EntryInfo) => boolean;
+    type: string;
+    lstat: boolean;
+    depth: number;
+    alwaysStat: boolean;
+    highWaterMark: number;
+};
+export type ReaddirpOptions = ReturnType<typeof defaultOptions>;
+export interface DirEntry {
+    files: PathOrDirent[];
+    depth: number;
+    path: Path;
+}
+export declare class ReaddirpStream extends Readable {
+    parents: any[];
+    reading: boolean;
+    parent?: DirEntry;
+    _stat: Function;
+    _maxDepth: number;
+    _wantsDir: boolean;
+    _wantsFile: boolean;
+    _wantsEverything: boolean;
+    _root: Path;
+    _isDirent: boolean;
+    _statsProp: 'dirent' | 'stats';
+    _rdOptions: {
+        encoding: 'utf8';
+        withFileTypes: boolean;
+    };
+    _fileFilter: Tester;
+    _directoryFilter: Tester;
+    constructor(options?: Partial<ReaddirpOptions>);
+    _read(batch: number): Promise<void>;
+    _exploreDir(path: Path, depth: number): Promise<{
+        files: string[] | undefined;
+        depth: number;
+        path: string;
+    }>;
+    _formatEntry(dirent: PathOrDirent, path: Path): Promise<EntryInfo | undefined>;
+    _onError(err: Error): void;
+    _getEntryType(entry: EntryInfo): Promise<void | "" | "file" | "directory">;
+    _includeAsFile(entry: EntryInfo): boolean | undefined;
+}
+/**
+ * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
+ * @param root Root directory
+ * @param options Options to specify root (start directory), filters and recursion depth
+ */
+export declare const readdirp: (root: Path, options?: Partial<ReaddirpOptions>) => ReaddirpStream;
+export declare const readdirpPromise: (root: Path, options?: Partial<ReaddirpOptions>) => Promise<string[]>;
+export default readdirp;
Index: imaps-frontend/node_modules/readdirp/index.js
===================================================================
--- imaps-frontend/node_modules/readdirp/index.js	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/index.js	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,244 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.readdirpPromise = exports.readdirp = exports.ReaddirpStream = void 0;
+const promises_1 = require("fs/promises");
+const stream_1 = require("stream");
+const path_1 = require("path");
+function defaultOptions() {
+    return {
+        root: '.',
+        fileFilter: (_path) => true,
+        directoryFilter: (_path) => true,
+        type: FILE_TYPE,
+        lstat: false,
+        depth: 2147483648,
+        alwaysStat: false,
+        highWaterMark: 4096,
+    };
+}
+const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR';
+const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]);
+const FILE_TYPE = 'files';
+const DIR_TYPE = 'directories';
+const FILE_DIR_TYPE = 'files_directories';
+const EVERYTHING_TYPE = 'all';
+const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];
+const DIR_TYPES = new Set([DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]);
+const FILE_TYPES = new Set([FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]);
+const isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code);
+const wantBigintFsStats = process.platform === 'win32';
+const emptyFn = (_path) => true;
+const normalizeFilter = (filter) => {
+    if (filter === undefined)
+        return emptyFn;
+    if (typeof filter === 'function')
+        return filter;
+    if (typeof filter === 'string') {
+        const fl = filter.trim();
+        return (entry) => entry.basename === fl;
+    }
+    if (Array.isArray(filter)) {
+        const trItems = filter.map((item) => item.trim());
+        return (entry) => trItems.some((f) => entry.basename === f);
+    }
+    return emptyFn;
+};
+class ReaddirpStream extends stream_1.Readable {
+    constructor(options = {}) {
+        super({
+            objectMode: true,
+            autoDestroy: true,
+            highWaterMark: options.highWaterMark,
+        });
+        const opts = { ...defaultOptions(), ...options };
+        const { root, type } = opts;
+        this._fileFilter = normalizeFilter(opts.fileFilter);
+        this._directoryFilter = normalizeFilter(opts.directoryFilter);
+        const statMethod = opts.lstat ? promises_1.lstat : promises_1.stat;
+        // Use bigint stats if it's windows and stat() supports options (node 10+).
+        if (wantBigintFsStats) {
+            this._stat = (path) => statMethod(path, { bigint: true });
+        }
+        else {
+            this._stat = statMethod;
+        }
+        this._maxDepth = opts.depth;
+        this._wantsDir = DIR_TYPES.has(type);
+        this._wantsFile = FILE_TYPES.has(type);
+        this._wantsEverything = type === EVERYTHING_TYPE;
+        this._root = (0, path_1.resolve)(root);
+        this._isDirent = !opts.alwaysStat;
+        this._statsProp = this._isDirent ? 'dirent' : 'stats';
+        this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };
+        // Launch stream with one parent, the root dir.
+        this.parents = [this._exploreDir(root, 1)];
+        this.reading = false;
+        this.parent = undefined;
+    }
+    async _read(batch) {
+        if (this.reading)
+            return;
+        this.reading = true;
+        try {
+            while (!this.destroyed && batch > 0) {
+                const par = this.parent;
+                const fil = par && par.files;
+                if (fil && fil.length > 0) {
+                    const { path, depth } = par;
+                    const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path));
+                    const awaited = await Promise.all(slice);
+                    for (const entry of awaited) {
+                        if (!entry) {
+                            batch--;
+                            return;
+                        }
+                        if (this.destroyed)
+                            return;
+                        const entryType = await this._getEntryType(entry);
+                        if (entryType === 'directory' && this._directoryFilter(entry)) {
+                            if (depth <= this._maxDepth) {
+                                this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
+                            }
+                            if (this._wantsDir) {
+                                this.push(entry);
+                                batch--;
+                            }
+                        }
+                        else if ((entryType === 'file' || this._includeAsFile(entry)) &&
+                            this._fileFilter(entry)) {
+                            if (this._wantsFile) {
+                                this.push(entry);
+                                batch--;
+                            }
+                        }
+                    }
+                }
+                else {
+                    const parent = this.parents.pop();
+                    if (!parent) {
+                        this.push(null);
+                        break;
+                    }
+                    this.parent = await parent;
+                    if (this.destroyed)
+                        return;
+                }
+            }
+        }
+        catch (error) {
+            this.destroy(error);
+        }
+        finally {
+            this.reading = false;
+        }
+    }
+    async _exploreDir(path, depth) {
+        let files;
+        try {
+            files = await (0, promises_1.readdir)(path, this._rdOptions);
+        }
+        catch (error) {
+            this._onError(error);
+        }
+        return { files, depth, path };
+    }
+    async _formatEntry(dirent, path) {
+        let entry;
+        const basename = this._isDirent ? dirent.name : dirent;
+        try {
+            const fullPath = (0, path_1.resolve)((0, path_1.join)(path, basename));
+            entry = { path: (0, path_1.relative)(this._root, fullPath), fullPath, basename };
+            entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
+        }
+        catch (err) {
+            this._onError(err);
+            return;
+        }
+        return entry;
+    }
+    _onError(err) {
+        if (isNormalFlowError(err) && !this.destroyed) {
+            this.emit('warn', err);
+        }
+        else {
+            this.destroy(err);
+        }
+    }
+    async _getEntryType(entry) {
+        // entry may be undefined, because a warning or an error were emitted
+        // and the statsProp is undefined
+        if (!entry && this._statsProp in entry) {
+            return '';
+        }
+        const stats = entry[this._statsProp];
+        if (stats.isFile())
+            return 'file';
+        if (stats.isDirectory())
+            return 'directory';
+        if (stats && stats.isSymbolicLink()) {
+            const full = entry.fullPath;
+            try {
+                const entryRealPath = await (0, promises_1.realpath)(full);
+                const entryRealPathStats = await (0, promises_1.lstat)(entryRealPath);
+                if (entryRealPathStats.isFile()) {
+                    return 'file';
+                }
+                if (entryRealPathStats.isDirectory()) {
+                    const len = entryRealPath.length;
+                    if (full.startsWith(entryRealPath) && full.substr(len, 1) === path_1.sep) {
+                        const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
+                        // @ts-ignore
+                        recursiveError.code = RECURSIVE_ERROR_CODE;
+                        return this._onError(recursiveError);
+                    }
+                    return 'directory';
+                }
+            }
+            catch (error) {
+                this._onError(error);
+                return '';
+            }
+        }
+    }
+    _includeAsFile(entry) {
+        const stats = entry && entry[this._statsProp];
+        return stats && this._wantsEverything && !stats.isDirectory();
+    }
+}
+exports.ReaddirpStream = ReaddirpStream;
+/**
+ * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
+ * @param root Root directory
+ * @param options Options to specify root (start directory), filters and recursion depth
+ */
+const readdirp = (root, options = {}) => {
+    // @ts-ignore
+    let type = options.entryType || options.type;
+    if (type === 'both')
+        type = FILE_DIR_TYPE; // backwards-compatibility
+    if (type)
+        options.type = type;
+    if (!root) {
+        throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
+    }
+    else if (typeof root !== 'string') {
+        throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
+    }
+    else if (type && !ALL_TYPES.includes(type)) {
+        throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
+    }
+    options.root = root;
+    return new ReaddirpStream(options);
+};
+exports.readdirp = readdirp;
+const readdirpPromise = (root, options = {}) => {
+    return new Promise((resolve, reject) => {
+        const files = [];
+        (0, exports.readdirp)(root, options)
+            .on('data', (entry) => files.push(entry))
+            .on('end', () => resolve(files))
+            .on('error', (error) => reject(error));
+    });
+};
+exports.readdirpPromise = readdirpPromise;
+exports.default = exports.readdirp;
Index: imaps-frontend/node_modules/readdirp/package.json
===================================================================
--- imaps-frontend/node_modules/readdirp/package.json	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/node_modules/readdirp/package.json	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,78 @@
+{
+  "name": "readdirp",
+  "description": "Recursive version of fs.readdir with streaming API.",
+  "version": "4.0.2",
+  "homepage": "https://github.com/paulmillr/readdirp",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/paulmillr/readdirp.git"
+  },
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/paulmillr/readdirp/issues"
+  },
+  "author": "Thorsten Lorenz <thlorenz@gmx.de> (thlorenz.com)",
+  "contributors": [
+    "Thorsten Lorenz <thlorenz@gmx.de> (thlorenz.com)",
+    "Paul Miller (https://paulmillr.com)"
+  ],
+  "engines": {
+    "node": ">= 14.16.0"
+  },
+  "files": [
+    "index.js",
+    "index.d.ts",
+    "index.d.ts.map",
+    "index.js.map",
+    "esm"
+  ],
+  "main": "./index.js",
+  "module": "./esm/index.js",
+  "types": "./index.d.ts",
+  "exports": {
+    ".": {
+      "import": "./esm/index.js",
+      "require": "./index.js"
+    }
+  },
+  "sideEffects": false,
+  "keywords": [
+    "recursive",
+    "fs",
+    "stream",
+    "streams",
+    "readdir",
+    "filesystem",
+    "find",
+    "filter"
+  ],
+  "scripts": {
+    "build": "tsc && tsc -p tsconfig.esm.json",
+    "nyc": "nyc",
+    "mocha": "mocha --exit",
+    "lint": "prettier --check index.ts",
+    "format": "prettier --write index.ts",
+    "test": "nyc npm run mocha"
+  },
+  "devDependencies": {
+    "@paulmillr/jsbt": "0.2.1",
+    "@types/node": "20.14.8",
+    "chai": "4.3.4",
+    "chai-subset": "1.6.0",
+    "mocha": "10.7.3",
+    "nyc": "15.0.1",
+    "prettier": "3.1.1",
+    "rimraf": "6.0.1",
+    "typescript": "5.5.2"
+  },
+  "nyc": {
+    "reporter": [
+      "html",
+      "text"
+    ]
+  },
+  "funding": {
+    "type": "individual",
+    "url": "https://paulmillr.com/funding/"
+  }
+}
