@photostructure/fs-metadata 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -14,6 +14,10 @@ Fixed for any bug fixes.
14
14
  Security in case of vulnerabilities.
15
15
  -->
16
16
 
17
+ ## [0.4.0] - 2025-01-09
18
+
19
+ - `Fixed`: Switch to thread-safe `getmntinfo_r_np()` for macOS. Improved darwin resource management.
20
+
17
21
  ## [0.3.3] - 2025-01-08
18
22
 
19
23
  - `Packaging`: Improved ESM/CJS support with common `__dirname` implementation thanks to `tsup` [shims](https://tsup.egoist.dev/#inject-cjs-and-esm-shims).
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/debuglog.ts","../src/defer.ts","../src/stack_path.ts","../src/platform.ts","../src/string.ts","../src/dirname.ts","../src/fs.ts","../src/async.ts","../src/number.ts","../src/units.ts","../src/hidden.ts","../src/object.ts","../src/error.ts","../src/path.ts","../src/options.ts","../src/string_enum.ts","../src/volume_health_status.ts","../src/linux/dev_disk.ts","../src/linux/mount_points.ts","../src/mount_point.ts","../src/remote_info.ts","../src/glob.ts","../src/system_volume.ts","../src/linux/mtab.ts","../src/unc.ts","../src/uuid.ts","../src/array.ts","../src/volume_mount_points.ts","../src/volume_metadata.ts"],"sourcesContent":["// src/index.ts\n\nimport NodeGypBuild from \"node-gyp-build\";\nimport { debug, debugLogContext, isDebugEnabled } from \"./debuglog.js\";\nimport { defer } from \"./defer.js\";\nimport { _dirname } from \"./dirname.js\";\nimport { findAncestorDir } from \"./fs.js\";\nimport type { HideMethod, SetHiddenResult } from \"./hidden.js\";\nimport {\n getHiddenMetadataImpl,\n isHiddenImpl,\n isHiddenRecursiveImpl,\n setHiddenImpl,\n} from \"./hidden.js\";\nimport {\n IncludeSystemVolumesDefault,\n LinuxMountTablePathsDefault,\n OptionsDefault,\n optionsWithDefaults,\n SystemFsTypesDefault,\n SystemPathPatternsDefault,\n TimeoutMsDefault,\n} from \"./options.js\";\nimport type {\n StringEnum,\n StringEnumKeys,\n StringEnumType,\n} from \"./string_enum.js\";\nimport type { SystemVolumeConfig } from \"./system_volume.js\";\nimport type { HiddenMetadata } from \"./types/hidden_metadata.js\";\nimport type { MountPoint } from \"./types/mount_point.js\";\nimport { NativeBindings } from \"./types/native_bindings.js\";\nimport type { Options } from \"./types/options.js\";\nimport type { VolumeMetadata } from \"./types/volume_metadata.js\";\nimport type { VolumeHealthStatus } from \"./volume_health_status.js\";\nimport { VolumeHealthStatuses } from \"./volume_health_status.js\";\nimport {\n getAllVolumeMetadataImpl,\n getVolumeMetadataImpl,\n} from \"./volume_metadata.js\";\nimport type { GetVolumeMountPointOptions } from \"./volume_mount_points.js\";\nimport { getVolumeMountPointsImpl } from \"./volume_mount_points.js\";\n\nexport type {\n GetVolumeMountPointOptions,\n HiddenMetadata,\n HideMethod,\n MountPoint,\n Options,\n SetHiddenResult,\n StringEnum,\n StringEnumKeys,\n StringEnumType,\n SystemVolumeConfig,\n VolumeHealthStatus,\n VolumeMetadata,\n};\n\nconst nativeFn = defer<Promise<NativeBindings>>(async () => {\n const start = Date.now();\n try {\n const dirname = _dirname();\n const dir = await findAncestorDir(dirname, \"binding.gyp\");\n if (dir == null) {\n throw new Error(\n \"Could not find bindings.gyp in any ancestor directory of \" + dirname,\n );\n }\n const bindings = NodeGypBuild(dir) as NativeBindings;\n bindings.setDebugLogging(isDebugEnabled());\n bindings.setDebugPrefix(debugLogContext() + \":native\");\n return bindings;\n } catch (error) {\n debug(\"Loading native bindings failed: %s\", error);\n throw error;\n } finally {\n debug(`Native bindings took %d ms to load`, Date.now() - start);\n }\n});\n\n/**\n * List all active local and remote mount points on the system.\n *\n * Only readable directories are included in the results.\n *\n * Note that on Windows, `timeoutMs` will be used **per system call** and not\n * for the entire operation.\n *\n * @param opts Optional filesystem operation settings to override default values\n */\nexport function getVolumeMountPoints(\n opts?: Partial<GetVolumeMountPointOptions>,\n): Promise<MountPoint[]> {\n return getVolumeMountPointsImpl(optionsWithDefaults(opts), nativeFn);\n}\n\n/**\n * Get metadata for the volume at the given mount point.\n *\n * @param mountPoint Must be a non-blank string\n * @param opts Optional filesystem operation settings\n */\nexport function getVolumeMetadata(\n mountPoint: string,\n opts?: Partial<Pick<Options, \"timeoutMs\">>,\n): Promise<VolumeMetadata> {\n return getVolumeMetadataImpl(\n { ...optionsWithDefaults(opts), mountPoint },\n nativeFn,\n );\n}\n\n/**\n * Retrieves metadata for all mounted volumes with optional filtering and\n * concurrency control.\n *\n * @param opts - Optional configuration object\n * @param opts.includeSystemVolumes - If true, includes system volumes in the\n * results. Defaults to true on Windows and false elsewhere.\n * @param opts.maxConcurrency - Maximum number of concurrent operations.\n * Defaults to the system's available parallelism: see\n * {@link https://nodejs.org/api/os.html#osavailableparallelism | os.availableParallelism()}\n * @param opts.timeoutMs - Maximum time to wait for\n * {@link getVolumeMountPointsImpl}, as well as **each** {@link getVolumeMetadataImpl}\n * to complete. Defaults to {@link TimeoutMsDefault}\n * @returns Promise that resolves to an array of either VolumeMetadata objects\n * or error objects containing the mount point and error\n * @throws Never - errors are caught and returned as part of the result array\n */\nexport function getAllVolumeMetadata(\n opts?: Partial<Options> & { includeSystemVolumes?: boolean },\n): Promise<VolumeMetadata[]> {\n return getAllVolumeMetadataImpl(optionsWithDefaults(opts), nativeFn);\n}\n\n/**\n * Check if a file or directory is hidden.\n *\n * Note that `path` may be _effectively_ hidden if any of the ancestor\n * directories are hidden: use {@link isHiddenRecursive} to check for this.\n *\n * @param pathname Path to file or directory\n * @returns Promise resolving to boolean indicating hidden state\n */\nexport function isHidden(pathname: string): Promise<boolean> {\n return isHiddenImpl(pathname, nativeFn);\n}\n\n/**\n * Check if a file or directory is hidden, or if any of its ancestor\n * directories are hidden.\n *\n * @param pathname Path to file or directory\n * @returns Promise resolving to boolean indicating hidden state\n */\nexport function isHiddenRecursive(pathname: string): Promise<boolean> {\n return isHiddenRecursiveImpl(pathname, nativeFn);\n}\n\n/**\n * Get detailed metadata about the hidden state of a file or directory.\n *\n * @param pathname Path to file or directory\n * @returns Promise resolving to metadata about the hidden state\n */\nexport function getHiddenMetadata(pathname: string): Promise<HiddenMetadata> {\n return getHiddenMetadataImpl(pathname, nativeFn);\n}\n\n/**\n * Set the hidden state of a file or directory\n *\n * @param pathname Path to file or directory\n * @param hidden - Whether the item should be hidden (true) or visible (false)\n * @param method Method to use for hiding the file or directory. The default\n * is \"auto\", which is \"dotPrefix\" on Linux and macOS, and \"systemFlag\" on\n * Windows. \"all\" will attempt to use all relevant methods for the current\n * operating system.\n * @returns Promise resolving the final name of the file or directory (as it\n * will change on POSIX systems), and the action(s) taken.\n * @throws {Error} If the file doesn't exist, permissions are insufficient, or\n * the requested method is unsupported\n */\nexport function setHidden(\n pathname: string,\n hidden: boolean,\n method: HideMethod = \"auto\",\n): Promise<SetHiddenResult> {\n return setHiddenImpl(pathname, hidden, method, nativeFn);\n}\n\nexport {\n IncludeSystemVolumesDefault,\n LinuxMountTablePathsDefault,\n OptionsDefault,\n optionsWithDefaults,\n SystemFsTypesDefault,\n SystemPathPatternsDefault,\n TimeoutMsDefault,\n VolumeHealthStatuses,\n};\n","import { debuglog, format } from \"node:util\";\n\n// inlined as a hack to get around relative imports broken in ts-node (used by\n// the debuglog tests):\nfunction defer<T>(thunk: () => T) {\n let t: T;\n return () => (t ??= thunk());\n}\n\nexport const debugLogContext = defer(() => {\n for (const ea of [\"fs-metadata\", \"fs-meta\"]) {\n if (debuglog(ea).enabled) {\n return ea;\n }\n if (debuglog(ea.toUpperCase()).enabled) {\n return ea;\n }\n }\n return \"photostructure:fs-metadata\";\n});\n\nexport const isDebugEnabled = defer(() => {\n return debuglog(debugLogContext()).enabled ?? false;\n});\n\nexport function debug(msg: string, ...args: unknown[]) {\n if (!isDebugEnabled()) return;\n const now = new Date();\n\n // Format: [HH:MM:SS.mmm] prefix: message\n const timestamp = `[${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}.${now.getMilliseconds().toString().padStart(3, \"0\")}] ${debugLogContext()} `;\n\n process.stderr.write(timestamp + format(msg, ...args) + \"\\n\");\n}\n","// src/defer.ts\n\nexport type Defer<T> = (() => T) & {\n reset: () => void;\n};\n\n/**\n * Creates a deferred value that is computed once on first access and cached for\n * subsequent accesses.\n * @param thunk A function that takes no arguments and returns a value\n * @returns A function that returns the computed value\n */\nexport function defer<T>(thunk: () => T): Defer<T> {\n let computed = false;\n let value: T;\n\n const fn = () => {\n if (!computed) {\n computed = true;\n value = thunk();\n }\n return value;\n };\n\n fn.reset = () => {\n computed = false;\n };\n\n return fn;\n}\n","import { dirname } from \"node:path\";\nimport { isWindows } from \"./platform\";\nimport { isNotBlank, toS } from \"./string\";\n\nexport function getCallerDirname(): string {\n const e = new Error();\n if (e.stack == null) {\n Error.captureStackTrace(e);\n }\n return dirname(extractCallerPath(e.stack as string));\n}\n\n// CURSE THE ESM MODULE SYSTEM 💩 THIS IS ALL HORRIBLE\n\n// THANK GOODNESS for tsup shims: this should only be used when running tests.\n\n// Comprehensive regex patterns for different stack frame formats. Note that we\n// only expect tests to have the first standard form, but if something's worth\n// doing, **it's worth overdoing**.\nconst patterns = isWindows\n ? [\n // Standard: \"at functionName (C:\\path\\file.js:1:1)\"\n /\\bat\\s.+?\\((?<path>[A-Z]:\\\\.+):\\d+:\\d+\\)$/,\n // direct: \"at C:\\path\\file.js:1:1\"\n /\\bat\\s(?<path>[A-Z]:\\\\.+):\\d+:\\d+$/,\n // UNC: \"at functionName (\\\\server\\share\\path\\file.js:1:1)\"\n /\\bat\\s.+?\\((?<path>\\\\\\\\.+):\\d+:\\d+\\)$/,\n // direct: \"at \\\\server\\share\\path\\file.js:1:1\"\n /\\bat\\s(?<path>\\\\\\\\.+):\\d+:\\d+$/,\n ]\n : [\n // Standard: \"at functionName (/path/file.js:1:1)\"\n /\\bat\\s.+?\\((?<path>\\/.+?):\\d+:\\d+\\)$/,\n // Anonymous or direct: \"at /path/file.js:1:1\"\n /\\bat\\s(.+[^/]\\s)?(?<path>\\/.+?):\\d+:\\d+$/,\n ];\n\nconst MaybeUrlRE = /^[a-z]{2,5}:\\/\\//i;\n\n// only exposed for tests:\nexport function extractCallerPath(stack: string): string {\n const frames = stack.split(\"\\n\").filter(Boolean);\n\n // First find getCallerDirname() in the stack:\n const callerFrame = frames.findIndex((frame) =>\n frame.includes(\"getCallerDirname\"),\n );\n if (callerFrame === -1) {\n throw new Error(\"Invalid stack trace format: missing caller frame\");\n }\n for (let i = callerFrame + 1; i < frames.length; i++) {\n const frame = frames[i];\n for (const pattern of patterns) {\n const g = toS(frame).trim().match(pattern)?.groups;\n if (g != null && isNotBlank(g[\"path\"])) {\n const path = g[\"path\"];\n // Windows requires us to check if it's a reasonable URL, as URL accepts\n // \"C:\\\\path\\\\file.txt\" as valid (!!)\n if (MaybeUrlRE.test(path)) {\n try {\n return new URL(path).pathname;\n } catch {\n // ignore\n }\n }\n return path;\n }\n }\n }\n throw new Error(\"Invalid stack trace format: no parsable frames\");\n}\n","// src/platform.ts\n\nimport { arch, platform } from \"node:process\";\n\nexport const isLinux = platform === \"linux\";\nexport const isWindows = platform === \"win32\";\nexport const isMacOS = platform === \"darwin\";\n\nexport const isArm = isLinux && arch.startsWith(\"arm\");\n","// src/string.ts\n\nexport function isString(input: unknown): input is string {\n return typeof input === \"string\";\n}\n\nexport function toS(input: unknown): string {\n return isString(input) ? input : input == null ? \"\" : String(input);\n}\n\n/**\n * @return true iff the input is a string and has at least one non-whitespace character\n */\nexport function isNotBlank(input: unknown): input is string {\n return typeof input === \"string\" && input.trim().length > 0;\n}\n\n/**\n * @return true iff the input is not a string or only has non-whitespace characters\n */\nexport function isBlank(input: unknown): input is undefined {\n return !isNotBlank(input);\n}\n\nexport function toNotBlank(input: unknown): string | undefined {\n return isNotBlank(input) ? input : undefined;\n}\n\n/**\n * Decodes a string containing octal (\\000-\\377) and/or hexadecimal\n * (\\x00-\\xFF) escape sequences\n * @param input The string containing escape sequences to decode\n * @returns The decoded string with escape sequences converted to their\n * corresponding characters\n * @throws Error if an invalid escape sequence is encountered\n */\nexport function decodeEscapeSequences(input: string): string {\n const escapeRegex = /\\\\(?:([0-7]{2,6})|x([0-9a-fA-F]{2,4}))/g;\n\n return input.replace(escapeRegex, (match, octal, hex) => {\n // Handle octal escape sequences\n if (octal != null) {\n return String.fromCharCode(parseInt(octal, 8));\n }\n\n // Handle hexadecimal escape sequences\n if (hex != null) {\n return String.fromCharCode(parseInt(hex, 16));\n }\n\n // This should never happen due to the regex pattern\n throw new Error(`Invalid escape sequence: ${match}`);\n });\n}\n\nconst AlphaNumericRE = /[/\\w.-]/;\n\nexport function encodeEscapeSequences(input: string): string {\n return input\n .split(\"\")\n .map((char) => {\n const encodedChar = AlphaNumericRE.test(char)\n ? char\n : \"\\\\\" + char.charCodeAt(0).toString(8).padStart(2, \"0\");\n return encodedChar;\n })\n .join(\"\");\n}\n\n/**\n * Sort an array of strings using the locale-aware collation algorithm.\n *\n * @param arr The array of strings to sort. The original array **is sorted in\n * place**.\n */\nexport function sortByLocale(\n arr: string[],\n locales?: Intl.LocalesArgument,\n options?: Intl.CollatorOptions,\n): string[] {\n return arr.sort((a, b) => a.localeCompare(b, locales, options));\n}\n\n/**\n * Sort an array of objects using the locale-aware collation algorithm.\n *\n * @param arr The array of objects to sort.\n * @param fn The function to extract the key to sort by from each object.\n * @param locales The locales to use for sorting.\n * @param options The collation options to use for sorting.\n */\nexport function sortObjectsByLocale<T>(\n arr: T[],\n fn: (key: T) => string,\n locales?: Intl.LocalesArgument,\n options?: Intl.CollatorOptions,\n): T[] {\n return arr.sort((a, b) => fn(a).localeCompare(fn(b), locales, options));\n}\n","import { getCallerDirname } from \"./stack_path\";\n\n// Thanks to tsup shims, __dirname should always be defined except when run by\n// jest (which will use the stack_path shim)\nexport function _dirname() {\n try {\n if (typeof __dirname !== \"undefined\") return __dirname;\n } catch {\n // ignore\n }\n // we must be in jest. Use the stack_path ~~hack~~ shim:\n return getCallerDirname();\n}\n","// src/fs.ts\n\nimport { type PathLike, type StatOptions, Stats, statSync } from \"node:fs\";\nimport { opendir, stat } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { withTimeout } from \"./async.js\";\n\n/**\n * Wrapping node:fs/promises.stat() so we can mock it in tests.\n */\nexport async function statAsync(\n path: PathLike,\n options?: StatOptions & { bigint?: false },\n): Promise<Stats> {\n return stat(path, options);\n}\n\nexport async function canStatAsync(path: string): Promise<boolean> {\n try {\n return null != (await statAsync(path));\n } catch {\n return false;\n }\n}\n\n/**\n * @return true if `path` exists and is a directory\n */\nexport async function isDirectory(path: string): Promise<boolean> {\n try {\n return (await statAsync(path))?.isDirectory() === true;\n } catch {\n return false;\n }\n}\n\n/**\n * @return the first directory containing `file` or an empty string\n */\nexport async function findAncestorDir(\n dir: string,\n file: string,\n): Promise<string | undefined> {\n dir = resolve(dir);\n try {\n const s = await statAsync(join(dir, file));\n if (s.isFile()) return dir;\n } catch {\n // fall through\n }\n const parent = resolve(dir, \"..\");\n return parent === dir ? undefined : findAncestorDir(parent, file);\n}\n\nexport function existsSync(path: string): boolean {\n return statSync(path, { throwIfNoEntry: false }) != null;\n}\n\n/**\n * @return `true` if `dir` exists and is a directory and at least one entry can be read.\n * @throws {Error} if `dir` does not exist or is not a directory or cannot be read.\n */\nexport async function canReaddir(\n dir: string,\n timeoutMs: number,\n): Promise<true> {\n return withTimeout({\n desc: \"canReaddir()\",\n promise: _canReaddir(dir),\n timeoutMs,\n });\n}\n\nasync function _canReaddir(dir: string): Promise<true> {\n await (await opendir(dir)).close();\n return true;\n}\n","import { availableParallelism } from \"node:os\";\nimport { env } from \"node:process\";\nimport { gt0, isNumber } from \"./number.js\";\nimport { isBlank } from \"./string.js\";\nimport { DayMs } from \"./units.js\";\n\n/**\n * An error that is thrown when a promise does not resolve within the specified\n * time.\n */\nexport class TimeoutError extends Error {\n constructor(message: string, captureStackTrace = true) {\n super(message);\n this.name = \"TimeoutError\";\n // Capture the stack trace up to the calling site\n if (captureStackTrace && Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n/**\n * Rejects the promise with a TimeoutError if it does not resolve within the\n * specified time.\n *\n * @param promise The promise to wrap.\n * @param timeoutMs The timeout in milliseconds. Timeouts are disabled if this is 0.\n * @returns A promise that resolves when the input promise resolves, or rejects\n * with a TimeoutError if the input promise does not resolve within the\n * specified time.\n * @throws {TimeoutError} if the input promise does not resolve within the\n * specified time.\n * @throws {TypeError} if timeoutMs is not a number that is greater than 0.\n */\nexport async function withTimeout<T>(opts: {\n desc?: string;\n promise: Promise<T>;\n timeoutMs: number;\n}): Promise<T> {\n const desc = isBlank(opts.desc) ? \"thenOrTimeout()\" : opts.desc;\n\n if (!isNumber(opts.timeoutMs)) {\n throw new TypeError(\n desc +\n \": Expected timeoutMs to be numeric, but got \" +\n JSON.stringify(opts.timeoutMs),\n );\n }\n\n const timeoutMs = Math.floor(opts.timeoutMs);\n\n if (timeoutMs < 0) {\n throw new TypeError(\n desc + \": Expected timeoutMs to be > 0, but got \" + timeoutMs,\n );\n }\n\n if (timeoutMs > DayMs) {\n throw new TypeError(\n desc +\n \": Invalid timeoutMs is too large: must be less than one day, but got \" +\n timeoutMs,\n );\n }\n\n if (timeoutMs === 0) {\n return opts.promise;\n }\n\n // Create error here to captured the caller's stack trace. If we create it in\n // the timeout callback, the stack trace will be truncated to this function.\n const timeoutError = new TimeoutError(\n `${desc}: timeout after ${timeoutMs}ms`,\n );\n\n if (env[\"NODE_ENV\"] === \"test\" && timeoutMs === 1) {\n timeoutError.message += \"(timeout test)\";\n opts.promise.catch(() => {}); // < avoid unhandled rejection warnings\n throw timeoutError;\n }\n\n let timeoutId: NodeJS.Timeout | undefined;\n\n opts.promise\n .catch(() => {}) // < avoid unhandled rejection warnings\n .finally(() => {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n });\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (timeoutId != null) {\n timeoutError.message += \"(timeout callback)\";\n reject(timeoutError);\n }\n timeoutId = undefined;\n }, timeoutMs);\n });\n\n return Promise.race([opts.promise, timeoutPromise]);\n}\n\n/**\n * Delay for the specified number of milliseconds.\n *\n * @param ms The number of milliseconds to delay\n * @param t Optional value to resolve with after delay\n * @returns Promise that resolves with the provided value (or void if none provided)\n */\nexport async function delay<T = void>(ms: number, t?: T): Promise<T> {\n return new Promise<T>((resolve) => setTimeout(() => resolve(t as T), ms));\n}\n\n/**\n * Apply `fn` to every item in `items` with a maximum concurrency of\n * `maxConcurrency`.\n */\nexport async function mapConcurrent<I, O>({\n items,\n fn,\n maxConcurrency = availableParallelism(),\n}: {\n items: I[];\n fn: (t: I) => Promise<O>;\n maxConcurrency?: number;\n}): Promise<(O | Error)[]> {\n // Validate maxConcurrency\n if (!gt0(maxConcurrency)) {\n throw new Error(\n `maxConcurrency must be a positive integer, got: ${maxConcurrency}`,\n );\n }\n\n if (typeof fn !== \"function\") {\n throw new TypeError(`fn must be a function, got: ${typeof fn}`);\n }\n\n const results: Promise<O | Error>[] = [];\n const executing: Set<Promise<void>> = new Set();\n\n for (const [index, item] of items.entries()) {\n // Create a wrapped promise that handles cleanup\n while (executing.size >= maxConcurrency) {\n await Promise.race(executing);\n }\n const p = (results[index] = fn(item).catch((error) => error));\n executing.add(p);\n p.finally(() => executing.delete(p));\n }\n\n return Promise.all(results);\n}\n","// src/number.ts\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === \"number\" && isFinite(value);\n}\n\nconst INTEGER_REGEX = /^-?\\d+$/;\n\nexport function toInt(value: unknown): number | undefined {\n try {\n if (value == null) return;\n const s = String(value).trim();\n return INTEGER_REGEX.test(s) ? parseInt(s) : undefined;\n } catch {\n return;\n }\n}\n\nexport function gt0(value: unknown): value is number {\n return isNumber(value) && value > 0;\n}\n","// src/units.ts\n\n/**\n * Milliseconds in a second\n */\nexport const SecondMs = 1000;\n\n/**\n * Milliseconds in a minute\n */\nexport const MinuteMs = 60 * SecondMs;\n\n/**\n * Milliseconds in an hour\n */\nexport const HourMs = 60 * MinuteMs;\n\n/**\n * Milliseconds in a day\n */\nexport const DayMs = 24 * HourMs;\n\n/**\n * Kibibyte (KiB) = 1024 bytes\n * @see https://en.wikipedia.org/wiki/Kibibyte\n */\nexport const KiB = 1024;\n\n/**\n * Mebibyte (MiB) = 1024 KiB\n * @see https://en.wikipedia.org/wiki/Mebibyte\n */\nexport const MiB = 1024 * KiB;\n\n/**\n * Gibibyte (GiB)= 1024 MiB\n * @see https://en.wikipedia.org/wiki/Gibibyte\n */\nexport const GiB = 1024 * MiB;\n\n/**\n * Tebibyte (TiB) = 1024 GiB\n *\n * @see https://en.wikipedia.org/wiki/Byte#Multiple-byte_units\n */\nexport const TiB = 1024 * GiB;\n\nconst f = 1023.995 / 1024;\n\nexport function fmtBytes(bytes: number): string {\n if (bytes < 1023.5) {\n bytes = Math.round(bytes);\n return `${bytes} B`;\n } else if (bytes < MiB * f) {\n return `${(bytes / KiB).toFixed(2)} KiB`;\n } else if (bytes < GiB * f) {\n return `${(bytes / MiB).toFixed(2)} MiB`;\n } else if (bytes < TiB * f) {\n return `${(bytes / GiB).toFixed(2)} GiB`;\n } else {\n return `${(bytes / TiB).toFixed(2)} TiB`;\n }\n}\n","// src/hidden.ts\n\nimport { rename } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { WrappedError } from \"./error.js\";\nimport { canStatAsync, statAsync } from \"./fs.js\";\nimport { isRootDirectory, normalizePath } from \"./path.js\";\nimport { isWindows } from \"./platform.js\";\nimport type { HiddenMetadata } from \"./types/hidden_metadata.js\";\nimport type { NativeBindingsFn } from \"./types/native_bindings.js\";\n\nconst HiddenSupportByPlatform: Partial<\n Record<NodeJS.Platform, Pick<HiddenMetadata, \"supported\">>\n> = {\n win32: {\n supported: {\n dotPrefix: false,\n systemFlag: true,\n },\n },\n darwin: {\n supported: {\n dotPrefix: true,\n systemFlag: true,\n },\n },\n linux: {\n supported: {\n dotPrefix: true,\n systemFlag: false,\n },\n },\n};\n\nexport const LocalSupport = HiddenSupportByPlatform[process.platform]\n ?.supported ?? {\n dotPrefix: false,\n systemFlag: false,\n};\n\n/**\n * Checks if the file or directory is hidden through any available method\n * @returns A boolean indicating if the item is hidden\n * @throws {Error} If the file doesn't exist or permissions are insufficient\n */\nexport async function isHiddenImpl(\n pathname: string,\n nativeFn: NativeBindingsFn,\n): Promise<boolean> {\n const norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n return (\n (LocalSupport.dotPrefix && isPosixHidden(norm)) ||\n (LocalSupport.systemFlag && isSystemHidden(norm, nativeFn))\n );\n}\n\nexport async function isHiddenRecursiveImpl(\n path: string,\n nativeFn: NativeBindingsFn,\n): Promise<boolean> {\n let norm = normalizePath(path);\n if (norm == null) {\n throw new Error(\"Invalid path: \" + JSON.stringify(path));\n }\n while (!isRootDirectory(norm)) {\n if (await isHiddenImpl(norm, nativeFn)) {\n return true;\n }\n norm = dirname(norm);\n }\n return false;\n}\n\nexport function createHiddenPosixPath(pathname: string, hidden: boolean) {\n const norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n const dir = dirname(norm);\n const srcBase = basename(norm).replace(/^\\./, \"\");\n const dest = join(dir, (hidden ? \".\" : \"\") + srcBase);\n return dest;\n}\n\nasync function setHiddenPosix(\n pathname: string,\n hidden: boolean,\n): Promise<string> {\n if (LocalSupport.dotPrefix) {\n const dest = createHiddenPosixPath(pathname, hidden);\n if (pathname !== dest) await rename(pathname, dest);\n return dest;\n }\n\n throw new Error(\"Unsupported platform\");\n}\n\nfunction isPosixHidden(pathname: string): boolean {\n if (!LocalSupport.dotPrefix) return false;\n const b = basename(pathname);\n return b.startsWith(\".\") && b !== \".\" && b !== \"..\";\n}\n\nasync function isSystemHidden(\n pathname: string,\n nativeFn: NativeBindingsFn,\n): Promise<boolean> {\n if (!LocalSupport.systemFlag) {\n // not supported on this platform\n return false;\n }\n if (isWindows && isRootDirectory(pathname)) {\n // windows `attr` thinks all drive letters don't exist.\n return false;\n }\n\n // don't bother the native bindings if the file doesn't exist:\n return (\n (await canStatAsync(pathname)) &&\n (await (await nativeFn()).isHidden(pathname))\n );\n}\n\n/**\n * Gets detailed information about the hidden state of the file or directory\n * @returns An object containing detailed hidden state information\n * @throws {Error} If the file doesn't exist or permissions are insufficient\n */\nexport async function getHiddenMetadataImpl(\n pathname: string,\n nativeFn: NativeBindingsFn,\n): Promise<HiddenMetadata> {\n const norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n const dotPrefix = isPosixHidden(norm);\n const systemFlag = await isSystemHidden(norm, nativeFn);\n return {\n hidden: dotPrefix || systemFlag,\n dotPrefix,\n systemFlag,\n supported: LocalSupport,\n };\n}\n\nexport type HideMethod = \"dotPrefix\" | \"systemFlag\" | \"all\" | \"auto\";\n\nexport type SetHiddenResult = {\n pathname: string;\n actions: {\n dotPrefix: boolean;\n systemFlag: boolean;\n };\n};\n\nexport async function setHiddenImpl(\n pathname: string,\n hide: boolean,\n method: HideMethod,\n nativeFn: NativeBindingsFn,\n): Promise<SetHiddenResult> {\n let norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n\n if (method === \"dotPrefix\" && !LocalSupport.dotPrefix) {\n throw new Error(\"Dot prefix hiding is not supported on this platform\");\n }\n\n if (method === \"systemFlag\" && !LocalSupport.systemFlag) {\n throw new Error(\"System flag hiding is not supported on this platform\");\n }\n\n try {\n await statAsync(norm);\n } catch (cause) {\n throw new WrappedError(\"setHidden()\", { cause });\n }\n\n if (isWindows && isRootDirectory(norm)) {\n throw new Error(\"Cannot hide root directory on Windows\");\n }\n\n const actions = {\n dotPrefix: false,\n systemFlag: false,\n };\n\n let acted = false;\n\n if (LocalSupport.dotPrefix && [\"auto\", \"all\", \"dotPrefix\"].includes(method)) {\n if (isPosixHidden(norm) !== hide) {\n norm = await setHiddenPosix(norm, hide);\n actions.dotPrefix = true;\n }\n acted = true;\n }\n\n if (\n LocalSupport.systemFlag &&\n ([\"all\", \"systemFlag\"].includes(method) || (!acted && method === \"auto\"))\n ) {\n await (await nativeFn()).setHidden(norm, hide);\n actions.systemFlag = true;\n }\n\n return { pathname: norm, actions };\n}\n","// src/object.js\n\nimport { isNotBlank, isString } from \"./string.js\";\n\n/**\n * Check if a value is an object\n */\nexport function isObject(value: unknown): value is object {\n // typeof null is 'object', so we need to check for that case YAY JAVASCRIPT\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Map a value to another value, or undefined if the value is undefined\n */\nexport function map<T, U>(\n obj: T | undefined,\n fn: (value: T) => U,\n): U | undefined {\n return obj == null ? undefined : fn(obj);\n}\n\n/**\n * Omit the specified fields from an object\n */\nexport function omit<T extends object, K extends keyof T>(\n obj: T,\n ...keys: K[]\n): Omit<T, K> {\n const result = {} as Omit<T, K>;\n const keysSet = new Set(keys);\n\n // OH THE TYPING HUGEMANATEE\n for (const key of Object.keys(obj) as Array<keyof Omit<T, K>>) {\n if (!keysSet.has(key as unknown as K)) {\n result[key] = obj[key];\n }\n }\n\n return result;\n}\n\nexport function compactValues<T extends object>(\n obj: T | undefined,\n): Partial<T> {\n const result = {} as Partial<T>;\n if (obj == null || !isObject(obj)) return {};\n for (const [key, value] of Object.entries(obj)) {\n // skip blank strings and nullish values:\n if (value != null && (!isString(value) || isNotBlank(value))) {\n result[key as keyof T] = value as T[keyof T];\n }\n }\n return result;\n}\n","// src/error.ts\n\nimport { isNumber } from \"./number.js\";\nimport { compactValues, map, omit } from \"./object.js\";\nimport { isBlank, isNotBlank } from \"./string.js\";\n\nfunction toMessage(context: string, cause: unknown): string {\n const causeStr =\n cause instanceof Error\n ? cause.message\n : typeof cause === \"string\"\n ? cause\n : cause\n ? JSON.stringify(cause)\n : \"\";\n return context + (isBlank(causeStr) ? \"\" : \": \" + causeStr);\n}\n\nexport class WrappedError extends Error {\n errno?: number;\n code?: string;\n syscall?: string;\n path?: string;\n constructor(\n context: string,\n options?: {\n name?: string;\n cause?: unknown;\n errno?: number;\n code?: string;\n syscall?: string;\n path?: string;\n },\n ) {\n super(toMessage(context, options?.cause));\n\n const cause = map(options?.cause, toError);\n const opts = { ...compactValues(cause), ...compactValues(options) };\n\n if (isNotBlank(options?.name)) {\n this.name = options.name;\n }\n\n if (cause != null) {\n this.cause = cause;\n if (cause instanceof Error) {\n this.stack = `${this.stack}\\nCaused by: ${cause.stack}`;\n }\n }\n\n if (isNumber(opts.errno)) {\n this.errno = opts.errno;\n }\n if (isNotBlank(opts.code)) {\n this.code = opts.code;\n }\n if (isNotBlank(opts.syscall)) {\n this.syscall = opts.syscall;\n }\n if (isNotBlank(options?.path)) {\n this.path = options.path;\n }\n }\n\n get details(): Record<string, unknown> {\n return compactValues(omit(this, \"name\", \"message\", \"cause\"));\n }\n\n override toString(): string {\n const details = this.details;\n const detailsStr =\n Object.keys(details).length === 0 ? \"\" : \" \" + JSON.stringify(details);\n return `${super.toString()}${detailsStr}`;\n }\n}\n\nexport function toError(cause: unknown): Error {\n return cause instanceof Error ? cause : new Error(String(cause));\n}\n","// src/path.ts\n\nimport { dirname, resolve } from \"node:path\";\nimport { isWindows } from \"./platform.js\";\nimport { isBlank } from \"./string.js\";\n\nexport function normalizePath(\n mountPoint: string | undefined,\n): string | undefined {\n if (isBlank(mountPoint)) return undefined;\n\n const result = isWindows\n ? normalizeWindowsPath(mountPoint)\n : normalizePosixPath(mountPoint);\n\n // Make sure the native code doesn't see anything weird:\n return result != null ? resolve(result) : undefined;\n}\n\n/**\n * Normalizes a Linux or macOS mount point by removing any trailing slashes.\n * This is a no-op for root mount points.\n */\nexport function normalizePosixPath(\n mountPoint: string | undefined,\n): string | undefined {\n if (isBlank(mountPoint)) return undefined;\n if (mountPoint === \"/\") return mountPoint;\n \n // Fast path: check last char only if no trailing slash\n if (mountPoint[mountPoint.length - 1] !== \"/\") return mountPoint;\n \n // Slower path: trim trailing slashes\n let end = mountPoint.length - 1;\n while (end > 0 && mountPoint[end] === \"/\") {\n end--;\n }\n return mountPoint.slice(0, end + 1);\n}\n\n/**\n * Normalizes a Windows mount point by ensuring drive letters end with a\n * backslash.\n */\nexport function normalizeWindowsPath(mountPoint: string): string {\n // Terrible things happen if we give syscalls \"C:\" instead of \"C:\\\"\n\n return /^[a-z]:$/i.test(mountPoint)\n ? mountPoint.toUpperCase() + \"\\\\\"\n : mountPoint;\n}\n\n/**\n * @return true if `path` is the root directory--this is platform-specific. Only\n * \"/\" on linux/macOS is considered a root directory. On Windows, the root\n * directory is a drive letter followed by a colon, e.g. \"C:\\\".\n */\nexport function isRootDirectory(path: string): boolean {\n const n = normalizePath(path);\n return n == null ? false : isWindows ? dirname(n) === n : n === \"/\";\n}\n","// src/options.ts\n\nimport { availableParallelism } from \"node:os\";\nimport { compactValues, isObject } from \"./object.js\";\nimport { isWindows } from \"./platform.js\";\nimport type { Options } from \"./types/options.js\";\n\n/**\n * Default timeout in milliseconds for {@link Options.timeoutMs}.\n *\n * Note that this timeout may be insufficient for some devices, like spun-down\n * optical drives or network shares that need to spin up or reconnect.\n */\nexport const TimeoutMsDefault = 5_000 as const;\n\n/**\n * System paths and globs that indicate system volumes\n */\nexport const SystemPathPatternsDefault = [\n \"/boot\",\n \"/boot/efi\",\n \"/dev\",\n \"/dev/**\",\n \"/proc/**\",\n \"/run\",\n \"/run/credentials/**\",\n \"/run/lock\",\n \"/run/snapd/**\",\n \"/run/user/*/doc\",\n \"/run/user/*/gvfs\",\n \"/snap/**\",\n \"/sys/**\",\n \"/tmp\",\n \"/var/tmp\",\n // we aren't including /tmp/**, as some people temporarily mount volumes there, like /tmp/project.\n \"**/#snapshot\", // Synology and Kubernetes volume snapshots\n\n // windows for linux:\n \"/mnt/wslg/distro\",\n \"/mnt/wslg/doc\",\n \"/mnt/wslg/versions.txt\",\n \"/usr/lib/wsl/drivers\",\n\n // MacOS stuff:\n \"/private/var/vm\", // macOS swap\n \"/System/Volumes/Hardware\",\n \"/System/Volumes/iSCPreboot\",\n \"/System/Volumes/Preboot\",\n \"/System/Volumes/Recovery\",\n \"/System/Volumes/Reserved\",\n \"/System/Volumes/Update\",\n \"/System/Volumes/VM\",\n \"/System/Volumes/xarts\",\n];\n\n/**\n * Filesystem types that indicate system volumes\n */\nexport const SystemFsTypesDefault = [\n \"autofs\",\n \"binfmt_misc\",\n \"cgroup\",\n \"cgroup2\",\n \"configfs\",\n \"debugfs\",\n \"devpts\",\n \"devtmpfs\",\n \"efivarfs\",\n \"fusectl\",\n \"fuse.snapfuse\",\n \"hugetlbfs\",\n \"mqueue\",\n \"none\",\n \"proc\",\n \"pstore\",\n \"rootfs\",\n \"securityfs\",\n \"snap*\",\n \"squashfs\",\n \"sysfs\",\n \"tmpfs\",\n] as const;\n\nexport const LinuxMountTablePathsDefault = [\n \"/proc/self/mounts\",\n \"/proc/mounts\",\n \"/etc/mtab\",\n] as const;\n\n/**\n * Should {@link getAllVolumeMetadata} include system volumes by\n * default?\n */\nexport const IncludeSystemVolumesDefault = isWindows;\n\n/**\n * Default {@link Options} object.\n *\n * @see {@link optionsWithDefaults} for creating an options object with default values\n */\nexport const OptionsDefault: Options = {\n timeoutMs: TimeoutMsDefault,\n maxConcurrency: availableParallelism(),\n systemPathPatterns: [...SystemPathPatternsDefault],\n systemFsTypes: [...SystemFsTypesDefault],\n linuxMountTablePaths: [...LinuxMountTablePathsDefault],\n includeSystemVolumes: IncludeSystemVolumesDefault,\n} as const;\n\n/**\n * Create an {@link Options} object using default values from\n * {@link OptionsDefault} for missing fields.\n */\nexport function optionsWithDefaults<T extends Options>(\n overrides: Partial<T> = {},\n): T {\n if (!isObject(overrides)) {\n throw new TypeError(\n \"options(): expected an object, got \" +\n typeof overrides +\n \": \" +\n JSON.stringify(overrides),\n );\n }\n\n return {\n ...OptionsDefault,\n ...(compactValues(overrides) as T),\n };\n}\n","// src/string_enum.ts\n\n// See https://basarat.gitbooks.io/typescript/content/docs/types/literal-types.html\n\nexport type StringEnumType<T extends string> = {\n [K in T]: K;\n};\n\nexport type StringEnum<T extends string> = StringEnumType<T> & {\n values: T[];\n size: number;\n get(s: string | undefined): T | undefined;\n};\n\nexport type StringEnumKeys<Type> = Type extends StringEnum<infer X> ? X : never;\n\n/**\n * Create a string enum with the given values. \n\nExample usage:\n\nexport const Directions = stringEnum(\"North\", \"South\", \"East\", \"West\")\nexport type Direction = StringEnumKeys<typeof Directions>\n\n*/\nexport function stringEnum<T extends string>(...o: T[]): StringEnum<T> {\n const set = new Set(o);\n\n const dict: StringEnumType<T> = {} as StringEnumType<T>;\n for (const key of o) {\n dict[key] = key;\n }\n\n return {\n ...dict,\n values: Object.freeze([...set]) as T[],\n size: set.size,\n get: (s: string | undefined) =>\n s != null && set.has(s as T) ? (s as T) : undefined,\n };\n}\n","// src/volume_health_status.ts\n\nimport { TimeoutError } from \"./async.js\";\nimport { debug } from \"./debuglog.js\";\nimport { toError } from \"./error.js\";\nimport { canReaddir } from \"./fs.js\";\nimport { isObject } from \"./object.js\";\nimport { stringEnum, StringEnumKeys } from \"./string_enum.js\";\n\n/**\n * Health statuses for volumes (mostly applicable to Windows).\n *\n * - `healthy`: Volume is \"OK\": accessible and functioning normally\n * - `timeout`: Volume could not be accessed before the specified timeout. It\n * may be inaccessible or disconnected.\n * - `inaccessible`: Volume exists but can't be accessed (permissions/locks)\n * - `disconnected`: Network volume that's offline\n * - `unknown`: Status can't be determined\n */\nexport const VolumeHealthStatuses = stringEnum(\n \"healthy\",\n \"timeout\",\n \"inaccessible\",\n \"disconnected\",\n \"unknown\",\n);\n\nexport type VolumeHealthStatus = StringEnumKeys<typeof VolumeHealthStatuses>;\n\n/**\n * Attempt to read a directory to determine if it's accessible, and if an error\n * is thrown, convert to a health status.\n * @returns the \"health status\" of the directory, based on the success of `readdir(dir)`.\n * @throws never\n */\nexport async function directoryStatus(\n dir: string,\n timeoutMs: number,\n canReaddirImpl: typeof canReaddir = canReaddir,\n): Promise<{ status: VolumeHealthStatus; error?: Error }> {\n try {\n if (await canReaddirImpl(dir, timeoutMs)) {\n return { status: VolumeHealthStatuses.healthy };\n }\n } catch (error) {\n debug(\"[directoryStatus] %s: %s\", dir, error);\n let status: VolumeHealthStatus = VolumeHealthStatuses.unknown;\n if (error instanceof TimeoutError) {\n status = VolumeHealthStatuses.timeout;\n } else if (isObject(error) && error instanceof Error && \"code\" in error) {\n if (error.code === \"EPERM\" || error.code === \"EACCES\") {\n status = VolumeHealthStatuses.inaccessible;\n }\n }\n return { status, error: toError(error) };\n }\n return { status: VolumeHealthStatuses.unknown };\n}\n","// src/linux/dev_disk.ts\n\nimport { Dirent } from \"node:fs\";\nimport { readdir, readlink } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { debug } from \"../debuglog.js\";\nimport { decodeEscapeSequences } from \"../string.js\";\n\n/**\n * Gets the UUID from symlinks for a given device path asynchronously\n * @param devicePath The device path to look up\n * @returns Promise that resolves to the UUID if found, empty string otherwise\n */\nexport async function getUuidFromDevDisk(devicePath: string) {\n try {\n const result = await getBasenameLinkedTo(\n \"/dev/disk/by-uuid\",\n resolve(devicePath),\n );\n debug(\"[getUuidFromDevDisk] result: %o\", result);\n return result;\n } catch (error) {\n debug(\"[getUuidFromDevDisk] failed: \" + error);\n return;\n }\n}\n\n/**\n * Gets the label from symlinks for a given device path asynchronously\n * @param devicePath The device path to look up\n * @returns Promise that resolves to the label if found, empty string otherwise\n */\nexport async function getLabelFromDevDisk(devicePath: string) {\n try {\n const result = await getBasenameLinkedTo(\n \"/dev/disk/by-label\",\n resolve(devicePath),\n );\n debug(\"[getLabelFromDevDisk] result: %o\", result);\n return result;\n } catch (error) {\n debug(\"[getLabelFromDevDisk] failed: \" + error);\n return;\n }\n}\n\n// only exposed for tests\nexport async function getBasenameLinkedTo(\n linkDir: string,\n linkPath: string,\n): Promise<string | undefined> {\n for await (const ea of readLinks(linkDir)) {\n if (ea.linkTarget === linkPath) {\n // Expect the symlink to be named like '1tb\\x20\\x28test\\x29'\n return decodeEscapeSequences(ea.dirent.name);\n }\n }\n return;\n}\n\nasync function* readLinks(\n directory: string,\n): AsyncGenerator<{ dirent: Dirent; linkTarget: string }, void, unknown> {\n for (const dirent of await readdir(directory, { withFileTypes: true })) {\n if (dirent.isSymbolicLink()) {\n try {\n const linkTarget = resolve(\n directory,\n await readlink(join(directory, dirent.name)),\n );\n yield { dirent, linkTarget };\n } catch {\n // Ignore errors\n }\n }\n }\n}\n","// src/linux/mount_points.ts\nimport { readFile } from \"node:fs/promises\";\nimport { debug } from \"../debuglog.js\";\nimport { toError, WrappedError } from \"../error.js\";\nimport { isMountPoint } from \"../mount_point.js\";\nimport { compactValues } from \"../object.js\";\nimport { optionsWithDefaults } from \"../options.js\";\nimport { type MountPoint } from \"../types/mount_point.js\";\nimport type { NativeBindingsFn } from \"../types/native_bindings.js\";\nimport type { Options } from \"../types/options.js\";\nimport { MountEntry, mountEntryToMountPoint, parseMtab } from \"./mtab.js\";\n\nexport async function getLinuxMountPoints(\n native: NativeBindingsFn,\n opts?: Pick<Options, \"linuxMountTablePaths\">,\n): Promise<MountPoint[]> {\n const o = optionsWithDefaults(opts);\n const raw: MountPoint[] = [];\n try {\n // Get GIO mounts if available from native module\n const arr = await (await native()).getGioMountPoints?.();\n debug(\"[getLinuxMountPoints] GIO mount points: %o\", arr);\n if (arr != null) raw.push(...arr);\n } catch (error) {\n debug(\"Failed to get GIO mount points: %s\", error);\n // GIO support not compiled in or failed, continue with just mtab mounts\n }\n\n let cause: Error | undefined;\n for (const input of o.linuxMountTablePaths) {\n try {\n const mtabContent = await readFile(input, \"utf8\");\n const arr = parseMtab(mtabContent)\n .map((ea) => mountEntryToMountPoint(ea))\n .filter((ea) => ea != null);\n debug(\"[getLinuxMountPoints] %s mount points: %o\", input, arr);\n if (arr.length > 0) {\n raw.push(...arr);\n break;\n }\n } catch (error) {\n cause ??= toError(error);\n }\n }\n\n const byMountPoint = new Map<string, MountPoint>();\n for (const ea of raw) {\n const prior = byMountPoint.get(ea.mountPoint);\n const merged = { ...compactValues(prior), ...compactValues(ea) };\n if (isMountPoint(merged)) {\n byMountPoint.set(merged.mountPoint, merged);\n }\n }\n\n if (byMountPoint.size === 0) {\n throw new WrappedError(\n `Failed to find any mount points (tried: ${JSON.stringify(o.linuxMountTablePaths)})`,\n { cause },\n );\n }\n\n const results = [...byMountPoint.values()];\n debug(\"[getLinuxMountPoints] %o\", {\n results: results.map((ea) => ea.mountPoint),\n });\n\n return results;\n}\n\nexport async function getLinuxMtabMetadata(\n mountPoint: string,\n opts?: Pick<Options, \"linuxMountTablePaths\">,\n): Promise<MountEntry> {\n let caughtError: Error | undefined;\n const inputs = optionsWithDefaults(opts).linuxMountTablePaths;\n for (const input of inputs) {\n try {\n const mtabContent = await readFile(input, \"utf8\");\n for (const ea of parseMtab(mtabContent)) {\n if (ea.fs_file === mountPoint) {\n return ea;\n }\n }\n } catch (error) {\n caughtError ??= toError(error);\n }\n }\n\n throw new WrappedError(\n `Failed to find mount point ${mountPoint} in an linuxMountTablePaths (tried: ${JSON.stringify(inputs)})`,\n caughtError,\n );\n}\n","import { isObject } from \"./object\";\nimport { isNotBlank } from \"./string\";\nimport { MountPoint } from \"./types/mount_point\";\n\nexport function isMountPoint(obj: unknown): obj is MountPoint {\n return isObject(obj) && \"mountPoint\" in obj && isNotBlank(obj.mountPoint);\n}\n","// src/remote_info.ts\n\nimport { debug } from \"./debuglog.js\";\nimport { compactValues, isObject } from \"./object.js\";\nimport { isWindows } from \"./platform.js\";\nimport { isBlank, isNotBlank, toS } from \"./string.js\";\nimport { RemoteInfo } from \"./types/remote_info.js\";\n\nexport function isRemoteInfo(obj: unknown): obj is RemoteInfo {\n if (!isObject(obj)) return false;\n const { remoteHost, remoteShare } = obj as Partial<RemoteInfo>;\n return isNotBlank(remoteHost) && isNotBlank(remoteShare);\n}\n\nconst NETWORK_FS_TYPE_ARRAY = [\n \"9p\",\n \"afp\",\n \"afs\",\n \"beegfs\",\n \"ceph\",\n \"cifs\",\n \"ftp\",\n \"fuse\",\n \"gfs2\",\n \"glusterfs\",\n \"lustre\",\n \"ncpfs\",\n \"nfs\",\n \"nfs4\",\n \"smb\",\n \"smbfs\",\n \"sshfs\",\n \"webdav\",\n] as const;\n\ntype NetworkFsType = (typeof NETWORK_FS_TYPE_ARRAY)[number];\n\nconst NETWORK_FS_TYPES = new Set<NetworkFsType>(NETWORK_FS_TYPE_ARRAY);\n\nconst FS_TYPE_ALIASES = new Map<string, NetworkFsType>([\n [\"nfs1\", \"nfs\"],\n [\"nfs2\", \"nfs\"],\n [\"nfs3\", \"nfs\"],\n [\"nfs4\", \"nfs4\"],\n [\"fuse.sshfs\", \"sshfs\"],\n [\"sshfs.fuse\", \"sshfs\"],\n [\"davfs2\", \"webdav\"],\n [\"davfs\", \"webdav\"],\n [\"cifs.smb\", \"cifs\"],\n [\"smbfs\", \"cifs\"],\n [\"cephfs\", \"ceph\"],\n [\"fuse.ceph\", \"ceph\"],\n [\"fuse.cephfs\", \"ceph\"],\n [\"rbd\", \"ceph\"],\n [\"fuse.glusterfs\", \"glusterfs\"],\n] as const);\n\nexport function normalizeFsType(fstype: string): string {\n const norm = toS(fstype).toLowerCase().replace(/:$/, \"\");\n return FS_TYPE_ALIASES.get(norm) ?? norm;\n}\n\nexport function isRemoteFsType(fstype: string | undefined): boolean {\n return (\n isNotBlank(fstype) &&\n NETWORK_FS_TYPES.has(normalizeFsType(fstype) as NetworkFsType)\n );\n}\n\nexport function parseURL(s: string): URL | undefined {\n try {\n return isBlank(s) ? undefined : new URL(s);\n } catch {\n return;\n }\n}\n\nexport function extractRemoteInfo(\n fsSpec: string | undefined,\n): RemoteInfo | undefined {\n if (fsSpec == null || isBlank(fsSpec)) return;\n\n if (isWindows) {\n fsSpec = fsSpec.replace(/\\\\/g, \"/\");\n }\n\n const url = parseURL(fsSpec);\n\n if (url?.protocol === \"file:\") {\n return {\n remote: false,\n uri: fsSpec,\n };\n }\n\n const patterns = [\n {\n // CIFS/SMB pattern: //hostname/share or //user@host/share\n regex:\n /^\\/\\/(?:(?<remoteUser>[^/@]+)@)?(?<remoteHost>[^/@]+)\\/(?<remoteShare>.+)$/,\n },\n {\n // sshfs pattern: sshfs#USER@HOST:REMOTE_PATH\n regex:\n /^(?:(?<protocol>\\w+)#)?(?<remoteUser>[^@]+)@(?<remoteHost>[^:]+):(?<remoteShare>.+)$/,\n },\n {\n // NFS pattern: hostname:/share\n protocol: \"nfs\",\n regex: /^(?<remoteHost>[^:]+):\\/(?!\\/)(?<remoteShare>.+)$/,\n },\n ];\n\n for (const { protocol, regex } of patterns) {\n const o = compactValues({\n protocol,\n remote: true,\n ...(fsSpec.match(regex)?.groups ?? {}),\n });\n if (isRemoteInfo(o)) {\n debug(\"[extractRemoteInfo] matched pattern: %o\", o);\n return o;\n }\n }\n\n // Let's try URL last, as nfs and webdav mounts are URI-ish\n try {\n // try to parse fsSpec as a uri:\n const parsed = new URL(fsSpec);\n if (parsed != null) {\n debug(\"[extractRemoteInfo] parsed URL: %o\", parsed);\n const fstype = normalizeFsType(parsed.protocol);\n if (!isRemoteFsType(fstype)) {\n // don't set remoteUser, remoteHost, or remoteShare, it's not remote!\n return {\n uri: fsSpec,\n remote: false,\n };\n } else {\n return compactValues({\n uri: fsSpec,\n protocol: fstype,\n remote: true,\n remoteUser: parsed.username,\n remoteHost: parsed.hostname,\n // URL pathname includes leading slash:\n remoteShare: parsed.pathname.replace(/^\\//, \"\"),\n }) as unknown as RemoteInfo;\n }\n }\n } catch {\n // ignore\n }\n\n return;\n}\n","// src/glob.ts\n\nimport { isWindows } from \"./platform.js\";\nimport { isNotBlank } from \"./string.js\";\n\nconst cache = new Map<string, RegExp>();\n\n/**\n * Compiles an array of glob patterns into a single regular expression.\n *\n * The function supports the following patterns:\n * - `**` matches any number of directories.\n * - `*` matches any number of characters except for `/`.\n * - `?` matches exactly one character except for `/`.\n * - `.` is escaped to match a literal period.\n * - `/` at the end of the pattern matches either a slash or the end of the string.\n * - Other regex special characters are escaped.\n *\n * @param patterns - An array of glob patterns to compile.\n * @returns A `RegExp` object that matches any of the provided patterns.\n */\nexport function compileGlob(\n patterns: string[] | readonly string[] | undefined,\n): RegExp {\n if (patterns == null || patterns.length === 0) {\n return NeverMatchRE;\n }\n const patternsKey = JSON.stringify(patterns);\n {\n const prior = cache.get(patternsKey);\n if (prior != null) {\n return prior;\n }\n }\n\n const sorted = patterns.slice().filter(isNotBlank).sort();\n const sortedKey = JSON.stringify(sorted);\n {\n const prior = cache.get(sortedKey);\n if (prior != null) {\n cache.set(patternsKey, prior);\n return prior;\n }\n }\n\n const result = _compileGlob(sorted);\n if (cache.size > 256) {\n // avoid unbounded memory usage\n cache.clear();\n }\n\n cache.set(patternsKey, result);\n cache.set(sortedKey, result);\n return result;\n}\n\nfunction _compileGlob(patterns: string[] | readonly string[]): RegExp {\n const regexPatterns = patterns.map((pattern) => {\n let regex = \"\";\n let i = 0;\n while (i < pattern.length) {\n // Handle '**' pattern\n if (pattern[i] === \"*\" && pattern[i + 1] === \"*\") {\n regex += \".*\";\n i += 2;\n if (pattern[i] === \"/\") {\n i++; // Skip the slash after **\n }\n continue;\n }\n\n // Handle single '*' pattern\n if (pattern[i] === \"*\") {\n regex += \"[^/]*\";\n i++;\n continue;\n }\n\n // Handle '?' pattern\n if (pattern[i] === \"?\") {\n regex += \"[^/]\";\n i++;\n continue;\n }\n\n // Handle period\n if (pattern[i] === \".\") {\n regex += \"\\\\.\";\n i++;\n continue;\n }\n\n // Handle end of directory pattern\n if (pattern[i] === \"/\") {\n if (i === pattern.length - 1) {\n regex += \"(?:/|$)\";\n i++;\n continue;\n } else if (isWindows) {\n regex += \"[\\\\/\\\\\\\\]\";\n i++;\n continue;\n }\n }\n\n // Escape other regex special characters\n if (/[+^${}()|[\\]\\\\]/.test(pattern[i] as string)) {\n regex += \"\\\\\" + pattern[i];\n i++;\n continue;\n }\n\n // Add other characters as-is\n regex += pattern[i];\n i++;\n }\n return regex;\n });\n const final = regexPatterns.filter((ea) => ea.length > 0);\n return final.length === 0\n ? // Empty pattern matches nothing\n NeverMatchRE // Case insensitive for Windows paths\n : new RegExp(`^(?:${final.join(\"|\")})$`, \"i\");\n}\n\n// eslint-disable-next-line regexp/no-empty-group\nexport const AlwaysMatchRE = /(?:)/;\n// eslint-disable-next-line regexp/no-empty-lookarounds-assertion\nexport const NeverMatchRE = /(?!)/;\n","// src/system_volume.ts\n\nimport { debug } from \"./debuglog.js\";\nimport { compileGlob } from \"./glob.js\";\nimport { SystemFsTypesDefault, SystemPathPatternsDefault } from \"./options.js\";\nimport { normalizePath } from \"./path.js\";\nimport { isWindows } from \"./platform.js\";\nimport { isNotBlank } from \"./string.js\";\nimport type { MountPoint } from \"./types/mount_point.js\";\nimport type { Options } from \"./types/options.js\";\n\n/**\n * Configuration for system volume detection\n *\n * @see {@link MountPoint.isSystemVolume}\n */\nexport type SystemVolumeConfig = Pick<\n Options,\n \"systemPathPatterns\" | \"systemFsTypes\"\n>;\n\n/**\n * Determines if a mount point represents a system volume based on its path and\n * filesystem type\n */\nexport function isSystemVolume(\n mountPoint: string,\n fstype: string | undefined,\n config: Partial<SystemVolumeConfig> = {},\n): boolean {\n if (isWindows) {\n const systemDrive = normalizePath(process.env[\"SystemDrive\"]);\n if (systemDrive != null && mountPoint === systemDrive) {\n debug(\"[isSystemVolume] %s is the Windows system drive\", mountPoint);\n return true;\n }\n }\n const isSystemFsType =\n isNotBlank(fstype) &&\n ((config.systemFsTypes ?? SystemFsTypesDefault) as string[]).includes(\n fstype,\n );\n const hasSystemPath = compileGlob(\n config.systemPathPatterns ?? SystemPathPatternsDefault,\n ).test(mountPoint);\n const result = isSystemFsType || hasSystemPath;\n debug(\"[isSystemVolume]\", {\n mountPoint,\n fstype,\n result,\n isSystemFsType,\n hasSystemPath,\n });\n return result;\n}\n\nexport function assignSystemVolume(\n mp: MountPoint,\n config: Partial<SystemVolumeConfig>,\n) {\n const result = isSystemVolume(mp.mountPoint, mp.fstype, config);\n\n if (isWindows) {\n // native code actually knows the system drive and has more in-depth\n // metadata information that we trust more than these heuristics\n mp.isSystemVolume ??= result;\n } else {\n // macOS and Linux don't have a concept of an explicit \"system drive\" like\n // Windows--always trust our heuristics\n mp.isSystemVolume = result;\n }\n}\n","// src/linux/mtab.ts\n\nimport { toInt } from \"../number.js\";\nimport { normalizePosixPath } from \"../path.js\";\nimport { extractRemoteInfo } from \"../remote_info.js\";\nimport {\n decodeEscapeSequences,\n encodeEscapeSequences,\n isBlank,\n toNotBlank,\n} from \"../string.js\";\nimport { isSystemVolume, SystemVolumeConfig } from \"../system_volume.js\";\nimport type { MountPoint } from \"../types/mount_point.js\";\nimport type { VolumeMetadata } from \"../types/volume_metadata.js\";\n\n/**\n * Represents an entry in the mount table.\n */\nexport interface MountEntry {\n /**\n * Device or remote filesystem\n */\n fs_spec: string;\n /**\n * Mount point\n */\n fs_file: string;\n /**\n * Filesystem type\n */\n fs_vfstype: string;\n /**\n * Mount options\n */\n fs_mntops: string | undefined;\n /**\n * Dump frequency\n */\n fs_freq: number | undefined;\n /**\n * fsck pass number\n */\n fs_passno: number | undefined;\n}\n\nexport function mountEntryToMountPoint(\n entry: MountEntry,\n): MountPoint | undefined {\n const mountPoint = normalizePosixPath(entry.fs_file);\n const fstype = toNotBlank(entry.fs_vfstype) ?? toNotBlank(entry.fs_spec);\n return mountPoint == null || fstype == null\n ? undefined\n : {\n mountPoint,\n fstype,\n };\n}\n\nexport type MtabVolumeMetadata = Omit<\n VolumeMetadata,\n \"size\" | \"used\" | \"available\" | \"label\" | \"uuid\" | \"status\"\n>;\n\nexport function mountEntryToPartialVolumeMetadata(\n entry: MountEntry,\n options: Partial<SystemVolumeConfig> = {},\n): MtabVolumeMetadata {\n return {\n mountPoint: entry.fs_file,\n fstype: entry.fs_vfstype,\n mountFrom: entry.fs_spec,\n isSystemVolume: isSystemVolume(entry.fs_file, entry.fs_vfstype, options),\n remote: false, // < default to false, but it may be overridden by extractRemoteInfo\n ...extractRemoteInfo(entry.fs_spec),\n };\n}\n\n/**\n * Parses an mtab/fstab file content into structured mount entries\n * @param content - Raw content of the mtab/fstab file\n * @returns Array of parsed mount entries\n */\nexport function parseMtab(content: string): MountEntry[] {\n const entries: MountEntry[] = [];\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n // Skip comments and empty lines\n if (isBlank(line) || line.trim().startsWith(\"#\")) {\n continue;\n }\n\n const fields = line\n .trim()\n .match(/(?:[^\\s\\\\]|\\\\.)+/g)\n ?.map(decodeEscapeSequences);\n\n if (!fields || fields.length < 3) {\n continue; // Skip malformed lines\n }\n const fs_file = normalizePosixPath(fields[1]);\n if (fs_file != null) {\n entries.push({\n fs_spec: fields[0] as string,\n // normalizeLinuxPath DOES NOT resolve()!\n fs_file,\n fs_vfstype: fields[2] as string,\n fs_mntops: fields[3],\n fs_freq: toInt(fields[4]),\n fs_passno: toInt(fields[5]),\n });\n }\n }\n return entries;\n}\n\n/**\n * Formats mount entries back into mtab file format\n * @param entries - Array of mount entries\n * @returns Formatted mtab file content\n */\nexport function formatMtab(entries: MountEntry[]): string {\n return entries\n .map((entry) => {\n const fields = [\n entry.fs_spec,\n encodeEscapeSequences(entry.fs_file),\n entry.fs_vfstype,\n entry.fs_mntops,\n entry.fs_freq?.toString(),\n entry.fs_passno?.toString(),\n ];\n return fields.join(\"\\t\");\n })\n .join(\"\\n\");\n}\n","// src/unc.ts\n\nimport { isBlank, isString } from \"./string.js\";\nimport { RemoteInfo } from \"./types/remote_info.js\";\n\n/**\n * Checks if a string is formatted as a valid UNC path.\n * A valid UNC path starts with double backslashes or slashes,\n * followed by a server/host name, and then a share name.\n * The path must use consistent slashes (all forward or all backward).\n *\n * @param path - The string to check\n * @returns boolean - True if the string is a valid UNC path, false otherwise\n */\nexport function parseUNCPath(\n path: string | null | undefined,\n): RemoteInfo | undefined {\n if (path == null || isBlank(path) || !isString(path)) {\n return;\n }\n\n // Check for two forward slashes or two backslashes at start\n if (!path.startsWith(\"\\\\\\\\\") && !path.startsWith(\"//\")) {\n return;\n }\n\n // Determine slash type from the start of the path\n const isForwardSlash = path.startsWith(\"//\");\n const slashChar = isForwardSlash ? \"/\" : \"\\\\\";\n\n // Split path using the correct slash type\n const parts = path.slice(2).split(slashChar);\n\n // Check minimum required parts (server and share)\n if (parts.length < 2) {\n return;\n }\n\n // Validate server and share names exist and aren't empty\n const [remoteHost, remoteShare] = parts;\n if (\n remoteHost == null ||\n isBlank(remoteHost) ||\n remoteShare == null ||\n isBlank(remoteShare)\n ) {\n return;\n }\n\n // Check for invalid characters in server and share names\n const invalidChars = /[<>:\"|?*]/;\n if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {\n return;\n }\n\n // Check for mixed slash usage\n const wrongSlash = isForwardSlash ? \"\\\\\" : \"/\";\n if (path.includes(wrongSlash)) {\n return;\n }\n\n return { remoteHost, remoteShare, remote: true };\n}\n","// src/uuid.ts\n\nimport { toS } from \"./string.js\";\n\nconst uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;\n\n/**\n * Some volume UUIDs are short, like, `ABCD1234`.\n *\n * Some volume UUIDs are in hexadecimal, but others and use G-Z. We will allow\n * that.\n *\n * Some Windows syscalls wrap the UUID in a \"\\\\\\\\?\\\\Volume{...}\\\\\" prefix and\n * suffix. This function will strip out that prefix and suffix.\n *\n * We will ignore any UUID-ish string that is not at least 8 characters long\n * (and return `undefined` if no other, longer uuid-ish string is found).\n *\n * UUIDs cannot start with a hyphen, and can only contain a-z, 0-9, and hyphens\n * (case-insensitive).\n */\nexport function extractUUID(uuid: string | undefined): string | undefined {\n return toS(uuid).match(uuidRegex)?.[0];\n}\n","// src/array.ts\n\n/**\n * Remove duplicate elements from an array.\n *\n * - Primitive values are compared using strict equality.\n * - Objects and arrays are compared by reference.\n *\n * @return A new array with duplicate elements removed\n */\nexport function uniq<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n}\n\n/**\n * Remove duplicate elements from an array based on a key function.\n * @param keyFn A function that returns a key for each element. Elements that\n * the key function returns nullish will be removed from the returned array.\n * @return a new array omitting duplicate elements based on a key function.\n */\nexport function uniqBy<T, K>(arr: T[], keyFn: (item: T) => K | undefined): T[] {\n const seen = new Set<K>();\n return arr.filter((item) => {\n const key = keyFn(item);\n if (key == null || seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/**\n * @return an array of specified length, with each element created by calling\n * the provided function.\n */\nexport function times<T>(length: number, fn: (index: number) => T): T[] {\n return Array.from({ length }, (_, i) => fn(i));\n}\n\n/**\n * @return a new array with elements that are not `null` or `undefined`.\n */\nexport function compact<T>(arr: (T | null | undefined)[] | undefined): T[] {\n return arr == null ? [] : arr.filter((ea): ea is T => ea != null);\n}\n","// src/mount_point.ts\n\nimport { uniqBy } from \"./array.js\";\nimport { mapConcurrent, withTimeout } from \"./async.js\";\nimport { debug } from \"./debuglog.js\";\nimport { getLinuxMountPoints } from \"./linux/mount_points.js\";\nimport { compactValues } from \"./object.js\";\nimport { isMacOS, isWindows } from \"./platform.js\";\nimport {\n isBlank,\n isNotBlank,\n sortObjectsByLocale,\n toNotBlank,\n} from \"./string.js\";\nimport { assignSystemVolume, SystemVolumeConfig } from \"./system_volume.js\";\nimport type { MountPoint } from \"./types/mount_point.js\";\nimport type { NativeBindingsFn } from \"./types/native_bindings.js\";\nimport type { Options } from \"./types/options.js\";\nimport { directoryStatus } from \"./volume_health_status.js\";\n\nexport type GetVolumeMountPointOptions = Partial<\n Pick<\n Options,\n | \"timeoutMs\"\n | \"linuxMountTablePaths\"\n | \"maxConcurrency\"\n | \"includeSystemVolumes\"\n > &\n SystemVolumeConfig\n>;\n\nexport async function getVolumeMountPointsImpl(\n opts: Required<GetVolumeMountPointOptions>,\n nativeFn: NativeBindingsFn,\n): Promise<MountPoint[]> {\n const p = _getVolumeMountPoints(opts, nativeFn);\n // we rely on the native bindings on Windows to do proper timeouts\n return isWindows\n ? p\n : withTimeout({ desc: \"getVolumeMountPoints\", ...opts, promise: p });\n}\n\nasync function _getVolumeMountPoints(\n o: Required<GetVolumeMountPointOptions>,\n nativeFn: NativeBindingsFn,\n): Promise<MountPoint[]> {\n debug(\"[getVolumeMountPoints] gathering mount points with options: %o\", o);\n\n const raw = await (isWindows || isMacOS\n ? (async () => {\n debug(\"[getVolumeMountPoints] using native implementation\");\n const points = await (await nativeFn()).getVolumeMountPoints(o);\n debug(\n \"[getVolumeMountPoints] native returned %d mount points\",\n points.length,\n );\n return points;\n })()\n : getLinuxMountPoints(nativeFn, o));\n\n debug(\"[getVolumeMountPoints] raw mount points: %o\", raw);\n\n const compacted = raw\n .map((ea) => compactValues(ea) as MountPoint)\n .filter((ea) => isNotBlank(ea.mountPoint));\n\n for (const ea of compacted) {\n assignSystemVolume(ea, o);\n }\n\n const filtered = o.includeSystemVolumes\n ? compacted\n : compacted.filter((ea) => !ea.isSystemVolume);\n\n const uniq = uniqBy(filtered, (ea) => toNotBlank(ea.mountPoint));\n debug(\"[getVolumeMountPoints] found %d unique mount points\", uniq.length);\n\n const results = sortObjectsByLocale(uniq, (ea) => ea.mountPoint);\n debug(\n \"[getVolumeMountPoints] getting status for %d mount points\",\n results.length,\n );\n\n await mapConcurrent({\n maxConcurrency: o.maxConcurrency,\n items: results.filter(\n // trust but verify\n (ea) => isBlank(ea.status) || ea.status === \"healthy\",\n ),\n fn: async (mp) => {\n debug(\"[getVolumeMountPoints] checking status of %s\", mp.mountPoint);\n mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;\n debug(\n \"[getVolumeMountPoints] status for %s: %s\",\n mp.mountPoint,\n mp.status,\n );\n },\n });\n\n debug(\n \"[getVolumeMountPoints] completed with %d mount points\",\n results.length,\n );\n return results;\n}\n","// src/volume_metadata.ts\n\nimport { mapConcurrent, withTimeout } from \"./async.js\";\nimport { debug } from \"./debuglog.js\";\nimport { WrappedError } from \"./error.js\";\nimport { getLabelFromDevDisk, getUuidFromDevDisk } from \"./linux/dev_disk.js\";\nimport { getLinuxMtabMetadata } from \"./linux/mount_points.js\";\nimport {\n type MtabVolumeMetadata,\n mountEntryToPartialVolumeMetadata,\n} from \"./linux/mtab.js\";\nimport { compactValues } from \"./object.js\";\nimport { IncludeSystemVolumesDefault, optionsWithDefaults } from \"./options.js\";\nimport { normalizePath } from \"./path.js\";\nimport { isLinux, isWindows } from \"./platform.js\";\nimport { extractRemoteInfo, isRemoteFsType } from \"./remote_info.js\";\nimport { isBlank, isNotBlank } from \"./string.js\";\nimport { assignSystemVolume } from \"./system_volume.js\";\nimport type {\n GetVolumeMetadataOptions,\n NativeBindingsFn,\n} from \"./types/native_bindings.js\";\nimport type { Options } from \"./types/options.js\";\nimport type { VolumeMetadata } from \"./types/volume_metadata.js\";\nimport { parseUNCPath } from \"./unc.js\";\nimport { extractUUID } from \"./uuid.js\";\nimport {\n VolumeHealthStatuses,\n directoryStatus,\n} from \"./volume_health_status.js\";\nimport { getVolumeMountPointsImpl } from \"./volume_mount_points.js\";\n\nexport async function getVolumeMetadataImpl(\n o: GetVolumeMetadataOptions & Options,\n nativeFn: NativeBindingsFn,\n): Promise<VolumeMetadata> {\n if (isBlank(o.mountPoint)) {\n throw new TypeError(\n \"Invalid mountPoint: got \" + JSON.stringify(o.mountPoint),\n );\n }\n\n const p = _getVolumeMetadata(o, nativeFn);\n // we rely on the native bindings on Windows to do proper timeouts\n return isWindows\n ? p\n : withTimeout({\n desc: \"getVolumeMetadata()\",\n timeoutMs: o.timeoutMs,\n promise: p,\n });\n}\n\nasync function _getVolumeMetadata(\n o: GetVolumeMetadataOptions & Options,\n nativeFn: NativeBindingsFn,\n): Promise<VolumeMetadata> {\n o = optionsWithDefaults(o);\n const norm = normalizePath(o.mountPoint);\n if (norm == null) {\n throw new Error(\"Invalid mountPoint: \" + JSON.stringify(o.mountPoint));\n }\n o.mountPoint = norm;\n\n debug(\n \"[getVolumeMetadata] starting metadata collection for %s\",\n o.mountPoint,\n );\n debug(\"[getVolumeMetadata] options: %o\", o);\n\n const { status, error } = await directoryStatus(o.mountPoint, o.timeoutMs);\n if (status !== VolumeHealthStatuses.healthy) {\n debug(\"[getVolumeMetadata] directoryStatus error: %s\", error);\n throw error ?? new Error(\"Volume not healthy: \" + status);\n }\n\n debug(\"[getVolumeMetadata] readdir status: %s\", status);\n\n let remote: boolean = false;\n // Get filesystem info from mtab first on Linux\n let mtabInfo: undefined | MtabVolumeMetadata;\n let device: undefined | string;\n if (isLinux) {\n debug(\"[getVolumeMetadata] collecting Linux mtab info\");\n try {\n const m = await getLinuxMtabMetadata(o.mountPoint, o);\n mtabInfo = mountEntryToPartialVolumeMetadata(m, o);\n debug(\"[getVolumeMetadata] mtab info: %o\", mtabInfo);\n if (mtabInfo.remote) {\n remote = true;\n }\n if (isNotBlank(m.fs_spec)) {\n device = m.fs_spec;\n }\n } catch (err) {\n debug(\"[getVolumeMetadata] failed to get mtab info: \" + err);\n // this may be a GIO mount. Ignore the error and continue.\n }\n }\n\n if (isNotBlank(device)) {\n o.device = device;\n debug(\"[getVolumeMetadata] using device: %s\", device);\n }\n\n debug(\"[getVolumeMetadata] requesting native metadata\");\n const metadata = (await (\n await nativeFn()\n ).getVolumeMetadata(o)) as VolumeMetadata;\n debug(\"[getVolumeMetadata] native metadata: %o\", metadata);\n\n // Some OS implementations leave it up to us to extract remote info:\n const remoteInfo =\n mtabInfo ??\n extractRemoteInfo(metadata.uri) ??\n extractRemoteInfo(metadata.mountFrom) ??\n (isWindows ? parseUNCPath(o.mountPoint) : undefined);\n\n debug(\"[getVolumeMetadata] extracted remote info: %o\", remoteInfo);\n\n remote ||=\n isRemoteFsType(metadata.fstype) ||\n (remoteInfo?.remote ?? metadata.remote ?? false);\n\n debug(\"[getVolumeMetadata] assembling: %o\", {\n status,\n mtabInfo,\n remoteInfo,\n metadata,\n mountPoint: o.mountPoint,\n remote,\n });\n const result = compactValues({\n status, // < let the implementation's status win by having this first\n ...compactValues(remoteInfo),\n ...compactValues(metadata),\n ...compactValues(mtabInfo),\n mountPoint: o.mountPoint,\n remote,\n }) as VolumeMetadata;\n\n // Backfill if blkid or gio failed us:\n if (isLinux && isNotBlank(device)) {\n // Sometimes blkid doesn't have the UUID in cache. Try to get it from\n // /dev/disk/by-uuid:\n result.uuid ??= (await getUuidFromDevDisk(device)) ?? \"\";\n result.label ??= (await getLabelFromDevDisk(device)) ?? \"\";\n }\n\n assignSystemVolume(result, o);\n\n // Fix microsoft's UUID format:\n result.uuid = extractUUID(result.uuid) ?? result.uuid ?? \"\";\n\n debug(\"[getVolumeMetadata] final result for %s: %o\", o.mountPoint, result);\n return compactValues(result) as VolumeMetadata;\n}\n\nexport async function getAllVolumeMetadataImpl(\n opts: Required<Options> & {\n includeSystemVolumes?: boolean;\n maxConcurrency?: number;\n },\n nativeFn: NativeBindingsFn,\n): Promise<VolumeMetadata[]> {\n const o = optionsWithDefaults(opts);\n debug(\"[getAllVolumeMetadata] starting with options: %o\", o);\n\n const arr = await getVolumeMountPointsImpl(o, nativeFn);\n debug(\"[getAllVolumeMetadata] found %d mount points\", arr.length);\n\n const unhealthyMountPoints = arr\n .filter(\n (ea) => ea.status != null && ea.status !== VolumeHealthStatuses.healthy,\n )\n .map((ea) => ({\n mountPoint: ea.mountPoint,\n error: new WrappedError(\"volume not healthy: \" + ea.status, {\n name: \"Skipped\",\n }),\n }));\n\n const includeSystemVolumes =\n opts?.includeSystemVolumes ?? IncludeSystemVolumesDefault;\n\n const systemMountPoints = includeSystemVolumes\n ? []\n : arr\n .filter((ea) => ea.isSystemVolume)\n .map((ea) => ({\n mountPoint: ea.mountPoint,\n error: new WrappedError(\"system volume\", { name: \"Skipped\" }),\n }));\n\n const healthy = arr.filter(\n (ea) => ea.status == null || ea.status === VolumeHealthStatuses.healthy,\n );\n\n debug(\"[getAllVolumeMetadata] \", {\n allMountPoints: arr.map((ea) => ea.mountPoint),\n healthyMountPoints: healthy.map((ea) => ea.mountPoint),\n });\n\n debug(\n \"[getAllVolumeMetadata] processing %d healthy volumes with max concurrency %d\",\n healthy.length,\n o.maxConcurrency,\n );\n\n const results = await (mapConcurrent({\n maxConcurrency: o.maxConcurrency,\n items:\n (opts?.includeSystemVolumes ?? IncludeSystemVolumesDefault)\n ? healthy\n : healthy.filter((ea) => !ea.isSystemVolume),\n fn: async (mp) =>\n getVolumeMetadataImpl({ ...mp, ...o }, nativeFn).catch((error) => ({\n mountPoint: mp.mountPoint,\n error,\n })),\n }) as Promise<(VolumeMetadata | { mountPoint: string; error: Error })[]>);\n\n debug(\"[getAllVolumeMetadata] completed processing all volumes\");\n return arr.map(\n (result) =>\n (results.find((ea) => ea.mountPoint === result.mountPoint) ??\n unhealthyMountPoints.find(\n (ea) => ea.mountPoint === result.mountPoint,\n ) ??\n systemMountPoints.find((ea) => ea.mountPoint === result.mountPoint) ?? {\n ...result,\n error: new WrappedError(\"Mount point metadata not retrieved\", {\n name: \"NotApplicableError\",\n }),\n }) as VolumeMetadata,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,4BAAyB;;;ACFzB,uBAAiC;AAIjC,SAAS,MAAS,OAAgB;AAChC,MAAI;AACJ,SAAO,MAAO,MAAM,MAAM;AAC5B;AAEO,IAAM,kBAAkB,MAAM,MAAM;AACzC,aAAW,MAAM,CAAC,eAAe,SAAS,GAAG;AAC3C,YAAI,2BAAS,EAAE,EAAE,SAAS;AACxB,aAAO;AAAA,IACT;AACA,YAAI,2BAAS,GAAG,YAAY,CAAC,EAAE,SAAS;AACtC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT,CAAC;AAEM,IAAM,iBAAiB,MAAM,MAAM;AACxC,aAAO,2BAAS,gBAAgB,CAAC,EAAE,WAAW;AAChD,CAAC;AAEM,SAAS,MAAM,QAAgB,MAAiB;AACrD,MAAI,CAAC,eAAe,EAAG;AACvB,QAAM,MAAM,oBAAI,KAAK;AAGrB,QAAM,YAAY,IAAI,IAAI,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,IAAI,gBAAgB,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK,gBAAgB,CAAC;AAE3O,UAAQ,OAAO,MAAM,gBAAY,yBAAO,KAAK,GAAG,IAAI,IAAI,IAAI;AAC9D;;;ACrBO,SAASA,OAAS,OAA0B;AACjD,MAAI,WAAW;AACf,MAAI;AAEJ,QAAM,KAAK,MAAM;AACf,QAAI,CAAC,UAAU;AACb,iBAAW;AACX,cAAQ,MAAM;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAEA,KAAG,QAAQ,MAAM;AACf,eAAW;AAAA,EACb;AAEA,SAAO;AACT;;;AC7BA,uBAAwB;;;ACExB,0BAA+B;AAExB,IAAM,UAAU,iCAAa;AAC7B,IAAM,YAAY,iCAAa;AAC/B,IAAM,UAAU,iCAAa;AAE7B,IAAM,QAAQ,WAAW,yBAAK,WAAW,KAAK;;;ACN9C,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,IAAI,OAAwB;AAC1C,SAAO,SAAS,KAAK,IAAI,QAAQ,SAAS,OAAO,KAAK,OAAO,KAAK;AACpE;AAKO,SAAS,WAAW,OAAiC;AAC1D,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAKO,SAAS,QAAQ,OAAoC;AAC1D,SAAO,CAAC,WAAW,KAAK;AAC1B;AAEO,SAAS,WAAW,OAAoC;AAC7D,SAAO,WAAW,KAAK,IAAI,QAAQ;AACrC;AAUO,SAAS,sBAAsB,OAAuB;AAC3D,QAAM,cAAc;AAEpB,SAAO,MAAM,QAAQ,aAAa,CAAC,OAAO,OAAO,QAAQ;AAEvD,QAAI,SAAS,MAAM;AACjB,aAAO,OAAO,aAAa,SAAS,OAAO,CAAC,CAAC;AAAA,IAC/C;AAGA,QAAI,OAAO,MAAM;AACf,aAAO,OAAO,aAAa,SAAS,KAAK,EAAE,CAAC;AAAA,IAC9C;AAGA,UAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,EACrD,CAAC;AACH;AAsCO,SAAS,oBACd,KACA,IACA,SACA,SACK;AACL,SAAO,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,cAAc,GAAG,CAAC,GAAG,SAAS,OAAO,CAAC;AACxE;;;AF9FO,SAAS,mBAA2B;AACzC,QAAM,IAAI,IAAI,MAAM;AACpB,MAAI,EAAE,SAAS,MAAM;AACnB,UAAM,kBAAkB,CAAC;AAAA,EAC3B;AACA,aAAO,0BAAQ,kBAAkB,EAAE,KAAe,CAAC;AACrD;AASA,IAAM,WAAW,YACb;AAAA;AAAA,EAEE;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF,IACA;AAAA;AAAA,EAEE;AAAA;AAAA,EAEA;AACF;AAEJ,IAAM,aAAa;AAGZ,SAAS,kBAAkB,OAAuB;AACvD,QAAM,SAAS,MAAM,MAAM,IAAI,EAAE,OAAO,OAAO;AAG/C,QAAM,cAAc,OAAO;AAAA,IAAU,CAAC,UACpC,MAAM,SAAS,kBAAkB;AAAA,EACnC;AACA,MAAI,gBAAgB,IAAI;AACtB,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AACA,WAAS,IAAI,cAAc,GAAG,IAAI,OAAO,QAAQ,KAAK;AACpD,UAAM,QAAQ,OAAO,CAAC;AACtB,eAAW,WAAW,UAAU;AAC9B,YAAM,IAAI,IAAI,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,GAAG;AAC5C,UAAI,KAAK,QAAQ,WAAW,EAAE,MAAM,CAAC,GAAG;AACtC,cAAM,OAAO,EAAE,MAAM;AAGrB,YAAI,WAAW,KAAK,IAAI,GAAG;AACzB,cAAI;AACF,mBAAO,IAAI,IAAI,IAAI,EAAE;AAAA,UACvB,QAAQ;AAAA,UAER;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI,MAAM,gDAAgD;AAClE;;;AGlEO,SAAS,WAAW;AACzB,MAAI;AACF,QAAI,OAAO,cAAc,YAAa,QAAO;AAAA,EAC/C,QAAQ;AAAA,EAER;AAEA,SAAO,iBAAiB;AAC1B;;;ACVA,qBAAiE;AACjE,sBAA8B;AAC9B,IAAAC,oBAA8B;;;ACJ9B,qBAAqC;AACrC,IAAAC,uBAAoB;;;ACCb,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU,YAAY,SAAS,KAAK;AACpD;AAEA,IAAM,gBAAgB;AAEf,SAAS,MAAM,OAAoC;AACxD,MAAI;AACF,QAAI,SAAS,KAAM;AACnB,UAAM,IAAI,OAAO,KAAK,EAAE,KAAK;AAC7B,WAAO,cAAc,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI;AAAA,EAC/C,QAAQ;AACN;AAAA,EACF;AACF;AAEO,SAAS,IAAI,OAAiC;AACnD,SAAO,SAAS,KAAK,KAAK,QAAQ;AACpC;;;ACfO,IAAM,WAAW;AAKjB,IAAM,WAAW,KAAK;AAKtB,IAAM,SAAS,KAAK;AAKpB,IAAM,QAAQ,KAAK;AAMnB,IAAM,MAAM;AAMZ,IAAM,MAAM,OAAO;AAMnB,IAAM,MAAM,OAAO;AAOnB,IAAM,MAAM,OAAO;AAE1B,IAAM,IAAI,WAAW;;;AFrCd,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB,oBAAoB,MAAM;AACrD,UAAM,OAAO;AACb,SAAK,OAAO;AAEZ,QAAI,qBAAqB,MAAM,mBAAmB;AAChD,YAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAChD;AAAA,EACF;AACF;AAcA,eAAsB,YAAe,MAItB;AACb,QAAM,OAAO,QAAQ,KAAK,IAAI,IAAI,oBAAoB,KAAK;AAE3D,MAAI,CAAC,SAAS,KAAK,SAAS,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR,OACE,iDACA,KAAK,UAAU,KAAK,SAAS;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,YAAY,KAAK,MAAM,KAAK,SAAS;AAE3C,MAAI,YAAY,GAAG;AACjB,UAAM,IAAI;AAAA,MACR,OAAO,6CAA6C;AAAA,IACtD;AAAA,EACF;AAEA,MAAI,YAAY,OAAO;AACrB,UAAM,IAAI;AAAA,MACR,OACE,0EACA;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,cAAc,GAAG;AACnB,WAAO,KAAK;AAAA,EACd;AAIA,QAAM,eAAe,IAAI;AAAA,IACvB,GAAG,IAAI,mBAAmB,SAAS;AAAA,EACrC;AAEA,MAAI,yBAAI,UAAU,MAAM,UAAU,cAAc,GAAG;AACjD,iBAAa,WAAW;AACxB,SAAK,QAAQ,MAAM,MAAM;AAAA,IAAC,CAAC;AAC3B,UAAM;AAAA,EACR;AAEA,MAAI;AAEJ,OAAK,QACF,MAAM,MAAM;AAAA,EAAC,CAAC,EACd,QAAQ,MAAM;AACb,QAAI,aAAa,MAAM;AACrB,mBAAa,SAAS;AACtB,kBAAY;AAAA,IACd;AAAA,EACF,CAAC;AAEH,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,gBAAY,WAAW,MAAM;AAC3B,UAAI,aAAa,MAAM;AACrB,qBAAa,WAAW;AACxB,eAAO,YAAY;AAAA,MACrB;AACA,kBAAY;AAAA,IACd,GAAG,SAAS;AAAA,EACd,CAAC;AAED,SAAO,QAAQ,KAAK,CAAC,KAAK,SAAS,cAAc,CAAC;AACpD;AAiBA,eAAsB,cAAoB;AAAA,EACxC;AAAA,EACA;AAAA,EACA,qBAAiB,qCAAqB;AACxC,GAI2B;AAEzB,MAAI,CAAC,IAAI,cAAc,GAAG;AACxB,UAAM,IAAI;AAAA,MACR,mDAAmD,cAAc;AAAA,IACnE;AAAA,EACF;AAEA,MAAI,OAAO,OAAO,YAAY;AAC5B,UAAM,IAAI,UAAU,+BAA+B,OAAO,EAAE,EAAE;AAAA,EAChE;AAEA,QAAM,UAAgC,CAAC;AACvC,QAAM,YAAgC,oBAAI,IAAI;AAE9C,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAE3C,WAAO,UAAU,QAAQ,gBAAgB;AACvC,YAAM,QAAQ,KAAK,SAAS;AAAA,IAC9B;AACA,UAAM,IAAK,QAAQ,KAAK,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,UAAU,KAAK;AAC3D,cAAU,IAAI,CAAC;AACf,MAAE,QAAQ,MAAM,UAAU,OAAO,CAAC,CAAC;AAAA,EACrC;AAEA,SAAO,QAAQ,IAAI,OAAO;AAC5B;;;AD/IA,eAAsB,UACpB,MACA,SACgB;AAChB,aAAO,sBAAK,MAAM,OAAO;AAC3B;AAEA,eAAsB,aAAa,MAAgC;AACjE,MAAI;AACF,WAAO,QAAS,MAAM,UAAU,IAAI;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAgBA,eAAsB,gBACpB,KACA,MAC6B;AAC7B,YAAM,2BAAQ,GAAG;AACjB,MAAI;AACF,UAAM,IAAI,MAAM,cAAU,wBAAK,KAAK,IAAI,CAAC;AACzC,QAAI,EAAE,OAAO,EAAG,QAAO;AAAA,EACzB,QAAQ;AAAA,EAER;AACA,QAAM,aAAS,2BAAQ,KAAK,IAAI;AAChC,SAAO,WAAW,MAAM,SAAY,gBAAgB,QAAQ,IAAI;AAClE;AAUA,eAAsB,WACpB,KACA,WACe;AACf,SAAO,YAAY;AAAA,IACjB,MAAM;AAAA,IACN,SAAS,YAAY,GAAG;AAAA,IACxB;AAAA,EACF,CAAC;AACH;AAEA,eAAe,YAAY,KAA4B;AACrD,SAAO,UAAM,yBAAQ,GAAG,GAAG,MAAM;AACjC,SAAO;AACT;;;AI1EA,IAAAC,mBAAuB;AACvB,IAAAC,oBAAwC;;;ACIjC,SAAS,SAAS,OAAiC;AAExD,SAAO,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAKO,SAAS,IACd,KACA,IACe;AACf,SAAO,OAAO,OAAO,SAAY,GAAG,GAAG;AACzC;AAKO,SAAS,KACd,QACG,MACS;AACZ,QAAM,SAAS,CAAC;AAChB,QAAM,UAAU,IAAI,IAAI,IAAI;AAG5B,aAAW,OAAO,OAAO,KAAK,GAAG,GAA8B;AAC7D,QAAI,CAAC,QAAQ,IAAI,GAAmB,GAAG;AACrC,aAAO,GAAG,IAAI,IAAI,GAAG;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,cACd,KACY;AACZ,QAAM,SAAS,CAAC;AAChB,MAAI,OAAO,QAAQ,CAAC,SAAS,GAAG,EAAG,QAAO,CAAC;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAE9C,QAAI,SAAS,SAAS,CAAC,SAAS,KAAK,KAAK,WAAW,KAAK,IAAI;AAC5D,aAAO,GAAc,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;;;AChDA,SAAS,UAAU,SAAiB,OAAwB;AAC1D,QAAM,WACJ,iBAAiB,QACb,MAAM,UACN,OAAO,UAAU,WACf,QACA,QACE,KAAK,UAAU,KAAK,IACpB;AACV,SAAO,WAAW,QAAQ,QAAQ,IAAI,KAAK,OAAO;AACpD;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YACE,SACA,SAQA;AACA,UAAM,UAAU,SAAS,SAAS,KAAK,CAAC;AAExC,UAAM,QAAQ,IAAI,SAAS,OAAO,OAAO;AACzC,UAAM,OAAO,EAAE,GAAG,cAAc,KAAK,GAAG,GAAG,cAAc,OAAO,EAAE;AAElE,QAAI,WAAW,SAAS,IAAI,GAAG;AAC7B,WAAK,OAAO,QAAQ;AAAA,IACtB;AAEA,QAAI,SAAS,MAAM;AACjB,WAAK,QAAQ;AACb,UAAI,iBAAiB,OAAO;AAC1B,aAAK,QAAQ,GAAG,KAAK,KAAK;AAAA,aAAgB,MAAM,KAAK;AAAA,MACvD;AAAA,IACF;AAEA,QAAI,SAAS,KAAK,KAAK,GAAG;AACxB,WAAK,QAAQ,KAAK;AAAA,IACpB;AACA,QAAI,WAAW,KAAK,IAAI,GAAG;AACzB,WAAK,OAAO,KAAK;AAAA,IACnB;AACA,QAAI,WAAW,KAAK,OAAO,GAAG;AAC5B,WAAK,UAAU,KAAK;AAAA,IACtB;AACA,QAAI,WAAW,SAAS,IAAI,GAAG;AAC7B,WAAK,OAAO,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,IAAI,UAAmC;AACrC,WAAO,cAAc,KAAK,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EAC7D;AAAA,EAES,WAAmB;AAC1B,UAAM,UAAU,KAAK;AACrB,UAAM,aACJ,OAAO,KAAK,OAAO,EAAE,WAAW,IAAI,KAAK,MAAM,KAAK,UAAU,OAAO;AACvE,WAAO,GAAG,MAAM,SAAS,CAAC,GAAG,UAAU;AAAA,EACzC;AACF;AAEO,SAAS,QAAQ,OAAuB;AAC7C,SAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACjE;;;AC5EA,IAAAC,oBAAiC;AAI1B,SAAS,cACd,YACoB;AACpB,MAAI,QAAQ,UAAU,EAAG,QAAO;AAEhC,QAAM,SAAS,YACX,qBAAqB,UAAU,IAC/B,mBAAmB,UAAU;AAGjC,SAAO,UAAU,WAAO,2BAAQ,MAAM,IAAI;AAC5C;AAMO,SAAS,mBACd,YACoB;AACpB,MAAI,QAAQ,UAAU,EAAG,QAAO;AAChC,MAAI,eAAe,IAAK,QAAO;AAG/B,MAAI,WAAW,WAAW,SAAS,CAAC,MAAM,IAAK,QAAO;AAGtD,MAAI,MAAM,WAAW,SAAS;AAC9B,SAAO,MAAM,KAAK,WAAW,GAAG,MAAM,KAAK;AACzC;AAAA,EACF;AACA,SAAO,WAAW,MAAM,GAAG,MAAM,CAAC;AACpC;AAMO,SAAS,qBAAqB,YAA4B;AAG/D,SAAO,YAAY,KAAK,UAAU,IAC9B,WAAW,YAAY,IAAI,OAC3B;AACN;AAOO,SAAS,gBAAgB,MAAuB;AACrD,QAAM,IAAI,cAAc,IAAI;AAC5B,SAAO,KAAK,OAAO,QAAQ,gBAAY,2BAAQ,CAAC,MAAM,IAAI,MAAM;AAClE;;;AHjDA,IAAM,0BAEF;AAAA,EACF,OAAO;AAAA,IACL,WAAW;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,WAAW;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,WAAW;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAEO,IAAM,eAAe,wBAAwB,QAAQ,QAAQ,GAChE,aAAa;AAAA,EACf,WAAW;AAAA,EACX,YAAY;AACd;AAOA,eAAsB,aACpB,UACAC,WACkB;AAClB,QAAM,OAAO,cAAc,QAAQ;AACnC,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,QAAQ,CAAC;AAAA,EACjE;AACA,SACG,aAAa,aAAa,cAAc,IAAI,KAC5C,aAAa,cAAc,eAAe,MAAMA,SAAQ;AAE7D;AAEA,eAAsB,sBACpB,MACAA,WACkB;AAClB,MAAI,OAAO,cAAc,IAAI;AAC7B,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,MAAM,mBAAmB,KAAK,UAAU,IAAI,CAAC;AAAA,EACzD;AACA,SAAO,CAAC,gBAAgB,IAAI,GAAG;AAC7B,QAAI,MAAM,aAAa,MAAMA,SAAQ,GAAG;AACtC,aAAO;AAAA,IACT;AACA,eAAO,2BAAQ,IAAI;AAAA,EACrB;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,UAAkB,QAAiB;AACvE,QAAM,OAAO,cAAc,QAAQ;AACnC,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,QAAQ,CAAC;AAAA,EACjE;AACA,QAAM,UAAM,2BAAQ,IAAI;AACxB,QAAM,cAAU,4BAAS,IAAI,EAAE,QAAQ,OAAO,EAAE;AAChD,QAAM,WAAO,wBAAK,MAAM,SAAS,MAAM,MAAM,OAAO;AACpD,SAAO;AACT;AAEA,eAAe,eACb,UACA,QACiB;AACjB,MAAI,aAAa,WAAW;AAC1B,UAAM,OAAO,sBAAsB,UAAU,MAAM;AACnD,QAAI,aAAa,KAAM,WAAM,yBAAO,UAAU,IAAI;AAClD,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,sBAAsB;AACxC;AAEA,SAAS,cAAc,UAA2B;AAChD,MAAI,CAAC,aAAa,UAAW,QAAO;AACpC,QAAM,QAAI,4BAAS,QAAQ;AAC3B,SAAO,EAAE,WAAW,GAAG,KAAK,MAAM,OAAO,MAAM;AACjD;AAEA,eAAe,eACb,UACAA,WACkB;AAClB,MAAI,CAAC,aAAa,YAAY;AAE5B,WAAO;AAAA,EACT;AACA,MAAI,aAAa,gBAAgB,QAAQ,GAAG;AAE1C,WAAO;AAAA,EACT;AAGA,SACG,MAAM,aAAa,QAAQ,KAC3B,OAAO,MAAMA,UAAS,GAAG,SAAS,QAAQ;AAE/C;AAOA,eAAsB,sBACpB,UACAA,WACyB;AACzB,QAAM,OAAO,cAAc,QAAQ;AACnC,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,QAAQ,CAAC;AAAA,EACjE;AACA,QAAM,YAAY,cAAc,IAAI;AACpC,QAAM,aAAa,MAAM,eAAe,MAAMA,SAAQ;AACtD,SAAO;AAAA,IACL,QAAQ,aAAa;AAAA,IACrB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb;AACF;AAYA,eAAsB,cACpB,UACA,MACA,QACAA,WAC0B;AAC1B,MAAI,OAAO,cAAc,QAAQ;AACjC,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,QAAQ,CAAC;AAAA,EACjE;AAEA,MAAI,WAAW,eAAe,CAAC,aAAa,WAAW;AACrD,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,MAAI,WAAW,gBAAgB,CAAC,aAAa,YAAY;AACvD,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AAEA,MAAI;AACF,UAAM,UAAU,IAAI;AAAA,EACtB,SAAS,OAAO;AACd,UAAM,IAAI,aAAa,eAAe,EAAE,MAAM,CAAC;AAAA,EACjD;AAEA,MAAI,aAAa,gBAAgB,IAAI,GAAG;AACtC,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,QAAM,UAAU;AAAA,IACd,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAEA,MAAI,QAAQ;AAEZ,MAAI,aAAa,aAAa,CAAC,QAAQ,OAAO,WAAW,EAAE,SAAS,MAAM,GAAG;AAC3E,QAAI,cAAc,IAAI,MAAM,MAAM;AAChC,aAAO,MAAM,eAAe,MAAM,IAAI;AACtC,cAAQ,YAAY;AAAA,IACtB;AACA,YAAQ;AAAA,EACV;AAEA,MACE,aAAa,eACZ,CAAC,OAAO,YAAY,EAAE,SAAS,MAAM,KAAM,CAAC,SAAS,WAAW,SACjE;AACA,WAAO,MAAMA,UAAS,GAAG,UAAU,MAAM,IAAI;AAC7C,YAAQ,aAAa;AAAA,EACvB;AAEA,SAAO,EAAE,UAAU,MAAM,QAAQ;AACnC;;;AIlNA,IAAAC,kBAAqC;AAW9B,IAAM,mBAAmB;AAKzB,IAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF;AAMO,IAAM,8BAA8B;AAOpC,IAAM,iBAA0B;AAAA,EACrC,WAAW;AAAA,EACX,oBAAgB,sCAAqB;AAAA,EACrC,oBAAoB,CAAC,GAAG,yBAAyB;AAAA,EACjD,eAAe,CAAC,GAAG,oBAAoB;AAAA,EACvC,sBAAsB,CAAC,GAAG,2BAA2B;AAAA,EACrD,sBAAsB;AACxB;AAMO,SAAS,oBACd,YAAwB,CAAC,GACtB;AACH,MAAI,CAAC,SAAS,SAAS,GAAG;AACxB,UAAM,IAAI;AAAA,MACR,wCACE,OAAO,YACP,OACA,KAAK,UAAU,SAAS;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,cAAc,SAAS;AAAA,EAC7B;AACF;;;ACxGO,SAAS,cAAgC,GAAuB;AACrE,QAAM,MAAM,IAAI,IAAI,CAAC;AAErB,QAAM,OAA0B,CAAC;AACjC,aAAW,OAAO,GAAG;AACnB,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,OAAO,OAAO,CAAC,GAAG,GAAG,CAAC;AAAA,IAC9B,MAAM,IAAI;AAAA,IACV,KAAK,CAAC,MACJ,KAAK,QAAQ,IAAI,IAAI,CAAM,IAAK,IAAU;AAAA,EAC9C;AACF;;;ACrBO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUA,eAAsB,gBACpB,KACA,WACA,iBAAoC,YACoB;AACxD,MAAI;AACF,QAAI,MAAM,eAAe,KAAK,SAAS,GAAG;AACxC,aAAO,EAAE,QAAQ,qBAAqB,QAAQ;AAAA,IAChD;AAAA,EACF,SAAS,OAAO;AACd,UAAM,4BAA4B,KAAK,KAAK;AAC5C,QAAI,SAA6B,qBAAqB;AACtD,QAAI,iBAAiB,cAAc;AACjC,eAAS,qBAAqB;AAAA,IAChC,WAAW,SAAS,KAAK,KAAK,iBAAiB,SAAS,UAAU,OAAO;AACvE,UAAI,MAAM,SAAS,WAAW,MAAM,SAAS,UAAU;AACrD,iBAAS,qBAAqB;AAAA,MAChC;AAAA,IACF;AACA,WAAO,EAAE,QAAQ,OAAO,QAAQ,KAAK,EAAE;AAAA,EACzC;AACA,SAAO,EAAE,QAAQ,qBAAqB,QAAQ;AAChD;;;ACtDA,IAAAC,mBAAkC;AAClC,IAAAC,oBAA8B;AAS9B,eAAsB,mBAAmB,YAAoB;AAC3D,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,UACA,2BAAQ,UAAU;AAAA,IACpB;AACA,UAAM,mCAAmC,MAAM;AAC/C,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,kCAAkC,KAAK;AAC7C;AAAA,EACF;AACF;AAOA,eAAsB,oBAAoB,YAAoB;AAC5D,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,UACA,2BAAQ,UAAU;AAAA,IACpB;AACA,UAAM,oCAAoC,MAAM;AAChD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,mCAAmC,KAAK;AAC9C;AAAA,EACF;AACF;AAGA,eAAsB,oBACpB,SACA,UAC6B;AAC7B,mBAAiB,MAAM,UAAU,OAAO,GAAG;AACzC,QAAI,GAAG,eAAe,UAAU;AAE9B,aAAO,sBAAsB,GAAG,OAAO,IAAI;AAAA,IAC7C;AAAA,EACF;AACA;AACF;AAEA,gBAAgB,UACd,WACuE;AACvE,aAAW,UAAU,UAAM,0BAAQ,WAAW,EAAE,eAAe,KAAK,CAAC,GAAG;AACtE,QAAI,OAAO,eAAe,GAAG;AAC3B,UAAI;AACF,cAAM,iBAAa;AAAA,UACjB;AAAA,UACA,UAAM,+BAAS,wBAAK,WAAW,OAAO,IAAI,CAAC;AAAA,QAC7C;AACA,cAAM,EAAE,QAAQ,WAAW;AAAA,MAC7B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;AC3EA,IAAAC,mBAAyB;;;ACGlB,SAAS,aAAa,KAAiC;AAC5D,SAAO,SAAS,GAAG,KAAK,gBAAgB,OAAO,WAAW,IAAI,UAAU;AAC1E;;;ACEO,SAAS,aAAa,KAAiC;AAC5D,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO;AAC3B,QAAM,EAAE,YAAY,YAAY,IAAI;AACpC,SAAO,WAAW,UAAU,KAAK,WAAW,WAAW;AACzD;AAEA,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,mBAAmB,IAAI,IAAmB,qBAAqB;AAErE,IAAM,kBAAkB,oBAAI,IAA2B;AAAA,EACrD,CAAC,QAAQ,KAAK;AAAA,EACd,CAAC,QAAQ,KAAK;AAAA,EACd,CAAC,QAAQ,KAAK;AAAA,EACd,CAAC,QAAQ,MAAM;AAAA,EACf,CAAC,cAAc,OAAO;AAAA,EACtB,CAAC,cAAc,OAAO;AAAA,EACtB,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,SAAS,QAAQ;AAAA,EAClB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,SAAS,MAAM;AAAA,EAChB,CAAC,UAAU,MAAM;AAAA,EACjB,CAAC,aAAa,MAAM;AAAA,EACpB,CAAC,eAAe,MAAM;AAAA,EACtB,CAAC,OAAO,MAAM;AAAA,EACd,CAAC,kBAAkB,WAAW;AAChC,CAAU;AAEH,SAAS,gBAAgB,QAAwB;AACtD,QAAM,OAAO,IAAI,MAAM,EAAE,YAAY,EAAE,QAAQ,MAAM,EAAE;AACvD,SAAO,gBAAgB,IAAI,IAAI,KAAK;AACtC;AAEO,SAAS,eAAe,QAAqC;AAClE,SACE,WAAW,MAAM,KACjB,iBAAiB,IAAI,gBAAgB,MAAM,CAAkB;AAEjE;AAEO,SAAS,SAAS,GAA4B;AACnD,MAAI;AACF,WAAO,QAAQ,CAAC,IAAI,SAAY,IAAI,IAAI,CAAC;AAAA,EAC3C,QAAQ;AACN;AAAA,EACF;AACF;AAEO,SAAS,kBACd,QACwB;AACxB,MAAI,UAAU,QAAQ,QAAQ,MAAM,EAAG;AAEvC,MAAI,WAAW;AACb,aAAS,OAAO,QAAQ,OAAO,GAAG;AAAA,EACpC;AAEA,QAAM,MAAM,SAAS,MAAM;AAE3B,MAAI,KAAK,aAAa,SAAS;AAC7B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,IACP;AAAA,EACF;AAEA,QAAMC,YAAW;AAAA,IACf;AAAA;AAAA,MAEE,OACE;AAAA,IACJ;AAAA,IACA;AAAA;AAAA,MAEE,OACE;AAAA,IACJ;AAAA,IACA;AAAA;AAAA,MAEE,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AAAA,EACF;AAEA,aAAW,EAAE,UAAU,MAAM,KAAKA,WAAU;AAC1C,UAAM,IAAI,cAAc;AAAA,MACtB;AAAA,MACA,QAAQ;AAAA,MACR,GAAI,OAAO,MAAM,KAAK,GAAG,UAAU,CAAC;AAAA,IACtC,CAAC;AACD,QAAI,aAAa,CAAC,GAAG;AACnB,YAAM,2CAA2C,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI;AAEF,UAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,QAAI,UAAU,MAAM;AAClB,YAAM,sCAAsC,MAAM;AAClD,YAAM,SAAS,gBAAgB,OAAO,QAAQ;AAC9C,UAAI,CAAC,eAAe,MAAM,GAAG;AAE3B,eAAO;AAAA,UACL,KAAK;AAAA,UACL,QAAQ;AAAA,QACV;AAAA,MACF,OAAO;AACL,eAAO,cAAc;AAAA,UACnB,KAAK;AAAA,UACL,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,YAAY,OAAO;AAAA,UACnB,YAAY,OAAO;AAAA;AAAA,UAEnB,aAAa,OAAO,SAAS,QAAQ,OAAO,EAAE;AAAA,QAChD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA;AACF;;;ACtJA,IAAM,QAAQ,oBAAI,IAAoB;AAgB/B,SAAS,YACdC,WACQ;AACR,MAAIA,aAAY,QAAQA,UAAS,WAAW,GAAG;AAC7C,WAAO;AAAA,EACT;AACA,QAAM,cAAc,KAAK,UAAUA,SAAQ;AAC3C;AACE,UAAM,QAAQ,MAAM,IAAI,WAAW;AACnC,QAAI,SAAS,MAAM;AACjB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,SAASA,UAAS,MAAM,EAAE,OAAO,UAAU,EAAE,KAAK;AACxD,QAAM,YAAY,KAAK,UAAU,MAAM;AACvC;AACE,UAAM,QAAQ,MAAM,IAAI,SAAS;AACjC,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,aAAa,KAAK;AAC5B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,SAAS,aAAa,MAAM;AAClC,MAAI,MAAM,OAAO,KAAK;AAEpB,UAAM,MAAM;AAAA,EACd;AAEA,QAAM,IAAI,aAAa,MAAM;AAC7B,QAAM,IAAI,WAAW,MAAM;AAC3B,SAAO;AACT;AAEA,SAAS,aAAaA,WAAgD;AACpE,QAAM,gBAAgBA,UAAS,IAAI,CAAC,YAAY;AAC9C,QAAI,QAAQ;AACZ,QAAI,IAAI;AACR,WAAO,IAAI,QAAQ,QAAQ;AAEzB,UAAI,QAAQ,CAAC,MAAM,OAAO,QAAQ,IAAI,CAAC,MAAM,KAAK;AAChD,iBAAS;AACT,aAAK;AACL,YAAI,QAAQ,CAAC,MAAM,KAAK;AACtB;AAAA,QACF;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,CAAC,MAAM,KAAK;AACtB,iBAAS;AACT;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,CAAC,MAAM,KAAK;AACtB,iBAAS;AACT;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,CAAC,MAAM,KAAK;AACtB,iBAAS;AACT;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,CAAC,MAAM,KAAK;AACtB,YAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,mBAAS;AACT;AACA;AAAA,QACF,WAAW,WAAW;AACpB,mBAAS;AACT;AACA;AAAA,QACF;AAAA,MACF;AAGA,UAAI,kBAAkB,KAAK,QAAQ,CAAC,CAAW,GAAG;AAChD,iBAAS,OAAO,QAAQ,CAAC;AACzB;AACA;AAAA,MACF;AAGA,eAAS,QAAQ,CAAC;AAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACD,QAAM,QAAQ,cAAc,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;AACxD,SAAO,MAAM,WAAW;AAAA;AAAA,IAEpB;AAAA,MACA,IAAI,OAAO,OAAO,MAAM,KAAK,GAAG,CAAC,MAAM,GAAG;AAChD;AAKO,IAAM,eAAe;;;ACvGrB,SAAS,eACd,YACA,QACA,SAAsC,CAAC,GAC9B;AACT,MAAI,WAAW;AACb,UAAM,cAAc,cAAc,QAAQ,IAAI,aAAa,CAAC;AAC5D,QAAI,eAAe,QAAQ,eAAe,aAAa;AACrD,YAAM,mDAAmD,UAAU;AACnE,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,iBACJ,WAAW,MAAM,MACf,OAAO,iBAAiB,sBAAmC;AAAA,IAC3D;AAAA,EACF;AACF,QAAM,gBAAgB;AAAA,IACpB,OAAO,sBAAsB;AAAA,EAC/B,EAAE,KAAK,UAAU;AACjB,QAAM,SAAS,kBAAkB;AACjC,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEO,SAAS,mBACd,IACA,QACA;AACA,QAAM,SAAS,eAAe,GAAG,YAAY,GAAG,QAAQ,MAAM;AAE9D,MAAI,WAAW;AAGb,OAAG,mBAAmB;AAAA,EACxB,OAAO;AAGL,OAAG,iBAAiB;AAAA,EACtB;AACF;;;AC1BO,SAAS,uBACd,OACwB;AACxB,QAAM,aAAa,mBAAmB,MAAM,OAAO;AACnD,QAAM,SAAS,WAAW,MAAM,UAAU,KAAK,WAAW,MAAM,OAAO;AACvE,SAAO,cAAc,QAAQ,UAAU,OACnC,SACA;AAAA,IACE;AAAA,IACA;AAAA,EACF;AACN;AAOO,SAAS,kCACd,OACA,UAAuC,CAAC,GACpB;AACpB,SAAO;AAAA,IACL,YAAY,MAAM;AAAA,IAClB,QAAQ,MAAM;AAAA,IACd,WAAW,MAAM;AAAA,IACjB,gBAAgB,eAAe,MAAM,SAAS,MAAM,YAAY,OAAO;AAAA,IACvE,QAAQ;AAAA;AAAA,IACR,GAAG,kBAAkB,MAAM,OAAO;AAAA,EACpC;AACF;AAOO,SAAS,UAAU,SAA+B;AACvD,QAAM,UAAwB,CAAC;AAC/B,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,aAAW,QAAQ,OAAO;AAExB,QAAI,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE,WAAW,GAAG,GAAG;AAChD;AAAA,IACF;AAEA,UAAM,SAAS,KACZ,KAAK,EACL,MAAM,mBAAmB,GACxB,IAAI,qBAAqB;AAE7B,QAAI,CAAC,UAAU,OAAO,SAAS,GAAG;AAChC;AAAA,IACF;AACA,UAAM,UAAU,mBAAmB,OAAO,CAAC,CAAC;AAC5C,QAAI,WAAW,MAAM;AACnB,cAAQ,KAAK;AAAA,QACX,SAAS,OAAO,CAAC;AAAA;AAAA,QAEjB;AAAA,QACA,YAAY,OAAO,CAAC;AAAA,QACpB,WAAW,OAAO,CAAC;AAAA,QACnB,SAAS,MAAM,OAAO,CAAC,CAAC;AAAA,QACxB,WAAW,MAAM,OAAO,CAAC,CAAC;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;;;ALtGA,eAAsB,oBACpB,QACA,MACuB;AACvB,QAAM,IAAI,oBAAoB,IAAI;AAClC,QAAM,MAAoB,CAAC;AAC3B,MAAI;AAEF,UAAM,MAAM,OAAO,MAAM,OAAO,GAAG,oBAAoB;AACvD,UAAM,8CAA8C,GAAG;AACvD,QAAI,OAAO,KAAM,KAAI,KAAK,GAAG,GAAG;AAAA,EAClC,SAAS,OAAO;AACd,UAAM,sCAAsC,KAAK;AAAA,EAEnD;AAEA,MAAI;AACJ,aAAW,SAAS,EAAE,sBAAsB;AAC1C,QAAI;AACF,YAAM,cAAc,UAAM,2BAAS,OAAO,MAAM;AAChD,YAAM,MAAM,UAAU,WAAW,EAC9B,IAAI,CAAC,OAAO,uBAAuB,EAAE,CAAC,EACtC,OAAO,CAAC,OAAO,MAAM,IAAI;AAC5B,YAAM,6CAA6C,OAAO,GAAG;AAC7D,UAAI,IAAI,SAAS,GAAG;AAClB,YAAI,KAAK,GAAG,GAAG;AACf;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,gBAAU,QAAQ,KAAK;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,eAAe,oBAAI,IAAwB;AACjD,aAAW,MAAM,KAAK;AACpB,UAAM,QAAQ,aAAa,IAAI,GAAG,UAAU;AAC5C,UAAM,SAAS,EAAE,GAAG,cAAc,KAAK,GAAG,GAAG,cAAc,EAAE,EAAE;AAC/D,QAAI,aAAa,MAAM,GAAG;AACxB,mBAAa,IAAI,OAAO,YAAY,MAAM;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,2CAA2C,KAAK,UAAU,EAAE,oBAAoB,CAAC;AAAA,MACjF,EAAE,MAAM;AAAA,IACV;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,GAAG,aAAa,OAAO,CAAC;AACzC,QAAM,4BAA4B;AAAA,IAChC,SAAS,QAAQ,IAAI,CAAC,OAAO,GAAG,UAAU;AAAA,EAC5C,CAAC;AAED,SAAO;AACT;AAEA,eAAsB,qBACpB,YACA,MACqB;AACrB,MAAI;AACJ,QAAM,SAAS,oBAAoB,IAAI,EAAE;AACzC,aAAW,SAAS,QAAQ;AAC1B,QAAI;AACF,YAAM,cAAc,UAAM,2BAAS,OAAO,MAAM;AAChD,iBAAW,MAAM,UAAU,WAAW,GAAG;AACvC,YAAI,GAAG,YAAY,YAAY;AAC7B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,sBAAgB,QAAQ,KAAK;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,8BAA8B,UAAU,uCAAuC,KAAK,UAAU,MAAM,CAAC;AAAA,IACrG;AAAA,EACF;AACF;;;AM9EO,SAAS,aACd,MACwB;AACxB,MAAI,QAAQ,QAAQ,QAAQ,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG;AACpD;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,WAAW,MAAM,KAAK,CAAC,KAAK,WAAW,IAAI,GAAG;AACtD;AAAA,EACF;AAGA,QAAM,iBAAiB,KAAK,WAAW,IAAI;AAC3C,QAAM,YAAY,iBAAiB,MAAM;AAGzC,QAAM,QAAQ,KAAK,MAAM,CAAC,EAAE,MAAM,SAAS;AAG3C,MAAI,MAAM,SAAS,GAAG;AACpB;AAAA,EACF;AAGA,QAAM,CAAC,YAAY,WAAW,IAAI;AAClC,MACE,cAAc,QACd,QAAQ,UAAU,KAClB,eAAe,QACf,QAAQ,WAAW,GACnB;AACA;AAAA,EACF;AAGA,QAAM,eAAe;AACrB,MAAI,aAAa,KAAK,UAAU,KAAK,aAAa,KAAK,WAAW,GAAG;AACnE;AAAA,EACF;AAGA,QAAM,aAAa,iBAAiB,OAAO;AAC3C,MAAI,KAAK,SAAS,UAAU,GAAG;AAC7B;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,aAAa,QAAQ,KAAK;AACjD;;;AC1DA,IAAM,YAAY;AAiBX,SAAS,YAAY,MAA8C;AACxE,SAAO,IAAI,IAAI,EAAE,MAAM,SAAS,IAAI,CAAC;AACvC;;;ACHO,SAAS,OAAa,KAAU,OAAwC;AAC7E,QAAM,OAAO,oBAAI,IAAO;AACxB,SAAO,IAAI,OAAO,CAAC,SAAS;AAC1B,UAAM,MAAM,MAAM,IAAI;AACtB,QAAI,OAAO,QAAQ,KAAK,IAAI,GAAG,EAAG,QAAO;AACzC,SAAK,IAAI,GAAG;AACZ,WAAO;AAAA,EACT,CAAC;AACH;;;ACGA,eAAsB,yBACpB,MACAC,WACuB;AACvB,QAAM,IAAI,sBAAsB,MAAMA,SAAQ;AAE9C,SAAO,YACH,IACA,YAAY,EAAE,MAAM,wBAAwB,GAAG,MAAM,SAAS,EAAE,CAAC;AACvE;AAEA,eAAe,sBACb,GACAA,WACuB;AACvB,QAAM,kEAAkE,CAAC;AAEzE,QAAM,MAAM,OAAO,aAAa,WAC3B,YAAY;AACX,UAAM,oDAAoD;AAC1D,UAAM,SAAS,OAAO,MAAMA,UAAS,GAAG,qBAAqB,CAAC;AAC9D;AAAA,MACE;AAAA,MACA,OAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,GAAG,IACH,oBAAoBA,WAAU,CAAC;AAEnC,QAAM,+CAA+C,GAAG;AAExD,QAAM,YAAY,IACf,IAAI,CAAC,OAAO,cAAc,EAAE,CAAe,EAC3C,OAAO,CAAC,OAAO,WAAW,GAAG,UAAU,CAAC;AAE3C,aAAW,MAAM,WAAW;AAC1B,uBAAmB,IAAI,CAAC;AAAA,EAC1B;AAEA,QAAM,WAAW,EAAE,uBACf,YACA,UAAU,OAAO,CAAC,OAAO,CAAC,GAAG,cAAc;AAE/C,QAAM,OAAO,OAAO,UAAU,CAAC,OAAO,WAAW,GAAG,UAAU,CAAC;AAC/D,QAAM,uDAAuD,KAAK,MAAM;AAExE,QAAM,UAAU,oBAAoB,MAAM,CAAC,OAAO,GAAG,UAAU;AAC/D;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,EACV;AAEA,QAAM,cAAc;AAAA,IAClB,gBAAgB,EAAE;AAAA,IAClB,OAAO,QAAQ;AAAA;AAAA,MAEb,CAAC,OAAO,QAAQ,GAAG,MAAM,KAAK,GAAG,WAAW;AAAA,IAC9C;AAAA,IACA,IAAI,OAAO,OAAO;AAChB,YAAM,gDAAgD,GAAG,UAAU;AACnE,SAAG,UAAU,MAAM,gBAAgB,GAAG,YAAY,EAAE,SAAS,GAAG;AAChE;AAAA,QACE;AAAA,QACA,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF,CAAC;AAED;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,EACV;AACA,SAAO;AACT;;;ACzEA,eAAsB,sBACpB,GACAC,WACyB;AACzB,MAAI,QAAQ,EAAE,UAAU,GAAG;AACzB,UAAM,IAAI;AAAA,MACR,6BAA6B,KAAK,UAAU,EAAE,UAAU;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,IAAI,mBAAmB,GAAGA,SAAQ;AAExC,SAAO,YACH,IACA,YAAY;AAAA,IACV,MAAM;AAAA,IACN,WAAW,EAAE;AAAA,IACb,SAAS;AAAA,EACX,CAAC;AACP;AAEA,eAAe,mBACb,GACAA,WACyB;AACzB,MAAI,oBAAoB,CAAC;AACzB,QAAM,OAAO,cAAc,EAAE,UAAU;AACvC,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,MAAM,yBAAyB,KAAK,UAAU,EAAE,UAAU,CAAC;AAAA,EACvE;AACA,IAAE,aAAa;AAEf;AAAA,IACE;AAAA,IACA,EAAE;AAAA,EACJ;AACA,QAAM,mCAAmC,CAAC;AAE1C,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,gBAAgB,EAAE,YAAY,EAAE,SAAS;AACzE,MAAI,WAAW,qBAAqB,SAAS;AAC3C,UAAM,iDAAiD,KAAK;AAC5D,UAAM,SAAS,IAAI,MAAM,yBAAyB,MAAM;AAAA,EAC1D;AAEA,QAAM,0CAA0C,MAAM;AAEtD,MAAI,SAAkB;AAEtB,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS;AACX,UAAM,gDAAgD;AACtD,QAAI;AACF,YAAM,IAAI,MAAM,qBAAqB,EAAE,YAAY,CAAC;AACpD,iBAAW,kCAAkC,GAAG,CAAC;AACjD,YAAM,qCAAqC,QAAQ;AACnD,UAAI,SAAS,QAAQ;AACnB,iBAAS;AAAA,MACX;AACA,UAAI,WAAW,EAAE,OAAO,GAAG;AACzB,iBAAS,EAAE;AAAA,MACb;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,kDAAkD,GAAG;AAAA,IAE7D;AAAA,EACF;AAEA,MAAI,WAAW,MAAM,GAAG;AACtB,MAAE,SAAS;AACX,UAAM,wCAAwC,MAAM;AAAA,EACtD;AAEA,QAAM,gDAAgD;AACtD,QAAM,WAAY,OAChB,MAAMA,UAAS,GACf,kBAAkB,CAAC;AACrB,QAAM,2CAA2C,QAAQ;AAGzD,QAAM,aACJ,YACA,kBAAkB,SAAS,GAAG,KAC9B,kBAAkB,SAAS,SAAS,MACnC,YAAY,aAAa,EAAE,UAAU,IAAI;AAE5C,QAAM,iDAAiD,UAAU;AAEjE,aACE,eAAe,SAAS,MAAM,MAC7B,YAAY,UAAU,SAAS,UAAU;AAE5C,QAAM,sCAAsC;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,EAAE;AAAA,IACd;AAAA,EACF,CAAC;AACD,QAAM,SAAS,cAAc;AAAA,IAC3B;AAAA;AAAA,IACA,GAAG,cAAc,UAAU;AAAA,IAC3B,GAAG,cAAc,QAAQ;AAAA,IACzB,GAAG,cAAc,QAAQ;AAAA,IACzB,YAAY,EAAE;AAAA,IACd;AAAA,EACF,CAAC;AAGD,MAAI,WAAW,WAAW,MAAM,GAAG;AAGjC,WAAO,SAAU,MAAM,mBAAmB,MAAM,KAAM;AACtD,WAAO,UAAW,MAAM,oBAAoB,MAAM,KAAM;AAAA,EAC1D;AAEA,qBAAmB,QAAQ,CAAC;AAG5B,SAAO,OAAO,YAAY,OAAO,IAAI,KAAK,OAAO,QAAQ;AAEzD,QAAM,+CAA+C,EAAE,YAAY,MAAM;AACzE,SAAO,cAAc,MAAM;AAC7B;AAEA,eAAsB,yBACpB,MAIAA,WAC2B;AAC3B,QAAM,IAAI,oBAAoB,IAAI;AAClC,QAAM,oDAAoD,CAAC;AAE3D,QAAM,MAAM,MAAM,yBAAyB,GAAGA,SAAQ;AACtD,QAAM,gDAAgD,IAAI,MAAM;AAEhE,QAAM,uBAAuB,IAC1B;AAAA,IACC,CAAC,OAAO,GAAG,UAAU,QAAQ,GAAG,WAAW,qBAAqB;AAAA,EAClE,EACC,IAAI,CAAC,QAAQ;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,OAAO,IAAI,aAAa,yBAAyB,GAAG,QAAQ;AAAA,MAC1D,MAAM;AAAA,IACR,CAAC;AAAA,EACH,EAAE;AAEJ,QAAM,uBACJ,MAAM,wBAAwB;AAEhC,QAAM,oBAAoB,uBACtB,CAAC,IACD,IACG,OAAO,CAAC,OAAO,GAAG,cAAc,EAChC,IAAI,CAAC,QAAQ;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,OAAO,IAAI,aAAa,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAAA,EAC9D,EAAE;AAER,QAAM,UAAU,IAAI;AAAA,IAClB,CAAC,OAAO,GAAG,UAAU,QAAQ,GAAG,WAAW,qBAAqB;AAAA,EAClE;AAEA,QAAM,2BAA2B;AAAA,IAC/B,gBAAgB,IAAI,IAAI,CAAC,OAAO,GAAG,UAAU;AAAA,IAC7C,oBAAoB,QAAQ,IAAI,CAAC,OAAO,GAAG,UAAU;AAAA,EACvD,CAAC;AAED;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,IACR,EAAE;AAAA,EACJ;AAEA,QAAM,UAAU,MAAO,cAAc;AAAA,IACnC,gBAAgB,EAAE;AAAA,IAClB,OACG,MAAM,wBAAwB,8BAC3B,UACA,QAAQ,OAAO,CAAC,OAAO,CAAC,GAAG,cAAc;AAAA,IAC/C,IAAI,OAAO,OACT,sBAAsB,EAAE,GAAG,IAAI,GAAG,EAAE,GAAGA,SAAQ,EAAE,MAAM,CAAC,WAAW;AAAA,MACjE,YAAY,GAAG;AAAA,MACf;AAAA,IACF,EAAE;AAAA,EACN,CAAC;AAED,QAAM,yDAAyD;AAC/D,SAAO,IAAI;AAAA,IACT,CAAC,WACE,QAAQ,KAAK,CAAC,OAAO,GAAG,eAAe,OAAO,UAAU,KACvD,qBAAqB;AAAA,MACnB,CAAC,OAAO,GAAG,eAAe,OAAO;AAAA,IACnC,KACA,kBAAkB,KAAK,CAAC,OAAO,GAAG,eAAe,OAAO,UAAU,KAAK;AAAA,MACrE,GAAG;AAAA,MACH,OAAO,IAAI,aAAa,sCAAsC;AAAA,QAC5D,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACN;AACF;;;A7BlLA,IAAM,WAAWC,OAA+B,YAAY;AAC1D,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI;AACF,UAAMC,WAAU,SAAS;AACzB,UAAM,MAAM,MAAM,gBAAgBA,UAAS,aAAa;AACxD,QAAI,OAAO,MAAM;AACf,YAAM,IAAI;AAAA,QACR,8DAA8DA;AAAA,MAChE;AAAA,IACF;AACA,UAAM,eAAW,sBAAAC,SAAa,GAAG;AACjC,aAAS,gBAAgB,eAAe,CAAC;AACzC,aAAS,eAAe,gBAAgB,IAAI,SAAS;AACrD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,sCAAsC,KAAK;AACjD,UAAM;AAAA,EACR,UAAE;AACA,UAAM,sCAAsC,KAAK,IAAI,IAAI,KAAK;AAAA,EAChE;AACF,CAAC;AAYM,SAAS,qBACd,MACuB;AACvB,SAAO,yBAAyB,oBAAoB,IAAI,GAAG,QAAQ;AACrE;AAQO,SAAS,kBACd,YACA,MACyB;AACzB,SAAO;AAAA,IACL,EAAE,GAAG,oBAAoB,IAAI,GAAG,WAAW;AAAA,IAC3C;AAAA,EACF;AACF;AAmBO,SAAS,qBACd,MAC2B;AAC3B,SAAO,yBAAyB,oBAAoB,IAAI,GAAG,QAAQ;AACrE;AAWO,SAAS,SAAS,UAAoC;AAC3D,SAAO,aAAa,UAAU,QAAQ;AACxC;AASO,SAAS,kBAAkB,UAAoC;AACpE,SAAO,sBAAsB,UAAU,QAAQ;AACjD;AAQO,SAAS,kBAAkB,UAA2C;AAC3E,SAAO,sBAAsB,UAAU,QAAQ;AACjD;AAgBO,SAAS,UACd,UACA,QACA,SAAqB,QACK;AAC1B,SAAO,cAAc,UAAU,QAAQ,QAAQ,QAAQ;AACzD;","names":["defer","import_node_path","import_node_process","import_promises","import_node_path","import_node_path","nativeFn","import_node_os","import_promises","import_node_path","import_promises","patterns","patterns","nativeFn","nativeFn","defer","dirname","NodeGypBuild"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/debuglog.ts","../src/defer.ts","../src/stack_path.ts","../src/platform.ts","../src/string.ts","../src/dirname.ts","../src/fs.ts","../src/async.ts","../src/number.ts","../src/units.ts","../src/hidden.ts","../src/object.ts","../src/error.ts","../src/path.ts","../src/options.ts","../src/string_enum.ts","../src/volume_health_status.ts","../src/linux/dev_disk.ts","../src/linux/mount_points.ts","../src/mount_point.ts","../src/remote_info.ts","../src/glob.ts","../src/system_volume.ts","../src/linux/mtab.ts","../src/unc.ts","../src/uuid.ts","../src/array.ts","../src/volume_mount_points.ts","../src/volume_metadata.ts"],"sourcesContent":["// src/index.ts\n\nimport NodeGypBuild from \"node-gyp-build\";\nimport { debug, debugLogContext, isDebugEnabled } from \"./debuglog.js\";\nimport { defer } from \"./defer.js\";\nimport { _dirname } from \"./dirname.js\";\nimport { findAncestorDir } from \"./fs.js\";\nimport type { HideMethod, SetHiddenResult } from \"./hidden.js\";\nimport {\n getHiddenMetadataImpl,\n isHiddenImpl,\n isHiddenRecursiveImpl,\n setHiddenImpl,\n} from \"./hidden.js\";\nimport {\n IncludeSystemVolumesDefault,\n LinuxMountTablePathsDefault,\n OptionsDefault,\n optionsWithDefaults,\n SystemFsTypesDefault,\n SystemPathPatternsDefault,\n TimeoutMsDefault,\n} from \"./options.js\";\nimport type {\n StringEnum,\n StringEnumKeys,\n StringEnumType,\n} from \"./string_enum.js\";\nimport type { SystemVolumeConfig } from \"./system_volume.js\";\nimport type { HiddenMetadata } from \"./types/hidden_metadata.js\";\nimport type { MountPoint } from \"./types/mount_point.js\";\nimport { NativeBindings } from \"./types/native_bindings.js\";\nimport type { Options } from \"./types/options.js\";\nimport type { VolumeMetadata } from \"./types/volume_metadata.js\";\nimport type { VolumeHealthStatus } from \"./volume_health_status.js\";\nimport { VolumeHealthStatuses } from \"./volume_health_status.js\";\nimport {\n getAllVolumeMetadataImpl,\n getVolumeMetadataImpl,\n} from \"./volume_metadata.js\";\nimport type { GetVolumeMountPointOptions } from \"./volume_mount_points.js\";\nimport { getVolumeMountPointsImpl } from \"./volume_mount_points.js\";\n\nexport type {\n GetVolumeMountPointOptions,\n HiddenMetadata,\n HideMethod,\n MountPoint,\n Options,\n SetHiddenResult,\n StringEnum,\n StringEnumKeys,\n StringEnumType,\n SystemVolumeConfig,\n VolumeHealthStatus,\n VolumeMetadata,\n};\n\nconst nativeFn = defer<Promise<NativeBindings>>(async () => {\n const start = Date.now();\n try {\n const dirname = _dirname();\n const dir = await findAncestorDir(dirname, \"binding.gyp\");\n if (dir == null) {\n throw new Error(\n \"Could not find bindings.gyp in any ancestor directory of \" + dirname,\n );\n }\n const bindings = NodeGypBuild(dir) as NativeBindings;\n bindings.setDebugLogging(isDebugEnabled());\n bindings.setDebugPrefix(debugLogContext() + \":native\");\n return bindings;\n } catch (error) {\n debug(\"Loading native bindings failed: %s\", error);\n throw error;\n } finally {\n debug(`Native bindings took %d ms to load`, Date.now() - start);\n }\n});\n\n/**\n * List all active local and remote mount points on the system.\n *\n * Only readable directories are included in the results.\n *\n * Note that on Windows, `timeoutMs` will be used **per system call** and not\n * for the entire operation.\n *\n * @param opts Optional filesystem operation settings to override default values\n */\nexport function getVolumeMountPoints(\n opts?: Partial<GetVolumeMountPointOptions>,\n): Promise<MountPoint[]> {\n return getVolumeMountPointsImpl(optionsWithDefaults(opts), nativeFn);\n}\n\n/**\n * Get metadata for the volume at the given mount point.\n *\n * @param mountPoint Must be a non-blank string\n * @param opts Optional filesystem operation settings\n */\nexport function getVolumeMetadata(\n mountPoint: string,\n opts?: Partial<Pick<Options, \"timeoutMs\">>,\n): Promise<VolumeMetadata> {\n return getVolumeMetadataImpl(\n { ...optionsWithDefaults(opts), mountPoint },\n nativeFn,\n );\n}\n\n/**\n * Retrieves metadata for all mounted volumes with optional filtering and\n * concurrency control.\n *\n * @param opts - Optional configuration object\n * @param opts.includeSystemVolumes - If true, includes system volumes in the\n * results. Defaults to true on Windows and false elsewhere.\n * @param opts.maxConcurrency - Maximum number of concurrent operations.\n * Defaults to the system's available parallelism: see\n * {@link https://nodejs.org/api/os.html#osavailableparallelism | os.availableParallelism()}\n * @param opts.timeoutMs - Maximum time to wait for\n * {@link getVolumeMountPointsImpl}, as well as **each** {@link getVolumeMetadataImpl}\n * to complete. Defaults to {@link TimeoutMsDefault}\n * @returns Promise that resolves to an array of either VolumeMetadata objects\n * or error objects containing the mount point and error\n * @throws Never - errors are caught and returned as part of the result array\n */\nexport function getAllVolumeMetadata(\n opts?: Partial<Options> & { includeSystemVolumes?: boolean },\n): Promise<VolumeMetadata[]> {\n return getAllVolumeMetadataImpl(optionsWithDefaults(opts), nativeFn);\n}\n\n/**\n * Check if a file or directory is hidden.\n *\n * Note that `path` may be _effectively_ hidden if any of the ancestor\n * directories are hidden: use {@link isHiddenRecursive} to check for this.\n *\n * @param pathname Path to file or directory\n * @returns Promise resolving to boolean indicating hidden state\n */\nexport function isHidden(pathname: string): Promise<boolean> {\n return isHiddenImpl(pathname, nativeFn);\n}\n\n/**\n * Check if a file or directory is hidden, or if any of its ancestor\n * directories are hidden.\n *\n * @param pathname Path to file or directory\n * @returns Promise resolving to boolean indicating hidden state\n */\nexport function isHiddenRecursive(pathname: string): Promise<boolean> {\n return isHiddenRecursiveImpl(pathname, nativeFn);\n}\n\n/**\n * Get detailed metadata about the hidden state of a file or directory.\n *\n * @param pathname Path to file or directory\n * @returns Promise resolving to metadata about the hidden state\n */\nexport function getHiddenMetadata(pathname: string): Promise<HiddenMetadata> {\n return getHiddenMetadataImpl(pathname, nativeFn);\n}\n\n/**\n * Set the hidden state of a file or directory\n *\n * @param pathname Path to file or directory\n * @param hidden - Whether the item should be hidden (true) or visible (false)\n * @param method Method to use for hiding the file or directory. The default\n * is \"auto\", which is \"dotPrefix\" on Linux and macOS, and \"systemFlag\" on\n * Windows. \"all\" will attempt to use all relevant methods for the current\n * operating system.\n * @returns Promise resolving the final name of the file or directory (as it\n * will change on POSIX systems), and the action(s) taken.\n * @throws {Error} If the file doesn't exist, permissions are insufficient, or\n * the requested method is unsupported\n */\nexport function setHidden(\n pathname: string,\n hidden: boolean,\n method: HideMethod = \"auto\",\n): Promise<SetHiddenResult> {\n return setHiddenImpl(pathname, hidden, method, nativeFn);\n}\n\nexport {\n IncludeSystemVolumesDefault,\n LinuxMountTablePathsDefault,\n OptionsDefault,\n optionsWithDefaults,\n SystemFsTypesDefault,\n SystemPathPatternsDefault,\n TimeoutMsDefault,\n VolumeHealthStatuses,\n};\n","import { debuglog, format } from \"node:util\";\n\n// inlined as a hack to get around relative imports broken in ts-node (used by\n// the debuglog tests):\nfunction defer<T>(thunk: () => T) {\n let t: T;\n return () => (t ??= thunk());\n}\n\nexport const debugLogContext = defer(() => {\n for (const ea of [\"fs-metadata\", \"fs-meta\"]) {\n if (debuglog(ea).enabled) {\n return ea;\n }\n if (debuglog(ea.toUpperCase()).enabled) {\n return ea;\n }\n }\n return \"photostructure:fs-metadata\";\n});\n\nexport const isDebugEnabled = defer(() => {\n return debuglog(debugLogContext()).enabled ?? false;\n});\n\nexport function debug(msg: string, ...args: unknown[]) {\n if (!isDebugEnabled()) return;\n const now = new Date();\n\n // Format: [HH:MM:SS.mmm] prefix: message\n const timestamp = `[${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}.${now.getMilliseconds().toString().padStart(3, \"0\")}] ${debugLogContext()} `;\n\n process.stderr.write(timestamp + format(msg, ...args) + \"\\n\");\n}\n","// src/defer.ts\n\nexport type Defer<T> = (() => T) & {\n reset: () => void;\n};\n\n/**\n * Creates a deferred value that is computed once on first access and cached for\n * subsequent accesses.\n * @param thunk A function that takes no arguments and returns a value\n * @returns A function that returns the computed value\n */\nexport function defer<T>(thunk: () => T): Defer<T> {\n let computed = false;\n let value: T;\n\n const fn = () => {\n if (!computed) {\n computed = true;\n value = thunk();\n }\n return value;\n };\n\n fn.reset = () => {\n computed = false;\n };\n\n return fn;\n}\n","import { dirname } from \"node:path\";\nimport { isWindows } from \"./platform\";\nimport { isNotBlank, toS } from \"./string\";\n\nexport function getCallerDirname(): string {\n const e = new Error();\n if (e.stack == null) {\n Error.captureStackTrace(e);\n }\n return dirname(extractCallerPath(e.stack as string));\n}\n\n// CURSE THE ESM MODULE SYSTEM 💩 THIS IS ALL HORRIBLE\n\n// THANK GOODNESS for tsup shims: this should only be used when running tests.\n\n// Comprehensive regex patterns for different stack frame formats. Note that we\n// only expect tests to have the first standard form, but if something's worth\n// doing, **it's worth overdoing**.\nconst patterns = isWindows\n ? [\n // Standard: \"at functionName (C:\\path\\file.js:1:1)\"\n /\\bat\\s.+?\\((?<path>[A-Z]:\\\\.+):\\d+:\\d+\\)$/,\n // direct: \"at C:\\path\\file.js:1:1\"\n /\\bat\\s(?<path>[A-Z]:\\\\.+):\\d+:\\d+$/,\n // UNC: \"at functionName (\\\\server\\share\\path\\file.js:1:1)\"\n /\\bat\\s.+?\\((?<path>\\\\\\\\.+):\\d+:\\d+\\)$/,\n // direct: \"at \\\\server\\share\\path\\file.js:1:1\"\n /\\bat\\s(?<path>\\\\\\\\.+):\\d+:\\d+$/,\n ]\n : [\n // Standard: \"at functionName (/path/file.js:1:1)\"\n /\\bat\\s.+?\\((?<path>\\/.+?):\\d+:\\d+\\)$/,\n // Anonymous or direct: \"at /path/file.js:1:1\"\n /\\bat\\s(.+[^/]\\s)?(?<path>\\/.+?):\\d+:\\d+$/,\n ];\n\nconst MaybeUrlRE = /^[a-z]{2,5}:\\/\\//i;\n\n// only exposed for tests:\nexport function extractCallerPath(stack: string): string {\n const frames = stack.split(\"\\n\").filter(Boolean);\n\n // First find getCallerDirname() in the stack:\n const callerFrame = frames.findIndex((frame) =>\n frame.includes(\"getCallerDirname\"),\n );\n if (callerFrame === -1) {\n throw new Error(\"Invalid stack trace format: missing caller frame\");\n }\n for (let i = callerFrame + 1; i < frames.length; i++) {\n const frame = frames[i];\n for (const pattern of patterns) {\n const g = toS(frame).trim().match(pattern)?.groups;\n if (g != null && isNotBlank(g[\"path\"])) {\n const path = g[\"path\"];\n // Windows requires us to check if it's a reasonable URL, as URL accepts\n // \"C:\\\\path\\\\file.txt\" as valid (!!)\n if (MaybeUrlRE.test(path)) {\n try {\n return new URL(path).pathname;\n } catch {\n // ignore\n }\n }\n return path;\n }\n }\n }\n throw new Error(\"Invalid stack trace format: no parsable frames\");\n}\n","// src/platform.ts\n\nimport { arch, platform } from \"node:process\";\n\nexport const isLinux = platform === \"linux\";\nexport const isWindows = platform === \"win32\";\nexport const isMacOS = platform === \"darwin\";\n\nexport const isArm = isLinux && arch.startsWith(\"arm\");\n","// src/string.ts\n\nexport function isString(input: unknown): input is string {\n return typeof input === \"string\";\n}\n\nexport function toS(input: unknown): string {\n return isString(input) ? input : input == null ? \"\" : String(input);\n}\n\n/**\n * @return true iff the input is a string and has at least one non-whitespace character\n */\nexport function isNotBlank(input: unknown): input is string {\n return typeof input === \"string\" && input.trim().length > 0;\n}\n\n/**\n * @return true iff the input is not a string or only has non-whitespace characters\n */\nexport function isBlank(input: unknown): input is undefined {\n return !isNotBlank(input);\n}\n\nexport function toNotBlank(input: unknown): string | undefined {\n return isNotBlank(input) ? input : undefined;\n}\n\n/**\n * Decodes a string containing octal (\\000-\\377) and/or hexadecimal\n * (\\x00-\\xFF) escape sequences\n * @param input The string containing escape sequences to decode\n * @returns The decoded string with escape sequences converted to their\n * corresponding characters\n * @throws Error if an invalid escape sequence is encountered\n */\nexport function decodeEscapeSequences(input: string): string {\n const escapeRegex = /\\\\(?:([0-7]{2,6})|x([0-9a-fA-F]{2,4}))/g;\n\n return input.replace(escapeRegex, (match, octal, hex) => {\n // Handle octal escape sequences\n if (octal != null) {\n return String.fromCharCode(parseInt(octal, 8));\n }\n\n // Handle hexadecimal escape sequences\n if (hex != null) {\n return String.fromCharCode(parseInt(hex, 16));\n }\n\n // This should never happen due to the regex pattern\n throw new Error(`Invalid escape sequence: ${match}`);\n });\n}\n\nconst AlphaNumericRE = /[/\\w.-]/;\n\nexport function encodeEscapeSequences(input: string): string {\n return input\n .split(\"\")\n .map((char) => {\n const encodedChar = AlphaNumericRE.test(char)\n ? char\n : \"\\\\\" + char.charCodeAt(0).toString(8).padStart(2, \"0\");\n return encodedChar;\n })\n .join(\"\");\n}\n\n/**\n * Sort an array of strings using the locale-aware collation algorithm.\n *\n * @param arr The array of strings to sort. The original array **is sorted in\n * place**.\n */\nexport function sortByLocale(\n arr: string[],\n locales?: Intl.LocalesArgument,\n options?: Intl.CollatorOptions,\n): string[] {\n return arr.sort((a, b) => a.localeCompare(b, locales, options));\n}\n\n/**\n * Sort an array of objects using the locale-aware collation algorithm.\n *\n * @param arr The array of objects to sort.\n * @param fn The function to extract the key to sort by from each object.\n * @param locales The locales to use for sorting.\n * @param options The collation options to use for sorting.\n */\nexport function sortObjectsByLocale<T>(\n arr: T[],\n fn: (key: T) => string,\n locales?: Intl.LocalesArgument,\n options?: Intl.CollatorOptions,\n): T[] {\n return arr.sort((a, b) => fn(a).localeCompare(fn(b), locales, options));\n}\n","import { getCallerDirname } from \"./stack_path\";\n\n// Thanks to tsup shims, __dirname should always be defined except when run by\n// jest (which will use the stack_path shim)\nexport function _dirname() {\n try {\n if (typeof __dirname !== \"undefined\") return __dirname;\n } catch {\n // ignore\n }\n // we must be in jest. Use the stack_path ~~hack~~ shim:\n return getCallerDirname();\n}\n","// src/fs.ts\n\nimport { type PathLike, type StatOptions, Stats, statSync } from \"node:fs\";\nimport { opendir, stat } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { withTimeout } from \"./async.js\";\n\n/**\n * Wrapping node:fs/promises.stat() so we can mock it in tests.\n */\nexport async function statAsync(\n path: PathLike,\n options?: StatOptions & { bigint?: false },\n): Promise<Stats> {\n return stat(path, options);\n}\n\nexport async function canStatAsync(path: string): Promise<boolean> {\n try {\n return null != (await statAsync(path));\n } catch {\n return false;\n }\n}\n\n/**\n * @return true if `path` exists and is a directory\n */\nexport async function isDirectory(path: string): Promise<boolean> {\n try {\n return (await statAsync(path))?.isDirectory() === true;\n } catch {\n return false;\n }\n}\n\n/**\n * @return the first directory containing `file` or an empty string\n */\nexport async function findAncestorDir(\n dir: string,\n file: string,\n): Promise<string | undefined> {\n dir = resolve(dir);\n try {\n const s = await statAsync(join(dir, file));\n if (s.isFile()) return dir;\n } catch {\n // fall through\n }\n const parent = resolve(dir, \"..\");\n return parent === dir ? undefined : findAncestorDir(parent, file);\n}\n\nexport function existsSync(path: string): boolean {\n return statSync(path, { throwIfNoEntry: false }) != null;\n}\n\n/**\n * @return `true` if `dir` exists and is a directory and at least one entry can be read.\n * @throws {Error} if `dir` does not exist or is not a directory or cannot be read.\n */\nexport async function canReaddir(\n dir: string,\n timeoutMs: number,\n): Promise<true> {\n return withTimeout({\n desc: \"canReaddir()\",\n promise: _canReaddir(dir),\n timeoutMs,\n });\n}\n\nasync function _canReaddir(dir: string): Promise<true> {\n await (await opendir(dir)).close();\n return true;\n}\n","import { availableParallelism } from \"node:os\";\nimport { env } from \"node:process\";\nimport { gt0, isNumber } from \"./number.js\";\nimport { isBlank } from \"./string.js\";\nimport { DayMs } from \"./units.js\";\n\n/**\n * An error that is thrown when a promise does not resolve within the specified\n * time.\n */\nexport class TimeoutError extends Error {\n constructor(message: string, captureStackTrace = true) {\n super(message);\n this.name = \"TimeoutError\";\n // Capture the stack trace up to the calling site\n if (captureStackTrace && Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n/**\n * Rejects the promise with a TimeoutError if it does not resolve within the\n * specified time.\n *\n * @param promise The promise to wrap.\n * @param timeoutMs The timeout in milliseconds. Timeouts are disabled if this is 0.\n * @returns A promise that resolves when the input promise resolves, or rejects\n * with a TimeoutError if the input promise does not resolve within the\n * specified time.\n * @throws {TimeoutError} if the input promise does not resolve within the\n * specified time.\n * @throws {TypeError} if timeoutMs is not a number that is greater than 0.\n */\nexport async function withTimeout<T>(opts: {\n desc?: string;\n promise: Promise<T>;\n timeoutMs: number;\n}): Promise<T> {\n const desc = isBlank(opts.desc) ? \"thenOrTimeout()\" : opts.desc;\n\n if (!isNumber(opts.timeoutMs)) {\n throw new TypeError(\n desc +\n \": Expected timeoutMs to be numeric, but got \" +\n JSON.stringify(opts.timeoutMs),\n );\n }\n\n const timeoutMs = Math.floor(opts.timeoutMs);\n\n if (timeoutMs < 0) {\n throw new TypeError(\n desc + \": Expected timeoutMs to be > 0, but got \" + timeoutMs,\n );\n }\n\n if (timeoutMs > DayMs) {\n throw new TypeError(\n desc +\n \": Invalid timeoutMs is too large: must be less than one day, but got \" +\n timeoutMs,\n );\n }\n\n if (timeoutMs === 0) {\n return opts.promise;\n }\n\n // Create error here to captured the caller's stack trace. If we create it in\n // the timeout callback, the stack trace will be truncated to this function.\n const timeoutError = new TimeoutError(\n `${desc}: timeout after ${timeoutMs}ms`,\n );\n\n if (env[\"NODE_ENV\"] === \"test\" && timeoutMs === 1) {\n timeoutError.message += \"(timeout test)\";\n opts.promise.catch(() => {}); // < avoid unhandled rejection warnings\n throw timeoutError;\n }\n\n let timeoutId: NodeJS.Timeout | undefined;\n\n opts.promise\n .catch(() => {}) // < avoid unhandled rejection warnings\n .finally(() => {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n });\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (timeoutId != null) {\n timeoutError.message += \"(timeout callback)\";\n reject(timeoutError);\n }\n timeoutId = undefined;\n }, timeoutMs);\n });\n\n return Promise.race([opts.promise, timeoutPromise]);\n}\n\n/**\n * Delay for the specified number of milliseconds.\n *\n * @param ms The number of milliseconds to delay\n * @param t Optional value to resolve with after delay\n * @returns Promise that resolves with the provided value (or void if none provided)\n */\nexport async function delay<T = void>(ms: number, t?: T): Promise<T> {\n return new Promise<T>((resolve) => setTimeout(() => resolve(t as T), ms));\n}\n\n/**\n * Apply `fn` to every item in `items` with a maximum concurrency of\n * `maxConcurrency`.\n */\nexport async function mapConcurrent<I, O>({\n items,\n fn,\n maxConcurrency = availableParallelism(),\n}: {\n items: I[];\n fn: (t: I) => Promise<O>;\n maxConcurrency?: number;\n}): Promise<(O | Error)[]> {\n // Validate maxConcurrency\n if (!gt0(maxConcurrency)) {\n throw new Error(\n `maxConcurrency must be a positive integer, got: ${maxConcurrency}`,\n );\n }\n\n if (typeof fn !== \"function\") {\n throw new TypeError(`fn must be a function, got: ${typeof fn}`);\n }\n\n const results: Promise<O | Error>[] = [];\n const executing: Set<Promise<void>> = new Set();\n\n for (const [index, item] of items.entries()) {\n // Create a wrapped promise that handles cleanup\n while (executing.size >= maxConcurrency) {\n await Promise.race(executing);\n }\n const p = (results[index] = fn(item).catch((error) => error));\n executing.add(p);\n p.finally(() => executing.delete(p));\n }\n\n return Promise.all(results);\n}\n","// src/number.ts\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === \"number\" && isFinite(value);\n}\n\nconst INTEGER_REGEX = /^-?\\d+$/;\n\nexport function toInt(value: unknown): number | undefined {\n try {\n if (value == null) return;\n const s = String(value).trim();\n return INTEGER_REGEX.test(s) ? parseInt(s) : undefined;\n } catch {\n return;\n }\n}\n\nexport function gt0(value: unknown): value is number {\n return isNumber(value) && value > 0;\n}\n","// src/units.ts\n\n/**\n * Milliseconds in a second\n */\nexport const SecondMs = 1000;\n\n/**\n * Milliseconds in a minute\n */\nexport const MinuteMs = 60 * SecondMs;\n\n/**\n * Milliseconds in an hour\n */\nexport const HourMs = 60 * MinuteMs;\n\n/**\n * Milliseconds in a day\n */\nexport const DayMs = 24 * HourMs;\n\n/**\n * Kibibyte (KiB) = 1024 bytes\n * @see https://en.wikipedia.org/wiki/Kibibyte\n */\nexport const KiB = 1024;\n\n/**\n * Mebibyte (MiB) = 1024 KiB\n * @see https://en.wikipedia.org/wiki/Mebibyte\n */\nexport const MiB = 1024 * KiB;\n\n/**\n * Gibibyte (GiB)= 1024 MiB\n * @see https://en.wikipedia.org/wiki/Gibibyte\n */\nexport const GiB = 1024 * MiB;\n\n/**\n * Tebibyte (TiB) = 1024 GiB\n *\n * @see https://en.wikipedia.org/wiki/Byte#Multiple-byte_units\n */\nexport const TiB = 1024 * GiB;\n\nconst f = 1023.995 / 1024;\n\nexport function fmtBytes(bytes: number): string {\n if (bytes < 1023.5) {\n bytes = Math.round(bytes);\n return `${bytes} B`;\n } else if (bytes < MiB * f) {\n return `${(bytes / KiB).toFixed(2)} KiB`;\n } else if (bytes < GiB * f) {\n return `${(bytes / MiB).toFixed(2)} MiB`;\n } else if (bytes < TiB * f) {\n return `${(bytes / GiB).toFixed(2)} GiB`;\n } else {\n return `${(bytes / TiB).toFixed(2)} TiB`;\n }\n}\n","// src/hidden.ts\n\nimport { rename } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { WrappedError } from \"./error.js\";\nimport { canStatAsync, statAsync } from \"./fs.js\";\nimport { isRootDirectory, normalizePath } from \"./path.js\";\nimport { isWindows } from \"./platform.js\";\nimport type { HiddenMetadata } from \"./types/hidden_metadata.js\";\nimport type { NativeBindingsFn } from \"./types/native_bindings.js\";\n\nconst HiddenSupportByPlatform: Partial<\n Record<NodeJS.Platform, Pick<HiddenMetadata, \"supported\">>\n> = {\n win32: {\n supported: {\n dotPrefix: false,\n systemFlag: true,\n },\n },\n darwin: {\n supported: {\n dotPrefix: true,\n systemFlag: true,\n },\n },\n linux: {\n supported: {\n dotPrefix: true,\n systemFlag: false,\n },\n },\n};\n\nexport const LocalSupport = HiddenSupportByPlatform[process.platform]\n ?.supported ?? {\n dotPrefix: false,\n systemFlag: false,\n};\n\n/**\n * Checks if the file or directory is hidden through any available method\n * @returns A boolean indicating if the item is hidden\n * @throws {Error} If the file doesn't exist or permissions are insufficient\n */\nexport async function isHiddenImpl(\n pathname: string,\n nativeFn: NativeBindingsFn,\n): Promise<boolean> {\n const norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n return (\n (LocalSupport.dotPrefix && isPosixHidden(norm)) ||\n (LocalSupport.systemFlag && isSystemHidden(norm, nativeFn))\n );\n}\n\nexport async function isHiddenRecursiveImpl(\n path: string,\n nativeFn: NativeBindingsFn,\n): Promise<boolean> {\n let norm = normalizePath(path);\n if (norm == null) {\n throw new Error(\"Invalid path: \" + JSON.stringify(path));\n }\n while (!isRootDirectory(norm)) {\n if (await isHiddenImpl(norm, nativeFn)) {\n return true;\n }\n norm = dirname(norm);\n }\n return false;\n}\n\nexport function createHiddenPosixPath(pathname: string, hidden: boolean) {\n const norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n const dir = dirname(norm);\n const srcBase = basename(norm).replace(/^\\./, \"\");\n const dest = join(dir, (hidden ? \".\" : \"\") + srcBase);\n return dest;\n}\n\nasync function setHiddenPosix(\n pathname: string,\n hidden: boolean,\n): Promise<string> {\n if (LocalSupport.dotPrefix) {\n const dest = createHiddenPosixPath(pathname, hidden);\n if (pathname !== dest) await rename(pathname, dest);\n return dest;\n }\n\n throw new Error(\"Unsupported platform\");\n}\n\nfunction isPosixHidden(pathname: string): boolean {\n if (!LocalSupport.dotPrefix) return false;\n const b = basename(pathname);\n return b.startsWith(\".\") && b !== \".\" && b !== \"..\";\n}\n\nasync function isSystemHidden(\n pathname: string,\n nativeFn: NativeBindingsFn,\n): Promise<boolean> {\n if (!LocalSupport.systemFlag) {\n // not supported on this platform\n return false;\n }\n if (isWindows && isRootDirectory(pathname)) {\n // windows `attr` thinks all drive letters don't exist.\n return false;\n }\n\n // don't bother the native bindings if the file doesn't exist:\n return (\n (await canStatAsync(pathname)) &&\n (await (await nativeFn()).isHidden(pathname))\n );\n}\n\n/**\n * Gets detailed information about the hidden state of the file or directory\n * @returns An object containing detailed hidden state information\n * @throws {Error} If the file doesn't exist or permissions are insufficient\n */\nexport async function getHiddenMetadataImpl(\n pathname: string,\n nativeFn: NativeBindingsFn,\n): Promise<HiddenMetadata> {\n const norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n const dotPrefix = isPosixHidden(norm);\n const systemFlag = await isSystemHidden(norm, nativeFn);\n return {\n hidden: dotPrefix || systemFlag,\n dotPrefix,\n systemFlag,\n supported: LocalSupport,\n };\n}\n\nexport type HideMethod = \"dotPrefix\" | \"systemFlag\" | \"all\" | \"auto\";\n\nexport type SetHiddenResult = {\n pathname: string;\n actions: {\n dotPrefix: boolean;\n systemFlag: boolean;\n };\n};\n\nexport async function setHiddenImpl(\n pathname: string,\n hide: boolean,\n method: HideMethod,\n nativeFn: NativeBindingsFn,\n): Promise<SetHiddenResult> {\n let norm = normalizePath(pathname);\n if (norm == null) {\n throw new Error(\"Invalid pathname: \" + JSON.stringify(pathname));\n }\n\n if (method === \"dotPrefix\" && !LocalSupport.dotPrefix) {\n throw new Error(\"Dot prefix hiding is not supported on this platform\");\n }\n\n if (method === \"systemFlag\" && !LocalSupport.systemFlag) {\n throw new Error(\"System flag hiding is not supported on this platform\");\n }\n\n try {\n await statAsync(norm);\n } catch (cause) {\n throw new WrappedError(\"setHidden()\", { cause });\n }\n\n if (isWindows && isRootDirectory(norm)) {\n throw new Error(\"Cannot hide root directory on Windows\");\n }\n\n const actions = {\n dotPrefix: false,\n systemFlag: false,\n };\n\n let acted = false;\n\n if (LocalSupport.dotPrefix && [\"auto\", \"all\", \"dotPrefix\"].includes(method)) {\n if (isPosixHidden(norm) !== hide) {\n norm = await setHiddenPosix(norm, hide);\n actions.dotPrefix = true;\n }\n acted = true;\n }\n\n if (\n LocalSupport.systemFlag &&\n ([\"all\", \"systemFlag\"].includes(method) || (!acted && method === \"auto\"))\n ) {\n await (await nativeFn()).setHidden(norm, hide);\n actions.systemFlag = true;\n }\n\n return { pathname: norm, actions };\n}\n","// src/object.js\n\nimport { isNotBlank, isString } from \"./string.js\";\n\n/**\n * @return true iff value is an object and not an array\n */\nexport function isObject(value: unknown): value is object {\n // typeof null is 'object', so we need to check for that case YAY JAVASCRIPT\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * @return undefined if `obj` is nullish, or the return value of `fn` applied\n * against `obj` if `obj` is defined\n */\nexport function map<T, U>(\n obj: T | undefined,\n fn: (value: T) => U,\n): U | undefined {\n return obj == null ? undefined : fn(obj);\n}\n\n/**\n * @return a shallow copy of `obj` that omits the specified `keys`\n */\nexport function omit<T extends object, K extends keyof T>(\n obj: T,\n ...keys: K[]\n): Omit<T, K> {\n const result = {} as Omit<T, K>;\n const keysSet = new Set(keys);\n\n // OH THE TYPING HUGEMANATEE\n for (const key of Object.keys(obj) as Array<keyof Omit<T, K>>) {\n if (!keysSet.has(key as unknown as K)) {\n result[key] = obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * @return a shallow copy of `obj` that only includes fields that are defined\n * and not nullish or blank.\n */\nexport function compactValues<T extends object>(\n obj: T | undefined,\n): Partial<T> {\n const result = {} as Partial<T>;\n if (obj == null || !isObject(obj)) return {};\n for (const [key, value] of Object.entries(obj)) {\n // skip blank strings and nullish values:\n if (value != null && (!isString(value) || isNotBlank(value))) {\n result[key as keyof T] = value as T[keyof T];\n }\n }\n return result;\n}\n","// src/error.ts\n\nimport { isNumber } from \"./number.js\";\nimport { compactValues, map, omit } from \"./object.js\";\nimport { isBlank, isNotBlank } from \"./string.js\";\n\nfunction toMessage(context: string, cause: unknown): string {\n const causeStr =\n cause instanceof Error\n ? cause.message\n : typeof cause === \"string\"\n ? cause\n : cause\n ? JSON.stringify(cause)\n : \"\";\n return context + (isBlank(causeStr) ? \"\" : \": \" + causeStr);\n}\n\nexport class WrappedError extends Error {\n errno?: number;\n code?: string;\n syscall?: string;\n path?: string;\n constructor(\n context: string,\n options?: {\n name?: string;\n cause?: unknown;\n errno?: number;\n code?: string;\n syscall?: string;\n path?: string;\n },\n ) {\n super(toMessage(context, options?.cause));\n\n const cause = map(options?.cause, toError);\n const opts = { ...compactValues(cause), ...compactValues(options) };\n\n if (isNotBlank(options?.name)) {\n this.name = options.name;\n }\n\n if (cause != null) {\n this.cause = cause;\n if (cause instanceof Error) {\n this.stack = `${this.stack}\\nCaused by: ${cause.stack}`;\n }\n }\n\n if (isNumber(opts.errno)) {\n this.errno = opts.errno;\n }\n if (isNotBlank(opts.code)) {\n this.code = opts.code;\n }\n if (isNotBlank(opts.syscall)) {\n this.syscall = opts.syscall;\n }\n if (isNotBlank(options?.path)) {\n this.path = options.path;\n }\n }\n\n get details(): Record<string, unknown> {\n return compactValues(omit(this, \"name\", \"message\", \"cause\"));\n }\n\n override toString(): string {\n const details = this.details;\n const detailsStr =\n Object.keys(details).length === 0 ? \"\" : \" \" + JSON.stringify(details);\n return `${super.toString()}${detailsStr}`;\n }\n}\n\nexport function toError(cause: unknown): Error {\n return cause instanceof Error ? cause : new Error(String(cause));\n}\n","// src/path.ts\n\nimport { dirname, resolve } from \"node:path\";\nimport { isWindows } from \"./platform.js\";\nimport { isBlank } from \"./string.js\";\n\nexport function normalizePath(\n mountPoint: string | undefined,\n): string | undefined {\n if (isBlank(mountPoint)) return undefined;\n\n const result = isWindows\n ? normalizeWindowsPath(mountPoint)\n : normalizePosixPath(mountPoint);\n\n // Make sure the native code doesn't see anything weird:\n return result != null ? resolve(result) : undefined;\n}\n\n/**\n * Normalizes a Linux or macOS mount point by removing any trailing slashes.\n * This is a no-op for root mount points.\n */\nexport function normalizePosixPath(\n mountPoint: string | undefined,\n): string | undefined {\n if (isBlank(mountPoint)) return undefined;\n if (mountPoint === \"/\") return mountPoint;\n\n // Fast path: check last char only if no trailing slash\n if (mountPoint[mountPoint.length - 1] !== \"/\") return mountPoint;\n\n // Slower path: trim trailing slashes\n let end = mountPoint.length - 1;\n while (end > 0 && mountPoint[end] === \"/\") {\n end--;\n }\n return mountPoint.slice(0, end + 1);\n}\n\n/**\n * Normalizes a Windows mount point by ensuring drive letters end with a\n * backslash.\n */\nexport function normalizeWindowsPath(mountPoint: string): string {\n // Terrible things happen if we give syscalls \"C:\" instead of \"C:\\\"\n\n return /^[a-z]:$/i.test(mountPoint)\n ? mountPoint.toUpperCase() + \"\\\\\"\n : mountPoint;\n}\n\n/**\n * @return true if `path` is the root directory--this is platform-specific. Only\n * \"/\" on linux/macOS is considered a root directory. On Windows, the root\n * directory is a drive letter followed by a colon, e.g. \"C:\\\".\n */\nexport function isRootDirectory(path: string): boolean {\n const n = normalizePath(path);\n return n == null ? false : isWindows ? dirname(n) === n : n === \"/\";\n}\n","// src/options.ts\n\nimport { availableParallelism } from \"node:os\";\nimport { compactValues, isObject } from \"./object.js\";\nimport { isWindows } from \"./platform.js\";\nimport type { Options } from \"./types/options.js\";\n\n/**\n * Default timeout in milliseconds for {@link Options.timeoutMs}.\n *\n * Note that this timeout may be insufficient for some devices, like spun-down\n * optical drives or network shares that need to spin up or reconnect.\n */\nexport const TimeoutMsDefault = 5_000 as const;\n\n/**\n * System paths and globs that indicate system volumes\n */\nexport const SystemPathPatternsDefault = [\n \"/boot\",\n \"/boot/efi\",\n \"/dev\",\n \"/dev/**\",\n \"/proc/**\",\n \"/run\",\n \"/run/credentials/**\",\n \"/run/lock\",\n \"/run/snapd/**\",\n \"/run/user/*/doc\",\n \"/run/user/*/gvfs\",\n \"/snap/**\",\n \"/sys/**\",\n \"/tmp\",\n \"/var/tmp\",\n // we aren't including /tmp/**, as some people temporarily mount volumes there, like /tmp/project.\n \"**/#snapshot\", // Synology and Kubernetes volume snapshots\n\n // windows for linux:\n \"/mnt/wslg/distro\",\n \"/mnt/wslg/doc\",\n \"/mnt/wslg/versions.txt\",\n \"/usr/lib/wsl/drivers\",\n\n // MacOS stuff:\n \"/private/var/vm\", // macOS swap\n \"/System/Volumes/Hardware\",\n \"/System/Volumes/iSCPreboot\",\n \"/System/Volumes/Preboot\",\n \"/System/Volumes/Recovery\",\n \"/System/Volumes/Reserved\",\n \"/System/Volumes/Update\",\n \"/System/Volumes/VM\",\n \"/System/Volumes/xarts\",\n] as const;\n\n/**\n * Filesystem types that indicate system volumes\n */\nexport const SystemFsTypesDefault = [\n \"autofs\",\n \"binfmt_misc\",\n \"cgroup\",\n \"cgroup2\",\n \"configfs\",\n \"debugfs\",\n \"devpts\",\n \"devtmpfs\",\n \"efivarfs\",\n \"fusectl\",\n \"fuse.snapfuse\",\n \"hugetlbfs\",\n \"mqueue\",\n \"none\",\n \"proc\",\n \"pstore\",\n \"rootfs\",\n \"securityfs\",\n \"snap*\",\n \"squashfs\",\n \"sysfs\",\n \"tmpfs\",\n] as const;\n\nexport const LinuxMountTablePathsDefault = [\n \"/proc/self/mounts\",\n \"/proc/mounts\",\n \"/etc/mtab\",\n] as const;\n\n/**\n * Should {@link getAllVolumeMetadata} include system volumes by\n * default?\n */\nexport const IncludeSystemVolumesDefault = isWindows;\n\n/**\n * Default {@link Options} object.\n *\n * @see {@link optionsWithDefaults} for creating an options object with default values\n */\nexport const OptionsDefault: Options = {\n timeoutMs: TimeoutMsDefault,\n maxConcurrency: availableParallelism(),\n systemPathPatterns: [...SystemPathPatternsDefault],\n systemFsTypes: [...SystemFsTypesDefault],\n linuxMountTablePaths: [...LinuxMountTablePathsDefault],\n includeSystemVolumes: IncludeSystemVolumesDefault,\n} as const;\n\n/**\n * Create an {@link Options} object using default values from\n * {@link OptionsDefault} for missing fields.\n */\nexport function optionsWithDefaults<T extends Options>(\n overrides: Partial<T> = {},\n): T {\n if (!isObject(overrides)) {\n throw new TypeError(\n \"options(): expected an object, got \" +\n typeof overrides +\n \": \" +\n JSON.stringify(overrides),\n );\n }\n\n return {\n ...OptionsDefault,\n ...(compactValues(overrides) as T),\n };\n}\n","// src/string_enum.ts\n\n// See https://basarat.gitbooks.io/typescript/content/docs/types/literal-types.html\n\nexport type StringEnumType<T extends string> = {\n [K in T]: K;\n};\n\nexport type StringEnum<T extends string> = StringEnumType<T> & {\n values: T[];\n size: number;\n get(s: string | undefined): T | undefined;\n};\n\nexport type StringEnumKeys<Type> = Type extends StringEnum<infer X> ? X : never;\n\n/**\n * Create a string enum with the given values. \n\nExample usage:\n\nexport const Directions = stringEnum(\"North\", \"South\", \"East\", \"West\")\nexport type Direction = StringEnumKeys<typeof Directions>\n\n*/\nexport function stringEnum<T extends string>(...o: T[]): StringEnum<T> {\n const set = new Set(o);\n\n const dict: StringEnumType<T> = {} as StringEnumType<T>;\n for (const key of o) {\n dict[key] = key;\n }\n\n return {\n ...dict,\n values: Object.freeze([...set]) as T[],\n size: set.size,\n get: (s: string | undefined) =>\n s != null && set.has(s as T) ? (s as T) : undefined,\n };\n}\n","// src/volume_health_status.ts\n\nimport { TimeoutError } from \"./async.js\";\nimport { debug } from \"./debuglog.js\";\nimport { toError } from \"./error.js\";\nimport { canReaddir } from \"./fs.js\";\nimport { isObject } from \"./object.js\";\nimport { stringEnum, StringEnumKeys } from \"./string_enum.js\";\n\n/**\n * Health statuses for volumes (mostly applicable to Windows).\n *\n * - `healthy`: Volume is \"OK\": accessible and functioning normally\n * - `timeout`: Volume could not be accessed before the specified timeout. It\n * may be inaccessible or disconnected.\n * - `inaccessible`: Volume exists but can't be accessed (permissions/locks)\n * - `disconnected`: Network volume that's offline\n * - `unknown`: Status can't be determined\n */\nexport const VolumeHealthStatuses = stringEnum(\n \"healthy\",\n \"timeout\",\n \"inaccessible\",\n \"disconnected\",\n \"unknown\",\n);\n\nexport type VolumeHealthStatus = StringEnumKeys<typeof VolumeHealthStatuses>;\n\n/**\n * Attempt to read a directory to determine if it's accessible, and if an error\n * is thrown, convert to a health status.\n * @returns the \"health status\" of the directory, based on the success of `readdir(dir)`.\n * @throws never\n */\nexport async function directoryStatus(\n dir: string,\n timeoutMs: number,\n canReaddirImpl: typeof canReaddir = canReaddir,\n): Promise<{ status: VolumeHealthStatus; error?: Error }> {\n try {\n if (await canReaddirImpl(dir, timeoutMs)) {\n return { status: VolumeHealthStatuses.healthy };\n }\n } catch (error) {\n debug(\"[directoryStatus] %s: %s\", dir, error);\n let status: VolumeHealthStatus = VolumeHealthStatuses.unknown;\n if (error instanceof TimeoutError) {\n status = VolumeHealthStatuses.timeout;\n } else if (isObject(error) && error instanceof Error && \"code\" in error) {\n if (error.code === \"EPERM\" || error.code === \"EACCES\") {\n status = VolumeHealthStatuses.inaccessible;\n }\n }\n return { status, error: toError(error) };\n }\n return { status: VolumeHealthStatuses.unknown };\n}\n","// src/linux/dev_disk.ts\n\nimport { Dirent } from \"node:fs\";\nimport { readdir, readlink } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { debug } from \"../debuglog.js\";\nimport { decodeEscapeSequences } from \"../string.js\";\n\n/**\n * Gets the UUID from symlinks for a given device path asynchronously\n * @param devicePath The device path to look up\n * @returns Promise that resolves to the UUID if found, empty string otherwise\n */\nexport async function getUuidFromDevDisk(devicePath: string) {\n try {\n const result = await getBasenameLinkedTo(\n \"/dev/disk/by-uuid\",\n resolve(devicePath),\n );\n debug(\"[getUuidFromDevDisk] result: %o\", result);\n return result;\n } catch (error) {\n debug(\"[getUuidFromDevDisk] failed: \" + error);\n return;\n }\n}\n\n/**\n * Gets the label from symlinks for a given device path asynchronously\n * @param devicePath The device path to look up\n * @returns Promise that resolves to the label if found, empty string otherwise\n */\nexport async function getLabelFromDevDisk(devicePath: string) {\n try {\n const result = await getBasenameLinkedTo(\n \"/dev/disk/by-label\",\n resolve(devicePath),\n );\n debug(\"[getLabelFromDevDisk] result: %o\", result);\n return result;\n } catch (error) {\n debug(\"[getLabelFromDevDisk] failed: \" + error);\n return;\n }\n}\n\n// only exposed for tests\nexport async function getBasenameLinkedTo(\n linkDir: string,\n linkPath: string,\n): Promise<string | undefined> {\n for await (const ea of readLinks(linkDir)) {\n if (ea.linkTarget === linkPath) {\n // Expect the symlink to be named like '1tb\\x20\\x28test\\x29'\n return decodeEscapeSequences(ea.dirent.name);\n }\n }\n return;\n}\n\nasync function* readLinks(\n directory: string,\n): AsyncGenerator<{ dirent: Dirent; linkTarget: string }, void, unknown> {\n for (const dirent of await readdir(directory, { withFileTypes: true })) {\n if (dirent.isSymbolicLink()) {\n try {\n const linkTarget = resolve(\n directory,\n await readlink(join(directory, dirent.name)),\n );\n yield { dirent, linkTarget };\n } catch {\n // Ignore errors\n }\n }\n }\n}\n","// src/linux/mount_points.ts\nimport { readFile } from \"node:fs/promises\";\nimport { debug } from \"../debuglog.js\";\nimport { toError, WrappedError } from \"../error.js\";\nimport { isMountPoint } from \"../mount_point.js\";\nimport { compactValues } from \"../object.js\";\nimport { optionsWithDefaults } from \"../options.js\";\nimport { type MountPoint } from \"../types/mount_point.js\";\nimport type { NativeBindingsFn } from \"../types/native_bindings.js\";\nimport type { Options } from \"../types/options.js\";\nimport { MountEntry, mountEntryToMountPoint, parseMtab } from \"./mtab.js\";\n\nexport async function getLinuxMountPoints(\n native: NativeBindingsFn,\n opts?: Pick<Options, \"linuxMountTablePaths\">,\n): Promise<MountPoint[]> {\n const o = optionsWithDefaults(opts);\n const raw: MountPoint[] = [];\n try {\n // Get GIO mounts if available from native module\n const arr = await (await native()).getGioMountPoints?.();\n debug(\"[getLinuxMountPoints] GIO mount points: %o\", arr);\n if (arr != null) raw.push(...arr);\n } catch (error) {\n debug(\"Failed to get GIO mount points: %s\", error);\n // GIO support not compiled in or failed, continue with just mtab mounts\n }\n\n let cause: Error | undefined;\n for (const input of o.linuxMountTablePaths) {\n try {\n const mtabContent = await readFile(input, \"utf8\");\n const arr = parseMtab(mtabContent)\n .map((ea) => mountEntryToMountPoint(ea))\n .filter((ea) => ea != null);\n debug(\"[getLinuxMountPoints] %s mount points: %o\", input, arr);\n if (arr.length > 0) {\n raw.push(...arr);\n break;\n }\n } catch (error) {\n cause ??= toError(error);\n }\n }\n\n const byMountPoint = new Map<string, MountPoint>();\n for (const ea of raw) {\n const prior = byMountPoint.get(ea.mountPoint);\n const merged = { ...compactValues(prior), ...compactValues(ea) };\n if (isMountPoint(merged)) {\n byMountPoint.set(merged.mountPoint, merged);\n }\n }\n\n if (byMountPoint.size === 0) {\n throw new WrappedError(\n `Failed to find any mount points (tried: ${JSON.stringify(o.linuxMountTablePaths)})`,\n { cause },\n );\n }\n\n const results = [...byMountPoint.values()];\n debug(\"[getLinuxMountPoints] %o\", {\n results: results.map((ea) => ea.mountPoint),\n });\n\n return results;\n}\n\nexport async function getLinuxMtabMetadata(\n mountPoint: string,\n opts?: Pick<Options, \"linuxMountTablePaths\">,\n): Promise<MountEntry> {\n let caughtError: Error | undefined;\n const inputs = optionsWithDefaults(opts).linuxMountTablePaths;\n for (const input of inputs) {\n try {\n const mtabContent = await readFile(input, \"utf8\");\n for (const ea of parseMtab(mtabContent)) {\n if (ea.fs_file === mountPoint) {\n return ea;\n }\n }\n } catch (error) {\n caughtError ??= toError(error);\n }\n }\n\n throw new WrappedError(\n `Failed to find mount point ${mountPoint} in an linuxMountTablePaths (tried: ${JSON.stringify(inputs)})`,\n caughtError,\n );\n}\n","import { isObject } from \"./object\";\nimport { isNotBlank } from \"./string\";\nimport { MountPoint } from \"./types/mount_point\";\n\nexport function isMountPoint(obj: unknown): obj is MountPoint {\n return isObject(obj) && \"mountPoint\" in obj && isNotBlank(obj.mountPoint);\n}\n","// src/remote_info.ts\n\nimport { debug } from \"./debuglog.js\";\nimport { compactValues, isObject } from \"./object.js\";\nimport { isWindows } from \"./platform.js\";\nimport { isBlank, isNotBlank, toS } from \"./string.js\";\nimport { RemoteInfo } from \"./types/remote_info.js\";\n\nexport function isRemoteInfo(obj: unknown): obj is RemoteInfo {\n if (!isObject(obj)) return false;\n const { remoteHost, remoteShare } = obj as Partial<RemoteInfo>;\n return isNotBlank(remoteHost) && isNotBlank(remoteShare);\n}\n\nconst NETWORK_FS_TYPE_ARRAY = [\n \"9p\",\n \"afp\",\n \"afs\",\n \"beegfs\",\n \"ceph\",\n \"cifs\",\n \"ftp\",\n \"fuse\",\n \"gfs2\",\n \"glusterfs\",\n \"lustre\",\n \"ncpfs\",\n \"nfs\",\n \"nfs4\",\n \"smb\",\n \"smbfs\",\n \"sshfs\",\n \"webdav\",\n] as const;\n\ntype NetworkFsType = (typeof NETWORK_FS_TYPE_ARRAY)[number];\n\nconst NETWORK_FS_TYPES = new Set<NetworkFsType>(NETWORK_FS_TYPE_ARRAY);\n\nconst FS_TYPE_ALIASES = new Map<string, NetworkFsType>([\n [\"nfs1\", \"nfs\"],\n [\"nfs2\", \"nfs\"],\n [\"nfs3\", \"nfs\"],\n [\"nfs4\", \"nfs4\"],\n [\"fuse.sshfs\", \"sshfs\"],\n [\"sshfs.fuse\", \"sshfs\"],\n [\"davfs2\", \"webdav\"],\n [\"davfs\", \"webdav\"],\n [\"cifs.smb\", \"cifs\"],\n [\"smbfs\", \"cifs\"],\n [\"cephfs\", \"ceph\"],\n [\"fuse.ceph\", \"ceph\"],\n [\"fuse.cephfs\", \"ceph\"],\n [\"rbd\", \"ceph\"],\n [\"fuse.glusterfs\", \"glusterfs\"],\n] as const);\n\nexport function normalizeFsType(fstype: string): string {\n const norm = toS(fstype).toLowerCase().replace(/:$/, \"\");\n return FS_TYPE_ALIASES.get(norm) ?? norm;\n}\n\nexport function isRemoteFsType(fstype: string | undefined): boolean {\n return (\n isNotBlank(fstype) &&\n NETWORK_FS_TYPES.has(normalizeFsType(fstype) as NetworkFsType)\n );\n}\n\nexport function parseURL(s: string): URL | undefined {\n try {\n return isBlank(s) ? undefined : new URL(s);\n } catch {\n return;\n }\n}\n\nexport function extractRemoteInfo(\n fsSpec: string | undefined,\n): RemoteInfo | undefined {\n if (fsSpec == null || isBlank(fsSpec)) return;\n\n if (isWindows) {\n fsSpec = fsSpec.replace(/\\\\/g, \"/\");\n }\n\n const url = parseURL(fsSpec);\n\n if (url?.protocol === \"file:\") {\n return {\n remote: false,\n uri: fsSpec,\n };\n }\n\n const patterns = [\n {\n // CIFS/SMB pattern: //hostname/share or //user@host/share\n regex:\n /^\\/\\/(?:(?<remoteUser>[^/@]+)@)?(?<remoteHost>[^/@]+)\\/(?<remoteShare>.+)$/,\n },\n {\n // sshfs pattern: sshfs#USER@HOST:REMOTE_PATH\n regex:\n /^(?:(?<protocol>\\w+)#)?(?<remoteUser>[^@]+)@(?<remoteHost>[^:]+):(?<remoteShare>.+)$/,\n },\n {\n // NFS pattern: hostname:/share\n protocol: \"nfs\",\n regex: /^(?<remoteHost>[^:]+):\\/(?!\\/)(?<remoteShare>.+)$/,\n },\n ];\n\n for (const { protocol, regex } of patterns) {\n const o = compactValues({\n protocol,\n remote: true,\n ...(fsSpec.match(regex)?.groups ?? {}),\n });\n if (isRemoteInfo(o)) {\n debug(\"[extractRemoteInfo] matched pattern: %o\", o);\n return o;\n }\n }\n\n // Let's try URL last, as nfs and webdav mounts are URI-ish\n try {\n // try to parse fsSpec as a uri:\n const parsed = new URL(fsSpec);\n if (parsed != null) {\n debug(\"[extractRemoteInfo] parsed URL: %o\", parsed);\n const fstype = normalizeFsType(parsed.protocol);\n if (!isRemoteFsType(fstype)) {\n // don't set remoteUser, remoteHost, or remoteShare, it's not remote!\n return {\n uri: fsSpec,\n remote: false,\n };\n } else {\n return compactValues({\n uri: fsSpec,\n protocol: fstype,\n remote: true,\n remoteUser: parsed.username,\n remoteHost: parsed.hostname,\n // URL pathname includes leading slash:\n remoteShare: parsed.pathname.replace(/^\\//, \"\"),\n }) as unknown as RemoteInfo;\n }\n }\n } catch {\n // ignore\n }\n\n return;\n}\n","// src/glob.ts\n\nimport { isWindows } from \"./platform.js\";\nimport { isNotBlank } from \"./string.js\";\n\nconst cache = new Map<string, RegExp>();\n\n/**\n * Compiles an array of glob patterns into a single regular expression.\n *\n * The function supports the following patterns:\n * - `**` matches any number of directories.\n * - `*` matches any number of characters except for `/`.\n * - `?` matches exactly one character except for `/`.\n * - `.` is escaped to match a literal period.\n * - `/` at the end of the pattern matches either a slash or the end of the string.\n * - Other regex special characters are escaped.\n *\n * @param patterns - An array of glob patterns to compile.\n * @returns A `RegExp` object that matches any of the provided patterns.\n */\nexport function compileGlob(\n patterns: string[] | readonly string[] | undefined,\n): RegExp {\n if (patterns == null || patterns.length === 0) {\n return NeverMatchRE;\n }\n const patternsKey = JSON.stringify(patterns);\n {\n const prior = cache.get(patternsKey);\n if (prior != null) {\n return prior;\n }\n }\n\n const sorted = patterns.slice().filter(isNotBlank).sort();\n const sortedKey = JSON.stringify(sorted);\n {\n const prior = cache.get(sortedKey);\n if (prior != null) {\n cache.set(patternsKey, prior);\n return prior;\n }\n }\n\n const result = _compileGlob(sorted);\n if (cache.size > 256) {\n // avoid unbounded memory usage\n cache.clear();\n }\n\n cache.set(patternsKey, result);\n cache.set(sortedKey, result);\n return result;\n}\n\nfunction _compileGlob(patterns: string[] | readonly string[]): RegExp {\n const regexPatterns = patterns.map((pattern) => {\n let regex = \"\";\n let i = 0;\n while (i < pattern.length) {\n // Handle '**' pattern\n if (pattern[i] === \"*\" && pattern[i + 1] === \"*\") {\n regex += \".*\";\n i += 2;\n if (pattern[i] === \"/\") {\n i++; // Skip the slash after **\n }\n continue;\n }\n\n // Handle single '*' pattern\n if (pattern[i] === \"*\") {\n regex += \"[^/]*\";\n i++;\n continue;\n }\n\n // Handle '?' pattern\n if (pattern[i] === \"?\") {\n regex += \"[^/]\";\n i++;\n continue;\n }\n\n // Handle period\n if (pattern[i] === \".\") {\n regex += \"\\\\.\";\n i++;\n continue;\n }\n\n // Handle end of directory pattern\n if (pattern[i] === \"/\") {\n if (i === pattern.length - 1) {\n regex += \"(?:/|$)\";\n i++;\n continue;\n } else if (isWindows) {\n regex += \"[\\\\/\\\\\\\\]\";\n i++;\n continue;\n }\n }\n\n // Escape other regex special characters\n if (/[+^${}()|[\\]\\\\]/.test(pattern[i] as string)) {\n regex += \"\\\\\" + pattern[i];\n i++;\n continue;\n }\n\n // Add other characters as-is\n regex += pattern[i];\n i++;\n }\n return regex;\n });\n const final = regexPatterns.filter((ea) => ea.length > 0);\n return final.length === 0\n ? // Empty pattern matches nothing\n NeverMatchRE // Case insensitive for Windows paths\n : new RegExp(`^(?:${final.join(\"|\")})$`, \"i\");\n}\n\n// eslint-disable-next-line regexp/no-empty-group\nexport const AlwaysMatchRE = /(?:)/;\n// eslint-disable-next-line regexp/no-empty-lookarounds-assertion\nexport const NeverMatchRE = /(?!)/;\n","// src/system_volume.ts\n\nimport { debug } from \"./debuglog.js\";\nimport { compileGlob } from \"./glob.js\";\nimport { SystemFsTypesDefault, SystemPathPatternsDefault } from \"./options.js\";\nimport { normalizePath } from \"./path.js\";\nimport { isWindows } from \"./platform.js\";\nimport { isNotBlank } from \"./string.js\";\nimport type { MountPoint } from \"./types/mount_point.js\";\nimport type { Options } from \"./types/options.js\";\n\n/**\n * Configuration for system volume detection\n *\n * @see {@link MountPoint.isSystemVolume}\n */\nexport type SystemVolumeConfig = Pick<\n Options,\n \"systemPathPatterns\" | \"systemFsTypes\"\n>;\n\n/**\n * Determines if a mount point represents a system volume based on its path and\n * filesystem type\n */\nexport function isSystemVolume(\n mountPoint: string,\n fstype: string | undefined,\n config: Partial<SystemVolumeConfig> = {},\n): boolean {\n if (isWindows) {\n const systemDrive = normalizePath(process.env[\"SystemDrive\"]);\n if (systemDrive != null && mountPoint === systemDrive) {\n debug(\"[isSystemVolume] %s is the Windows system drive\", mountPoint);\n return true;\n }\n }\n const isSystemFsType =\n isNotBlank(fstype) &&\n ((config.systemFsTypes ?? SystemFsTypesDefault) as string[]).includes(\n fstype,\n );\n const hasSystemPath = compileGlob(\n config.systemPathPatterns ?? SystemPathPatternsDefault,\n ).test(mountPoint);\n const result = isSystemFsType || hasSystemPath;\n debug(\"[isSystemVolume]\", {\n mountPoint,\n fstype,\n result,\n isSystemFsType,\n hasSystemPath,\n });\n return result;\n}\n\nexport function assignSystemVolume(\n mp: MountPoint,\n config: Partial<SystemVolumeConfig>,\n) {\n const result = isSystemVolume(mp.mountPoint, mp.fstype, config);\n\n if (isWindows) {\n // native code actually knows the system drive and has more in-depth\n // metadata information that we trust more than these heuristics\n mp.isSystemVolume ??= result;\n } else {\n // macOS and Linux don't have a concept of an explicit \"system drive\" like\n // Windows--always trust our heuristics\n mp.isSystemVolume = result;\n }\n}\n","// src/linux/mtab.ts\n\nimport { toInt } from \"../number.js\";\nimport { normalizePosixPath } from \"../path.js\";\nimport { extractRemoteInfo } from \"../remote_info.js\";\nimport {\n decodeEscapeSequences,\n encodeEscapeSequences,\n isBlank,\n toNotBlank,\n} from \"../string.js\";\nimport { isSystemVolume, SystemVolumeConfig } from \"../system_volume.js\";\nimport type { MountPoint } from \"../types/mount_point.js\";\nimport type { VolumeMetadata } from \"../types/volume_metadata.js\";\n\n/**\n * Represents an entry in the mount table.\n */\nexport interface MountEntry {\n /**\n * Device or remote filesystem\n */\n fs_spec: string;\n /**\n * Mount point\n */\n fs_file: string;\n /**\n * Filesystem type\n */\n fs_vfstype: string;\n /**\n * Mount options\n */\n fs_mntops: string | undefined;\n /**\n * Dump frequency\n */\n fs_freq: number | undefined;\n /**\n * fsck pass number\n */\n fs_passno: number | undefined;\n}\n\nexport function mountEntryToMountPoint(\n entry: MountEntry,\n): MountPoint | undefined {\n const mountPoint = normalizePosixPath(entry.fs_file);\n const fstype = toNotBlank(entry.fs_vfstype) ?? toNotBlank(entry.fs_spec);\n return mountPoint == null || fstype == null\n ? undefined\n : {\n mountPoint,\n fstype,\n };\n}\n\nexport type MtabVolumeMetadata = Omit<\n VolumeMetadata,\n \"size\" | \"used\" | \"available\" | \"label\" | \"uuid\" | \"status\"\n>;\n\nexport function mountEntryToPartialVolumeMetadata(\n entry: MountEntry,\n options: Partial<SystemVolumeConfig> = {},\n): MtabVolumeMetadata {\n return {\n mountPoint: entry.fs_file,\n fstype: entry.fs_vfstype,\n mountFrom: entry.fs_spec,\n isSystemVolume: isSystemVolume(entry.fs_file, entry.fs_vfstype, options),\n remote: false, // < default to false, but it may be overridden by extractRemoteInfo\n ...extractRemoteInfo(entry.fs_spec),\n };\n}\n\n/**\n * Parses an mtab/fstab file content into structured mount entries\n * @param content - Raw content of the mtab/fstab file\n * @returns Array of parsed mount entries\n */\nexport function parseMtab(content: string): MountEntry[] {\n const entries: MountEntry[] = [];\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n // Skip comments and empty lines\n if (isBlank(line) || line.trim().startsWith(\"#\")) {\n continue;\n }\n\n const fields = line\n .trim()\n .match(/(?:[^\\s\\\\]|\\\\.)+/g)\n ?.map(decodeEscapeSequences);\n\n if (!fields || fields.length < 3) {\n continue; // Skip malformed lines\n }\n const fs_file = normalizePosixPath(fields[1]);\n if (fs_file != null) {\n entries.push({\n fs_spec: fields[0] as string,\n // normalizeLinuxPath DOES NOT resolve()!\n fs_file,\n fs_vfstype: fields[2] as string,\n fs_mntops: fields[3],\n fs_freq: toInt(fields[4]),\n fs_passno: toInt(fields[5]),\n });\n }\n }\n return entries;\n}\n\n/**\n * Formats mount entries back into mtab file format\n * @param entries - Array of mount entries\n * @returns Formatted mtab file content\n */\nexport function formatMtab(entries: MountEntry[]): string {\n return entries\n .map((entry) => {\n const fields = [\n entry.fs_spec,\n encodeEscapeSequences(entry.fs_file),\n entry.fs_vfstype,\n entry.fs_mntops,\n entry.fs_freq?.toString(),\n entry.fs_passno?.toString(),\n ];\n return fields.join(\"\\t\");\n })\n .join(\"\\n\");\n}\n","// src/unc.ts\n\nimport { isBlank, isString } from \"./string.js\";\nimport { RemoteInfo } from \"./types/remote_info.js\";\n\n/**\n * Checks if a string is formatted as a valid UNC path.\n * A valid UNC path starts with double backslashes or slashes,\n * followed by a server/host name, and then a share name.\n * The path must use consistent slashes (all forward or all backward).\n *\n * @param path - The string to check\n * @returns boolean - True if the string is a valid UNC path, false otherwise\n */\nexport function parseUNCPath(\n path: string | null | undefined,\n): RemoteInfo | undefined {\n if (path == null || isBlank(path) || !isString(path)) {\n return;\n }\n\n // Check for two forward slashes or two backslashes at start\n if (!path.startsWith(\"\\\\\\\\\") && !path.startsWith(\"//\")) {\n return;\n }\n\n // Determine slash type from the start of the path\n const isForwardSlash = path.startsWith(\"//\");\n const slashChar = isForwardSlash ? \"/\" : \"\\\\\";\n\n // Split path using the correct slash type\n const parts = path.slice(2).split(slashChar);\n\n // Check minimum required parts (server and share)\n if (parts.length < 2) {\n return;\n }\n\n // Validate server and share names exist and aren't empty\n const [remoteHost, remoteShare] = parts;\n if (\n remoteHost == null ||\n isBlank(remoteHost) ||\n remoteShare == null ||\n isBlank(remoteShare)\n ) {\n return;\n }\n\n // Check for invalid characters in server and share names\n const invalidChars = /[<>:\"|?*]/;\n if (invalidChars.test(remoteHost) || invalidChars.test(remoteShare)) {\n return;\n }\n\n // Check for mixed slash usage\n const wrongSlash = isForwardSlash ? \"\\\\\" : \"/\";\n if (path.includes(wrongSlash)) {\n return;\n }\n\n return { remoteHost, remoteShare, remote: true };\n}\n","// src/uuid.ts\n\nimport { toS } from \"./string.js\";\n\nconst uuidRegex = /[a-z0-9][a-z0-9-]{7,}/i;\n\n/**\n * Some volume UUIDs are short, like, `ABCD1234`.\n *\n * Some volume UUIDs are in hexadecimal, but others and use G-Z. We will allow\n * that.\n *\n * Some Windows syscalls wrap the UUID in a \"\\\\\\\\?\\\\Volume{...}\\\\\" prefix and\n * suffix. This function will strip out that prefix and suffix.\n *\n * We will ignore any UUID-ish string that is not at least 8 characters long\n * (and return `undefined` if no other, longer uuid-ish string is found).\n *\n * UUIDs cannot start with a hyphen, and can only contain a-z, 0-9, and hyphens\n * (case-insensitive).\n */\nexport function extractUUID(uuid: string | undefined): string | undefined {\n return toS(uuid).match(uuidRegex)?.[0];\n}\n","// src/array.ts\n\n/**\n * Remove duplicate elements from an array.\n *\n * - Primitive values are compared using strict equality.\n * - Objects and arrays are compared by reference.\n *\n * @return A new array with duplicate elements removed\n */\nexport function uniq<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n}\n\n/**\n * Remove duplicate elements from an array based on a key function.\n * @param keyFn A function that returns a key for each element. Elements that\n * the key function returns nullish will be removed from the returned array.\n * @return a new array omitting duplicate elements based on a key function.\n */\nexport function uniqBy<T, K>(arr: T[], keyFn: (item: T) => K | undefined): T[] {\n const seen = new Set<K>();\n return arr.filter((item) => {\n const key = keyFn(item);\n if (key == null || seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/**\n * @return an array of specified length, with each element created by calling\n * the provided function.\n */\nexport function times<T>(length: number, fn: (index: number) => T): T[] {\n return Array.from({ length }, (_, i) => fn(i));\n}\n\n/**\n * @return a new array with elements that are not `null` or `undefined`.\n */\nexport function compact<T>(arr: (T | null | undefined)[] | undefined): T[] {\n return arr == null ? [] : arr.filter((ea): ea is T => ea != null);\n}\n","// src/mount_point.ts\n\nimport { uniqBy } from \"./array.js\";\nimport { mapConcurrent, withTimeout } from \"./async.js\";\nimport { debug } from \"./debuglog.js\";\nimport { getLinuxMountPoints } from \"./linux/mount_points.js\";\nimport { compactValues } from \"./object.js\";\nimport { isMacOS, isWindows } from \"./platform.js\";\nimport {\n isBlank,\n isNotBlank,\n sortObjectsByLocale,\n toNotBlank,\n} from \"./string.js\";\nimport { assignSystemVolume, SystemVolumeConfig } from \"./system_volume.js\";\nimport type { MountPoint } from \"./types/mount_point.js\";\nimport type { NativeBindingsFn } from \"./types/native_bindings.js\";\nimport type { Options } from \"./types/options.js\";\nimport { directoryStatus } from \"./volume_health_status.js\";\n\nexport type GetVolumeMountPointOptions = Partial<\n Pick<\n Options,\n | \"timeoutMs\"\n | \"linuxMountTablePaths\"\n | \"maxConcurrency\"\n | \"includeSystemVolumes\"\n > &\n SystemVolumeConfig\n>;\n\nexport async function getVolumeMountPointsImpl(\n opts: Required<GetVolumeMountPointOptions>,\n nativeFn: NativeBindingsFn,\n): Promise<MountPoint[]> {\n const p = _getVolumeMountPoints(opts, nativeFn);\n // we rely on the native bindings on Windows to do proper timeouts\n return isWindows\n ? p\n : withTimeout({ desc: \"getVolumeMountPoints\", ...opts, promise: p });\n}\n\nasync function _getVolumeMountPoints(\n o: Required<GetVolumeMountPointOptions>,\n nativeFn: NativeBindingsFn,\n): Promise<MountPoint[]> {\n debug(\"[getVolumeMountPoints] gathering mount points with options: %o\", o);\n\n const raw = await (isWindows || isMacOS\n ? (async () => {\n debug(\"[getVolumeMountPoints] using native implementation\");\n const points = await (await nativeFn()).getVolumeMountPoints(o);\n debug(\n \"[getVolumeMountPoints] native returned %d mount points\",\n points.length,\n );\n return points;\n })()\n : getLinuxMountPoints(nativeFn, o));\n\n debug(\"[getVolumeMountPoints] raw mount points: %o\", raw);\n\n const compacted = raw\n .map((ea) => compactValues(ea) as MountPoint)\n .filter((ea) => isNotBlank(ea.mountPoint));\n\n for (const ea of compacted) {\n assignSystemVolume(ea, o);\n }\n\n const filtered = o.includeSystemVolumes\n ? compacted\n : compacted.filter((ea) => !ea.isSystemVolume);\n\n const uniq = uniqBy(filtered, (ea) => toNotBlank(ea.mountPoint));\n debug(\"[getVolumeMountPoints] found %d unique mount points\", uniq.length);\n\n const results = sortObjectsByLocale(uniq, (ea) => ea.mountPoint);\n debug(\n \"[getVolumeMountPoints] getting status for %d mount points\",\n results.length,\n );\n\n await mapConcurrent({\n maxConcurrency: o.maxConcurrency,\n items: results.filter(\n // trust but verify\n (ea) => isBlank(ea.status) || ea.status === \"healthy\",\n ),\n fn: async (mp) => {\n debug(\"[getVolumeMountPoints] checking status of %s\", mp.mountPoint);\n mp.status = (await directoryStatus(mp.mountPoint, o.timeoutMs)).status;\n debug(\n \"[getVolumeMountPoints] status for %s: %s\",\n mp.mountPoint,\n mp.status,\n );\n },\n });\n\n debug(\n \"[getVolumeMountPoints] completed with %d mount points\",\n results.length,\n );\n return results;\n}\n","// src/volume_metadata.ts\n\nimport { mapConcurrent, withTimeout } from \"./async.js\";\nimport { debug } from \"./debuglog.js\";\nimport { WrappedError } from \"./error.js\";\nimport { getLabelFromDevDisk, getUuidFromDevDisk } from \"./linux/dev_disk.js\";\nimport { getLinuxMtabMetadata } from \"./linux/mount_points.js\";\nimport {\n type MtabVolumeMetadata,\n mountEntryToPartialVolumeMetadata,\n} from \"./linux/mtab.js\";\nimport { compactValues } from \"./object.js\";\nimport { IncludeSystemVolumesDefault, optionsWithDefaults } from \"./options.js\";\nimport { normalizePath } from \"./path.js\";\nimport { isLinux, isWindows } from \"./platform.js\";\nimport { extractRemoteInfo, isRemoteFsType } from \"./remote_info.js\";\nimport { isBlank, isNotBlank } from \"./string.js\";\nimport { assignSystemVolume } from \"./system_volume.js\";\nimport type {\n GetVolumeMetadataOptions,\n NativeBindingsFn,\n} from \"./types/native_bindings.js\";\nimport type { Options } from \"./types/options.js\";\nimport type { VolumeMetadata } from \"./types/volume_metadata.js\";\nimport { parseUNCPath } from \"./unc.js\";\nimport { extractUUID } from \"./uuid.js\";\nimport {\n VolumeHealthStatuses,\n directoryStatus,\n} from \"./volume_health_status.js\";\nimport { getVolumeMountPointsImpl } from \"./volume_mount_points.js\";\n\nexport async function getVolumeMetadataImpl(\n o: GetVolumeMetadataOptions & Options,\n nativeFn: NativeBindingsFn,\n): Promise<VolumeMetadata> {\n if (isBlank(o.mountPoint)) {\n throw new TypeError(\n \"Invalid mountPoint: got \" + JSON.stringify(o.mountPoint),\n );\n }\n\n const p = _getVolumeMetadata(o, nativeFn);\n // we rely on the native bindings on Windows to do proper timeouts\n return isWindows\n ? p\n : withTimeout({\n desc: \"getVolumeMetadata()\",\n timeoutMs: o.timeoutMs,\n promise: p,\n });\n}\n\nasync function _getVolumeMetadata(\n o: GetVolumeMetadataOptions & Options,\n nativeFn: NativeBindingsFn,\n): Promise<VolumeMetadata> {\n o = optionsWithDefaults(o);\n const norm = normalizePath(o.mountPoint);\n if (norm == null) {\n throw new Error(\"Invalid mountPoint: \" + JSON.stringify(o.mountPoint));\n }\n o.mountPoint = norm;\n\n debug(\n \"[getVolumeMetadata] starting metadata collection for %s\",\n o.mountPoint,\n );\n debug(\"[getVolumeMetadata] options: %o\", o);\n\n const { status, error } = await directoryStatus(o.mountPoint, o.timeoutMs);\n if (status !== VolumeHealthStatuses.healthy) {\n debug(\"[getVolumeMetadata] directoryStatus error: %s\", error);\n throw error ?? new Error(\"Volume not healthy: \" + status);\n }\n\n debug(\"[getVolumeMetadata] readdir status: %s\", status);\n\n let remote: boolean = false;\n // Get filesystem info from mtab first on Linux\n let mtabInfo: undefined | MtabVolumeMetadata;\n let device: undefined | string;\n if (isLinux) {\n debug(\"[getVolumeMetadata] collecting Linux mtab info\");\n try {\n const m = await getLinuxMtabMetadata(o.mountPoint, o);\n mtabInfo = mountEntryToPartialVolumeMetadata(m, o);\n debug(\"[getVolumeMetadata] mtab info: %o\", mtabInfo);\n if (mtabInfo.remote) {\n remote = true;\n }\n if (isNotBlank(m.fs_spec)) {\n device = m.fs_spec;\n }\n } catch (err) {\n debug(\"[getVolumeMetadata] failed to get mtab info: \" + err);\n // this may be a GIO mount. Ignore the error and continue.\n }\n }\n\n if (isNotBlank(device)) {\n o.device = device;\n debug(\"[getVolumeMetadata] using device: %s\", device);\n }\n\n debug(\"[getVolumeMetadata] requesting native metadata\");\n const metadata = (await (\n await nativeFn()\n ).getVolumeMetadata(o)) as VolumeMetadata;\n debug(\"[getVolumeMetadata] native metadata: %o\", metadata);\n\n // Some OS implementations leave it up to us to extract remote info:\n const remoteInfo =\n mtabInfo ??\n extractRemoteInfo(metadata.uri) ??\n extractRemoteInfo(metadata.mountFrom) ??\n (isWindows ? parseUNCPath(o.mountPoint) : undefined);\n\n debug(\"[getVolumeMetadata] extracted remote info: %o\", remoteInfo);\n\n remote ||=\n isRemoteFsType(metadata.fstype) ||\n (remoteInfo?.remote ?? metadata.remote ?? false);\n\n debug(\"[getVolumeMetadata] assembling: %o\", {\n status,\n mtabInfo,\n remoteInfo,\n metadata,\n mountPoint: o.mountPoint,\n remote,\n });\n const result = compactValues({\n status, // < let the implementation's status win by having this first\n ...compactValues(remoteInfo),\n ...compactValues(metadata),\n ...compactValues(mtabInfo),\n mountPoint: o.mountPoint,\n remote,\n }) as VolumeMetadata;\n\n // Backfill if blkid or gio failed us:\n if (isLinux && isNotBlank(device)) {\n // Sometimes blkid doesn't have the UUID in cache. Try to get it from\n // /dev/disk/by-uuid:\n result.uuid ??= (await getUuidFromDevDisk(device)) ?? \"\";\n result.label ??= (await getLabelFromDevDisk(device)) ?? \"\";\n }\n\n assignSystemVolume(result, o);\n\n // Fix microsoft's UUID format:\n result.uuid = extractUUID(result.uuid) ?? result.uuid ?? \"\";\n\n debug(\"[getVolumeMetadata] final result for %s: %o\", o.mountPoint, result);\n return compactValues(result) as VolumeMetadata;\n}\n\nexport async function getAllVolumeMetadataImpl(\n opts: Required<Options> & {\n includeSystemVolumes?: boolean;\n maxConcurrency?: number;\n },\n nativeFn: NativeBindingsFn,\n): Promise<VolumeMetadata[]> {\n const o = optionsWithDefaults(opts);\n debug(\"[getAllVolumeMetadata] starting with options: %o\", o);\n\n const arr = await getVolumeMountPointsImpl(o, nativeFn);\n debug(\"[getAllVolumeMetadata] found %d mount points\", arr.length);\n\n const unhealthyMountPoints = arr\n .filter(\n (ea) => ea.status != null && ea.status !== VolumeHealthStatuses.healthy,\n )\n .map((ea) => ({\n mountPoint: ea.mountPoint,\n error: new WrappedError(\"volume not healthy: \" + ea.status, {\n name: \"Skipped\",\n }),\n }));\n\n const includeSystemVolumes =\n opts?.includeSystemVolumes ?? IncludeSystemVolumesDefault;\n\n const systemMountPoints = includeSystemVolumes\n ? []\n : arr\n .filter((ea) => ea.isSystemVolume)\n .map((ea) => ({\n mountPoint: ea.mountPoint,\n error: new WrappedError(\"system volume\", { name: \"Skipped\" }),\n }));\n\n const healthy = arr.filter(\n (ea) => ea.status == null || ea.status === VolumeHealthStatuses.healthy,\n );\n\n debug(\"[getAllVolumeMetadata] \", {\n allMountPoints: arr.map((ea) => ea.mountPoint),\n healthyMountPoints: healthy.map((ea) => ea.mountPoint),\n });\n\n debug(\n \"[getAllVolumeMetadata] processing %d healthy volumes with max concurrency %d\",\n healthy.length,\n o.maxConcurrency,\n );\n\n const results = await (mapConcurrent({\n maxConcurrency: o.maxConcurrency,\n items:\n (opts?.includeSystemVolumes ?? IncludeSystemVolumesDefault)\n ? healthy\n : healthy.filter((ea) => !ea.isSystemVolume),\n fn: async (mp) =>\n getVolumeMetadataImpl({ ...mp, ...o }, nativeFn).catch((error) => ({\n mountPoint: mp.mountPoint,\n error,\n })),\n }) as Promise<(VolumeMetadata | { mountPoint: string; error: Error })[]>);\n\n debug(\"[getAllVolumeMetadata] completed processing all volumes\");\n return arr.map(\n (result) =>\n (results.find((ea) => ea.mountPoint === result.mountPoint) ??\n unhealthyMountPoints.find(\n (ea) => ea.mountPoint === result.mountPoint,\n ) ??\n systemMountPoints.find((ea) => ea.mountPoint === result.mountPoint) ?? {\n ...result,\n error: new WrappedError(\"Mount point metadata not retrieved\", {\n name: \"NotApplicableError\",\n }),\n }) as VolumeMetadata,\n );\n}\n"],"mappings":"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","names":["defer","import_node_path","import_node_process","import_promises","import_node_path","import_node_path","nativeFn","import_node_os","import_promises","import_node_path","import_promises","patterns","patterns","nativeFn","nativeFn","defer","dirname","NodeGypBuild"]}