@zero-transfer/google-drive 0.1.5 → 0.3.1
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/README.md +1 -1
- package/dist/index.cjs +2811 -8469
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +19 -44
- package/dist/index.d.ts +19 -44
- package/dist/index.mjs +2872 -8530
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/ZeroTransfer.ts","../../../src/errors/ZeroTransferError.ts","../../../src/logging/Logger.ts","../../../src/profiles/ProfileValidator.ts","../../../src/core/ProviderId.ts","../../../src/core/ProviderRegistry.ts","../../../src/core/TransferClient.ts","../../../src/core/createTransferClient.ts","../../../src/client/operations.ts","../../../src/transfers/BandwidthThrottle.ts","../../../src/transfers/createProviderTransferExecutor.ts","../../../src/services/TransferService.ts","../../../src/transfers/TransferEngine.ts","../../../src/mft/runRoute.ts","../../../src/logging/redaction.ts","../../../src/profiles/SecretSource.ts","../../../src/profiles/ProfileRedactor.ts","../../../src/diagnostics/index.ts","../../../src/providers/classic/ftp/FtpProvider.ts","../../../src/profiles/resolveConnectionProfileSecrets.ts","../../../src/utils/path.ts","../../../src/providers/classic/ftp/FtpListParser.ts","../../../src/providers/classic/ftp/FtpResponseParser.ts","../../../src/providers/classic/sftp/SftpProvider.ts","../../../src/providers/web/httpInternals.ts","../../../src/providers/cloud/DropboxProvider.ts","../../../src/providers/cloud/GoogleDriveProvider.ts","../../../src/providers/cloud/OneDriveProvider.ts","../../../src/providers/cloud/AzureBlobProvider.ts","../../../src/providers/cloud/GcsProvider.ts","../../../src/providers/local/LocalProvider.ts","../../../src/providers/memory/MemoryProvider.ts","../../../src/providers/web/HttpProvider.ts","../../../src/providers/web/WebDavProvider.ts","../../../src/providers/web/awsSigv4.ts","../../../src/providers/web/S3Provider.ts","../../../src/providers/capabilityMatrix.ts","../../../src/profiles/OAuthTokenSource.ts","../../../src/profiles/importers/KnownHostsParser.ts","../../../src/profiles/importers/OpenSshConfigImporter.ts","../../../src/profiles/importers/FileZillaImporter.ts","../../../src/profiles/importers/WinScpImporter.ts","../../../src/errors/errorFactory.ts","../../../src/transfers/TransferPlan.ts","../../../src/transfers/TransferQueue.ts","../../../src/sync/createRemoteBrowser.ts","../../../src/sync/createSyncPlan.ts","../../../src/sync/createAtomicDeployPlan.ts","../../../src/sync/walkRemoteTree.ts","../../../src/sync/diffRemoteTrees.ts","../../../src/sync/manifest.ts"],"sourcesContent":["/**\n * Client facade for the ZeroTransfer SDK foundation.\n *\n * This module intentionally keeps the top-level API small while protocol-specific\n * behavior is delegated to injected adapters. The facade owns lifecycle state,\n * event emission, logging coordination, and common capability discovery.\n *\n * @module client/ZeroTransfer\n */\nimport { EventEmitter } from \"node:events\";\nimport { createTransferClient } from \"../core/createTransferClient\";\nimport { isClassicProviderId } from \"../core/ProviderId\";\nimport { UnsupportedFeatureError } from \"../errors/ZeroTransferError\";\nimport { emitLog, noopLogger, type ZeroTransferLogger } from \"../logging/Logger\";\nimport type { RemoteFileAdapter } from \"../protocols/RemoteFileAdapter\";\nimport type {\n ConnectionProfile,\n ListOptions,\n RemoteEntry,\n RemoteProtocol,\n RemoteStat,\n StatOptions,\n} from \"../types/public\";\n\n/**\n * Construction options for a {@link ZeroTransfer} instance.\n *\n * @remarks\n * The adapter option is primarily used by protocol implementations and tests. Until\n * the built-in FTP, FTPS, and SFTP adapters are implemented, callers can inject a\n * compatible adapter to exercise the facade contract.\n */\nexport interface ZeroTransferOptions {\n /** Protocol used when the connection profile does not provide one. */\n protocol?: RemoteProtocol;\n /** Structured logger used for lifecycle and operation records. */\n logger?: ZeroTransferLogger;\n /** Protocol adapter that performs concrete remote file operations. */\n adapter?: RemoteFileAdapter;\n}\n\n/**\n * Lightweight capability snapshot for the current client instance.\n */\nexport interface ZeroTransferCapabilities {\n /** The protocol selected for this client facade. */\n protocol: RemoteProtocol;\n /** Whether a concrete protocol adapter has been supplied. */\n adapterReady: boolean;\n}\n\n/**\n * SDK entry point for FTP, FTPS, and SFTP workflows.\n *\n * @remarks\n * ZeroTransfer extends Node.js EventEmitter so applications can observe lifecycle\n * events while still using promise-based APIs for operations. The facade is\n * deliberately protocol-neutral; concrete behavior lives behind\n * {@link RemoteFileAdapter}.\n *\n */\nexport class ZeroTransfer extends EventEmitter {\n /** Creates a provider-neutral transfer client with the built-in provider registry. */\n static readonly createTransferClient = createTransferClient;\n\n /** Protocol selected for this client instance. */\n readonly protocol: RemoteProtocol;\n\n private readonly logger: ZeroTransferLogger;\n private readonly adapter: RemoteFileAdapter | undefined;\n private connected = false;\n\n /**\n * Creates a client facade without opening a network connection.\n *\n * @param options - Optional facade configuration, logger, and protocol adapter.\n */\n constructor(options: ZeroTransferOptions = {}) {\n super();\n this.protocol = options.protocol ?? \"ftp\";\n this.logger = options.logger ?? noopLogger;\n this.adapter = options.adapter;\n }\n\n /**\n * Creates a new client facade using the provided options.\n *\n * @param options - Optional facade configuration, logger, and adapter.\n * @returns A disconnected {@link ZeroTransfer} instance.\n */\n static create(options: ZeroTransferOptions = {}): ZeroTransfer {\n return new ZeroTransfer(options);\n }\n\n /**\n * Creates a client and connects it in one step.\n *\n * @param profile - Remote host, authentication, and protocol connection settings.\n * @param options - Optional facade settings that can be overridden by the profile.\n * @returns A connected {@link ZeroTransfer} instance.\n * @throws {@link UnsupportedFeatureError} When no adapter is available for the protocol.\n */\n static async connect(\n profile: ConnectionProfile,\n options: ZeroTransferOptions = {},\n ): Promise<ZeroTransfer> {\n const clientOptions: ZeroTransferOptions = { ...options };\n\n if (profile.logger !== undefined) {\n clientOptions.logger = profile.logger;\n }\n\n if (profile.protocol !== undefined) {\n clientOptions.protocol = profile.protocol;\n } else if (isClassicProviderId(profile.provider)) {\n clientOptions.protocol = profile.provider;\n }\n\n const client = new ZeroTransfer(clientOptions);\n await client.connect(profile);\n return client;\n }\n\n /**\n * Opens a remote connection through the configured protocol adapter.\n *\n * @param profile - Remote host, authentication, timeout, logger, and protocol settings.\n * @returns A promise that resolves after the adapter reports a successful connection.\n * @throws {@link UnsupportedFeatureError} When the client does not have an adapter.\n */\n async connect(profile: ConnectionProfile): Promise<void> {\n const adapter = this.requireAdapter();\n const protocol =\n profile.protocol ??\n (isClassicProviderId(profile.provider) ? profile.provider : this.protocol);\n emitLog(this.logger, \"info\", {\n component: \"client\",\n host: profile.host,\n message: \"Connecting\",\n protocol,\n });\n await adapter.connect({\n ...profile,\n protocol,\n });\n this.connected = true;\n this.emit(\"connect\", {\n host: profile.host,\n protocol,\n });\n }\n\n /**\n * Closes the active remote connection if one exists.\n *\n * @returns A promise that resolves after the adapter disconnects or immediately when idle.\n */\n async disconnect(): Promise<void> {\n if (this.adapter !== undefined && this.connected) {\n await this.adapter.disconnect();\n }\n\n this.connected = false;\n this.emit(\"disconnect\");\n }\n\n /**\n * Checks whether the facade currently considers the adapter connected.\n *\n * @returns `true` after a successful connection and before disconnection.\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Describes protocol and adapter readiness for feature discovery.\n *\n * @returns A capability snapshot for diagnostics and UI state.\n */\n getCapabilities(): ZeroTransferCapabilities {\n return {\n adapterReady: this.adapter !== undefined,\n protocol: this.protocol,\n };\n }\n\n /**\n * Lists remote entries for a path using the configured adapter.\n *\n * @param path - Remote directory path to inspect.\n * @param options - Optional listing controls such as recursion and abort signal.\n * @returns Normalized remote entries for the requested directory.\n * @throws {@link UnsupportedFeatureError} When the client does not have an adapter.\n */\n async list(path: string, options?: ListOptions): Promise<RemoteEntry[]> {\n return this.requireAdapter().list(path, options);\n }\n\n /**\n * Reads metadata for a remote path using the configured adapter.\n *\n * @param path - Remote file, directory, or symbolic-link path to inspect.\n * @param options - Optional stat controls such as abort signal.\n * @returns Normalized metadata for an existing remote entry.\n * @throws {@link UnsupportedFeatureError} When the client does not have an adapter.\n */\n async stat(path: string, options?: StatOptions): Promise<RemoteStat> {\n return this.requireAdapter().stat(path, options);\n }\n\n /**\n * Returns the configured adapter or raises the alpha unsupported-feature error.\n *\n * @returns A concrete remote file adapter ready to execute operations.\n * @throws {@link UnsupportedFeatureError} When no adapter has been provided.\n */\n private requireAdapter(): RemoteFileAdapter {\n if (this.adapter === undefined) {\n throw new UnsupportedFeatureError({\n message: `The ${this.protocol.toUpperCase()} adapter is not implemented in this alpha foundation yet`,\n protocol: this.protocol,\n retryable: false,\n });\n }\n\n return this.adapter;\n }\n}\n","/**\n * Structured ZeroTransfer error hierarchy.\n *\n * The classes in this module preserve protocol details, retryability, command/path\n * context, and machine-readable codes so application code does not need to parse\n * human error messages.\n *\n * @module errors/ZeroTransferError\n */\nimport type { RemoteProtocol } from \"../types/public\";\n\n/**\n * Complete set of fields required to create a ZeroTransfer error.\n */\nexport interface ZeroTransferErrorDetails {\n /** Stable machine-readable error code. */\n code: string;\n /** Human-readable error message safe to show in logs or diagnostics. */\n message: string;\n /** Original error or exception that caused this error. */\n cause?: unknown;\n /** Protocol active when the error occurred. */\n protocol?: RemoteProtocol;\n /** Remote host associated with the failing operation. */\n host?: string;\n /** Protocol command associated with the failure, if any. */\n command?: string;\n /** FTP response code associated with the failure. */\n ftpCode?: number;\n /** SFTP status code associated with the failure. */\n sftpCode?: number;\n /** Remote path associated with the failure. */\n path?: string;\n /** Whether retry policy may safely retry this failure. */\n retryable: boolean;\n /** Additional structured details for diagnostics. */\n details?: Record<string, unknown>;\n}\n\n/**\n * Error construction input for subclasses that provide default codes.\n */\nexport type SpecializedErrorDetails = Omit<ZeroTransferErrorDetails, \"code\"> & {\n /** Optional override for the subclass default code. */\n code?: string;\n};\n\n/**\n * Base class for all typed ZeroTransfer errors.\n */\nexport class ZeroTransferError extends Error {\n /** Stable machine-readable error code. */\n readonly code: string;\n /** Protocol active when the error occurred. */\n readonly protocol?: RemoteProtocol;\n /** Remote host associated with the failing operation. */\n readonly host?: string;\n /** Protocol command associated with the failure, if any. */\n readonly command?: string;\n /** FTP response code associated with the failure. */\n readonly ftpCode?: number;\n /** SFTP status code associated with the failure. */\n readonly sftpCode?: number;\n /** Remote path associated with the failure. */\n readonly path?: string;\n /** Whether retry policy may safely retry this failure. */\n readonly retryable: boolean;\n /** Additional structured details for diagnostics. */\n readonly details?: Record<string, unknown>;\n\n /**\n * Creates a structured SDK error.\n *\n * @param details - Code, message, retryability, and optional protocol context.\n */\n constructor(details: ZeroTransferErrorDetails) {\n super(details.message, details.cause === undefined ? undefined : { cause: details.cause });\n this.name = new.target.name;\n this.code = details.code;\n this.retryable = details.retryable;\n\n if (details.protocol !== undefined) this.protocol = details.protocol;\n if (details.host !== undefined) this.host = details.host;\n if (details.command !== undefined) this.command = details.command;\n if (details.ftpCode !== undefined) this.ftpCode = details.ftpCode;\n if (details.sftpCode !== undefined) this.sftpCode = details.sftpCode;\n if (details.path !== undefined) this.path = details.path;\n if (details.details !== undefined) this.details = details.details;\n }\n\n /**\n * Serializes the error into a plain object suitable for logs or API responses.\n *\n * @returns A JSON-safe object containing public structured error fields.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n protocol: this.protocol,\n host: this.host,\n command: this.command,\n ftpCode: this.ftpCode,\n sftpCode: this.sftpCode,\n path: this.path,\n retryable: this.retryable,\n details: this.details,\n };\n }\n}\n\n/**\n * Applies a subclass default code while preserving caller overrides.\n *\n * @param details - Subclass error details with optional code override.\n * @param code - Default code for the specific subclass.\n * @returns Complete base error details.\n */\nfunction withDefaultCode(details: SpecializedErrorDetails, code: string): ZeroTransferErrorDetails {\n return {\n ...details,\n code: details.code ?? code,\n };\n}\n\n/** Error raised when a remote connection cannot be opened or is lost unexpectedly. */\nexport class ConnectionError extends ZeroTransferError {\n /**\n * Creates a connection failure.\n *\n * @param details - Error context with optional host, protocol, and retryability details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_CONNECTION_ERROR\"));\n }\n}\n\n/** Error raised when authentication credentials are rejected. */\nexport class AuthenticationError extends ZeroTransferError {\n /**\n * Creates an authentication failure.\n *\n * @param details - Error context with optional host, protocol, and command details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_AUTHENTICATION_ERROR\"));\n }\n}\n\n/** Error raised when authenticated credentials are not authorized for an operation. */\nexport class AuthorizationError extends ZeroTransferError {\n /**\n * Creates an authorization failure.\n *\n * @param details - Error context with optional path and protocol details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_AUTHORIZATION_ERROR\"));\n }\n}\n\n/** Error raised when a requested remote path does not exist. */\nexport class PathNotFoundError extends ZeroTransferError {\n /**\n * Creates a missing-path failure.\n *\n * @param details - Error context with optional path and protocol details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PATH_NOT_FOUND\"));\n }\n}\n\n/** Error raised when a create or rename operation targets an existing path. */\nexport class PathAlreadyExistsError extends ZeroTransferError {\n /**\n * Creates an already-exists failure.\n *\n * @param details - Error context with optional path and command details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PATH_ALREADY_EXISTS\"));\n }\n}\n\n/** Error raised when the remote server denies access to a path or command. */\nexport class PermissionDeniedError extends ZeroTransferError {\n /**\n * Creates a permission failure.\n *\n * @param details - Error context with optional path, command, and protocol details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PERMISSION_DENIED\"));\n }\n}\n\n/** Error raised when an operation exceeds its configured timeout. */\nexport class TimeoutError extends ZeroTransferError {\n /**\n * Creates a timeout failure.\n *\n * @param details - Error context with optional duration and retryability details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_TIMEOUT\"));\n }\n}\n\n/** Error raised when an operation is cancelled by an AbortSignal or caller action. */\nexport class AbortError extends ZeroTransferError {\n /**\n * Creates an aborted-operation failure.\n *\n * @param details - Error context with optional operation and path details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_ABORTED\"));\n }\n}\n\n/** Error raised when a server response violates protocol expectations. */\nexport class ProtocolError extends ZeroTransferError {\n /**\n * Creates a protocol failure.\n *\n * @param details - Error context with optional response code and command details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PROTOCOL_ERROR\"));\n }\n}\n\n/** Error raised when protocol text or metadata cannot be parsed safely. */\nexport class ParseError extends ZeroTransferError {\n /**\n * Creates a parser failure.\n *\n * @param details - Error context with malformed input details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PARSE_ERROR\"));\n }\n}\n\n/** Error raised when an upload, download, or stream transfer fails. */\nexport class TransferError extends ZeroTransferError {\n /**\n * Creates a transfer failure.\n *\n * @param details - Error context with optional path, bytes, and retryability details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_TRANSFER_ERROR\"));\n }\n}\n\n/** Error raised when post-transfer verification fails. */\nexport class VerificationError extends ZeroTransferError {\n /**\n * Creates a verification failure.\n *\n * @param details - Error context with checksum, size, or timestamp mismatch details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_VERIFICATION_ERROR\"));\n }\n}\n\n/** Error raised when a requested protocol feature is not implemented or unavailable. */\nexport class UnsupportedFeatureError extends ZeroTransferError {\n /**\n * Creates an unsupported-feature failure.\n *\n * @param details - Error context describing the missing feature or adapter.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_UNSUPPORTED_FEATURE\"));\n }\n}\n\n/** Error raised when user-provided options or paths are invalid before network I/O. */\nexport class ConfigurationError extends ZeroTransferError {\n /**\n * Creates a configuration failure.\n *\n * @param details - Error context describing the invalid option or argument.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_CONFIGURATION_ERROR\"));\n }\n}\n","/**\n * Structured logging contracts and helpers for ZeroTransfer.\n *\n * The logger shape is intentionally compatible with popular structured loggers while\n * staying small enough for applications to implement directly.\n *\n * @module logging/Logger\n */\n/** Supported ZeroTransfer log levels. */\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/**\n * Complete structured log record emitted by ZeroTransfer helpers.\n */\nexport interface LogRecord {\n /** Severity level for the record. */\n level: LogLevel;\n /** Human-readable summary message. */\n message: string;\n /** SDK component that produced the record. */\n component?: string;\n /** Active protocol for the record. */\n protocol?: string;\n /** Remote host associated with the record. */\n host?: string;\n /** Correlation id for a connection lifecycle. */\n connectionId?: string;\n /** Correlation id for a protocol command. */\n commandId?: string;\n /** Correlation id for a transfer lifecycle. */\n transferId?: string;\n /** Remote or local path associated with the record. */\n path?: string;\n /** Operation duration in milliseconds. */\n durationMs?: number;\n /** Byte count associated with the operation. */\n bytes?: number;\n /** Additional structured fields supplied by adapters or services. */\n [key: string]: unknown;\n}\n\n/**\n * Log record input accepted by {@link emitLog}; the helper adds the level.\n */\nexport interface LogRecordInput extends Omit<LogRecord, \"level\"> {\n /** Human-readable summary message. */\n message: string;\n}\n\n/**\n * Logger method signature used for each severity level.\n *\n * @param record - Structured log record.\n * @param message - Convenience message argument for console-like loggers.\n */\nexport type LoggerMethod = (record: LogRecord, message?: string) => void;\n\n/**\n * Partial structured logger accepted by ZeroTransfer.\n */\nexport interface ZeroTransferLogger {\n /** Receives highly detailed diagnostic records. */\n trace?: LoggerMethod;\n /** Receives development/debugging records. */\n debug?: LoggerMethod;\n /** Receives normal lifecycle records. */\n info?: LoggerMethod;\n /** Receives recoverable issue records. */\n warn?: LoggerMethod;\n /** Receives failed operation records. */\n error?: LoggerMethod;\n}\n\n/**\n * Logger implementation that intentionally drops every record.\n */\nexport const noopLogger: Required<ZeroTransferLogger> = {\n trace() {},\n debug() {},\n info() {},\n warn() {},\n error() {},\n};\n\n/**\n * Emits a structured log record if the logger implements the requested level.\n *\n * @param logger - Logger that may contain a method for the requested level.\n * @param level - Severity level to emit.\n * @param record - Log record fields without the level property.\n * @returns Nothing; missing logger methods are ignored.\n */\nexport function emitLog(logger: ZeroTransferLogger, level: LogLevel, record: LogRecordInput): void {\n const method = logger[level];\n\n if (method === undefined) {\n return;\n }\n\n const logRecord: LogRecord = {\n ...record,\n level,\n };\n\n method(logRecord, logRecord.message);\n}\n","/**\n * Connection profile validation helpers.\n *\n * @module profiles/ProfileValidator\n */\nimport { Buffer } from \"node:buffer\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { ConnectionProfile, SshProfile, TlsProfile } from \"../types/public\";\nimport { resolveProviderId } from \"../core/ProviderId\";\n\n/** TLS protocol versions accepted by Node's `SecureVersion` option. */\nconst TLS_VERSIONS = new Set([\"TLSv1\", \"TLSv1.1\", \"TLSv1.2\", \"TLSv1.3\"]);\n/** Hex characters in a SHA-256 certificate fingerprint after separators are removed. */\nconst SHA256_FINGERPRINT_HEX_LENGTH = 64;\n/** Raw SHA-256 digest byte length. */\nconst SHA256_DIGEST_BYTE_LENGTH = 32;\n\n/**\n * Validates provider-neutral connection profile fields before provider lookup.\n *\n * @param profile - Profile to validate.\n * @returns The original profile when valid.\n * @throws {@link ConfigurationError} When required provider, host, or numeric fields are invalid.\n */\nexport function validateConnectionProfile(profile: ConnectionProfile): ConnectionProfile {\n if (resolveProviderId(profile) === undefined) {\n throw new ConfigurationError({\n message: \"Connection profiles must include a provider or protocol\",\n retryable: false,\n });\n }\n\n if (profile.host.trim().length === 0) {\n throw new ConfigurationError({\n message: \"Connection profiles must include a non-empty host\",\n retryable: false,\n });\n }\n\n if (profile.port !== undefined && !isValidPort(profile.port)) {\n throw new ConfigurationError({\n details: { port: profile.port },\n message: \"Connection profile port must be an integer between 1 and 65535\",\n retryable: false,\n });\n }\n\n if (profile.timeoutMs !== undefined && !isPositiveFiniteNumber(profile.timeoutMs)) {\n throw new ConfigurationError({\n details: { timeoutMs: profile.timeoutMs },\n message: \"Connection profile timeoutMs must be a positive finite number\",\n retryable: false,\n });\n }\n\n if (profile.tls !== undefined) {\n validateTlsProfile(profile.tls);\n }\n\n if (profile.ssh !== undefined) {\n validateSshProfile(profile.ssh);\n }\n\n return profile;\n}\n\n/**\n * Validates SSH profile policy fields that can be checked without resolving secrets.\n *\n * @param profile - SSH profile to validate.\n * @throws {@link ConfigurationError} When host-key pin values are invalid.\n */\nfunction validateSshProfile(profile: SshProfile): void {\n validatePinnedHostKeySha256(profile.pinnedHostKeySha256);\n\n if (profile.algorithms !== undefined) {\n validateSshAlgorithms(profile.algorithms);\n }\n\n if (profile.agent !== undefined) {\n validateSshAgentSource(profile.agent);\n }\n\n if (\n profile.keyboardInteractive !== undefined &&\n typeof profile.keyboardInteractive !== \"function\"\n ) {\n throw new ConfigurationError({\n details: { keyboardInteractive: typeof profile.keyboardInteractive },\n message: \"Connection profile ssh.keyboardInteractive must be a function when provided\",\n retryable: false,\n });\n }\n\n if (profile.socketFactory !== undefined && typeof profile.socketFactory !== \"function\") {\n throw new ConfigurationError({\n details: { socketFactory: typeof profile.socketFactory },\n message: \"Connection profile ssh.socketFactory must be a function when provided\",\n retryable: false,\n });\n }\n}\n\n/**\n * Validates SSH algorithm override shape without duplicating ssh2's literal unions.\n *\n * @param value - Algorithm override object from an SSH profile.\n * @throws {@link ConfigurationError} When overrides are not object-shaped or contain empty lists.\n */\nfunction validateSshAlgorithms(value: SshProfile[\"algorithms\"]): void {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw createSshAlgorithmsError(value);\n }\n\n const algorithms = value as Record<string, unknown>;\n\n for (const [name, list] of Object.entries(algorithms)) {\n if (list === undefined) {\n continue;\n }\n\n if (Array.isArray(list)) {\n if (!isNonEmptyStringArray(list)) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n\n continue;\n }\n\n if (typeof list !== \"object\" || list === null || Array.isArray(list)) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n\n const operationLists = list as Record<string, unknown>;\n\n for (const [operation, operationList] of Object.entries(operationLists)) {\n if (![\"append\", \"prepend\", \"remove\"].includes(operation)) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n\n if (\n typeof operationList !== \"string\" &&\n (!Array.isArray(operationList) || !isNonEmptyStringArray(operationList))\n ) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n }\n }\n}\n\nfunction isNonEmptyStringArray(value: unknown[]): value is string[] {\n return value.length > 0 && value.every((item) => typeof item === \"string\" && item.length > 0);\n}\n\n/**\n * Validates SSH agent source values.\n *\n * @param value - Agent socket path or agent implementation.\n * @throws {@link ConfigurationError} When the value is neither a non-empty path nor an agent object.\n */\nfunction validateSshAgentSource(value: SshProfile[\"agent\"]): void {\n if (typeof value === \"string\") {\n if (value.trim().length > 0) {\n return;\n }\n } else if (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { getIdentities?: unknown }).getIdentities === \"function\" &&\n typeof (value as { sign?: unknown }).sign === \"function\"\n ) {\n return;\n }\n\n throw new ConfigurationError({\n details: { agent: typeof value },\n message: \"Connection profile ssh.agent must be a non-empty socket path or agent object\",\n retryable: false,\n });\n}\n\n/**\n * Validates TLS profile policy fields that can be checked without resolving secrets.\n *\n * @param profile - TLS profile to validate.\n * @throws {@link ConfigurationError} When server name, boolean, or TLS-version fields are invalid.\n */\nfunction validateTlsProfile(profile: TlsProfile): void {\n if (profile.servername !== undefined && profile.servername.trim().length === 0) {\n throw new ConfigurationError({\n message: \"Connection profile tls.servername must be non-empty when provided\",\n retryable: false,\n });\n }\n\n if (profile.rejectUnauthorized !== undefined && typeof profile.rejectUnauthorized !== \"boolean\") {\n throw new ConfigurationError({\n details: { rejectUnauthorized: profile.rejectUnauthorized },\n message: \"Connection profile tls.rejectUnauthorized must be a boolean\",\n retryable: false,\n });\n }\n\n validateTlsVersion(profile.minVersion, \"minVersion\");\n validateTlsVersion(profile.maxVersion, \"maxVersion\");\n validatePinnedFingerprint256(profile.pinnedFingerprint256);\n}\n\n/**\n * Validates SHA-256 certificate fingerprint pinning values.\n *\n * @param value - Single fingerprint or allowed fingerprint set from the TLS profile.\n * @throws {@link ConfigurationError} When a fingerprint is empty or not SHA-256 hex.\n */\nfunction validatePinnedFingerprint256(value: TlsProfile[\"pinnedFingerprint256\"]): void {\n if (value === undefined) {\n return;\n }\n\n const fingerprints = Array.isArray(value) ? value : [value];\n\n if (fingerprints.length === 0) {\n throw createPinnedFingerprintError(value);\n }\n\n for (const fingerprint of fingerprints) {\n if (typeof fingerprint !== \"string\" || !isSha256Fingerprint(fingerprint)) {\n throw createPinnedFingerprintError(value);\n }\n }\n}\n\n/**\n * Validates SHA-256 SSH host-key pinning values.\n *\n * @param value - Single fingerprint or allowed fingerprint set from the SSH profile.\n * @throws {@link ConfigurationError} When a fingerprint is empty or not a SHA-256 digest.\n */\nfunction validatePinnedHostKeySha256(value: SshProfile[\"pinnedHostKeySha256\"]): void {\n if (value === undefined) {\n return;\n }\n\n const fingerprints = Array.isArray(value) ? value : [value];\n\n if (fingerprints.length === 0) {\n throw createPinnedHostKeyError(value);\n }\n\n for (const fingerprint of fingerprints) {\n if (typeof fingerprint !== \"string\" || !isSshHostKeySha256Fingerprint(fingerprint)) {\n throw createPinnedHostKeyError(value);\n }\n }\n}\n\n/**\n * Checks whether a string is a supported SHA-256 certificate fingerprint.\n *\n * @param value - Candidate fingerprint string.\n * @returns `true` when the value is 64 hex characters after optional colons are removed.\n */\nfunction isSha256Fingerprint(value: string): boolean {\n const normalized = value.trim().replace(/:/g, \"\");\n return normalized.length === SHA256_FINGERPRINT_HEX_LENGTH && /^[a-f0-9]+$/i.test(normalized);\n}\n\n/**\n * Checks whether a string is a supported SSH SHA-256 host-key fingerprint.\n *\n * @param value - Candidate fingerprint string.\n * @returns `true` when the value is OpenSSH SHA256 base64, bare base64, or SHA-256 hex.\n */\nfunction isSshHostKeySha256Fingerprint(value: string): boolean {\n const trimmed = value.trim();\n\n if (isSha256Fingerprint(trimmed)) {\n return true;\n }\n\n const bare = trimmed.startsWith(\"SHA256:\") ? trimmed.slice(\"SHA256:\".length) : trimmed;\n const padded = padBase64(bare);\n\n if (!/^[a-z0-9+/]+={0,2}$/i.test(padded)) {\n return false;\n }\n\n try {\n return Buffer.from(padded, \"base64\").byteLength === SHA256_DIGEST_BYTE_LENGTH;\n } catch {\n return false;\n }\n}\n\nfunction padBase64(value: string): string {\n const remainder = value.length % 4;\n\n return remainder === 0 ? value : `${value}${\"=\".repeat(4 - remainder)}`;\n}\n\n/**\n * Creates a consistent validation error for invalid certificate pin values.\n *\n * @param value - Invalid profile value included in diagnostics.\n * @returns Configuration error describing the supported fingerprint format.\n */\nfunction createPinnedFingerprintError(value: unknown): ConfigurationError {\n return new ConfigurationError({\n details: { pinnedFingerprint256: value },\n message:\n \"Connection profile tls.pinnedFingerprint256 must be a SHA-256 hex fingerprint or non-empty array of fingerprints\",\n retryable: false,\n });\n}\n\n/**\n * Creates a consistent validation error for invalid SSH host-key pin values.\n *\n * @param value - Invalid profile value included in diagnostics.\n * @returns Configuration error describing the supported fingerprint formats.\n */\nfunction createPinnedHostKeyError(value: unknown): ConfigurationError {\n return new ConfigurationError({\n details: { pinnedHostKeySha256: value },\n message:\n \"Connection profile ssh.pinnedHostKeySha256 must be an OpenSSH SHA256, base64, or hex fingerprint or non-empty array of fingerprints\",\n retryable: false,\n });\n}\n\n/**\n * Creates a consistent validation error for invalid SSH algorithm overrides.\n *\n * @param value - Invalid profile value included in diagnostics.\n * @returns Configuration error describing the expected ssh2-compatible shape.\n */\nfunction createSshAlgorithmsError(value: unknown): ConfigurationError {\n return new ConfigurationError({\n details: { algorithms: value },\n message: \"Connection profile ssh.algorithms must use ssh2-compatible non-empty algorithm lists\",\n retryable: false,\n });\n}\n\n/**\n * Validates a configured TLS protocol version string.\n *\n * @param value - TLS version value from the profile, if provided.\n * @param field - Profile field name used in diagnostics.\n * @throws {@link ConfigurationError} When the value is not one of Node's supported TLS versions.\n */\nfunction validateTlsVersion(value: TlsProfile[\"minVersion\"], field: string): void {\n if (value === undefined) {\n return;\n }\n\n if (!TLS_VERSIONS.has(value)) {\n throw new ConfigurationError({\n details: { [field]: value },\n message: `Connection profile tls.${field} must be a supported TLS version`,\n retryable: false,\n });\n }\n}\n\nfunction isValidPort(value: number): boolean {\n return Number.isInteger(value) && value >= 1 && value <= 65_535;\n}\n\nfunction isPositiveFiniteNumber(value: number): boolean {\n return Number.isFinite(value) && value > 0;\n}\n","/**\n * Provider identifiers used by the provider-neutral ZeroTransfer core.\n *\n * @module core/ProviderId\n */\n\n/** Classic remote-transfer providers kept compatible with the original protocol field. */\nexport const CLASSIC_PROVIDER_IDS = [\"ftp\", \"ftps\", \"sftp\"] as const;\n\n/** Provider ids that map directly to the original protocol-focused alpha facade. */\nexport type ClassicProviderId = (typeof CLASSIC_PROVIDER_IDS)[number];\n\n/** Provider ids reserved for first-party ZeroTransfer adapters. */\nexport type BuiltInProviderId =\n | ClassicProviderId\n | \"memory\"\n | \"local\"\n | \"http\"\n | \"https\"\n | \"webdav\"\n | \"s3\"\n | \"azure-blob\"\n | \"gcs\"\n | \"dropbox\"\n | \"google-drive\"\n | \"one-drive\";\n\n/** Provider identifier accepted by registries, profiles, and provider factories. */\nexport type ProviderId = BuiltInProviderId | (string & {});\n\n/** Minimal shape used to resolve a provider from new and compatibility profile fields. */\nexport interface ProviderSelection {\n /** Provider id for provider-neutral ZeroTransfer profiles. */\n provider?: ProviderId;\n /** Compatibility protocol field accepted while the provider-neutral API rolls out. */\n protocol?: ClassicProviderId;\n}\n\n/**\n * Checks whether a provider id belongs to the classic FTP/FTPS/SFTP family.\n *\n * @param providerId - Provider id to inspect.\n * @returns `true` when the id is one of the classic protocol providers.\n */\nexport function isClassicProviderId(\n providerId: ProviderId | undefined,\n): providerId is ClassicProviderId {\n return (\n typeof providerId === \"string\" && CLASSIC_PROVIDER_IDS.includes(providerId as ClassicProviderId)\n );\n}\n\n/**\n * Resolves the provider id from a profile, preferring the new `provider` field.\n *\n * @param selection - Profile-like object containing provider and/or protocol fields.\n * @returns The selected provider id, or `undefined` when neither field is present.\n */\nexport function resolveProviderId(selection: ProviderSelection): ProviderId | undefined {\n return selection.provider ?? selection.protocol;\n}\n","/**\n * Provider registry for the provider-neutral ZeroTransfer core.\n *\n * @module core/ProviderRegistry\n */\nimport { ConfigurationError, UnsupportedFeatureError } from \"../errors/ZeroTransferError\";\nimport type { ProviderFactory } from \"../providers/ProviderFactory\";\nimport type { CapabilitySet } from \"./CapabilitySet\";\nimport type { ProviderId } from \"./ProviderId\";\n\n/** Mutable registry of provider factories available to a transfer client. */\nexport class ProviderRegistry {\n private readonly factories = new Map<ProviderId, ProviderFactory>();\n\n /**\n * Creates a registry and optionally seeds it with provider factories.\n *\n * @param providers - Provider factories to register immediately.\n */\n constructor(providers: Iterable<ProviderFactory> = []) {\n for (const provider of providers) {\n this.register(provider);\n }\n }\n\n /**\n * Registers a provider factory.\n *\n * @param provider - Provider factory to add.\n * @returns This registry for fluent setup.\n * @throws {@link ConfigurationError} When a provider id is registered twice.\n */\n register(provider: ProviderFactory): this {\n if (this.factories.has(provider.id)) {\n throw new ConfigurationError({\n details: { provider: provider.id },\n message: `Provider \"${provider.id}\" is already registered`,\n retryable: false,\n });\n }\n\n this.factories.set(provider.id, provider);\n return this;\n }\n\n /**\n * Removes a provider factory from the registry.\n *\n * @param providerId - Provider id to remove.\n * @returns `true` when a provider was removed.\n */\n unregister(providerId: ProviderId): boolean {\n return this.factories.delete(providerId);\n }\n\n /**\n * Checks whether a provider id is registered.\n *\n * @param providerId - Provider id to inspect.\n * @returns `true` when a provider factory exists.\n */\n has(providerId: ProviderId): boolean {\n return this.factories.has(providerId);\n }\n\n /**\n * Gets a provider factory when registered.\n *\n * @param providerId - Provider id to retrieve.\n * @returns The provider factory, or `undefined` when missing.\n */\n get(providerId: ProviderId): ProviderFactory | undefined {\n return this.factories.get(providerId);\n }\n\n /**\n * Gets a registered provider factory or throws a typed SDK error.\n *\n * @param providerId - Provider id to retrieve.\n * @returns The registered provider factory.\n * @throws {@link UnsupportedFeatureError} When no provider has been registered.\n */\n require(providerId: ProviderId): ProviderFactory {\n const provider = this.get(providerId);\n\n if (provider === undefined) {\n throw new UnsupportedFeatureError({\n details: { provider: providerId },\n message: `Provider \"${providerId}\" is not registered`,\n retryable: false,\n });\n }\n\n return provider;\n }\n\n /**\n * Gets a provider capability snapshot when registered.\n *\n * @param providerId - Provider id to inspect.\n * @returns Capability snapshot, or `undefined` when missing.\n */\n getCapabilities(providerId: ProviderId): CapabilitySet | undefined {\n return this.get(providerId)?.capabilities;\n }\n\n /**\n * Gets a provider capability snapshot or throws a typed SDK error.\n *\n * @param providerId - Provider id to inspect.\n * @returns Capability snapshot for the registered provider.\n * @throws {@link UnsupportedFeatureError} When no provider has been registered.\n */\n requireCapabilities(providerId: ProviderId): CapabilitySet {\n return this.require(providerId).capabilities;\n }\n\n /**\n * Lists registered provider factories in insertion order.\n *\n * @returns Registered provider factories.\n */\n list(): ProviderFactory[] {\n return [...this.factories.values()];\n }\n\n /**\n * Lists registered provider capabilities in insertion order.\n *\n * @returns Capability snapshots for every registered provider.\n */\n listCapabilities(): CapabilitySet[] {\n return this.list().map((provider) => provider.capabilities);\n }\n}\n","/**\n * Provider-neutral transfer client foundation.\n *\n * @module core/TransferClient\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport {\n emitLog,\n noopLogger,\n type LogRecordInput,\n type ZeroTransferLogger,\n} from \"../logging/Logger\";\nimport { validateConnectionProfile } from \"../profiles/ProfileValidator\";\nimport type { ProviderFactory } from \"../providers/ProviderFactory\";\nimport type { ConnectionProfile } from \"../types/public\";\nimport type { CapabilitySet } from \"./CapabilitySet\";\nimport type { ProviderId } from \"./ProviderId\";\nimport { isClassicProviderId, resolveProviderId } from \"./ProviderId\";\nimport { ProviderRegistry } from \"./ProviderRegistry\";\nimport type { TransferSession } from \"./TransferSession\";\n\n/** Options used to create a provider-neutral transfer client. */\nexport interface TransferClientOptions {\n /** Existing registry to reuse. When omitted, a fresh empty registry is created. */\n registry?: ProviderRegistry;\n /** Provider factories to register with the client registry. */\n providers?: ProviderFactory[];\n /** Structured logger used for client lifecycle records. */\n logger?: ZeroTransferLogger;\n}\n\n/** Small provider-neutral client that owns provider lookup and connection setup. */\nexport class TransferClient {\n /** Provider registry used by this client. */\n readonly registry: ProviderRegistry;\n\n private readonly logger: ZeroTransferLogger;\n\n /**\n * Creates a transfer client without opening any provider connections.\n *\n * @param options - Optional registry, provider factories, and logger.\n */\n constructor(options: TransferClientOptions = {}) {\n this.registry = options.registry ?? new ProviderRegistry();\n this.logger = options.logger ?? noopLogger;\n\n for (const provider of options.providers ?? []) {\n this.registry.register(provider);\n }\n }\n\n /**\n * Registers a provider factory with this client's registry.\n *\n * @param provider - Provider factory to register.\n * @returns This client for fluent setup.\n */\n registerProvider(provider: ProviderFactory): this {\n this.registry.register(provider);\n return this;\n }\n\n /**\n * Checks whether this client can create sessions for a provider id.\n *\n * @param providerId - Provider id to inspect.\n * @returns `true` when a provider factory is registered.\n */\n hasProvider(providerId: ProviderId): boolean {\n return this.registry.has(providerId);\n }\n\n /** Lists all registered provider capability snapshots. */\n getCapabilities(): CapabilitySet[];\n /** Gets a specific provider capability snapshot. */\n getCapabilities(providerId: ProviderId): CapabilitySet;\n getCapabilities(providerId?: ProviderId): CapabilitySet | CapabilitySet[] {\n if (providerId === undefined) {\n return this.registry.listCapabilities();\n }\n\n return this.registry.requireCapabilities(providerId);\n }\n\n /**\n * Opens a provider session using `profile.provider`, with `profile.protocol` as compatibility fallback.\n *\n * @param profile - Connection profile containing a provider or legacy protocol field.\n * @returns A connected provider session.\n * @throws {@link ConfigurationError} When neither provider nor protocol is present.\n */\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n const validProfile = validateConnectionProfile(profile);\n const providerId = resolveProviderId(validProfile);\n\n if (providerId === undefined) {\n throw new ConfigurationError({\n message: \"Connection profiles must include a provider or protocol\",\n retryable: false,\n });\n }\n\n const providerFactory = this.registry.require(providerId);\n const provider = providerFactory.create();\n const normalizedProfile: ConnectionProfile = {\n ...validProfile,\n provider: providerId,\n };\n\n if (normalizedProfile.protocol === undefined && isClassicProviderId(providerId)) {\n normalizedProfile.protocol = providerId;\n }\n\n emitLog(this.logger, \"info\", createConnectLogRecord(normalizedProfile, providerId));\n\n return provider.connect(normalizedProfile);\n }\n}\n\nfunction createConnectLogRecord(\n profile: ConnectionProfile,\n providerId: ProviderId,\n): LogRecordInput {\n const record: LogRecordInput = {\n component: \"core\",\n host: profile.host,\n message: \"Connecting through provider\",\n provider: providerId,\n };\n\n if (isClassicProviderId(providerId)) {\n record.protocol = providerId;\n }\n\n return record;\n}\n","/**\n * Factory for provider-neutral ZeroTransfer clients.\n *\n * @module core/createTransferClient\n */\nimport { TransferClient, type TransferClientOptions } from \"./TransferClient\";\n\n/**\n * Creates a provider-neutral transfer client.\n *\n * The returned client owns a registry of provider factories and produces\n * `TransferSession` instances on demand via {@link TransferClient.connect}.\n * Registering only the providers you actually use keeps bundle size small\n * (each factory pulls in its own SDK dependencies).\n *\n * @param options - Optional registry, provider factories, and logger.\n * @returns A disconnected {@link TransferClient} instance.\n *\n * @example Multi-provider client\n * ```ts\n * import {\n * createS3ProviderFactory,\n * createSftpProviderFactory,\n * createTransferClient,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({\n * providers: [createSftpProviderFactory(), createS3ProviderFactory()],\n * });\n *\n * const session = await client.connect({\n * host: \"sftp.example.com\",\n * provider: \"sftp\",\n * username: \"deploy\",\n * ssh: { privateKey: { path: \"./keys/id_ed25519\" } },\n * });\n * try {\n * const list = await session.fs.list(\"/uploads\");\n * console.log(list);\n * } finally {\n * await session.disconnect();\n * }\n * ```\n *\n * @example Friendly one-shot helpers\n * ```ts\n * import { uploadFile } from \"@zero-transfer/sdk\";\n *\n * await uploadFile({\n * client,\n * destination: { path: \"/uploads/report.csv\", profile },\n * localPath: \"./out/report.csv\",\n * });\n * ```\n */\nexport function createTransferClient(options: TransferClientOptions = {}): TransferClient {\n return new TransferClient(options);\n}\n","/**\n * Friendly one-call helpers built on top of {@link runRoute}.\n *\n * These helpers give applications a quick surface for the common single-file flows\n * (`uploadFile`, `downloadFile`, `copyBetween`) without forcing them to assemble\n * {@link MftRoute} objects directly. Each helper composes a one-shot route and\n * delegates execution to the existing route runner so retry, abort, progress,\n * timeout, and bandwidth controls behave identically to scheduled runs.\n *\n * @module client/operations\n */\nimport { isAbsolute, resolve as resolvePath } from \"node:path\";\nimport type { TransferClient } from \"../core/TransferClient\";\nimport type { MftRoute } from \"../mft/MftRoute\";\nimport { runRoute, type RunRouteOptions } from \"../mft/runRoute\";\nimport type { TransferReceipt } from \"../transfers/TransferJob\";\nimport type { ConnectionProfile } from \"../types/public\";\n\n/** Endpoint shape accepted by the friendly helpers. */\nexport interface RemoteFileEndpoint {\n /** Provider profile used to open the session. */\n profile: ConnectionProfile;\n /** Provider, remote, or local path the helper operates on. */\n path: string;\n}\n\n/** Shared options consumed by {@link uploadFile}, {@link downloadFile}, and {@link copyBetween}. */\nexport type FriendlyTransferOptions = Omit<RunRouteOptions, \"client\" | \"route\"> & {\n /** Stable route id assigned to the synthetic route. Defaults to `\"upload:...\"`, `\"download:...\"`, or `\"copy:...\"`. */\n routeId?: string;\n /** Optional human-readable route name forwarded to telemetry. */\n routeName?: string;\n};\n\n/** Connection profile for the local filesystem provider. */\nconst LOCAL_PROFILE: ConnectionProfile = { host: \"local\", provider: \"local\" };\n\n/** Options for {@link uploadFile}. */\nexport interface UploadFileOptions extends FriendlyTransferOptions {\n /** Transfer client used to resolve both endpoint providers. */\n client: TransferClient;\n /** Local source path. Relative paths are resolved against `process.cwd()`. */\n localPath: string;\n /** Remote destination endpoint. */\n destination: RemoteFileEndpoint;\n}\n\n/**\n * Uploads a single local file to a remote endpoint.\n *\n * The remote provider is resolved from `destination.profile.provider`, so any\n * provider factory you registered with {@link createTransferClient} can be used\n * as the destination.\n *\n * @param options - Friendly upload options.\n * @returns Receipt produced by the underlying transfer engine.\n *\n * @example Upload to SFTP with public-key auth\n * ```ts\n * import {\n * createSftpProviderFactory,\n * createTransferClient,\n * uploadFile,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createSftpProviderFactory()] });\n *\n * await uploadFile({\n * client,\n * destination: {\n * path: \"/uploads/report.csv\",\n * profile: {\n * host: \"sftp.example.com\",\n * provider: \"sftp\",\n * username: \"deploy\",\n * ssh: { privateKey: { path: \"./keys/id_ed25519\" } },\n * },\n * },\n * localPath: \"./out/report.csv\",\n * });\n * ```\n */\nexport function uploadFile(options: UploadFileOptions): Promise<TransferReceipt> {\n const { client, destination, localPath, routeId, routeName, ...rest } = options;\n const route = buildRoute({\n destination: { path: destination.path, profile: destination.profile },\n id: routeId ?? `upload:${defaultRouteSuffix(localPath, destination.path)}`,\n name: routeName,\n operation: \"upload\",\n source: { path: absolutePath(localPath), profile: LOCAL_PROFILE },\n });\n return runRoute({ client, route, ...rest });\n}\n\n/** Options for {@link downloadFile}. */\nexport interface DownloadFileOptions extends FriendlyTransferOptions {\n /** Transfer client used to resolve both endpoint providers. */\n client: TransferClient;\n /** Remote source endpoint. */\n source: RemoteFileEndpoint;\n /** Local destination path. Relative paths are resolved against `process.cwd()`. */\n localPath: string;\n}\n\n/**\n * Downloads a single remote file to a local path.\n *\n * The remote provider is resolved from `source.profile.provider`. The local\n * destination path is created (including parent directories) on demand.\n *\n * @param options - Friendly download options.\n * @returns Receipt produced by the underlying transfer engine.\n *\n * @example Download from S3\n * ```ts\n * import {\n * createS3ProviderFactory,\n * createTransferClient,\n * downloadFile,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createS3ProviderFactory()] });\n *\n * await downloadFile({\n * client,\n * localPath: \"./tmp/snapshot.tar.gz\",\n * source: {\n * path: \"snapshots/2026-04-28/snapshot.tar.gz\",\n * profile: {\n * host: \"snapshots\", // S3 bucket\n * provider: \"s3\",\n * s3: { region: \"us-east-1\" },\n * },\n * },\n * });\n * ```\n */\nexport function downloadFile(options: DownloadFileOptions): Promise<TransferReceipt> {\n const { client, localPath, routeId, routeName, source, ...rest } = options;\n const route = buildRoute({\n destination: { path: absolutePath(localPath), profile: LOCAL_PROFILE },\n id: routeId ?? `download:${defaultRouteSuffix(source.path, localPath)}`,\n name: routeName,\n operation: \"download\",\n source: { path: source.path, profile: source.profile },\n });\n return runRoute({ client, route, ...rest });\n}\n\n/** Options for {@link copyBetween}. */\nexport interface CopyBetweenOptions extends FriendlyTransferOptions {\n /** Transfer client used to resolve both endpoint providers. */\n client: TransferClient;\n /** Source remote endpoint. */\n source: RemoteFileEndpoint;\n /** Destination remote endpoint. */\n destination: RemoteFileEndpoint;\n}\n\n/**\n * Copies a file between two remote endpoints in a single call.\n *\n * Both source and destination providers must be registered with the\n * {@link TransferClient}. Streams are piped end-to-end without staging the file\n * on the local disk.\n *\n * @param options - Friendly copy options.\n * @returns Receipt produced by the underlying transfer engine.\n *\n * @example Copy from SFTP to S3\n * ```ts\n * import {\n * copyBetween,\n * createS3ProviderFactory,\n * createSftpProviderFactory,\n * createTransferClient,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({\n * providers: [createSftpProviderFactory(), createS3ProviderFactory()],\n * });\n *\n * await copyBetween({\n * client,\n * source: {\n * path: \"/exports/daily.csv\",\n * profile: { host: \"sftp.example.com\", provider: \"sftp\", username: \"etl\" },\n * },\n * destination: {\n * path: \"warehouse/daily.csv\",\n * profile: { host: \"warehouse\", provider: \"s3\", s3: { region: \"us-east-1\" } },\n * },\n * });\n * ```\n */\nexport function copyBetween(options: CopyBetweenOptions): Promise<TransferReceipt> {\n const { client, destination, routeId, routeName, source, ...rest } = options;\n const route = buildRoute({\n destination: { path: destination.path, profile: destination.profile },\n id: routeId ?? `copy:${defaultRouteSuffix(source.path, destination.path)}`,\n name: routeName,\n operation: \"copy\",\n source: { path: source.path, profile: source.profile },\n });\n return runRoute({ client, route, ...rest });\n}\n\ninterface BuildRouteInput {\n id: string;\n name?: string | undefined;\n operation: NonNullable<MftRoute[\"operation\"]>;\n source: MftRoute[\"source\"];\n destination: MftRoute[\"destination\"];\n}\n\nfunction buildRoute(input: BuildRouteInput): MftRoute {\n const route: MftRoute = {\n destination: input.destination,\n id: input.id,\n operation: input.operation,\n source: input.source,\n };\n if (input.name !== undefined) route.name = input.name;\n return route;\n}\n\nfunction absolutePath(localPath: string): string {\n return isAbsolute(localPath) ? localPath : resolvePath(localPath);\n}\n\nfunction defaultRouteSuffix(source: string, destination: string): string {\n return `${source}->${destination}`;\n}\n","/**\n * Token-bucket bandwidth throttle for transfer streams.\n *\n * @module transfers/BandwidthThrottle\n */\nimport { AbortError, ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferBandwidthLimit } from \"./TransferJob\";\n\n/** Sleep helper signature used by {@link createBandwidthThrottle}. */\nexport type BandwidthSleep = (delayMs: number, signal?: AbortSignal) => Promise<void>;\n\n/** Construction overrides for deterministic tests. */\nexport interface BandwidthThrottleOptions {\n /** Monotonic clock returning milliseconds since an arbitrary epoch. Defaults to `Date.now`. */\n now?: () => number;\n /** Sleep implementation honoring an optional abort signal. Defaults to a `setTimeout` helper. */\n sleep?: BandwidthSleep;\n}\n\n/** Token-bucket throttle used to pace transfer chunks. */\nexport interface BandwidthThrottle {\n /** Maximum sustained transfer rate in bytes per second. */\n readonly bytesPerSecond: number;\n /** Burst capacity in bytes available before throttling kicks in. */\n readonly burstBytes: number;\n /**\n * Consumes `bytes` from the bucket, awaiting refill when not enough tokens are available.\n *\n * @param bytes - Non-negative byte count being released by the throttle.\n * @param signal - Optional abort signal that interrupts pending waits.\n * @throws {@link AbortError} When the signal is aborted while waiting.\n */\n consume(bytes: number, signal?: AbortSignal): Promise<void>;\n}\n\n/**\n * Creates a token-bucket throttle that paces an asynchronous data pipeline to\n * a sustained {@link TransferBandwidthLimit}.\n *\n * Returns `undefined` when no limit is supplied so callers can omit throttling\n * without conditional branches at the call site.\n *\n * @param limit - Optional throughput limit. Returns `undefined` when omitted.\n * @param options - Optional clock/sleep overrides for deterministic tests.\n * @returns Throttle implementation when a limit is supplied, otherwise `undefined`.\n * @throws {@link ConfigurationError} When the supplied limit shape is invalid.\n */\nexport function createBandwidthThrottle(\n limit: TransferBandwidthLimit | undefined,\n options: BandwidthThrottleOptions = {},\n): BandwidthThrottle | undefined {\n if (limit === undefined) return undefined;\n\n const bytesPerSecond = normalizeRate(limit.bytesPerSecond);\n const burstBytes = normalizeBurst(limit.burstBytes, bytesPerSecond);\n const now = options.now ?? Date.now;\n const sleep = options.sleep ?? defaultSleep;\n\n let tokens = burstBytes;\n let lastRefillAt = now();\n\n function refill(): void {\n const current = now();\n const elapsedMs = Math.max(0, current - lastRefillAt);\n\n if (elapsedMs > 0) {\n tokens = Math.min(burstBytes, tokens + (elapsedMs / 1000) * bytesPerSecond);\n lastRefillAt = current;\n }\n }\n\n async function consume(bytes: number, signal?: AbortSignal): Promise<void> {\n if (!Number.isFinite(bytes) || bytes < 0) {\n throw new ConfigurationError({\n details: { bytes },\n message: \"Bandwidth throttle byte count must be a non-negative number\",\n retryable: false,\n });\n }\n\n if (bytes === 0) return;\n\n let remaining = bytes;\n\n while (remaining > 0) {\n throwIfAborted(signal);\n refill();\n\n if (tokens >= remaining) {\n tokens -= remaining;\n return;\n }\n\n if (tokens >= burstBytes) {\n // Bucket is full but the request still exceeds the burst. Drain the\n // full bucket and wait for the remainder at the sustained rate.\n const drained = tokens;\n tokens = 0;\n remaining -= drained;\n const waitMs = Math.ceil((Math.min(remaining, burstBytes) / bytesPerSecond) * 1000);\n await sleep(waitMs, signal);\n continue;\n }\n\n const deficit = Math.min(remaining, burstBytes) - tokens;\n const waitMs = Math.max(1, Math.ceil((deficit / bytesPerSecond) * 1000));\n await sleep(waitMs, signal);\n }\n }\n\n return { burstBytes, bytesPerSecond, consume };\n}\n\n/**\n * Wraps an async iterable of byte chunks so each chunk is released only after\n * the throttle has admitted its byte count.\n *\n * When `throttle` is `undefined`, the source iterable is returned unchanged.\n *\n * @param source - Async iterable that produces byte chunks.\n * @param throttle - Optional throttle that paces chunk emission.\n * @param signal - Optional abort signal interrupting pending waits.\n * @returns Async generator emitting the original chunks at the throttled rate.\n */\nexport function throttleByteIterable(\n source: AsyncIterable<Uint8Array>,\n throttle: BandwidthThrottle | undefined,\n signal?: AbortSignal,\n): AsyncIterable<Uint8Array> {\n if (throttle === undefined) return source;\n\n return {\n [Symbol.asyncIterator]: async function* () {\n for await (const chunk of source) {\n throwIfAborted(signal);\n if (chunk.byteLength > 0) {\n await throttle.consume(chunk.byteLength, signal);\n }\n yield chunk;\n }\n },\n };\n}\n\nfunction normalizeRate(value: number): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw new ConfigurationError({\n details: { bytesPerSecond: value },\n message: \"Bandwidth limit bytesPerSecond must be a positive number\",\n retryable: false,\n });\n }\n\n return value;\n}\n\nfunction normalizeBurst(value: number | undefined, bytesPerSecond: number): number {\n if (value === undefined) return bytesPerSecond;\n\n if (!Number.isFinite(value) || value <= 0) {\n throw new ConfigurationError({\n details: { burstBytes: value },\n message: \"Bandwidth limit burstBytes must be a positive number when provided\",\n retryable: false,\n });\n }\n\n return value;\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw new AbortError({\n message: \"Bandwidth throttle wait aborted\",\n retryable: false,\n });\n }\n}\n\nfunction defaultSleep(delayMs: number, signal?: AbortSignal): Promise<void> {\n if (delayMs <= 0) return Promise.resolve();\n\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, delayMs);\n\n const onAbort = () => {\n cleanup();\n reject(\n new AbortError({\n message: \"Bandwidth throttle wait aborted\",\n retryable: false,\n }),\n );\n };\n\n function cleanup(): void {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onAbort);\n }\n\n if (signal !== undefined) {\n if (signal.aborted) {\n onAbort();\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n","/**\n * Transfer executor bridge for provider-backed read/write sessions.\n *\n * @module transfers/createProviderTransferExecutor\n */\nimport type { TransferSession } from \"../core/TransferSession\";\nimport { ConfigurationError, UnsupportedFeatureError } from \"../errors/ZeroTransferError\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../providers/ProviderTransferOperations\";\nimport {\n createBandwidthThrottle,\n throttleByteIterable,\n type BandwidthThrottleOptions,\n} from \"./BandwidthThrottle\";\nimport type { TransferExecutionContext, TransferExecutor } from \"./TransferEngine\";\nimport type {\n TransferEndpoint,\n TransferExecutionResult,\n TransferJob,\n TransferOperation,\n TransferVerificationResult,\n} from \"./TransferJob\";\n\n/** Endpoint role used while resolving provider sessions for a transfer job. */\nexport type ProviderTransferEndpointRole = \"source\" | \"destination\";\n\n/** Input passed to provider transfer session resolvers. */\nexport interface ProviderTransferSessionResolverInput {\n /** Endpoint being resolved. */\n endpoint: TransferEndpoint;\n /** Whether the endpoint is the source or destination side of the transfer. */\n role: ProviderTransferEndpointRole;\n /** Job currently being executed. */\n job: TransferJob;\n}\n\n/** Resolves the connected provider session that owns an endpoint. */\nexport type ProviderTransferSessionResolver = (\n input: ProviderTransferSessionResolverInput,\n) => TransferSession | undefined;\n\n/** Options for {@link createProviderTransferExecutor}. */\nexport interface ProviderTransferExecutorOptions {\n /** Resolves connected provider sessions for source and destination endpoints. */\n resolveSession: ProviderTransferSessionResolver;\n /** Optional clock/sleep overrides for the bandwidth throttle. */\n throttle?: BandwidthThrottleOptions;\n}\n\n/**\n * Creates a {@link TransferExecutor} that reads from a source provider and writes to a destination provider.\n *\n * The returned executor supports single-object `upload`, `download`, and `copy` jobs. Provider sessions must\n * expose `session.transfers.read()` and `session.transfers.write()`; concrete providers remain responsible for\n * the actual streaming implementation.\n *\n * @param options - Session resolver used for source and destination endpoints.\n * @returns Transfer executor suitable for {@link TransferEngine.execute} or {@link TransferQueue}.\n */\nexport function createProviderTransferExecutor(\n options: ProviderTransferExecutorOptions,\n): TransferExecutor {\n return async (context) => {\n const { job } = context;\n\n if (!isReadWriteOperation(job.operation)) {\n throw new UnsupportedFeatureError({\n details: { jobId: job.id, operation: job.operation },\n message: `Provider read/write executor does not support transfer operation: ${job.operation}`,\n retryable: false,\n });\n }\n\n const source = requireEndpoint(job, \"source\");\n const destination = requireEndpoint(job, \"destination\");\n const sourceSession = options.resolveSession({ endpoint: source, job, role: \"source\" });\n const destinationSession = options.resolveSession({\n endpoint: destination,\n job,\n role: \"destination\",\n });\n const sourceTransfers = requireTransferOperations(sourceSession, source, \"source\", job);\n const destinationTransfers = requireTransferOperations(\n destinationSession,\n destination,\n \"destination\",\n job,\n );\n\n context.throwIfAborted();\n const readResult = await sourceTransfers.read(createReadRequest(context, source));\n context.throwIfAborted();\n const throttledReadResult = applyBandwidthThrottle(readResult, context, options.throttle);\n const writeResult = await destinationTransfers.write(\n createWriteRequest(context, destination, throttledReadResult),\n );\n\n return mergeProviderTransferResult(readResult, writeResult, job);\n };\n}\n\nfunction applyBandwidthThrottle(\n readResult: ProviderTransferReadResult,\n context: TransferExecutionContext,\n options: BandwidthThrottleOptions | undefined,\n): ProviderTransferReadResult {\n const throttle = createBandwidthThrottle(context.bandwidthLimit, options);\n\n if (throttle === undefined) return readResult;\n\n return {\n ...readResult,\n content: throttleByteIterable(readResult.content, throttle, context.signal),\n };\n}\n\nfunction isReadWriteOperation(operation: TransferOperation): boolean {\n return operation === \"copy\" || operation === \"download\" || operation === \"upload\";\n}\n\nfunction requireEndpoint(job: TransferJob, role: ProviderTransferEndpointRole): TransferEndpoint {\n const endpoint = role === \"source\" ? job.source : job.destination;\n\n if (endpoint === undefined) {\n throw new ConfigurationError({\n details: { jobId: job.id, operation: job.operation, role },\n message: `Transfer job requires a ${role} endpoint: ${job.id}`,\n retryable: false,\n });\n }\n\n return endpoint;\n}\n\nfunction requireTransferOperations(\n session: TransferSession | undefined,\n endpoint: TransferEndpoint,\n role: ProviderTransferEndpointRole,\n job: TransferJob,\n): ProviderTransferOperations {\n if (session === undefined) {\n throw new UnsupportedFeatureError({\n details: { endpoint: cloneEndpoint(endpoint), jobId: job.id, operation: job.operation, role },\n message: `No provider session resolved for ${role} endpoint: ${endpoint.path}`,\n retryable: false,\n });\n }\n\n if (session.transfers === undefined) {\n throw new UnsupportedFeatureError({\n details: {\n endpoint: cloneEndpoint(endpoint),\n jobId: job.id,\n operation: job.operation,\n provider: session.provider,\n role,\n },\n message: `Provider session does not expose transfer operations: ${session.provider}`,\n retryable: false,\n });\n }\n\n return session.transfers;\n}\n\nfunction createReadRequest(\n context: TransferExecutionContext,\n endpoint: TransferEndpoint,\n): ProviderTransferReadRequest {\n const request: ProviderTransferReadRequest = {\n attempt: context.attempt,\n endpoint: cloneEndpoint(endpoint),\n job: context.job,\n reportProgress: (bytesTransferred, totalBytes) =>\n context.reportProgress(bytesTransferred, totalBytes),\n throwIfAborted: () => context.throwIfAborted(),\n };\n\n if (context.signal !== undefined) request.signal = context.signal;\n if (context.bandwidthLimit !== undefined) {\n request.bandwidthLimit = { ...context.bandwidthLimit };\n }\n\n return request;\n}\n\nfunction createWriteRequest(\n context: TransferExecutionContext,\n endpoint: TransferEndpoint,\n readResult: ProviderTransferReadResult,\n): ProviderTransferWriteRequest {\n const request: ProviderTransferWriteRequest = {\n attempt: context.attempt,\n content: readResult.content,\n endpoint: cloneEndpoint(endpoint),\n job: context.job,\n reportProgress: (bytesTransferred, totalBytes) =>\n context.reportProgress(bytesTransferred, totalBytes),\n throwIfAborted: () => context.throwIfAborted(),\n };\n const totalBytes = readResult.totalBytes ?? context.job.totalBytes;\n\n if (context.signal !== undefined) request.signal = context.signal;\n if (context.bandwidthLimit !== undefined) {\n request.bandwidthLimit = { ...context.bandwidthLimit };\n }\n if (totalBytes !== undefined) request.totalBytes = totalBytes;\n if (context.job.resumed === true) request.offset = readResult.bytesRead ?? 0;\n if (readResult.verification !== undefined) {\n request.verification = cloneVerification(readResult.verification);\n }\n\n return request;\n}\n\nfunction mergeProviderTransferResult(\n readResult: ProviderTransferReadResult,\n writeResult: ProviderTransferWriteResult,\n job: TransferJob,\n): TransferExecutionResult {\n const result: TransferExecutionResult = {\n bytesTransferred: writeResult.bytesTransferred,\n };\n const totalBytes = writeResult.totalBytes ?? readResult.totalBytes ?? job.totalBytes;\n const warnings = [...(readResult.warnings ?? []), ...(writeResult.warnings ?? [])];\n\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (writeResult.resumed !== undefined) result.resumed = writeResult.resumed;\n if (writeResult.verified !== undefined) result.verified = writeResult.verified;\n if (writeResult.checksum !== undefined) result.checksum = writeResult.checksum;\n else if (readResult.checksum !== undefined) result.checksum = readResult.checksum;\n if (writeResult.verification !== undefined) {\n result.verification = cloneVerification(writeResult.verification);\n } else if (readResult.verification !== undefined) {\n result.verification = cloneVerification(readResult.verification);\n }\n if (warnings.length > 0) result.warnings = warnings;\n\n return result;\n}\n\nfunction cloneEndpoint(endpoint: TransferEndpoint): TransferEndpoint {\n const clone: TransferEndpoint = { path: endpoint.path };\n\n if (endpoint.provider !== undefined) clone.provider = endpoint.provider;\n\n return clone;\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n","/**\n * Transfer result and progress calculation helpers.\n *\n * These helpers are pure functions so future FTP, FTPS, and SFTP adapters can share\n * timing, throughput, and progress calculations without coupling to transport code.\n *\n * @module services/TransferService\n */\nimport type { TransferProgressEvent, TransferResult } from \"../types/public\";\n\n/**\n * Input used to create a final transfer result.\n */\nexport interface TransferResultInput {\n /** Local or remote source path when known. */\n sourcePath?: string;\n /** Local or remote destination path for the transfer. */\n destinationPath: string;\n /** Total bytes transferred. */\n bytesTransferred: number;\n /** Time the transfer began. */\n startedAt: Date;\n /** Time the transfer completed. */\n completedAt: Date;\n /** Whether the transfer resumed from an earlier partial state. */\n resumed?: boolean;\n /** Whether post-transfer verification succeeded. */\n verified?: boolean;\n /** Optional checksum value produced or verified by the transfer. */\n checksum?: string;\n}\n\n/**\n * Input used to create a transfer progress event.\n */\nexport interface ProgressEventInput {\n /** Stable transfer identifier for correlation. */\n transferId: string;\n /** Bytes transferred so far. */\n bytesTransferred: number;\n /** Time the transfer began. */\n startedAt: Date;\n /** Time to use for the progress calculation; defaults to current time. */\n now?: Date;\n /** Total expected bytes when known. */\n totalBytes?: number;\n}\n\n/**\n * Creates a final transfer result with duration and average throughput.\n *\n * @param input - Transfer paths, byte count, timestamps, and optional verification metadata.\n * @returns A normalized transfer result.\n */\nexport function createTransferResult(input: TransferResultInput): TransferResult {\n const durationMs = Math.max(0, input.completedAt.getTime() - input.startedAt.getTime());\n const result: TransferResult = {\n destinationPath: input.destinationPath,\n bytesTransferred: input.bytesTransferred,\n startedAt: input.startedAt,\n completedAt: input.completedAt,\n durationMs,\n averageBytesPerSecond: calculateBytesPerSecond(input.bytesTransferred, durationMs),\n resumed: input.resumed ?? false,\n verified: input.verified ?? false,\n };\n\n if (input.sourcePath !== undefined) result.sourcePath = input.sourcePath;\n if (input.checksum !== undefined) result.checksum = input.checksum;\n\n return result;\n}\n\n/**\n * Creates a progress event with elapsed time, rate, and optional percentage.\n *\n * @param input - Transfer id, byte count, start time, optional current time, and total bytes.\n * @returns A normalized transfer progress event.\n */\nexport function createProgressEvent(input: ProgressEventInput): TransferProgressEvent {\n const now = input.now ?? new Date();\n const elapsedMs = Math.max(0, now.getTime() - input.startedAt.getTime());\n const event: TransferProgressEvent = {\n transferId: input.transferId,\n bytesTransferred: input.bytesTransferred,\n startedAt: input.startedAt,\n elapsedMs,\n bytesPerSecond: calculateBytesPerSecond(input.bytesTransferred, elapsedMs),\n };\n\n if (input.totalBytes !== undefined) {\n event.totalBytes = input.totalBytes;\n event.percent = input.totalBytes > 0 ? (input.bytesTransferred / input.totalBytes) * 100 : 0;\n }\n\n return event;\n}\n\n/**\n * Calculates average throughput for a byte count and duration.\n *\n * @param bytes - Number of bytes transferred.\n * @param durationMs - Transfer duration in milliseconds.\n * @returns Average bytes per second, falling back to bytes for zero-duration samples.\n */\nfunction calculateBytesPerSecond(bytes: number, durationMs: number): number {\n if (durationMs <= 0) {\n return bytes;\n }\n\n return bytes / (durationMs / 1000);\n}\n","/**\n * Abort-aware transfer engine foundation.\n *\n * @module transfers/TransferEngine\n */\nimport {\n AbortError,\n TimeoutError,\n TransferError,\n ZeroTransferError,\n} from \"../errors/ZeroTransferError\";\nimport { createProgressEvent } from \"../services/TransferService\";\nimport type { TransferProgressEvent } from \"../types/public\";\nimport type {\n TransferAttempt,\n TransferAttemptError,\n TransferBandwidthLimit,\n TransferExecutionResult,\n TransferJob,\n TransferReceipt,\n TransferTimeoutPolicy,\n TransferVerificationResult,\n} from \"./TransferJob\";\n\n/** Context passed to a concrete transfer operation. */\nexport interface TransferExecutionContext {\n /** Job being executed. */\n job: TransferJob;\n /** One-based attempt number. */\n attempt: number;\n /** Abort signal active for this execution when supplied. */\n signal?: AbortSignal;\n /** Optional throughput limit shape for concrete executors to honor. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Throws an SDK abort error when the active signal has been cancelled. */\n throwIfAborted(): void;\n /** Emits a normalized progress event through engine options. */\n reportProgress(bytesTransferred: number, totalBytes?: number): TransferProgressEvent;\n}\n\n/** Concrete transfer operation implementation used by the engine. */\nexport type TransferExecutor = (\n context: TransferExecutionContext,\n) => Promise<TransferExecutionResult> | TransferExecutionResult;\n\n/** Input used by retry policy hooks. */\nexport interface TransferRetryDecisionInput {\n /** Error thrown by the failed attempt. */\n error: unknown;\n /** One-based attempt number that failed. */\n attempt: number;\n /** Job being executed. */\n job: TransferJob;\n}\n\n/** Retry policy for transfer execution. */\nexport interface TransferRetryPolicy {\n /** Maximum total attempts, including the first attempt. Defaults to `1`. */\n maxAttempts?: number;\n /** Decides whether a failed attempt should be retried. Defaults to SDK retryability metadata. */\n shouldRetry?(input: TransferRetryDecisionInput): boolean;\n /** Observes retry decisions before the next attempt starts. */\n onRetry?(input: TransferRetryDecisionInput): void;\n}\n\n/** Options used by {@link TransferEngine.execute}. */\nexport interface TransferEngineExecuteOptions {\n /** Abort signal used to cancel the job. */\n signal?: AbortSignal;\n /** Retry policy used for failed attempts. */\n retry?: TransferRetryPolicy;\n /** Progress observer for normalized transfer progress events. */\n onProgress?(event: TransferProgressEvent): void;\n /** Timeout policy enforced by the engine. */\n timeout?: TransferTimeoutPolicy;\n /** Optional throughput limit shape passed through to concrete executors. */\n bandwidthLimit?: TransferBandwidthLimit;\n}\n\n/** Construction options for deterministic tests and host integration. */\nexport interface TransferEngineOptions {\n /** Clock used for receipts and progress events. Defaults to `new Date()`. */\n now?: () => Date;\n}\n\n/** Executes transfer jobs and produces audit-friendly receipts. */\nexport class TransferEngine {\n private readonly now: () => Date;\n\n /**\n * Creates a transfer engine.\n *\n * @param options - Optional clock override for deterministic tests.\n */\n constructor(options: TransferEngineOptions = {}) {\n this.now = options.now ?? (() => new Date());\n }\n\n /**\n * Executes a transfer job through a caller-supplied operation.\n *\n * @param job - Job metadata used for correlation and receipts.\n * @param executor - Concrete transfer operation implementation.\n * @param options - Optional abort, retry, and progress hooks.\n * @returns Receipt for the completed transfer.\n * @throws {@link AbortError} When execution is cancelled.\n * @throws {@link TransferError} When all attempts fail.\n */\n async execute(\n job: TransferJob,\n executor: TransferExecutor,\n options: TransferEngineExecuteOptions = {},\n ): Promise<TransferReceipt> {\n const maxAttempts = normalizeMaxAttempts(options.retry?.maxAttempts);\n const attempts: TransferAttempt[] = [];\n const startedAt = this.now();\n const abortScope = createAbortScope(options.signal, options.timeout, job);\n let latestBytesTransferred = 0;\n\n try {\n for (let attemptNumber = 1; attemptNumber <= maxAttempts; attemptNumber += 1) {\n this.throwIfAborted(abortScope.signal, job);\n\n const attemptStartedAt = this.now();\n const context = this.createExecutionContext(\n job,\n attemptNumber,\n attemptStartedAt,\n options,\n abortScope.signal,\n (bytesTransferred) => {\n latestBytesTransferred = bytesTransferred;\n },\n );\n\n try {\n const result = await runExecutor(executor, context, abortScope.signal, job);\n context.throwIfAborted();\n latestBytesTransferred = result.bytesTransferred;\n\n const completedAt = this.now();\n attempts.push(\n createAttempt(attemptNumber, attemptStartedAt, completedAt, result.bytesTransferred),\n );\n\n return createReceipt(job, result, attempts, startedAt, completedAt);\n } catch (error) {\n const completedAt = this.now();\n const attempt = createAttempt(\n attemptNumber,\n attemptStartedAt,\n completedAt,\n latestBytesTransferred,\n summarizeError(error),\n );\n attempts.push(attempt);\n\n if (error instanceof AbortError || error instanceof TimeoutError) {\n throw error;\n }\n\n const retryInput: TransferRetryDecisionInput = { attempt: attemptNumber, error, job };\n const shouldRetry =\n attemptNumber < maxAttempts &&\n (options.retry?.shouldRetry?.(retryInput) ?? isRetryable(error));\n\n if (shouldRetry) {\n options.retry?.onRetry?.(retryInput);\n continue;\n }\n\n throw createTransferFailure(job, error, attempts);\n }\n }\n\n throw createTransferFailure(job, undefined, attempts);\n } finally {\n abortScope.dispose();\n }\n }\n\n private createExecutionContext(\n job: TransferJob,\n attempt: number,\n startedAt: Date,\n options: TransferEngineExecuteOptions,\n signal: AbortSignal | undefined,\n updateBytesTransferred: (bytesTransferred: number) => void,\n ): TransferExecutionContext {\n const context: TransferExecutionContext = {\n attempt,\n job,\n reportProgress: (bytesTransferred, totalBytes) => {\n this.throwIfAborted(signal, job);\n updateBytesTransferred(bytesTransferred);\n const progressInput = {\n bytesTransferred,\n now: this.now(),\n startedAt,\n transferId: job.id,\n };\n const resolvedTotalBytes = totalBytes ?? job.totalBytes;\n const event = createProgressEvent(\n resolvedTotalBytes === undefined\n ? progressInput\n : { ...progressInput, totalBytes: resolvedTotalBytes },\n );\n options.onProgress?.(event);\n return event;\n },\n throwIfAborted: () => this.throwIfAborted(signal, job),\n };\n\n if (signal !== undefined) {\n context.signal = signal;\n }\n\n if (options.bandwidthLimit !== undefined) {\n context.bandwidthLimit = { ...options.bandwidthLimit };\n }\n\n return context;\n }\n\n private throwIfAborted(signal: AbortSignal | undefined, job: TransferJob): void {\n if (signal?.aborted === true) {\n if (signal.reason instanceof ZeroTransferError) {\n throw signal.reason;\n }\n\n throw new AbortError({\n details: { jobId: job.id, operation: job.operation },\n message: `Transfer job aborted: ${job.id}`,\n retryable: false,\n });\n }\n }\n}\n\ninterface AbortScope {\n signal?: AbortSignal;\n dispose(): void;\n}\n\nfunction createAbortScope(\n parentSignal: AbortSignal | undefined,\n timeout: TransferTimeoutPolicy | undefined,\n job: TransferJob,\n): AbortScope {\n const timeoutMs = normalizeTimeoutMs(timeout?.timeoutMs);\n\n if (parentSignal === undefined && timeoutMs === undefined) {\n return { dispose: () => undefined };\n }\n\n const controller = new AbortController();\n const abortFromParent = (): void => controller.abort(parentSignal?.reason);\n const timeoutHandle =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n controller.abort(\n new TimeoutError({\n details: { jobId: job.id, operation: job.operation, timeoutMs },\n message: `Transfer job timed out after ${timeoutMs}ms: ${job.id}`,\n retryable: timeout?.retryable ?? true,\n }),\n );\n }, timeoutMs);\n\n if (parentSignal?.aborted === true) {\n abortFromParent();\n } else {\n parentSignal?.addEventListener(\"abort\", abortFromParent, { once: true });\n }\n\n return {\n dispose: () => {\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle);\n }\n parentSignal?.removeEventListener(\"abort\", abortFromParent);\n },\n signal: controller.signal,\n };\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number | undefined {\n if (value === undefined || !Number.isFinite(value) || value <= 0) {\n return undefined;\n }\n\n return Math.floor(value);\n}\n\nasync function runExecutor(\n executor: TransferExecutor,\n context: TransferExecutionContext,\n signal: AbortSignal | undefined,\n job: TransferJob,\n): Promise<TransferExecutionResult> {\n if (signal === undefined) {\n return executor(context);\n }\n\n return Promise.race([executor(context), rejectWhenAborted(signal, job)]);\n}\n\nfunction rejectWhenAborted(\n signal: AbortSignal,\n job: TransferJob,\n): Promise<TransferExecutionResult> {\n return new Promise((_, reject) => {\n const rejectAbort = (): void => {\n if (signal.reason instanceof ZeroTransferError) {\n reject(signal.reason);\n return;\n }\n\n reject(\n new AbortError({\n details: { jobId: job.id, operation: job.operation },\n message: `Transfer job aborted: ${job.id}`,\n retryable: false,\n }),\n );\n };\n\n if (signal.aborted) {\n rejectAbort();\n return;\n }\n\n signal.addEventListener(\"abort\", rejectAbort, { once: true });\n });\n}\n\nfunction normalizeMaxAttempts(value: number | undefined): number {\n if (value === undefined) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction createAttempt(\n attempt: number,\n startedAt: Date,\n completedAt: Date,\n bytesTransferred: number,\n error?: TransferAttemptError,\n): TransferAttempt {\n const result: TransferAttempt = {\n attempt,\n bytesTransferred,\n completedAt,\n durationMs: Math.max(0, completedAt.getTime() - startedAt.getTime()),\n startedAt,\n };\n\n if (error !== undefined) {\n result.error = error;\n }\n\n return result;\n}\n\nfunction createReceipt(\n job: TransferJob,\n result: TransferExecutionResult,\n attempts: TransferAttempt[],\n startedAt: Date,\n completedAt: Date,\n): TransferReceipt {\n const durationMs = Math.max(0, completedAt.getTime() - startedAt.getTime());\n const verification = normalizeVerificationResult(result);\n const receipt: TransferReceipt = {\n attempts,\n averageBytesPerSecond: calculateBytesPerSecond(result.bytesTransferred, durationMs),\n bytesTransferred: result.bytesTransferred,\n completedAt,\n durationMs,\n jobId: job.id,\n operation: job.operation,\n resumed: result.resumed ?? job.resumed ?? false,\n startedAt,\n transferId: job.id,\n verified: verification?.verified ?? result.verified ?? false,\n warnings: [...(result.warnings ?? [])],\n };\n\n if (job.source !== undefined) receipt.source = { ...job.source };\n if (job.destination !== undefined) receipt.destination = { ...job.destination };\n if (result.totalBytes !== undefined) receipt.totalBytes = result.totalBytes;\n else if (job.totalBytes !== undefined) receipt.totalBytes = job.totalBytes;\n if (result.checksum !== undefined) receipt.checksum = result.checksum;\n else if (verification?.checksum !== undefined) receipt.checksum = verification.checksum;\n if (verification !== undefined) receipt.verification = verification;\n if (job.metadata !== undefined) receipt.metadata = { ...job.metadata };\n\n return receipt;\n}\n\nfunction normalizeVerificationResult(\n result: TransferExecutionResult,\n): TransferVerificationResult | undefined {\n const verification = result.verification;\n\n if (verification !== undefined) {\n const normalized: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) normalized.method = verification.method;\n if (verification.checksum !== undefined) normalized.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n normalized.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined)\n normalized.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) normalized.details = { ...verification.details };\n\n return normalized;\n }\n\n if (result.verified === undefined && result.checksum === undefined) {\n return undefined;\n }\n\n const normalized: TransferVerificationResult = { verified: result.verified ?? false };\n\n if (result.checksum !== undefined) {\n normalized.checksum = result.checksum;\n }\n\n return normalized;\n}\n\nfunction createTransferFailure(\n job: TransferJob,\n error: unknown,\n attempts: TransferAttempt[],\n): TransferError {\n return new TransferError({\n cause: error,\n details: {\n attempts,\n jobId: job.id,\n operation: job.operation,\n },\n message: `Transfer job failed: ${job.id}`,\n retryable: isRetryable(error),\n });\n}\n\nfunction summarizeError(error: unknown): TransferAttemptError {\n if (error instanceof ZeroTransferError) {\n return {\n code: error.code,\n message: error.message,\n name: error.name,\n retryable: error.retryable,\n };\n }\n\n if (error instanceof Error) {\n return {\n message: error.message,\n name: error.name,\n };\n }\n\n return {\n message: String(error),\n name: \"Error\",\n };\n}\n\nfunction isRetryable(error: unknown): boolean {\n return error instanceof ZeroTransferError && error.retryable;\n}\n\nfunction calculateBytesPerSecond(bytes: number, durationMs: number): number {\n if (durationMs <= 0) {\n return bytes;\n }\n\n return bytes / (durationMs / 1000);\n}\n","/**\n * Route executor that dispatches a single transfer through {@link TransferEngine}.\n *\n * `runRoute` opens both endpoints through the supplied {@link TransferClient},\n * builds a {@link TransferJob} with route correlation metadata, and runs the\n * provider read/write executor under retry, abort, progress, timeout, and\n * bandwidth-limit hooks. Sessions are released in `finally` blocks even when\n * the transfer fails, throws, or is aborted.\n *\n * @module mft/runRoute\n */\nimport type { TransferClient } from \"../core/TransferClient\";\nimport type { TransferSession } from \"../core/TransferSession\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferProgressEvent } from \"../types/public\";\nimport { createProviderTransferExecutor } from \"../transfers/createProviderTransferExecutor\";\nimport { TransferEngine } from \"../transfers/TransferEngine\";\nimport type {\n TransferEngineExecuteOptions,\n TransferRetryPolicy,\n} from \"../transfers/TransferEngine\";\nimport type {\n TransferBandwidthLimit,\n TransferEndpoint,\n TransferJob,\n TransferReceipt,\n TransferTimeoutPolicy,\n} from \"../transfers/TransferJob\";\nimport type { MftRoute } from \"./MftRoute\";\n\n/** Options accepted by {@link runRoute}. */\nexport interface RunRouteOptions {\n /** Transfer client whose registry can resolve both endpoint providers. */\n client: TransferClient;\n /** Route to execute. */\n route: MftRoute;\n /** Optional transfer engine override. A fresh engine is created when omitted. */\n engine?: TransferEngine;\n /** Optional explicit job id. Defaults to a deterministic route-derived id. */\n jobId?: string;\n /** Optional clock used to derive the default job id. Defaults to `Date.now`. */\n now?: () => Date;\n /** Abort signal used to cancel the route execution. */\n signal?: AbortSignal;\n /** Retry policy forwarded to the engine. */\n retry?: TransferRetryPolicy;\n /** Progress observer forwarded to the engine. */\n onProgress?: (event: TransferProgressEvent) => void;\n /** Timeout policy forwarded to the engine. */\n timeout?: TransferTimeoutPolicy;\n /** Optional bandwidth limit forwarded to the engine. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Caller-defined metadata merged into the resulting transfer job. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Executes an MFT route as a single transfer through the supplied client.\n *\n * @param options - Client, route, and optional engine/abort/retry hooks.\n * @returns Receipt produced by the underlying transfer engine.\n * @throws {@link ConfigurationError} When the route is disabled.\n */\nexport async function runRoute(options: RunRouteOptions): Promise<TransferReceipt> {\n const { client, route } = options;\n\n if (route.enabled === false) {\n throw new ConfigurationError({\n details: { routeId: route.id },\n message: `MFT route \"${route.id}\" is disabled`,\n retryable: false,\n });\n }\n\n const sourceSession = await client.connect(route.source.profile);\n\n let destinationSession: TransferSession | undefined;\n try {\n destinationSession = await client.connect(route.destination.profile);\n const engine = options.engine ?? new TransferEngine();\n const job = createRouteJob(route, sourceSession, destinationSession, options);\n const sessions = new Map<string, TransferSession>([\n [\"source\", sourceSession],\n [\"destination\", destinationSession],\n ]);\n const executor = createProviderTransferExecutor({\n resolveSession: ({ role }) => sessions.get(role),\n });\n\n return await engine.execute(job, executor, buildExecuteOptions(options));\n } finally {\n if (destinationSession !== undefined) {\n await destinationSession.disconnect();\n }\n await sourceSession.disconnect();\n }\n}\n\nfunction createRouteJob(\n route: MftRoute,\n sourceSession: TransferSession,\n destinationSession: TransferSession,\n options: RunRouteOptions,\n): TransferJob {\n const operation = route.operation ?? \"copy\";\n const source: TransferEndpoint = {\n path: route.source.path,\n provider: sourceSession.provider,\n };\n const destination: TransferEndpoint = {\n path: route.destination.path,\n provider: destinationSession.provider,\n };\n\n const baseMetadata: Record<string, unknown> = { routeId: route.id };\n if (route.name !== undefined) baseMetadata[\"routeName\"] = route.name;\n if (route.metadata !== undefined) Object.assign(baseMetadata, route.metadata);\n if (options.metadata !== undefined) Object.assign(baseMetadata, options.metadata);\n\n const job: TransferJob = {\n destination,\n id: options.jobId ?? defaultJobId(route, options.now),\n operation,\n source,\n };\n\n if (Object.keys(baseMetadata).length > 0) {\n job.metadata = baseMetadata;\n }\n\n return job;\n}\n\nfunction defaultJobId(route: MftRoute, now: (() => Date) | undefined): string {\n const timestamp = (now?.() ?? new Date()).getTime();\n return `route:${route.id}:${timestamp.toString(36)}`;\n}\n\nfunction buildExecuteOptions(options: RunRouteOptions): TransferEngineExecuteOptions {\n const execute: TransferEngineExecuteOptions = {};\n if (options.signal !== undefined) execute.signal = options.signal;\n if (options.retry !== undefined) execute.retry = options.retry;\n if (options.onProgress !== undefined) execute.onProgress = options.onProgress;\n if (options.timeout !== undefined) execute.timeout = options.timeout;\n if (options.bandwidthLimit !== undefined) execute.bandwidthLimit = options.bandwidthLimit;\n return execute;\n}\n","/**\n * Secret redaction helpers for logs, events, and diagnostics.\n *\n * These functions focus on preserving useful operational context while removing\n * credentials and command payloads that should not appear in logs.\n *\n * @module logging/redaction\n */\n/** Placeholder used when sensitive content has been removed. */\nexport const REDACTED = \"[REDACTED]\";\n\nconst SENSITIVE_KEY_PATTERN = /(?:password|passphrase|privatekey|token|secret|username|user)$/i;\nconst SECRET_COMMAND_PATTERN = /^(PASS|USER|ACCT)\\s+(.+)$/i;\n\n/**\n * Checks whether an object key is likely to contain sensitive data.\n *\n * @param key - Object key to inspect.\n * @returns `true` when the key name should be redacted.\n */\nexport function isSensitiveKey(key: string): boolean {\n return SENSITIVE_KEY_PATTERN.test(key.replace(/[_-]/g, \"\"));\n}\n\n/**\n * Redacts sensitive FTP command payloads while preserving the command name.\n *\n * @param command - Raw command text such as `PASS secret` or `USER deploy`.\n * @returns Command text with secret arguments replaced by {@link REDACTED}.\n */\nexport function redactCommand(command: string): string {\n return command.replace(SECRET_COMMAND_PATTERN, (_fullMatch, commandName: string) => {\n return `${commandName.toUpperCase()} ${REDACTED}`;\n });\n}\n\n/**\n * Recursively redacts strings, arrays, and plain object values.\n *\n * @param value - Arbitrary value to sanitize for diagnostics.\n * @returns A redacted copy for arrays and objects, or the original primitive value.\n */\nexport function redactValue(value: unknown): unknown {\n if (typeof value === \"string\") {\n return redactCommand(value);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => redactValue(item));\n }\n\n if (value !== null && typeof value === \"object\") {\n return redactObject(value as Record<string, unknown>);\n }\n\n return value;\n}\n\n/**\n * Redacts sensitive keys and nested values in a plain object.\n *\n * @param input - Object containing diagnostic fields.\n * @returns A shallow object copy with sensitive fields and nested secrets redacted.\n */\nexport function redactObject(input: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(input).map(([key, value]) => {\n if (isSensitiveKey(key)) {\n return [key, REDACTED];\n }\n\n return [key, redactValue(value)];\n }),\n );\n}\n","/**\n * Secret source contracts and resolution helpers for connection profiles.\n *\n * @module profiles/SecretSource\n */\nimport { Buffer } from \"node:buffer\";\nimport { readFile } from \"node:fs/promises\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport { REDACTED } from \"../logging/redaction\";\n\n/** Resolved secret value accepted by profile credential fields. */\nexport type SecretValue = string | Buffer;\n\n/** Callback source used by applications to integrate vaults or credential brokers. */\nexport type SecretProvider = () => SecretValue | Promise<SecretValue>;\n\n/** Inline secret descriptor. Prefer env, path, or callback sources for real applications. */\nexport interface ValueSecretSource {\n /** Inline secret value. */\n value: SecretValue;\n}\n\n/** Environment variable descriptor for text secrets. */\nexport interface EnvSecretSource {\n /** Environment variable containing the secret. */\n env: string;\n}\n\n/** Environment variable descriptor for base64-encoded binary secrets. */\nexport interface Base64EnvSecretSource {\n /** Environment variable containing a base64-encoded secret. */\n base64Env: string;\n}\n\n/** File-backed secret descriptor. */\nexport interface FileSecretSource {\n /** Path to the file containing the secret. */\n path: string;\n /** Text encoding to use, or `buffer` to return raw bytes. Defaults to `utf8`. */\n encoding?: BufferEncoding | \"buffer\";\n}\n\n/** Secret source accepted by profile credential fields. */\nexport type SecretSource =\n | SecretValue\n | SecretProvider\n | ValueSecretSource\n | EnvSecretSource\n | Base64EnvSecretSource\n | FileSecretSource;\n\n/** Injectable dependencies used by tests or host applications during secret resolution. */\nexport interface ResolveSecretOptions {\n /** Environment source. Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n /** File reader. Defaults to `fs.promises.readFile`. */\n readFile?: (path: string) => Promise<Buffer> | Buffer;\n}\n\n/**\n * Resolves a secret source into a string or Buffer without logging the value.\n *\n * @param source - Secret source to resolve.\n * @param options - Optional env and file-reader overrides.\n * @returns Resolved secret value.\n * @throws {@link ConfigurationError} When a descriptor is invalid or unavailable.\n */\nexport async function resolveSecret(\n source: SecretSource,\n options: ResolveSecretOptions = {},\n): Promise<SecretValue> {\n if (isSecretValue(source)) {\n return cloneSecretValue(source);\n }\n\n if (typeof source === \"function\") {\n return cloneSecretValue(await source());\n }\n\n if (isValueSecretSource(source)) {\n return cloneSecretValue(source.value);\n }\n\n if (isEnvSecretSource(source)) {\n const value = (options.env ?? process.env)[source.env];\n\n if (value === undefined) {\n throw createSecretConfigurationError(\n \"Secret environment variable is not set\",\n \"env\",\n source.env,\n );\n }\n\n return value;\n }\n\n if (isBase64EnvSecretSource(source)) {\n const value = (options.env ?? process.env)[source.base64Env];\n\n if (value === undefined) {\n throw createSecretConfigurationError(\n \"Secret environment variable is not set\",\n \"base64Env\",\n source.base64Env,\n );\n }\n\n return Buffer.from(value, \"base64\");\n }\n\n if (isFileSecretSource(source)) {\n const fileReader = options.readFile ?? readFile;\n const value = await fileReader(source.path);\n\n if (source.encoding === \"buffer\") {\n return Buffer.from(value);\n }\n\n return value.toString(source.encoding ?? \"utf8\");\n }\n\n throw createSecretConfigurationError(\"Unsupported secret source\", \"source\", \"unknown\");\n}\n\n/**\n * Redacts a secret source or resolved secret for safe diagnostics.\n *\n * @param source - Secret source or resolved value to sanitize.\n * @returns Redacted placeholder or descriptor shape.\n */\nexport function redactSecretSource(source: SecretSource | SecretValue): unknown {\n if (isSecretValue(source) || typeof source === \"function\") {\n return REDACTED;\n }\n\n if (isValueSecretSource(source)) return { value: REDACTED };\n if (isEnvSecretSource(source)) return { env: REDACTED };\n if (isBase64EnvSecretSource(source)) return { base64Env: REDACTED };\n if (isFileSecretSource(source)) return { encoding: source.encoding, path: REDACTED };\n\n return REDACTED;\n}\n\nfunction isSecretValue(value: unknown): value is SecretValue {\n return typeof value === \"string\" || Buffer.isBuffer(value);\n}\n\nfunction isValueSecretSource(value: unknown): value is ValueSecretSource {\n return isRecord(value) && \"value\" in value && isSecretValue(value.value);\n}\n\nfunction isEnvSecretSource(value: unknown): value is EnvSecretSource {\n return isRecord(value) && typeof value.env === \"string\";\n}\n\nfunction isBase64EnvSecretSource(value: unknown): value is Base64EnvSecretSource {\n return isRecord(value) && typeof value.base64Env === \"string\";\n}\n\nfunction isFileSecretSource(value: unknown): value is FileSecretSource {\n return isRecord(value) && typeof value.path === \"string\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction cloneSecretValue(value: SecretValue): SecretValue {\n return Buffer.isBuffer(value) ? Buffer.from(value) : value;\n}\n\nfunction createSecretConfigurationError(\n message: string,\n sourceType: string,\n sourceName: string,\n): ConfigurationError {\n return new ConfigurationError({\n details: { sourceName, sourceType },\n message,\n retryable: false,\n });\n}\n","/**\n * Connection profile redaction helpers.\n *\n * @module profiles/ProfileRedactor\n */\nimport type { ConnectionProfile, SshProfile, TlsProfile, TlsSecretSource } from \"../types/public\";\nimport { REDACTED, redactObject } from \"../logging/redaction\";\nimport { redactSecretSource } from \"./SecretSource\";\n\n/**\n * Produces a diagnostics-safe profile copy with credentials and runtime hooks redacted.\n *\n * @param profile - Connection profile to sanitize.\n * @returns Plain object safe to include in logs, traces, or validation reports.\n */\nexport function redactConnectionProfile(profile: ConnectionProfile): Record<string, unknown> {\n const { logger, password, signal, ssh, tls, username, ...rest } = profile;\n const redacted = redactObject(rest);\n\n if (username !== undefined) redacted.username = redactSecretSource(username);\n if (password !== undefined) redacted.password = redactSecretSource(password);\n if (ssh !== undefined) redacted.ssh = redactSshProfile(ssh);\n if (tls !== undefined) redacted.tls = redactTlsProfile(tls);\n if (signal !== undefined) redacted.signal = \"[AbortSignal]\";\n if (logger !== undefined) redacted.logger = REDACTED;\n\n return redacted;\n}\n\n/**\n * Redacts SSH private-key profile fields while preserving non-sensitive policy settings.\n *\n * @param profile - SSH profile to sanitize.\n * @returns Plain object safe to include in diagnostics.\n */\nfunction redactSshProfile(profile: SshProfile): Record<string, unknown> {\n const { agent, keyboardInteractive, knownHosts, passphrase, privateKey, socketFactory, ...rest } =\n profile;\n const redacted = redactObject(rest);\n\n if (agent !== undefined) redacted.agent = REDACTED;\n if (privateKey !== undefined) redacted.privateKey = redactSecretSource(privateKey);\n if (passphrase !== undefined) redacted.passphrase = redactSecretSource(passphrase);\n if (knownHosts !== undefined) redacted.knownHosts = redactSshKnownHostsSource(knownHosts);\n if (keyboardInteractive !== undefined) redacted.keyboardInteractive = REDACTED;\n if (socketFactory !== undefined) redacted.socketFactory = REDACTED;\n\n return redacted;\n}\n\n/**\n * Redacts an SSH known_hosts source, preserving array shape for diagnostics.\n *\n * @param source - Single known_hosts source or ordered source array.\n * @returns Redacted source descriptor.\n */\nfunction redactSshKnownHostsSource(source: NonNullable<SshProfile[\"knownHosts\"]>): unknown {\n if (Array.isArray(source)) {\n return source.map((item) => redactSecretSource(item));\n }\n\n return redactSecretSource(source);\n}\n\n/**\n * Redacts certificate-bearing TLS profile fields while preserving non-sensitive policy settings.\n *\n * @param profile - TLS profile to sanitize.\n * @returns Plain object safe to include in diagnostics.\n */\nfunction redactTlsProfile(profile: TlsProfile): Record<string, unknown> {\n const { ca, cert, checkServerIdentity, key, passphrase, pfx, ...rest } = profile;\n const redacted = redactObject(rest);\n\n if (ca !== undefined) redacted.ca = redactTlsSecretSource(ca);\n if (cert !== undefined) redacted.cert = redactSecretSource(cert);\n if (key !== undefined) redacted.key = redactSecretSource(key);\n if (passphrase !== undefined) redacted.passphrase = redactSecretSource(passphrase);\n if (pfx !== undefined) redacted.pfx = redactSecretSource(pfx);\n if (checkServerIdentity !== undefined) redacted.checkServerIdentity = REDACTED;\n\n return redacted;\n}\n\n/**\n * Redacts a TLS material source, preserving array shape for CA bundle diagnostics.\n *\n * @param source - Single secret source or ordered source array.\n * @returns Redacted source descriptor.\n */\nfunction redactTlsSecretSource(source: TlsSecretSource): unknown {\n if (Array.isArray(source)) {\n return source.map((item) => redactSecretSource(item));\n }\n\n return redactSecretSource(source);\n}\n","/**\n * Diagnostics helpers for inspecting a {@link TransferClient} and probing connection profiles.\n *\n * These helpers are intentionally side-effect-light: they exercise an existing client without\n * mutating registry state and never log secret material. Use them to render setup screens,\n * collect bug-report payloads, or verify a profile after an importer run.\n *\n * @module diagnostics\n */\nimport type { TransferClient } from \"../core/TransferClient\";\nimport type { CapabilitySet } from \"../core/CapabilitySet\";\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { redactConnectionProfile } from \"../profiles/ProfileRedactor\";\nimport type { ConnectionProfile, RemoteEntry } from \"../types/public\";\n\n/** Snapshot of the providers registered with a client. */\nexport interface ClientDiagnostics {\n /** Providers currently registered, keyed by id. */\n providers: ReadonlyArray<{ id: ProviderId; capabilities: CapabilitySet }>;\n}\n\n/**\n * Returns a redaction-safe snapshot of the providers registered with a client.\n *\n * @param client - Transfer client to inspect.\n * @returns Provider id and capability snapshot tuples.\n */\nexport function summarizeClientDiagnostics(client: TransferClient): ClientDiagnostics {\n const capabilities = client.getCapabilities();\n return {\n providers: capabilities.map((entry) => ({ capabilities: entry, id: entry.provider })),\n };\n}\n\n/** Per-step duration measurements collected by {@link runConnectionDiagnostics}. */\nexport interface ConnectionDiagnosticTimings {\n /** Total time spent inside `client.connect`. */\n connectMs?: number;\n /** Time spent inside the optional `fs.list` probe. */\n listMs?: number;\n /** Time spent inside the optional `session.disconnect`. */\n disconnectMs?: number;\n}\n\n/** Result returned by {@link runConnectionDiagnostics}. */\nexport interface ConnectionDiagnosticsResult {\n /** Resolved provider id used to open the session. */\n provider?: ProviderId;\n /** Profile host (after redaction). */\n host: string;\n /** Capability snapshot reported by the connected session. */\n capabilities?: CapabilitySet;\n /** Redacted connection profile mirroring {@link redactConnectionProfile}. */\n redactedProfile: Record<string, unknown>;\n /** Per-step duration measurements. */\n timings: ConnectionDiagnosticTimings;\n /** Sample of entries returned by the optional `fs.list` probe. */\n sample?: readonly RemoteEntry[];\n /** Whether all probes ran without throwing. */\n ok: boolean;\n /** Captured error summary when the diagnostics could not complete. */\n error?: { message: string; name?: string; code?: string };\n}\n\n/** Options accepted by {@link runConnectionDiagnostics}. */\nexport interface RunConnectionDiagnosticsOptions {\n /** Transfer client used to open the session. */\n client: TransferClient;\n /** Connection profile to probe. */\n profile: ConnectionProfile;\n /** Path passed to the optional `fs.list` probe. Defaults to `\"/\"`. */\n listPath?: string;\n /** When `false`, skips the `fs.list` probe. Defaults to `true`. */\n probeList?: boolean;\n /** Maximum number of entries retained in the result sample. Defaults to `5`. */\n sampleSize?: number;\n /** Optional clock injected for deterministic test timings. Defaults to `performance.now`. */\n now?: () => number;\n}\n\n/**\n * Connects to a profile, captures capability and listing samples, and returns a redaction-safe report.\n *\n * @param options - Diagnostic probe options.\n * @returns Diagnostic report including timings and any captured error.\n */\nexport async function runConnectionDiagnostics(\n options: RunConnectionDiagnosticsOptions,\n): Promise<ConnectionDiagnosticsResult> {\n const now = options.now ?? (() => performance.now());\n const probeList = options.probeList !== false;\n const listPath = options.listPath ?? \"/\";\n const sampleSize = Math.max(0, options.sampleSize ?? 5);\n const redactedProfile = redactConnectionProfile(options.profile);\n\n const result: ConnectionDiagnosticsResult = {\n host: options.profile.host,\n ok: false,\n redactedProfile,\n timings: {},\n };\n\n const connectStart = now();\n try {\n const session = await options.client.connect(options.profile);\n result.timings.connectMs = now() - connectStart;\n result.provider = session.provider;\n result.capabilities = session.capabilities;\n try {\n if (probeList) {\n const listStart = now();\n const entries = await session.fs.list(listPath);\n result.timings.listMs = now() - listStart;\n result.sample = entries.slice(0, sampleSize);\n }\n result.ok = true;\n } finally {\n const disconnectStart = now();\n await session.disconnect();\n result.timings.disconnectMs = now() - disconnectStart;\n }\n } catch (error) {\n result.error = summarizeDiagnosticError(error);\n }\n return result;\n}\n\nfunction summarizeDiagnosticError(error: unknown): {\n message: string;\n name?: string;\n code?: string;\n} {\n if (error instanceof Error) {\n const summary: { message: string; name?: string; code?: string } = { message: error.message };\n if (error.name !== \"Error\") summary.name = error.name;\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\") summary.code = code;\n return summary;\n }\n return { message: String(error) };\n}\n","/**\n * Classic FTP and FTPS providers backed by MLST/MLSD metadata commands.\n * @module providers/classic/ftp/FtpProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport { createConnection, isIP, type Socket } from \"node:net\";\nimport {\n connect as connectTls,\n type ConnectionOptions as TlsConnectionOptions,\n type PeerCertificate,\n type TLSSocket,\n} from \"node:tls\";\nimport type { CapabilitySet } from \"../../../core/CapabilitySet\";\nimport type { ClassicProviderId } from \"../../../core/ProviderId\";\nimport type { TransferSession } from \"../../../core/TransferSession\";\nimport {\n AbortError,\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n ProtocolError,\n TimeoutError,\n} from \"../../../errors/ZeroTransferError\";\nimport {\n resolveConnectionProfileSecrets,\n type ResolvedConnectionProfile,\n type ResolvedTlsProfile,\n} from \"../../../profiles/resolveConnectionProfileSecrets\";\nimport type { TransferVerificationResult } from \"../../../transfers/TransferJob\";\nimport type { ProviderFactory } from \"../../ProviderFactory\";\nimport type { TransferProvider } from \"../../Provider\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../../RemoteFileSystem\";\nimport type {\n ConnectionProfile,\n MkdirOptions,\n RemoteEntry,\n RemoteStat,\n RemoveOptions,\n RmdirOptions,\n} from \"../../../types/public\";\nimport {\n assertSafeFtpArgument,\n basenameRemotePath,\n normalizeRemotePath,\n} from \"../../../utils/path\";\nimport { parseMlsdLine, parseMlsdList, parseUnixList } from \"./FtpListParser\";\nimport { FtpResponseParser, type FtpResponse } from \"./FtpResponseParser\";\n\nconst FTP_PROVIDER_ID = \"ftp\";\nconst FTPS_PROVIDER_ID = \"ftps\";\nconst DEFAULT_FTP_PORT = 21;\nconst DEFAULT_FTPS_IMPLICIT_PORT = 990;\nconst DEFAULT_PASSIVE_HOST_STRATEGY: FtpPassiveHostStrategy = \"control\";\n\nconst FTP_PROVIDER_CAPABILITIES = createClassicFtpCapabilities(FTP_PROVIDER_ID, [\n \"Classic FTP provider foundation with MLST/MLSD metadata, EPSV/PASV passive mode, timeout-guarded operations, and RETR/STOR streaming support\",\n]);\n\nconst FTPS_PROVIDER_CAPABILITIES = createClassicFtpCapabilities(FTPS_PROVIDER_ID, [\n \"FTPS provider foundation with explicit AUTH TLS or implicit TLS, PBSZ/PROT setup, TLS profile support, MLST/MLSD metadata, EPSV/PASV passive mode, and RETR/STOR streaming support\",\n]);\n\n/**\n * Builds the shared classic-provider capability snapshot for FTP-family providers.\n *\n * @param provider - Provider id represented by the capability snapshot.\n * @param notes - Human-readable caveats exposed through capability discovery.\n * @returns Provider capabilities advertised before and after connection.\n */\nfunction createClassicFtpCapabilities(provider: ClassicProviderId, notes: string[]): CapabilitySet {\n return {\n provider,\n authentication:\n provider === FTPS_PROVIDER_ID\n ? [\"anonymous\", \"password\", \"client-certificate\"]\n : [\"anonymous\", \"password\"],\n list: true,\n stat: true,\n readStream: true,\n writeStream: true,\n serverSideCopy: false,\n serverSideMove: false,\n resumeDownload: true,\n resumeUpload: true,\n checksum: [],\n atomicRename: false,\n chmod: false,\n chown: false,\n symlink: true,\n metadata: [\"modifiedAt\", \"permissions\", \"uniqueId\"],\n maxConcurrency: 1,\n notes,\n };\n}\n\n/** Internal configuration used to instantiate an FTP-family provider implementation. */\ninterface ClassicFtpProviderConfig {\n /** Provider id exposed by the created provider and sessions. */\n providerId: ClassicProviderId;\n /** Capability snapshot associated with this provider variant. */\n capabilities: CapabilitySet;\n /** Control-channel port used when the profile omits one. */\n defaultPort: number;\n /** Host selection strategy used for PASV data endpoints. */\n passiveHostStrategy: FtpPassiveHostStrategy;\n /** Optional FTPS negotiation settings. Omitted for plain FTP. */\n security?: FtpsSecurityConfig;\n}\n\n/** FTPS-specific security settings derived from provider factory options. */\ninterface FtpsSecurityConfig {\n /** Control-channel TLS mode for the connection. */\n mode: FtpsMode;\n /** Data-channel protection level requested through PROT. */\n dataProtection: FtpsDataProtection;\n}\n\n/**\n * FTPS control-channel TLS mode.\n *\n * `explicit` connects on a plain FTP control socket and upgrades with `AUTH TLS`;\n * `implicit` starts TLS immediately, typically on port 990.\n */\nexport type FtpsMode = \"explicit\" | \"implicit\";\n\n/**\n * FTPS data-channel protection level requested after TLS negotiation.\n *\n * `private` sends `PROT P` and wraps passive data sockets in TLS. `clear` sends\n * `PROT C`, keeping the control channel encrypted while leaving data sockets plain.\n */\nexport type FtpsDataProtection = \"clear\" | \"private\";\n\n/**\n * Host selection strategy for PASV data endpoints.\n *\n * `control` connects data sockets back to the control connection host, which avoids\n * broken private or unroutable PASV addresses from NATed servers. `advertised` uses\n * the host supplied by the server's PASV response for deployments that require it.\n */\nexport type FtpPassiveHostStrategy = \"advertised\" | \"control\";\n\n/** Options used to create the classic FTP provider factory. */\nexport interface FtpProviderOptions {\n /** Default control port used when a connection profile omits `port`. */\n defaultPort?: number;\n /** PASV host selection strategy. Defaults to `control` for NAT-friendly compatibility. */\n passiveHostStrategy?: FtpPassiveHostStrategy;\n}\n\n/** Options used to create the FTPS provider factory. */\nexport interface FtpsProviderOptions extends FtpProviderOptions {\n /** TLS mode used for the control connection. Defaults to explicit FTPS on port 21. */\n mode?: FtpsMode;\n /** Data channel protection requested through PROT. Defaults to private/encrypted data. */\n dataProtection?: FtpsDataProtection;\n}\n\n/**\n * Creates a provider factory for classic FTP connections.\n *\n * @param options - Optional provider defaults.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n *\n * @example Plain FTP (cleartext — prefer FTPS or SFTP whenever possible)\n * ```ts\n * import { createFtpProviderFactory, createTransferClient } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createFtpProviderFactory()] });\n *\n * const session = await client.connect({\n * host: \"ftp.example.com\",\n * provider: \"ftp\",\n * username: \"deploy\",\n * password: { env: \"FTP_PASSWORD\" },\n * });\n * ```\n */\nexport function createFtpProviderFactory(options: FtpProviderOptions = {}): ProviderFactory {\n return {\n id: FTP_PROVIDER_ID,\n capabilities: FTP_PROVIDER_CAPABILITIES,\n create: () =>\n new FtpProvider({\n capabilities: FTP_PROVIDER_CAPABILITIES,\n defaultPort: options.defaultPort ?? DEFAULT_FTP_PORT,\n passiveHostStrategy: options.passiveHostStrategy ?? DEFAULT_PASSIVE_HOST_STRATEGY,\n providerId: FTP_PROVIDER_ID,\n }),\n };\n}\n\n/**\n * Creates a provider factory for explicit or implicit FTPS connections.\n *\n * The factory resolves TLS material from each connection profile, upgrades explicit\n * sessions with `AUTH TLS`, and applies the configured `PROT` data-channel policy.\n *\n * @param options - Optional provider defaults.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n *\n * @example FTPS with public-CA TLS (no extra TLS material needed)\n * ```ts\n * import { createFtpsProviderFactory, createTransferClient } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createFtpsProviderFactory()] });\n *\n * const session = await client.connect({\n * host: \"ftps.example.com\",\n * provider: \"ftps\",\n * username: \"deploy\",\n * password: { env: \"FTPS_PASSWORD\" },\n * tls: { minVersion: \"TLSv1.2\" },\n * });\n * ```\n *\n * @example FTPS with private CA + certificate pinning (defence-in-depth)\n * ```ts\n * await client.connect({\n * host: \"ftps.internal.example\",\n * provider: \"ftps\",\n * username: \"audit\",\n * tls: {\n * ca: { path: \"./certs/ca-bundle.pem\" },\n * cert: { path: \"./certs/client.crt\" },\n * key: { path: \"./certs/client.key\" },\n * // Optional but recommended:\n * pinnedFingerprint256: \"AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99\",\n * },\n * });\n * ```\n */\nexport function createFtpsProviderFactory(options: FtpsProviderOptions = {}): ProviderFactory {\n const mode = options.mode ?? \"explicit\";\n const defaultPort =\n options.defaultPort ?? (mode === \"implicit\" ? DEFAULT_FTPS_IMPLICIT_PORT : DEFAULT_FTP_PORT);\n\n return {\n id: FTPS_PROVIDER_ID,\n capabilities: FTPS_PROVIDER_CAPABILITIES,\n create: () =>\n new FtpProvider({\n capabilities: FTPS_PROVIDER_CAPABILITIES,\n defaultPort,\n passiveHostStrategy: options.passiveHostStrategy ?? DEFAULT_PASSIVE_HOST_STRATEGY,\n providerId: FTPS_PROVIDER_ID,\n security: {\n dataProtection: options.dataProtection ?? \"private\",\n mode,\n },\n }),\n };\n}\n\n/** Provider implementation shared by plain FTP and FTPS factory variants. */\nclass FtpProvider implements TransferProvider {\n /** Stable provider id registered in the transfer client. */\n readonly id: ClassicProviderId;\n /** Provider capability snapshot exposed without opening a connection. */\n readonly capabilities: CapabilitySet;\n\n /**\n * Creates a provider instance for a single connection attempt.\n *\n * @param config - Provider id, defaults, capabilities, and optional FTPS settings.\n */\n constructor(private readonly config: ClassicFtpProviderConfig) {\n this.id = config.providerId;\n this.capabilities = config.capabilities;\n }\n\n /**\n * Opens an FTP-family transfer session from a provider-neutral connection profile.\n *\n * @param profile - Connection profile containing host, credentials, timeout, and optional TLS settings.\n * @returns Connected transfer session with filesystem and transfer operations.\n */\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n const resolvedProfile = await resolveConnectionProfileSecrets(profile);\n const port = resolvedProfile.port ?? this.config.defaultPort;\n const connectOptions: FtpConnectOptions = {\n host: resolvedProfile.host,\n passiveHostStrategy: this.config.passiveHostStrategy,\n port,\n providerId: this.config.providerId,\n };\n\n if (this.config.security !== undefined) {\n const pinnedFingerprint256 = createTlsPinnedFingerprints(resolvedProfile);\n\n connectOptions.security = {\n ...this.config.security,\n ...(pinnedFingerprint256 === undefined ? {} : { pinnedFingerprint256 }),\n tlsOptions: createTlsConnectionOptions(resolvedProfile),\n };\n }\n\n if (resolvedProfile.signal !== undefined) {\n connectOptions.signal = resolvedProfile.signal;\n }\n\n if (resolvedProfile.timeoutMs !== undefined) {\n connectOptions.timeoutMs = resolvedProfile.timeoutMs;\n }\n\n const control = await FtpControlConnection.connect(connectOptions);\n\n try {\n await authenticateFtpSession(\n control,\n resolvedProfile.username === undefined\n ? \"anonymous\"\n : secretToString(resolvedProfile.username),\n resolvedProfile.password === undefined\n ? \"anonymous@\"\n : secretToString(resolvedProfile.password),\n resolvedProfile.host,\n );\n return new FtpTransferSession(control, this.capabilities);\n } catch (error) {\n control.close();\n throw error;\n }\n }\n}\n\n/** Transfer session backed by one FTP-family control connection. */\nclass FtpTransferSession implements TransferSession {\n /** Provider id selected for this session. */\n readonly provider: ClassicProviderId;\n /** Capability snapshot for this connected session. */\n readonly capabilities: CapabilitySet;\n /** Remote file-system operations backed by FTP metadata/data commands. */\n readonly fs: RemoteFileSystem;\n /** Stream-oriented provider transfer operations. */\n readonly transfers: ProviderTransferOperations;\n\n /**\n * Creates session facades over an authenticated control connection.\n *\n * @param control - Authenticated FTP-family control connection.\n * @param capabilities - Capability snapshot to expose through the session.\n */\n constructor(\n private readonly control: FtpControlConnection,\n capabilities: CapabilitySet,\n ) {\n this.provider = control.providerId;\n this.capabilities = capabilities;\n this.fs = new FtpFileSystem(control);\n this.transfers = new FtpTransferOperations(control);\n }\n\n /** Disconnects the control connection, swallowing QUIT cleanup noise. */\n async disconnect(): Promise<void> {\n try {\n await this.control.sendCommand(\"QUIT\");\n } catch {\n // The connection is closing anyway; callers should not see QUIT cleanup noise.\n } finally {\n this.control.close();\n }\n }\n}\n\nclass FtpTransferOperations implements ProviderTransferOperations {\n constructor(private readonly control: FtpControlConnection) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const remotePath = normalizeFtpPath(request.endpoint.path);\n const range = resolveReadRange(request.range);\n\n await expectCompletion(this.control, \"TYPE I\", remotePath);\n const dataConnection = await openPassiveDataCommand(\n this.control,\n `RETR ${remotePath}`,\n remotePath,\n {\n offset: range.offset,\n },\n );\n request.throwIfAborted();\n const result: ProviderTransferReadResult = {\n content: createPassiveReadSource(\n this.control,\n dataConnection,\n `RETR ${remotePath}`,\n remotePath,\n range,\n request,\n ),\n };\n\n if (range.length !== undefined) {\n result.totalBytes = range.length;\n }\n\n if (range.offset > 0) {\n result.bytesRead = range.offset;\n }\n\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const remotePath = normalizeFtpPath(request.endpoint.path);\n const offset = normalizeOptionalByteCount(request.offset, \"offset\", remotePath);\n\n await expectCompletion(this.control, \"TYPE I\", remotePath);\n const bytesTransferred = await writePassiveDataCommand(\n this.control,\n `STOR ${remotePath}`,\n remotePath,\n request,\n offset === undefined ? {} : { offset },\n );\n\n const result: ProviderTransferWriteResult = {\n bytesTransferred,\n resumed: offset !== undefined && offset > 0,\n totalBytes: request.totalBytes ?? (offset ?? 0) + bytesTransferred,\n verified: request.verification?.verified ?? false,\n };\n\n if (request.verification !== undefined) {\n result.verification = cloneVerification(request.verification);\n }\n\n return result;\n }\n}\n\nclass FtpFileSystem implements RemoteFileSystem {\n constructor(private readonly control: FtpControlConnection) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const remotePath = normalizeFtpPath(path);\n await expectCompletion(this.control, \"TYPE I\", remotePath);\n const entries = await readDirectoryEntries(this.control, remotePath);\n return entries.sort(compareEntries);\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const remotePath = normalizeFtpPath(path);\n const response = await this.control.sendCommand(`MLST ${remotePath}`);\n assertPathCommandSucceeded(response, \"MLST\", remotePath, this.control.providerId);\n\n const factLine = response.lines.map((line) => line.trim()).find(isFtpFactLine);\n\n if (factLine === undefined) {\n throw createProtocolError(\n \"MLST\",\n `${this.control.providerId.toUpperCase()} MLST response did not include a fact line`,\n response,\n this.control.providerId,\n );\n }\n\n const entry = parseMlsdLine(factLine, getParentPath(remotePath) ?? \"/\");\n\n return {\n ...entry,\n exists: true,\n name: basenameRemotePath(remotePath),\n path: remotePath,\n };\n }\n\n async remove(path: string, options: RemoveOptions = {}): Promise<void> {\n const remotePath = normalizeFtpPath(path);\n const response = await this.control.sendCommand(`DELE ${remotePath}`);\n if (response.completion) return;\n if (response.code === 550 && options.ignoreMissing) return;\n assertPathCommandSucceeded(response, \"DELE\", remotePath, this.control.providerId);\n }\n\n async rename(from: string, to: string): Promise<void> {\n const fromPath = normalizeFtpPath(from);\n const toPath = normalizeFtpPath(to);\n const rnfr = await this.control.sendCommand(`RNFR ${fromPath}`);\n if (!rnfr.intermediate && !rnfr.completion) {\n assertPathCommandSucceeded(rnfr, \"RNFR\", fromPath, this.control.providerId);\n }\n await expectCompletion(this.control, `RNTO ${toPath}`, toPath);\n }\n\n async mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n const remotePath = normalizeFtpPath(path);\n if (!options.recursive) {\n await expectCompletion(this.control, `MKD ${remotePath}`, remotePath);\n return;\n }\n const segments = remotePath.split(\"/\").filter((s) => s.length > 0);\n let current = \"\";\n for (const segment of segments) {\n current = `${current}/${segment}`;\n const response = await this.control.sendCommand(`MKD ${current}`);\n if (response.completion) continue;\n // 550 here is typically \"directory already exists\" — tolerated for recursive create.\n if (response.code === 550) continue;\n assertPathCommandSucceeded(response, \"MKD\", current, this.control.providerId);\n }\n }\n\n async rmdir(path: string, options: RmdirOptions = {}): Promise<void> {\n const remotePath = normalizeFtpPath(path);\n if (options.recursive) {\n await this.removeDirectoryRecursive(remotePath);\n return;\n }\n const response = await this.control.sendCommand(`RMD ${remotePath}`);\n if (response.completion) return;\n if (response.code === 550 && options.ignoreMissing) return;\n assertPathCommandSucceeded(response, \"RMD\", remotePath, this.control.providerId);\n }\n\n private async removeDirectoryRecursive(remotePath: string): Promise<void> {\n let entries: RemoteEntry[];\n try {\n entries = await readDirectoryEntries(this.control, remotePath);\n } catch (error) {\n // Treat a missing directory as already removed.\n if (error instanceof PathNotFoundError) return;\n throw error;\n }\n for (const entry of entries) {\n if (entry.name === \".\" || entry.name === \"..\") continue;\n const childPath = entry.path.startsWith(\"/\")\n ? entry.path\n : normalizeFtpPath(`${remotePath.replace(/\\/+$/, \"\")}/${entry.name}`);\n if (entry.type === \"directory\") {\n await this.removeDirectoryRecursive(childPath);\n } else {\n const del = await this.control.sendCommand(`DELE ${childPath}`);\n if (!del.completion && del.code !== 550) {\n assertPathCommandSucceeded(del, \"DELE\", childPath, this.control.providerId);\n }\n }\n }\n const response = await this.control.sendCommand(`RMD ${remotePath}`);\n if (response.completion) return;\n if (response.code === 550) return;\n assertPathCommandSucceeded(response, \"RMD\", remotePath, this.control.providerId);\n }\n}\n\n/** Socket-level connection settings used by the FTP-family control connection. */\ninterface FtpConnectOptions {\n /** Remote control endpoint host. */\n host: string;\n /** Host selection strategy used for PASV data endpoints. */\n passiveHostStrategy: FtpPassiveHostStrategy;\n /** Remote control endpoint port. */\n port: number;\n /** Provider id used in errors and session metadata. */\n providerId: ClassicProviderId;\n /** Optional FTPS negotiation settings. */\n security?: FtpConnectSecurity;\n /** Abort signal used during initial socket setup. */\n signal?: AbortSignal;\n /** Operation timeout applied to connection and control reads. */\n timeoutMs?: number;\n}\n\n/** Resolved FTPS settings including Node TLS connection options. */\ninterface FtpConnectSecurity extends FtpsSecurityConfig {\n /** TLS options derived from the resolved connection profile. */\n tlsOptions: TlsConnectionOptions;\n /** Normalized SHA-256 certificate fingerprints accepted for server pinning. */\n pinnedFingerprint256?: readonly string[];\n}\n\n/** Pending control-response reader waiting for the next parsed FTP reply. */\ninterface ResponseWaiter {\n /** Resolves the waiter with the next parsed response. */\n resolve(response: FtpResponse): void;\n /** Rejects the waiter when the control connection fails. */\n reject(error: Error): void;\n}\n\n/** Context used to create timeout diagnostics for control and data operations. */\ninterface FtpTimeoutContext {\n /** Human-readable operation phase, such as `greeting` or `passive data transfer`. */\n operation: string;\n /** FTP command associated with the wait, when one exists. */\n command?: string;\n /** Remote path associated with the operation, when one exists. */\n path?: string;\n}\n\n/** Stateful FTP-family control connection with optional explicit TLS upgrade support. */\nclass FtpControlConnection {\n private readonly parser = new FtpResponseParser();\n private readonly responses: FtpResponse[] = [];\n private readonly waiters: ResponseWaiter[] = [];\n private closedError: Error | undefined;\n private socket: Socket;\n\n private readonly handleSocketData = (chunk: Buffer | string) => this.handleData(chunk);\n private readonly handleSocketError = (error: Error) => {\n this.failPending(createConnectionError(this.host, error, this.providerId));\n };\n private readonly handleSocketClose = () => {\n this.failPending(\n new ConnectionError({\n host: this.host,\n message: `${this.providerId.toUpperCase()} control connection closed`,\n protocol: this.providerId,\n retryable: true,\n }),\n );\n };\n\n /**\n * Creates a control connection around an already-open socket.\n *\n * @param socket - Plain TCP or TLS socket connected to the server.\n * @param host - Host used for diagnostics and passive endpoint defaults.\n * @param passiveHostStrategy - Host selection strategy for PASV data endpoints.\n * @param providerId - Provider id used for errors and sessions.\n * @param timeoutMs - Optional timeout applied to control reads.\n * @param security - Optional FTPS settings, omitted for plain FTP.\n */\n private constructor(\n socket: Socket,\n private readonly host: string,\n private readonly passiveHostStrategy: FtpPassiveHostStrategy,\n readonly providerId: ClassicProviderId,\n private readonly timeoutMs: number | undefined,\n private readonly security: FtpConnectSecurity | undefined,\n ) {\n this.socket = socket;\n this.attachSocket(socket);\n }\n\n /** Host used for EPSV passive data connections. */\n get passiveHost(): string {\n return this.host;\n }\n\n /** Host selection strategy used for PASV data endpoints. */\n get passiveEndpointHostStrategy(): FtpPassiveHostStrategy {\n return this.passiveHostStrategy;\n }\n\n /** Timeout inherited by command waits and passive data operations. */\n get operationTimeoutMs(): number | undefined {\n return this.timeoutMs;\n }\n\n /** FTPS security settings for encrypted passive data sockets. */\n get dataTlsSecurity(): FtpConnectSecurity | undefined {\n return this.security?.dataProtection === \"private\" ? this.security : undefined;\n }\n\n /**\n * Opens a new control connection, reads the greeting, and negotiates FTPS when configured.\n *\n * @param options - Socket and provider connection options.\n * @returns Connected control connection ready for authentication.\n */\n static async connect(options: FtpConnectOptions): Promise<FtpControlConnection> {\n const socket = createControlSocket(options);\n const control = new FtpControlConnection(\n socket,\n options.host,\n options.passiveHostStrategy,\n options.providerId,\n options.timeoutMs,\n options.security,\n );\n\n try {\n await waitForSocketConnect(\n socket,\n options,\n options.security?.mode === \"implicit\" ? \"secureConnect\" : \"connect\",\n );\n\n if (options.security?.mode === \"implicit\") {\n assertPinnedTlsCertificate(socket, options.security, options.host, options.providerId);\n }\n\n const greeting = await control.readFinalResponse({ operation: \"greeting\" });\n\n if (!greeting.completion) {\n throw createProtocolError(\n \"greeting\",\n `${options.providerId.toUpperCase()} server greeting was not successful`,\n greeting,\n options.providerId,\n );\n }\n\n if (options.security?.mode === \"explicit\") {\n await negotiateExplicitFtps(control, options.security);\n } else if (options.security?.mode === \"implicit\") {\n await configureFtpsProtection(control, options.security);\n }\n\n return control;\n } catch (error) {\n control.close();\n throw error;\n }\n }\n\n /**\n * Writes one raw FTP command line to the control socket.\n *\n * @param command - Command text without CRLF.\n */\n writeCommand(command: string): void {\n this.socket.write(`${command}\\r\\n`);\n }\n\n /**\n * Sends a command and waits for the final non-preliminary response.\n *\n * @param command - Command text without CRLF.\n * @returns Final FTP response for the command.\n */\n async sendCommand(command: string): Promise<FtpResponse> {\n this.writeCommand(command);\n return this.readFinalResponse({ command, operation: \"command response\" });\n }\n\n /**\n * Reads responses until a final response is reached.\n *\n * @param context - Timeout diagnostic context for the wait.\n * @returns Final FTP response, skipping any preliminary 1xx replies.\n */\n async readFinalResponse(\n context: FtpTimeoutContext = { operation: \"response\" },\n ): Promise<FtpResponse> {\n let response = await this.readResponse(context);\n\n while (response.preliminary) {\n response = await this.readResponse(context);\n }\n\n return response;\n }\n\n /**\n * Reads the next parsed control-channel response.\n *\n * @param context - Timeout diagnostic context for the wait.\n * @returns Next parsed response from the control channel.\n */\n readResponse(context: FtpTimeoutContext = { operation: \"response\" }): Promise<FtpResponse> {\n const response = this.responses.shift();\n\n if (response !== undefined) {\n return Promise.resolve(response);\n }\n\n if (this.closedError !== undefined) {\n return Promise.reject(this.closedError);\n }\n\n return new Promise((resolve, reject) => {\n let timeout: NodeJS.Timeout | undefined;\n const clearWaiterTimeout = () => {\n if (timeout !== undefined) {\n clearTimeout(timeout);\n }\n };\n const waiter: ResponseWaiter = {\n reject(error) {\n clearWaiterTimeout();\n reject(error);\n },\n resolve(response) {\n clearWaiterTimeout();\n resolve(response);\n },\n };\n\n this.waiters.push(waiter);\n\n const timeoutMs = this.timeoutMs;\n\n if (timeoutMs !== undefined) {\n timeout = setTimeout(() => {\n const error = createFtpTimeoutError({\n ...context,\n host: this.host,\n providerId: this.providerId,\n timeoutMs,\n });\n\n this.failPending(error);\n this.close();\n }, timeoutMs);\n }\n });\n }\n\n /** Closes the current control socket. */\n close(): void {\n if (!this.socket.destroyed) {\n this.socket.end();\n this.socket.destroy();\n }\n }\n\n /**\n * Upgrades an explicit-FTPS control connection from plain TCP to TLS.\n *\n * @param security - Resolved FTPS security settings and TLS options.\n */\n async upgradeToTls(security: FtpConnectSecurity): Promise<void> {\n const plainSocket = this.socket;\n this.detachSocket(plainSocket);\n const tlsSocket = connectTls({ ...security.tlsOptions, socket: plainSocket });\n\n this.socket = tlsSocket;\n this.attachSocket(tlsSocket);\n\n const connectOptions: FtpConnectOptions = {\n host: this.host,\n passiveHostStrategy: this.passiveHostStrategy,\n port: 0,\n providerId: this.providerId,\n };\n\n if (this.timeoutMs !== undefined) {\n connectOptions.timeoutMs = this.timeoutMs;\n }\n\n await waitForSocketConnect(tlsSocket, connectOptions, \"secureConnect\", \"TLS negotiation\");\n assertPinnedTlsCertificate(tlsSocket, security, this.host, this.providerId);\n }\n\n /**\n * Attaches shared parser and failure handlers to the active control socket.\n *\n * @param socket - Socket that should feed control-channel responses.\n */\n private attachSocket(socket: Socket): void {\n socket.on(\"data\", this.handleSocketData);\n socket.on(\"error\", this.handleSocketError);\n socket.on(\"close\", this.handleSocketClose);\n }\n\n /**\n * Detaches shared parser and failure handlers before replacing a control socket.\n *\n * @param socket - Socket being removed from the control connection.\n */\n private detachSocket(socket: Socket): void {\n socket.off(\"data\", this.handleSocketData);\n socket.off(\"error\", this.handleSocketError);\n socket.off(\"close\", this.handleSocketClose);\n }\n\n /**\n * Parses inbound control-channel bytes into queued responses.\n *\n * @param chunk - Socket data chunk from the control channel.\n */\n private handleData(chunk: Buffer | string): void {\n try {\n for (const response of this.parser.push(chunk)) {\n this.enqueueResponse(response);\n }\n } catch (error) {\n this.failPending(\n error instanceof Error ? error : createConnectionError(this.host, error, this.providerId),\n );\n }\n }\n\n /**\n * Delivers a parsed response to a waiter or queues it for the next read.\n *\n * @param response - Parsed FTP response.\n */\n private enqueueResponse(response: FtpResponse): void {\n const waiter = this.waiters.shift();\n\n if (waiter === undefined) {\n this.responses.push(response);\n return;\n }\n\n waiter.resolve(response);\n }\n\n /**\n * Fails outstanding waits and records the first terminal connection error.\n *\n * @param error - Error that closed or invalidated the control connection.\n */\n private failPending(error: Error): void {\n if (this.closedError !== undefined) {\n return;\n }\n\n this.closedError = error;\n\n for (const waiter of this.waiters.splice(0)) {\n waiter.reject(error);\n }\n }\n}\n\n/** Host and port returned by EPSV or PASV negotiation. */\ninterface PassiveEndpoint {\n /** Data socket host to connect to. */\n host: string;\n /** Data socket port to connect to. */\n port: number;\n}\n\n/** Passive data connection opened before issuing a transfer command. */\ninterface PassiveDataConnection {\n /** Endpoint used for diagnostics and timeout errors. */\n endpoint: PassiveEndpoint;\n /** Resolves when the data socket is connected and ready. */\n ready: Promise<void>;\n /** Plain or TLS data socket for the transfer. */\n socket: Socket;\n /** Closes the data socket. */\n close(): void;\n}\n\n/** Transfer options applied before opening the passive data command. */\ninterface PassiveTransferOptions {\n /** Restart offset sent via REST before the data command. */\n offset?: number;\n}\n\n/** Normalized byte range requested for a provider read operation. */\ninterface ResolvedReadRange {\n /** Starting byte offset. */\n offset: number;\n /** Maximum number of bytes to emit, when bounded. */\n length?: number;\n}\n\nasync function expectCompletion(\n control: FtpControlConnection,\n command: string,\n path: string,\n): Promise<void> {\n const response = await control.sendCommand(command);\n assertPathCommandSucceeded(response, command, path, control.providerId);\n}\n\nasync function readPassiveDataCommand(\n control: FtpControlConnection,\n command: string,\n path: string,\n options: PassiveTransferOptions = {},\n): Promise<Buffer> {\n const dataConnection = await openPassiveDataCommand(control, command, path, options);\n\n try {\n const payload = await collectPassiveData(\n dataConnection,\n control.operationTimeoutMs,\n path,\n control.providerId,\n );\n const finalResponse = await control.readFinalResponse({\n command,\n operation: \"data command completion\",\n path,\n });\n assertPathCommandSucceeded(finalResponse, command, path, control.providerId);\n return payload;\n } catch (error) {\n dataConnection.close();\n throw error;\n }\n}\n\n/**\n * Reads directory entries with MLSD first and Unix LIST as an unsupported-command fallback.\n *\n * @param control - Active FTP-family control connection.\n * @param path - Normalized remote directory path.\n * @returns Parsed remote directory entries.\n */\nasync function readDirectoryEntries(\n control: FtpControlConnection,\n path: string,\n): Promise<RemoteEntry[]> {\n try {\n const payload = await readPassiveDataCommand(control, `MLSD ${path}`, path);\n return parseMlsdList(payload.toString(\"utf8\"), path);\n } catch (error) {\n if (!isUnsupportedFtpCommandError(error, \"MLSD\")) {\n throw error;\n }\n }\n\n const payload = await readPassiveDataCommand(control, `LIST ${path}`, path);\n return parseUnixList(payload.toString(\"utf8\"), path);\n}\n\nasync function openPassiveDataCommand(\n control: FtpControlConnection,\n command: string,\n path: string,\n options: PassiveTransferOptions = {},\n): Promise<PassiveDataConnection> {\n const offset = normalizeOptionalByteCount(options.offset, \"offset\", path);\n\n if (offset !== undefined && offset > 0) {\n await sendRestartOffset(control, offset, path);\n }\n\n const passiveEndpoint = await openPassiveEndpoint(control, path);\n const dataConnection = openPassiveDataConnection(\n passiveEndpoint,\n control.operationTimeoutMs,\n path,\n control,\n );\n\n try {\n await dataConnection.ready;\n control.writeCommand(command);\n const initialResponse = await control.readResponse({\n command,\n operation: \"data command response\",\n path,\n });\n\n if (!initialResponse.preliminary) {\n dataConnection.close();\n assertPathCommandSucceeded(initialResponse, command, path, control.providerId);\n throw createProtocolError(\n command,\n `${control.providerId.toUpperCase()} data command did not open a data transfer`,\n initialResponse,\n control.providerId,\n );\n }\n\n return dataConnection;\n } catch (error) {\n dataConnection.close();\n throw error;\n }\n}\n\nasync function openPassiveEndpoint(\n control: FtpControlConnection,\n path: string,\n): Promise<PassiveEndpoint> {\n const extendedPassiveResponse = await control.sendCommand(\"EPSV\");\n\n if (extendedPassiveResponse.completion) {\n return parseExtendedPassiveEndpoint(\n extendedPassiveResponse,\n control.passiveHost,\n control.providerId,\n );\n }\n\n if (!isExtendedPassiveUnsupported(extendedPassiveResponse)) {\n assertPathCommandSucceeded(extendedPassiveResponse, \"EPSV\", path, control.providerId);\n }\n\n const passiveResponse = await control.sendCommand(\"PASV\");\n assertPathCommandSucceeded(passiveResponse, \"PASV\", path, control.providerId);\n return parsePassiveEndpoint(\n passiveResponse,\n control.passiveHost,\n control.passiveEndpointHostStrategy,\n control.providerId,\n );\n}\n\nasync function writePassiveDataCommand(\n control: FtpControlConnection,\n command: string,\n path: string,\n request: ProviderTransferWriteRequest,\n options: PassiveTransferOptions = {},\n): Promise<number> {\n const dataConnection = await openPassiveDataCommand(control, command, path, options);\n let bytesTransferred = 0;\n const timeoutContext = {\n host: dataConnection.endpoint.host,\n operation: \"passive data transfer\",\n path,\n providerId: control.providerId,\n };\n\n try {\n for await (const chunk of request.content) {\n request.throwIfAborted();\n const output = new Uint8Array(chunk);\n await writeSocketChunk(\n dataConnection.socket,\n output,\n control.operationTimeoutMs,\n timeoutContext,\n );\n bytesTransferred += output.byteLength;\n request.reportProgress(bytesTransferred, request.totalBytes);\n }\n\n await endSocket(dataConnection.socket, control.operationTimeoutMs, timeoutContext);\n const finalResponse = await control.readFinalResponse({\n command,\n operation: \"data command completion\",\n path,\n });\n assertPathCommandSucceeded(finalResponse, command, path, control.providerId);\n return bytesTransferred;\n } catch (error) {\n dataConnection.close();\n throw error;\n }\n}\n\nasync function sendRestartOffset(\n control: FtpControlConnection,\n offset: number,\n path: string,\n): Promise<void> {\n const response = await control.sendCommand(`REST ${offset}`);\n\n if (response.completion || response.intermediate) {\n return;\n }\n\n assertPathCommandSucceeded(response, \"REST\", path, control.providerId);\n}\n\n/**\n * Opens a passive data socket, using TLS when FTPS data protection is private.\n *\n * @param endpoint - Passive endpoint advertised by EPSV or PASV.\n * @param timeoutMs - Optional timeout for the data socket connection.\n * @param path - Remote path associated with the transfer for diagnostics.\n * @param control - Control connection that owns provider id and TLS settings.\n * @returns Passive data connection wrapper with a readiness promise.\n */\nfunction openPassiveDataConnection(\n endpoint: PassiveEndpoint,\n timeoutMs: number | undefined,\n path: string,\n control: FtpControlConnection,\n): PassiveDataConnection {\n const dataSecurity = control.dataTlsSecurity;\n const socket =\n dataSecurity === undefined\n ? createConnection({ host: endpoint.host, port: endpoint.port })\n : connectTls({ ...dataSecurity.tlsOptions, host: endpoint.host, port: endpoint.port });\n socket.on(\"error\", () => undefined);\n const ready = new Promise<void>((resolve, reject) => {\n let settled = false;\n let timeout: NodeJS.Timeout | undefined;\n const readyEvent = dataSecurity === undefined ? \"connect\" : \"secureConnect\";\n\n const cleanup = () => {\n socket.off(readyEvent, handleConnect);\n socket.off(\"error\", handleError);\n\n if (timeout !== undefined) {\n clearTimeout(timeout);\n }\n };\n const rejectOnce = (error: Error) => {\n if (settled) {\n return;\n }\n\n settled = true;\n cleanup();\n socket.destroy();\n reject(error);\n };\n const handleConnect = () => {\n if (settled) {\n return;\n }\n\n try {\n if (dataSecurity !== undefined) {\n assertPinnedTlsCertificate(socket, dataSecurity, endpoint.host, control.providerId);\n }\n\n settled = true;\n cleanup();\n resolve();\n } catch (error) {\n rejectOnce(\n error instanceof Error\n ? error\n : createConnectionError(endpoint.host, error, control.providerId),\n );\n }\n };\n const handleError = (error: Error) => {\n rejectOnce(\n error instanceof TimeoutError\n ? error\n : createConnectionError(endpoint.host, error, control.providerId),\n );\n };\n\n socket.once(readyEvent, handleConnect);\n socket.once(\"error\", handleError);\n\n if (timeoutMs !== undefined) {\n timeout = setTimeout(\n () =>\n rejectOnce(\n createFtpTimeoutError({\n host: endpoint.host,\n operation: \"passive data connection\",\n path,\n providerId: control.providerId,\n timeoutMs,\n }),\n ),\n timeoutMs,\n );\n }\n });\n\n return {\n endpoint,\n ready,\n socket,\n close() {\n socket.destroy();\n },\n };\n}\n\nasync function collectPassiveData(\n dataConnection: PassiveDataConnection,\n timeoutMs: number | undefined,\n path: string,\n providerId: ClassicProviderId,\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n const clearIdleTimeout = setSocketTimeout(dataConnection.socket, timeoutMs, {\n host: dataConnection.endpoint.host,\n operation: \"passive data transfer\",\n path,\n providerId,\n });\n\n try {\n for await (const chunk of dataConnection.socket as AsyncIterable<Buffer>) {\n chunks.push(Buffer.from(chunk));\n }\n } finally {\n clearIdleTimeout();\n }\n\n return Buffer.concat(chunks);\n}\n\nasync function* createPassiveReadSource(\n control: FtpControlConnection,\n dataConnection: PassiveDataConnection,\n command: string,\n path: string,\n range: ResolvedReadRange,\n request: ProviderTransferReadRequest,\n): AsyncGenerator<Uint8Array> {\n let bytesEmitted = 0;\n let completed = false;\n let clearIdleTimeout: () => void = () => undefined;\n const closeOnAbort = () => dataConnection.close();\n\n request.signal?.addEventListener(\"abort\", closeOnAbort, { once: true });\n\n try {\n clearIdleTimeout = setSocketTimeout(dataConnection.socket, control.operationTimeoutMs, {\n host: dataConnection.endpoint.host,\n operation: \"passive data transfer\",\n path,\n providerId: control.providerId,\n });\n\n for await (const chunk of dataConnection.socket as AsyncIterable<Buffer>) {\n request.throwIfAborted();\n const buffer = Buffer.from(chunk);\n\n if (range.length === undefined) {\n bytesEmitted += buffer.byteLength;\n yield new Uint8Array(buffer);\n continue;\n }\n\n const remaining = range.length - bytesEmitted;\n\n if (remaining <= 0) {\n continue;\n }\n\n const output = buffer.subarray(0, Math.min(remaining, buffer.byteLength));\n bytesEmitted += output.byteLength;\n\n if (output.byteLength > 0) {\n yield new Uint8Array(output);\n }\n }\n\n const finalResponse = await control.readFinalResponse({\n command,\n operation: \"data command completion\",\n path,\n });\n assertPathCommandSucceeded(finalResponse, command, path, control.providerId);\n completed = true;\n } finally {\n clearIdleTimeout();\n request.signal?.removeEventListener(\"abort\", closeOnAbort);\n\n if (!completed) {\n dataConnection.close();\n }\n }\n}\n\nfunction writeSocketChunk(\n socket: Socket,\n chunk: Uint8Array,\n timeoutMs: number | undefined,\n context: Omit<FtpTimeoutErrorInput, \"timeoutMs\">,\n): Promise<void> {\n if (chunk.byteLength === 0) {\n return Promise.resolve();\n }\n\n return new Promise<void>((resolve, reject) => {\n const clearIdleTimeout = setSocketTimeout(socket, timeoutMs, context);\n const handleError = (error: Error) => {\n clearIdleTimeout();\n socket.off(\"error\", handleError);\n reject(error);\n };\n\n socket.once(\"error\", handleError);\n socket.write(chunk, (error?: Error | null) => {\n clearIdleTimeout();\n socket.off(\"error\", handleError);\n\n if (error != null) {\n reject(error);\n return;\n }\n\n resolve();\n });\n });\n}\n\nfunction endSocket(\n socket: Socket,\n timeoutMs: number | undefined,\n context: Omit<FtpTimeoutErrorInput, \"timeoutMs\">,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const clearIdleTimeout = setSocketTimeout(socket, timeoutMs, context);\n const handleError = (error: Error) => {\n clearIdleTimeout();\n socket.off(\"error\", handleError);\n reject(error);\n };\n\n socket.once(\"error\", handleError);\n socket.end(() => {\n clearIdleTimeout();\n socket.off(\"error\", handleError);\n resolve();\n });\n });\n}\n\nfunction resolveReadRange(range: ProviderTransferReadRequest[\"range\"]): ResolvedReadRange {\n if (range === undefined) {\n return { offset: 0 };\n }\n\n const resolved: ResolvedReadRange = {\n offset: normalizeByteCount(range.offset, \"offset\", \"/\"),\n };\n\n if (range.length !== undefined) {\n resolved.length = normalizeByteCount(range.length, \"length\", \"/\");\n }\n\n return resolved;\n}\n\nfunction normalizeOptionalByteCount(\n value: number | undefined,\n field: string,\n path: string,\n): number | undefined {\n return value === undefined ? undefined : normalizeByteCount(value, field, path);\n}\n\nfunction normalizeByteCount(value: number, field: string, path: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new ConfigurationError({\n details: { field, provider: FTP_PROVIDER_ID },\n message: `FTP provider ${field} must be a non-negative number`,\n path,\n protocol: FTP_PROVIDER_ID,\n retryable: false,\n });\n }\n\n return Math.floor(value);\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n\n/**\n * Parses a PASV response into a concrete data endpoint.\n *\n * @param response - Successful PASV response from the server.\n * @param controlHost - Host used by the control connection.\n * @param hostStrategy - Strategy used to choose the passive data endpoint host.\n * @param providerId - Provider id used in protocol diagnostics.\n * @returns Host and port for the passive data socket.\n */\nfunction parsePassiveEndpoint(\n response: FtpResponse,\n controlHost: string,\n hostStrategy: FtpPassiveHostStrategy,\n providerId: ClassicProviderId,\n): PassiveEndpoint {\n const endpointMatch = /(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)/.exec(response.message);\n\n if (endpointMatch === null) {\n throw createProtocolError(\n \"PASV\",\n `${providerId.toUpperCase()} PASV response did not include a host and port`,\n response,\n providerId,\n );\n }\n\n const [, first, second, third, fourth, highByte, lowByte] = endpointMatch;\n const parts = [first, second, third, fourth, highByte, lowByte].map((part) => Number(part));\n\n if (parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {\n throw createProtocolError(\n \"PASV\",\n `${providerId.toUpperCase()} PASV response included an invalid host or port`,\n response,\n providerId,\n );\n }\n\n const advertisedHost = `${parts[0]}.${parts[1]}.${parts[2]}.${parts[3]}`;\n\n return {\n host: hostStrategy === \"advertised\" ? advertisedHost : controlHost,\n port: parts[4]! * 256 + parts[5]!,\n };\n}\n\n/**\n * Parses an EPSV response into a data endpoint using the control host.\n *\n * @param response - Successful EPSV response from the server.\n * @param host - Host from the control connection.\n * @param providerId - Provider id used in protocol diagnostics.\n * @returns Host and port for the passive data socket.\n */\nfunction parseExtendedPassiveEndpoint(\n response: FtpResponse,\n host: string,\n providerId: ClassicProviderId,\n): PassiveEndpoint {\n const endpointMatch = /\\((.+)\\)/.exec(response.message);\n\n if (endpointMatch === null) {\n throw createProtocolError(\n \"EPSV\",\n `${providerId.toUpperCase()} EPSV response did not include a port`,\n response,\n providerId,\n );\n }\n\n const endpointText = endpointMatch[1] ?? \"\";\n const delimiter = endpointText[0];\n\n if (delimiter === undefined) {\n throw createProtocolError(\n \"EPSV\",\n `${providerId.toUpperCase()} EPSV response did not include a delimiter`,\n response,\n providerId,\n );\n }\n\n const parts = endpointText.split(delimiter);\n const port = Number(parts[3]);\n\n if (!Number.isInteger(port) || port <= 0 || port > 65_535) {\n throw createProtocolError(\n \"EPSV\",\n `${providerId.toUpperCase()} EPSV response included an invalid port`,\n response,\n providerId,\n );\n }\n\n return { host, port };\n}\n\n/**\n * Checks whether an EPSV response should fall back to PASV.\n *\n * @param response - Final response from the EPSV command.\n * @returns `true` when the server reports EPSV as unsupported.\n */\nfunction isExtendedPassiveUnsupported(response: FtpResponse): boolean {\n return (\n response.code === 500 ||\n response.code === 501 ||\n response.code === 502 ||\n response.code === 504 ||\n response.code === 522\n );\n}\n\n/**\n * Checks whether an FTP command failed with an unsupported-command response.\n *\n * @param error - Error thrown while waiting for a command response.\n * @param commandName - FTP command name that may be unsupported.\n * @returns `true` when the server rejected the command as unavailable.\n */\nfunction isUnsupportedFtpCommandError(error: unknown, commandName: string): boolean {\n return (\n error instanceof ProtocolError &&\n error.command?.startsWith(commandName) === true &&\n isUnsupportedFtpCommandCode(error.ftpCode)\n );\n}\n\n/**\n * Checks whether an FTP status code usually means a command is unsupported.\n *\n * @param code - FTP status code from a failed command.\n * @returns `true` for permanent unsupported-command responses.\n */\nfunction isUnsupportedFtpCommandCode(code: number | undefined): boolean {\n return code === 500 || code === 501 || code === 502 || code === 504;\n}\n\n/**\n * Creates the initial control socket for plain FTP, explicit FTPS, or implicit FTPS.\n *\n * @param options - Connection options including FTPS mode and TLS settings.\n * @returns Connected socket instance in progress; callers wait for the appropriate ready event.\n */\nfunction createControlSocket(options: FtpConnectOptions): Socket {\n if (options.security?.mode === \"implicit\") {\n return connectTls({\n ...options.security.tlsOptions,\n host: options.host,\n port: options.port,\n });\n }\n\n return createConnection({ host: options.host, port: options.port });\n}\n\n/**\n * Performs explicit FTPS negotiation on a connected plain control socket.\n *\n * @param control - Control connection that has received a successful server greeting.\n * @param security - Resolved FTPS mode and data-channel protection settings.\n * @returns A promise that resolves after AUTH TLS, PBSZ, and PROT setup complete.\n */\nasync function negotiateExplicitFtps(\n control: FtpControlConnection,\n security: FtpConnectSecurity,\n): Promise<void> {\n const authResponse = await control.sendCommand(\"AUTH TLS\");\n\n if (!authResponse.completion) {\n throw createProtocolError(\n \"AUTH TLS\",\n \"FTPS AUTH TLS negotiation failed\",\n authResponse,\n control.providerId,\n );\n }\n\n await control.upgradeToTls(security);\n await configureFtpsProtection(control, security);\n}\n\n/**\n * Configures FTPS buffer size and data-channel protection for an encrypted control session.\n *\n * @param control - TLS-protected FTPS control connection.\n * @param security - Resolved FTPS data-channel protection settings.\n * @returns A promise that resolves after PBSZ and PROT commands complete.\n */\nasync function configureFtpsProtection(\n control: FtpControlConnection,\n security: FtpConnectSecurity,\n): Promise<void> {\n await expectCompletion(control, \"PBSZ 0\", \"/\");\n await expectCompletion(control, security.dataProtection === \"private\" ? \"PROT P\" : \"PROT C\", \"/\");\n}\n\n/**\n * Converts a resolved connection profile into Node TLS connection options.\n *\n * @param profile - Connection profile with credential and TLS secrets already resolved.\n * @returns TLS options for control and protected data sockets.\n */\nfunction createTlsConnectionOptions(profile: ResolvedConnectionProfile): TlsConnectionOptions {\n const tlsProfile = profile.tls;\n const options: TlsConnectionOptions = {\n rejectUnauthorized: tlsProfile?.rejectUnauthorized ?? true,\n };\n const servername =\n tlsProfile?.servername ?? (isIP(profile.host) === 0 ? profile.host : undefined);\n\n if (servername !== undefined) {\n options.servername = servername;\n }\n\n if (tlsProfile === undefined) {\n return options;\n }\n\n if (tlsProfile.ca !== undefined) options.ca = normalizeTlsSecretValue(tlsProfile.ca);\n if (tlsProfile.cert !== undefined) options.cert = normalizeTlsSecretValue(tlsProfile.cert);\n if (tlsProfile.key !== undefined) options.key = normalizeTlsSecretValue(tlsProfile.key);\n if (tlsProfile.pfx !== undefined) options.pfx = normalizeTlsSecretValue(tlsProfile.pfx);\n if (tlsProfile.passphrase !== undefined)\n options.passphrase = secretToString(tlsProfile.passphrase);\n if (tlsProfile.minVersion !== undefined) options.minVersion = tlsProfile.minVersion;\n if (tlsProfile.maxVersion !== undefined) options.maxVersion = tlsProfile.maxVersion;\n if (tlsProfile.checkServerIdentity !== undefined) {\n options.checkServerIdentity = tlsProfile.checkServerIdentity;\n }\n\n return options;\n}\n\n/**\n * Normalizes SHA-256 certificate pinning values from a resolved profile.\n *\n * @param profile - Connection profile with TLS policy fields already resolved.\n * @returns Normalized lowercase fingerprint pins, or `undefined` when no pins are configured.\n */\nfunction createTlsPinnedFingerprints(\n profile: ResolvedConnectionProfile,\n): readonly string[] | undefined {\n const pinnedFingerprint256 = profile.tls?.pinnedFingerprint256;\n\n if (pinnedFingerprint256 === undefined) {\n return undefined;\n }\n\n const fingerprints = Array.isArray(pinnedFingerprint256)\n ? pinnedFingerprint256\n : [pinnedFingerprint256];\n\n if (fingerprints.length === 0) {\n throw new ConfigurationError({\n details: { pinnedFingerprint256 },\n message: \"FTPS tls.pinnedFingerprint256 must include at least one SHA-256 fingerprint\",\n protocol: FTPS_PROVIDER_ID,\n retryable: false,\n });\n }\n\n return fingerprints.map(normalizePinnedFingerprint256);\n}\n\n/**\n * Normalizes one SHA-256 certificate fingerprint pin.\n *\n * @param fingerprint - Fingerprint string using hex with optional colon separators.\n * @returns Lowercase hex fingerprint without separators.\n * @throws {@link ConfigurationError} When the fingerprint is not valid SHA-256 hex.\n */\nfunction normalizePinnedFingerprint256(fingerprint: string): string {\n const normalized = fingerprint.trim().replace(/:/g, \"\").toLowerCase();\n\n if (!/^[a-f0-9]{64}$/.test(normalized)) {\n throw new ConfigurationError({\n details: { pinnedFingerprint256: fingerprint },\n message: \"FTPS tls.pinnedFingerprint256 must be a SHA-256 hex fingerprint\",\n protocol: FTPS_PROVIDER_ID,\n retryable: false,\n });\n }\n\n return normalized;\n}\n\n/**\n * Verifies a TLS peer certificate against configured SHA-256 pins.\n *\n * @param socket - TLS socket with a completed handshake.\n * @param security - FTPS security settings containing normalized certificate pins.\n * @param host - Host used for connection diagnostics.\n * @param providerId - Provider id used for typed connection errors.\n * @throws {@link ConnectionError} When the server certificate fingerprint is not pinned.\n */\nfunction assertPinnedTlsCertificate(\n socket: Socket,\n security: FtpConnectSecurity,\n host: string,\n providerId: ClassicProviderId,\n): void {\n const pinnedFingerprint256 = security.pinnedFingerprint256;\n\n if (pinnedFingerprint256 === undefined) {\n return;\n }\n\n if (!isTlsSocket(socket)) {\n throw createConnectionError(\n host,\n new Error(\"FTPS certificate pinning requires a TLS socket\"),\n providerId,\n );\n }\n\n const certificate = socket.getPeerCertificate();\n const actualFingerprint = normalizeCertificateFingerprint256(certificate);\n\n if (pinnedFingerprint256.includes(actualFingerprint)) {\n return;\n }\n\n throw createConnectionError(\n host,\n new Error(\"FTPS server certificate SHA-256 fingerprint did not match tls.pinnedFingerprint256\"),\n providerId,\n );\n}\n\n/**\n * Checks whether a socket exposes TLS peer-certificate inspection.\n *\n * @param socket - Socket created for a control or data connection.\n * @returns `true` when the socket is a TLS socket.\n */\nfunction isTlsSocket(socket: Socket): socket is TLSSocket {\n return typeof (socket as Partial<TLSSocket>).getPeerCertificate === \"function\";\n}\n\n/**\n * Normalizes the SHA-256 fingerprint reported by a TLS peer certificate.\n *\n * @param certificate - Peer certificate returned by Node's TLS socket APIs.\n * @returns Lowercase SHA-256 hex fingerprint without separators.\n */\nfunction normalizeCertificateFingerprint256(certificate: PeerCertificate): string {\n return certificate.fingerprint256.replace(/:/g, \"\").toLowerCase();\n}\n\n/**\n * Clones resolved TLS material into the shape expected by Node TLS APIs.\n *\n * @param value - Resolved single TLS value or ordered CA bundle array.\n * @returns String, Buffer, or array accepted by `tls.connect()`.\n */\nfunction normalizeTlsSecretValue(\n value: NonNullable<ResolvedTlsProfile[\"ca\"]> | NonNullable<ResolvedTlsProfile[\"cert\"]>,\n): string | Buffer | Array<string | Buffer> {\n if (Array.isArray(value)) {\n return value.map((item) => (Buffer.isBuffer(item) ? Buffer.from(item) : item));\n }\n\n return Buffer.isBuffer(value) ? Buffer.from(value) : value;\n}\n\nasync function authenticateFtpSession(\n control: FtpControlConnection,\n username: string,\n password: string,\n host: string,\n): Promise<void> {\n const safeUsername = assertSafeFtpArgument(username, \"username\");\n const safePassword = assertSafeFtpArgument(password, \"password\");\n const userResponse = await control.sendCommand(`USER ${safeUsername}`);\n\n if (userResponse.completion) {\n return;\n }\n\n if (!userResponse.intermediate) {\n throw createAuthenticationError(host, \"USER\", userResponse, control.providerId);\n }\n\n const passwordResponse = await control.sendCommand(`PASS ${safePassword}`);\n\n if (!passwordResponse.completion) {\n throw createAuthenticationError(host, \"PASS\", passwordResponse, control.providerId);\n }\n}\n\nfunction assertPathCommandSucceeded(\n response: FtpResponse,\n command: string,\n path: string,\n providerId: ClassicProviderId,\n): void {\n if (response.completion) {\n return;\n }\n\n if (response.code === 550) {\n throw new PathNotFoundError({\n command,\n ftpCode: response.code,\n message: `${providerId.toUpperCase()} path not found: ${path}`,\n path,\n protocol: providerId,\n retryable: false,\n });\n }\n\n throw createProtocolError(\n command,\n `${providerId.toUpperCase()} command failed: ${command}`,\n response,\n providerId,\n );\n}\n\nfunction waitForSocketConnect(\n socket: Socket,\n options: FtpConnectOptions,\n readyEvent: \"connect\" | \"secureConnect\" = \"connect\",\n operation = \"connection\",\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let timeout: NodeJS.Timeout | undefined;\n\n const cleanup = () => {\n socket.off(\"connect\", handleConnect);\n socket.off(readyEvent, handleConnect);\n socket.off(\"error\", handleError);\n options.signal?.removeEventListener(\"abort\", handleAbort);\n\n if (timeout !== undefined) {\n clearTimeout(timeout);\n }\n };\n const rejectOnce = (error: Error) => {\n if (settled) {\n return;\n }\n\n settled = true;\n cleanup();\n socket.destroy();\n reject(error);\n };\n const handleConnect = () => {\n if (settled) {\n return;\n }\n\n settled = true;\n cleanup();\n resolve();\n };\n const handleError = (error: Error) =>\n rejectOnce(createConnectionError(options.host, error, options.providerId));\n const handleAbort = () =>\n rejectOnce(\n new AbortError({\n details: { operation },\n host: options.host,\n message: `${options.providerId.toUpperCase()} ${operation} aborted`,\n protocol: options.providerId,\n retryable: false,\n }),\n );\n\n socket.once(readyEvent, handleConnect);\n socket.once(\"error\", handleError);\n\n if (options.signal?.aborted === true) {\n handleAbort();\n return;\n }\n\n options.signal?.addEventListener(\"abort\", handleAbort, { once: true });\n\n const timeoutMs = options.timeoutMs;\n\n if (timeoutMs !== undefined) {\n timeout = setTimeout(\n () =>\n rejectOnce(\n createFtpTimeoutError({\n host: options.host,\n operation,\n providerId: options.providerId,\n timeoutMs,\n }),\n ),\n timeoutMs,\n );\n }\n });\n}\n\ninterface FtpTimeoutErrorInput extends FtpTimeoutContext {\n host: string;\n providerId: ClassicProviderId;\n timeoutMs: number;\n}\n\nfunction createFtpTimeoutError(input: FtpTimeoutErrorInput): TimeoutError {\n const details: Record<string, unknown> = {\n operation: input.operation,\n timeoutMs: input.timeoutMs,\n };\n\n return new TimeoutError({\n details,\n host: input.host,\n message: `${input.providerId.toUpperCase()} ${input.operation} timed out after ${input.timeoutMs}ms`,\n protocol: input.providerId,\n retryable: true,\n ...(input.command === undefined ? {} : { command: input.command }),\n ...(input.path === undefined ? {} : { path: input.path }),\n });\n}\n\nfunction setSocketTimeout(\n socket: Socket,\n timeoutMs: number | undefined,\n context: Omit<FtpTimeoutErrorInput, \"timeoutMs\">,\n): () => void {\n if (timeoutMs === undefined) {\n return () => undefined;\n }\n\n const handleTimeout = () => {\n socket.destroy(createFtpTimeoutError({ ...context, timeoutMs }));\n };\n\n socket.setTimeout(timeoutMs);\n socket.once(\"timeout\", handleTimeout);\n\n return () => {\n socket.off(\"timeout\", handleTimeout);\n socket.setTimeout(0);\n };\n}\n\nfunction createAuthenticationError(\n host: string,\n command: string,\n response: FtpResponse,\n providerId: ClassicProviderId,\n): AuthenticationError {\n return new AuthenticationError({\n command,\n ftpCode: response.code,\n host,\n message: `${providerId.toUpperCase()} authentication failed during ${command}`,\n protocol: providerId,\n retryable: false,\n });\n}\n\nfunction createConnectionError(\n host: string,\n cause: unknown,\n providerId: ClassicProviderId,\n): ConnectionError {\n return new ConnectionError({\n cause,\n host,\n message: `${providerId.toUpperCase()} connection failed`,\n protocol: providerId,\n retryable: true,\n });\n}\n\nfunction createProtocolError(\n command: string,\n message: string,\n response: FtpResponse,\n providerId: ClassicProviderId,\n): ProtocolError {\n return new ProtocolError({\n command,\n ftpCode: response.code,\n message,\n protocol: providerId,\n retryable: response.transientFailure,\n });\n}\n\nfunction normalizeFtpPath(path: string): string {\n const normalized = normalizeRemotePath(path);\n\n if (normalized === \".\" || normalized === \"/\") {\n return \"/\";\n }\n\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction getParentPath(path: string): string | undefined {\n if (path === \"/\") {\n return undefined;\n }\n\n const parentEnd = path.lastIndexOf(\"/\");\n return parentEnd <= 0 ? \"/\" : path.slice(0, parentEnd);\n}\n\nfunction isFtpFactLine(line: string): boolean {\n return line.includes(\";\") && line.includes(\" \");\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction secretToString(value: string | Buffer): string {\n return Buffer.isBuffer(value) ? value.toString(\"utf8\") : value;\n}\n","/**\n * Connection profile secret resolution helpers.\n *\n * @module profiles/resolveConnectionProfileSecrets\n */\nimport type { ConnectionProfile, SshProfile, TlsProfile, TlsSecretSource } from \"../types/public\";\nimport { resolveSecret, type ResolveSecretOptions, type SecretValue } from \"./SecretSource\";\n\n/** SSH profile with private-key and known-host material resolved. */\nexport interface ResolvedSshProfile extends Omit<\n SshProfile,\n \"knownHosts\" | \"passphrase\" | \"privateKey\"\n> {\n /** Resolved private key material. */\n privateKey?: SecretValue;\n /** Resolved private-key passphrase. */\n passphrase?: SecretValue;\n /** Resolved OpenSSH known_hosts material. */\n knownHosts?: SecretValue | SecretValue[];\n}\n\n/** TLS profile with certificate-bearing secret sources resolved. */\nexport interface ResolvedTlsProfile extends Omit<\n TlsProfile,\n \"ca\" | \"cert\" | \"key\" | \"passphrase\" | \"pfx\"\n> {\n /** Resolved certificate authority bundle. */\n ca?: SecretValue | SecretValue[];\n /** Resolved client certificate PEM. */\n cert?: SecretValue;\n /** Resolved client private key PEM. */\n key?: SecretValue;\n /** Resolved encrypted private-key or PFX/P12 passphrase. */\n passphrase?: SecretValue;\n /** Resolved PFX/P12 client certificate bundle. */\n pfx?: SecretValue;\n}\n\n/** Connection profile with username, password, TLS, and SSH material sources resolved. */\nexport interface ResolvedConnectionProfile extends Omit<\n ConnectionProfile,\n \"password\" | \"ssh\" | \"tls\" | \"username\"\n> {\n /** Resolved username or account identifier. */\n username?: SecretValue;\n /** Resolved password or credential bytes. */\n password?: SecretValue;\n /** Resolved TLS profile when certificate material is configured. */\n tls?: ResolvedTlsProfile;\n /** Resolved SSH profile when private-key material is configured. */\n ssh?: ResolvedSshProfile;\n}\n\n/**\n * Resolves credential and TLS material secret sources without mutating the original profile.\n *\n * @param profile - Profile containing optional secret sources.\n * @param options - Optional env and file-reader overrides.\n * @returns Profile copy with username, password, TLS material, and SSH material resolved when present.\n */\nexport async function resolveConnectionProfileSecrets(\n profile: ConnectionProfile,\n options: ResolveSecretOptions = {},\n): Promise<ResolvedConnectionProfile> {\n const { password, ssh, tls, username, ...rest } = profile;\n const resolved: ResolvedConnectionProfile = { ...rest };\n\n if (username !== undefined) {\n resolved.username = await resolveSecret(username, options);\n }\n\n if (password !== undefined) {\n resolved.password = await resolveSecret(password, options);\n }\n\n if (tls !== undefined) {\n resolved.tls = await resolveTlsProfile(tls, options);\n }\n\n if (ssh !== undefined) {\n resolved.ssh = await resolveSshProfile(ssh, options);\n }\n\n return resolved;\n}\n\n/**\n * Resolves SSH private-key, passphrase, and known-host source descriptors.\n *\n * @param profile - SSH profile containing optional secret-backed material.\n * @param options - Optional env and file-reader overrides.\n * @returns SSH profile copy with private-key material resolved.\n */\nasync function resolveSshProfile(\n profile: SshProfile,\n options: ResolveSecretOptions,\n): Promise<ResolvedSshProfile> {\n const { knownHosts, passphrase, privateKey, ...rest } = profile;\n const resolved: ResolvedSshProfile = { ...rest };\n\n if (privateKey !== undefined) resolved.privateKey = await resolveSecret(privateKey, options);\n if (passphrase !== undefined) resolved.passphrase = await resolveSecret(passphrase, options);\n if (knownHosts !== undefined)\n resolved.knownHosts = await resolveKnownHostsSource(knownHosts, options);\n\n return resolved;\n}\n\n/**\n * Resolves known_hosts material while preserving ordered source arrays.\n *\n * @param source - Single known_hosts source or source array.\n * @param options - Optional env and file-reader overrides.\n * @returns Resolved known_hosts value or value array.\n */\nasync function resolveKnownHostsSource(\n source: NonNullable<SshProfile[\"knownHosts\"]>,\n options: ResolveSecretOptions,\n): Promise<SecretValue | SecretValue[]> {\n if (Array.isArray(source)) {\n return Promise.all(source.map((item) => resolveSecret(item, options)));\n }\n\n return resolveSecret(source, options);\n}\n\n/**\n * Resolves TLS certificate, key, PFX, passphrase, and CA source descriptors.\n *\n * @param profile - TLS profile containing optional secret-backed material.\n * @param options - Optional env and file-reader overrides.\n * @returns TLS profile copy with material sources resolved.\n */\nasync function resolveTlsProfile(\n profile: TlsProfile,\n options: ResolveSecretOptions,\n): Promise<ResolvedTlsProfile> {\n const { ca, cert, key, passphrase, pfx, ...rest } = profile;\n const resolved: ResolvedTlsProfile = { ...rest };\n\n if (ca !== undefined) resolved.ca = await resolveTlsSecretSource(ca, options);\n if (cert !== undefined) resolved.cert = await resolveSecret(cert, options);\n if (key !== undefined) resolved.key = await resolveSecret(key, options);\n if (passphrase !== undefined) resolved.passphrase = await resolveSecret(passphrase, options);\n if (pfx !== undefined) resolved.pfx = await resolveSecret(pfx, options);\n\n return resolved;\n}\n\n/**\n * Resolves a TLS material source while preserving ordered CA bundle arrays.\n *\n * @param source - Single secret source or source array.\n * @param options - Optional env and file-reader overrides.\n * @returns Resolved secret value or resolved value array.\n */\nasync function resolveTlsSecretSource(\n source: TlsSecretSource,\n options: ResolveSecretOptions,\n): Promise<SecretValue | SecretValue[]> {\n if (Array.isArray(source)) {\n return Promise.all(source.map((item) => resolveSecret(item, options)));\n }\n\n return resolveSecret(source, options);\n}\n","/**\n * Remote path normalization and FTP command-argument safety helpers.\n *\n * The functions in this module avoid platform-specific local path behavior and reject\n * CR/LF characters before values can be interpolated into FTP commands.\n *\n * @module utils/path\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\n\nconst UNSAFE_FTP_ARGUMENT_PATTERN = /[\\r\\n]/;\n\n/**\n * Validates that an FTP command argument cannot inject additional command lines.\n *\n * @param value - Argument value to validate.\n * @param label - Human-readable argument label used in error messages.\n * @returns The original value when it is safe.\n * @throws {@link ConfigurationError} When the value contains CR or LF characters.\n */\nexport function assertSafeFtpArgument(value: string, label = \"path\"): string {\n if (UNSAFE_FTP_ARGUMENT_PATTERN.test(value)) {\n throw new ConfigurationError({\n message: `Unsafe FTP ${label}: CR and LF characters are not allowed`,\n retryable: false,\n details: {\n label,\n },\n });\n }\n\n return value;\n}\n\n/**\n * Normalizes a remote path using POSIX-style separators without escaping absolute roots.\n *\n * @param input - Remote path that may contain duplicate separators or dot segments.\n * @returns A normalized remote path, `/` for absolute root, or `.` for an empty relative path.\n * @throws {@link ConfigurationError} When the input contains unsafe CR or LF characters.\n */\nexport function normalizeRemotePath(input: string): string {\n assertSafeFtpArgument(input);\n\n if (input.length === 0) {\n return \".\";\n }\n\n const isAbsolute = input.startsWith(\"/\");\n const segments: string[] = [];\n\n for (const segment of input.split(/[\\\\/]+/)) {\n if (segment.length === 0 || segment === \".\") {\n continue;\n }\n\n if (segment === \"..\") {\n if (segments.length > 0 && segments[segments.length - 1] !== \"..\") {\n segments.pop();\n } else if (!isAbsolute) {\n segments.push(segment);\n }\n continue;\n }\n\n segments.push(segment);\n }\n\n const normalized = segments.join(\"/\");\n\n if (isAbsolute) {\n return normalized.length > 0 ? `/${normalized}` : \"/\";\n }\n\n return normalized.length > 0 ? normalized : \".\";\n}\n\n/**\n * Joins remote path segments and normalizes the result.\n *\n * @param segments - Remote path segments to concatenate.\n * @returns A normalized remote path.\n * @throws {@link ConfigurationError} When any joined segment contains unsafe characters.\n */\nexport function joinRemotePath(...segments: string[]): string {\n if (segments.length === 0) {\n return \".\";\n }\n\n return normalizeRemotePath(segments.join(\"/\"));\n}\n\n/**\n * Extracts the final name segment from a normalized remote path.\n *\n * @param input - Remote path to inspect.\n * @returns The final path segment, or `/` when the input is the absolute root.\n * @throws {@link ConfigurationError} When the input contains unsafe characters.\n */\nexport function basenameRemotePath(input: string): string {\n const normalized = normalizeRemotePath(input);\n const parts = normalized.split(\"/\").filter(Boolean);\n return parts[parts.length - 1] ?? normalized;\n}\n","/**\n * FTP MLSD and MLST metadata parsers.\n *\n * The helpers in this module convert machine-readable FTP listing facts into the\n * protocol-neutral {@link RemoteEntry} model used by the rest of ZeroTransfer.\n *\n * @module providers/classic/ftp/FtpListParser\n */\nimport { ParseError } from \"../../../errors/ZeroTransferError\";\nimport type { RemoteEntry, RemoteEntryType } from \"../../../types/public\";\nimport { joinRemotePath } from \"../../../utils/path\";\n\nconst UNIX_LIST_MONTHS = new Map(\n [\"jan\", \"feb\", \"mar\", \"apr\", \"may\", \"jun\", \"jul\", \"aug\", \"sep\", \"oct\", \"nov\", \"dec\"].map(\n (month, index) => [month, index],\n ),\n);\n\n/**\n * Parses an MLSD directory listing into normalized remote entries.\n *\n * @param input - Raw MLSD response body.\n * @param directory - Parent remote directory used to build entry paths.\n * @returns Remote entries excluding the `.` and `..` pseudo entries.\n * @throws {@link ParseError} When any listing line is malformed.\n */\nexport function parseMlsdList(input: string, directory = \".\"): RemoteEntry[] {\n return input\n .split(/\\r?\\n/)\n .map((line) => line.trimEnd())\n .filter((line) => line.length > 0)\n .map((line) => parseMlsdLine(line, directory))\n .filter((entry) => entry.name !== \".\" && entry.name !== \"..\");\n}\n\n/**\n * Parses a Unix-style FTP `LIST` response into normalized remote entries.\n *\n * This parser covers the common `ls -l` shape returned by classic FTP daemons and\n * is used as a compatibility fallback when a server does not support MLSD.\n *\n * @param input - Raw LIST response body.\n * @param directory - Parent remote directory used to build entry paths.\n * @param now - Reference date used when LIST entries include time but omit year.\n * @returns Remote entries excluding `.` and `..` pseudo entries.\n * @throws {@link ParseError} When any non-summary listing line is malformed.\n */\nexport function parseUnixList(input: string, directory = \".\", now = new Date()): RemoteEntry[] {\n return input\n .split(/\\r?\\n/)\n .map((line) => line.trimEnd())\n .filter((line) => line.length > 0 && !line.toLowerCase().startsWith(\"total \"))\n .map((line) => parseUnixListLine(line, directory, now))\n .filter((entry) => entry.name !== \".\" && entry.name !== \"..\");\n}\n\n/**\n * Parses one Unix-style FTP `LIST` line.\n *\n * @param line - Raw listing line in an `ls -l` compatible format.\n * @param directory - Parent remote directory used to build the entry path.\n * @param now - Reference date used when the line omits a year.\n * @returns Normalized remote entry with raw LIST metadata retained.\n * @throws {@link ParseError} When the line is not a supported Unix LIST entry.\n */\nexport function parseUnixListLine(line: string, directory = \".\", now = new Date()): RemoteEntry {\n const match =\n /^(\\S{10})\\s+\\d+\\s+(\\S+)\\s+(\\S+)\\s+(\\d+)\\s+([A-Za-z]{3})\\s+(\\d{1,2})\\s+(\\d{4}|\\d{1,2}:\\d{2})\\s+(.+)$/.exec(\n line,\n );\n\n if (match === null) {\n throw new ParseError({\n details: { line },\n message: `Malformed Unix LIST line: ${line}`,\n retryable: false,\n });\n }\n\n const [, mode = \"\", owner, group, sizeText, monthText, dayText, yearOrTime, rawName] = match;\n const { name, symlinkTarget } = parseUnixListName(rawName, mode);\n const entry: RemoteEntry = {\n name,\n path: joinRemotePath(directory, name),\n permissions: { raw: mode },\n raw: { line },\n type: mapUnixListType(mode),\n };\n const modifiedAt = parseUnixListTimestamp(monthText, dayText, yearOrTime, now);\n\n if (owner !== undefined) entry.owner = owner;\n if (group !== undefined) entry.group = group;\n if (sizeText !== undefined) entry.size = Number(sizeText);\n if (modifiedAt !== undefined) entry.modifiedAt = modifiedAt;\n if (symlinkTarget !== undefined) entry.symlinkTarget = symlinkTarget;\n\n return entry;\n}\n\n/**\n * Parses a single MLSD or MLST fact line.\n *\n * @param line - Raw fact line in `fact=value; name` format.\n * @param directory - Parent remote directory used to build the entry path.\n * @returns A normalized remote entry with parsed facts in `raw` metadata.\n * @throws {@link ParseError} When the line does not contain facts and a name.\n */\nexport function parseMlsdLine(line: string, directory = \".\"): RemoteEntry {\n const separatorIndex = line.indexOf(\" \");\n\n if (separatorIndex <= 0 || separatorIndex === line.length - 1) {\n throw new ParseError({\n message: `Malformed MLSD line: ${line}`,\n retryable: false,\n details: {\n line,\n },\n });\n }\n\n const factText = line.slice(0, separatorIndex);\n const name = line.slice(separatorIndex + 1);\n const facts = parseFacts(factText);\n const type = mapMlsdType(facts.get(\"type\"));\n const modifiedAt = parseMlstTimestamp(facts.get(\"modify\"));\n const sizeText = facts.get(\"size\");\n const permissions = facts.get(\"perm\");\n const uniqueId = facts.get(\"unique\");\n\n const entry: RemoteEntry = {\n name,\n path: joinRemotePath(directory, name),\n raw: {\n facts: Object.fromEntries(facts),\n line,\n },\n type,\n };\n\n if (sizeText !== undefined) entry.size = Number(sizeText);\n if (modifiedAt !== undefined) entry.modifiedAt = modifiedAt;\n if (permissions !== undefined) entry.permissions = { raw: permissions };\n if (uniqueId !== undefined) entry.uniqueId = uniqueId;\n\n return entry;\n}\n\n/**\n * Parses the UTC timestamp format used by MLST/MLSD `modify` facts.\n *\n * @param input - Timestamp text such as `20260427010203.123`.\n * @returns A UTC Date when the timestamp is valid, otherwise `undefined`.\n */\nexport function parseMlstTimestamp(input: string | undefined): Date | undefined {\n if (input === undefined) {\n return undefined;\n }\n\n const timestampMatch = /^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(?:\\.(\\d{1,3}))?$/.exec(input);\n\n if (timestampMatch === null) {\n return undefined;\n }\n\n const [, year, month, day, hour, minute, second, millisecond = \"0\"] = timestampMatch;\n const normalizedMillisecond = millisecond.padEnd(3, \"0\");\n\n return new Date(\n Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n Number(normalizedMillisecond),\n ),\n );\n}\n\n/**\n * Parses semicolon-delimited MLST facts into lowercase keys.\n *\n * @param input - Fact text before the entry name.\n * @returns A map of lowercase fact names to fact values.\n */\nfunction parseFacts(input: string): Map<string, string> {\n const facts = new Map<string, string>();\n\n for (const fact of input.split(\";\")) {\n if (fact.length === 0) {\n continue;\n }\n\n const separatorIndex = fact.indexOf(\"=\");\n\n if (separatorIndex <= 0) {\n continue;\n }\n\n facts.set(fact.slice(0, separatorIndex).toLowerCase(), fact.slice(separatorIndex + 1));\n }\n\n return facts;\n}\n\n/**\n * Maps the MLSD `type` fact to a normalized remote entry kind.\n *\n * @param input - Raw MLSD type fact value.\n * @returns Normalized entry kind.\n */\nfunction mapMlsdType(input: string | undefined): RemoteEntryType {\n switch (input?.toLowerCase()) {\n case \"file\":\n return \"file\";\n case \"cdir\":\n case \"dir\":\n case \"pdir\":\n return \"directory\";\n case \"os.unix=slink\":\n return \"symlink\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Maps a Unix LIST mode string to a normalized remote entry kind.\n *\n * @param mode - Permission and file-type mode string from a LIST line.\n * @returns Normalized entry kind.\n */\nfunction mapUnixListType(mode: string): RemoteEntryType {\n switch (mode[0]) {\n case \"-\":\n return \"file\";\n case \"d\":\n return \"directory\";\n case \"l\":\n return \"symlink\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Parses a Unix LIST timestamp into a UTC date when possible.\n *\n * @param monthText - Three-letter English month name.\n * @param dayText - Day of month text.\n * @param yearOrTime - Four-digit year or `HH:mm` time field.\n * @param now - Reference date used when the year is omitted.\n * @returns UTC date when the timestamp fields are valid, otherwise `undefined`.\n */\nfunction parseUnixListTimestamp(\n monthText: string | undefined,\n dayText: string | undefined,\n yearOrTime: string | undefined,\n now: Date,\n): Date | undefined {\n if (monthText === undefined || dayText === undefined || yearOrTime === undefined) {\n return undefined;\n }\n\n const month = UNIX_LIST_MONTHS.get(monthText.toLowerCase());\n const day = Number(dayText);\n\n if (month === undefined || !Number.isInteger(day) || day < 1 || day > 31) {\n return undefined;\n }\n\n if (/^\\d{4}$/.test(yearOrTime)) {\n return new Date(Date.UTC(Number(yearOrTime), month, day));\n }\n\n const timeMatch = /^(\\d{1,2}):(\\d{2})$/.exec(yearOrTime);\n\n if (timeMatch === null) {\n return undefined;\n }\n\n const [, hourText, minuteText] = timeMatch;\n const hour = Number(hourText);\n const minute = Number(minuteText);\n\n if (hour > 23 || minute > 59) {\n return undefined;\n }\n\n return new Date(Date.UTC(now.getUTCFullYear(), month, day, hour, minute));\n}\n\n/**\n * Splits a Unix LIST entry name from a symlink target when present.\n *\n * @param rawName - Name field from the LIST line.\n * @param mode - Permission and file-type mode string from the LIST line.\n * @returns Entry name and optional symbolic-link target.\n */\nfunction parseUnixListName(\n rawName: string | undefined,\n mode: string,\n): {\n name: string;\n symlinkTarget?: string;\n} {\n const name = rawName ?? \"\";\n\n if (!mode.startsWith(\"l\")) {\n return { name };\n }\n\n const separator = \" -> \";\n const separatorIndex = name.indexOf(separator);\n\n if (separatorIndex < 0) {\n return { name };\n }\n\n return {\n name: name.slice(0, separatorIndex),\n symlinkTarget: name.slice(separatorIndex + separator.length),\n };\n}\n","/**\n * FTP control-channel response parser.\n *\n * The parser accepts arbitrary chunks from a socket and produces complete FTP\n * responses, including multi-line replies defined by RFC 959.\n *\n * @module providers/classic/ftp/FtpResponseParser\n */\nimport { ParseError } from \"../../../errors/ZeroTransferError\";\n\n/** FTP response status family derived from the first digit of the reply code. */\nexport type FtpResponseStatus =\n | \"preliminary\"\n | \"completion\"\n | \"intermediate\"\n | \"transientFailure\"\n | \"permanentFailure\";\n\n/**\n * Complete parsed FTP response.\n */\nexport interface FtpResponse {\n /** Numeric three-digit FTP reply code. */\n code: number;\n /** Response message with multi-line content joined by newlines. */\n message: string;\n /** Individual message lines without the reply-code prefix. */\n lines: string[];\n /** Raw response lines joined by newlines. */\n raw: string;\n /** Classified response status family. */\n status: FtpResponseStatus;\n /** Whether the response is a 1xx preliminary reply. */\n preliminary: boolean;\n /** Whether the response is a 2xx completion reply. */\n completion: boolean;\n /** Whether the response is a 3xx intermediate reply. */\n intermediate: boolean;\n /** Whether the response is a 4xx transient failure reply. */\n transientFailure: boolean;\n /** Whether the response is a 5xx permanent failure reply. */\n permanentFailure: boolean;\n}\n\n/** Internal accumulator for an incomplete multi-line FTP response. */\ninterface PendingResponse {\n code: number;\n lines: string[];\n rawLines: string[];\n}\n\nconst FTP_LINE_PATTERN = /^(\\d{3})([ -])(.*)$/;\n\n/**\n * Stateful parser for socket-delivered FTP response text.\n */\nexport class FtpResponseParser {\n private buffer = \"\";\n private pendingResponse: PendingResponse | undefined;\n\n /**\n * Adds incoming socket data and returns any complete responses.\n *\n * @param chunk - Buffer or string chunk from the FTP control connection.\n * @returns Zero or more complete parsed responses.\n * @throws {@link ParseError} When a malformed standalone response line is received.\n */\n push(chunk: Buffer | string): FtpResponse[] {\n this.buffer += chunk.toString();\n const rawLines = this.buffer.split(/\\r?\\n/);\n this.buffer = rawLines.pop() ?? \"\";\n\n const responses: FtpResponse[] = [];\n\n for (const rawLine of rawLines) {\n const response = this.consumeLine(rawLine);\n\n if (response !== undefined) {\n responses.push(response);\n }\n }\n\n return responses;\n }\n\n /**\n * Clears buffered text and any incomplete multi-line response state.\n *\n * @returns Nothing.\n */\n reset(): void {\n this.buffer = \"\";\n this.pendingResponse = undefined;\n }\n\n /**\n * Checks whether the parser is holding buffered or incomplete response data.\n *\n * @returns `true` when there is unconsumed text or an open multi-line response.\n */\n hasPendingResponse(): boolean {\n return this.pendingResponse !== undefined || this.buffer.length > 0;\n }\n\n /**\n * Consumes one line of FTP response text.\n *\n * @param rawLine - Line without a trailing CRLF delimiter.\n * @returns A complete response when the line finishes one, otherwise `undefined`.\n * @throws {@link ParseError} When a malformed standalone line is encountered.\n */\n private consumeLine(rawLine: string): FtpResponse | undefined {\n const lineMatch = FTP_LINE_PATTERN.exec(rawLine);\n\n if (lineMatch === null) {\n if (this.pendingResponse !== undefined) {\n this.pendingResponse.lines.push(rawLine);\n this.pendingResponse.rawLines.push(rawLine);\n return undefined;\n }\n\n if (rawLine.length === 0) {\n return undefined;\n }\n\n throw new ParseError({\n message: `Malformed FTP response line: ${rawLine}`,\n retryable: false,\n details: {\n rawLine,\n },\n });\n }\n\n const code = Number(lineMatch[1]!);\n const separator = lineMatch[2]!;\n const message = lineMatch[3]!;\n\n if (this.pendingResponse !== undefined) {\n this.pendingResponse.lines.push(messageFromRawLine(rawLine, this.pendingResponse.code));\n this.pendingResponse.rawLines.push(rawLine);\n\n if (code === this.pendingResponse.code && separator === \" \") {\n const completed = this.pendingResponse;\n this.pendingResponse = undefined;\n return buildResponse(completed.code, completed.lines, completed.rawLines);\n }\n\n return undefined;\n }\n\n if (separator === \"-\") {\n this.pendingResponse = {\n code,\n lines: [message],\n rawLines: [rawLine],\n };\n return undefined;\n }\n\n return buildResponse(code, [message], [rawLine]);\n }\n}\n\n/**\n * Parses an exact set of response lines into one complete FTP response.\n *\n * @param lines - Raw response lines without trailing newline delimiters.\n * @returns A single complete parsed FTP response.\n * @throws {@link ParseError} When the lines do not contain exactly one complete response.\n */\nexport function parseFtpResponseLines(lines: string[]): FtpResponse {\n const parser = new FtpResponseParser();\n const responses = parser.push(`${lines.join(\"\\r\\n\")}\\r\\n`);\n\n if (responses.length !== 1 || parser.hasPendingResponse()) {\n throw new ParseError({\n message: \"Expected exactly one complete FTP response\",\n retryable: false,\n details: {\n responseCount: responses.length,\n },\n });\n }\n\n return responses[0]!;\n}\n\n/**\n * Builds a normalized response object from parsed message and raw lines.\n *\n * @param code - FTP status code shared by the response lines.\n * @param lines - Message lines without status prefixes.\n * @param rawLines - Original raw response lines.\n * @returns A normalized response with status-family booleans.\n */\nfunction buildResponse(code: number, lines: string[], rawLines: string[]): FtpResponse {\n const status = classifyStatus(code);\n\n return {\n code,\n message: lines.join(\"\\n\"),\n lines,\n raw: rawLines.join(\"\\n\"),\n status,\n preliminary: status === \"preliminary\",\n completion: status === \"completion\",\n intermediate: status === \"intermediate\",\n transientFailure: status === \"transientFailure\",\n permanentFailure: status === \"permanentFailure\",\n };\n}\n\n/**\n * Classifies an FTP status code into its response family.\n *\n * @param code - Numeric FTP reply code.\n * @returns The matching response status family.\n */\nfunction classifyStatus(code: number): FtpResponseStatus {\n if (code >= 100 && code < 200) return \"preliminary\";\n if (code >= 200 && code < 300) return \"completion\";\n if (code >= 300 && code < 400) return \"intermediate\";\n if (code >= 400 && code < 500) return \"transientFailure\";\n return \"permanentFailure\";\n}\n\n/**\n * Removes a matching FTP reply prefix from a raw response line.\n *\n * @param rawLine - Original response line.\n * @param code - Expected multi-line response code.\n * @returns Message text without the FTP prefix when present.\n */\nfunction messageFromRawLine(rawLine: string, code: number): string {\n const codeText = String(code);\n\n if (rawLine.startsWith(`${codeText} `) || rawLine.startsWith(`${codeText}-`)) {\n return rawLine.slice(4);\n }\n\n return rawLine;\n}\n","/**\n * SSH2-backed SFTP provider.\n *\n * This initial SFTP slice supports password/private-key/agent authenticated sessions, custom sockets,\n * provider-neutral directory listing, metadata reads, transfer streaming, and profile-level host-key policies.\n *\n * @module providers/classic/sftp/SftpProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport ssh2 from \"ssh2\";\nimport type {\n AnyAuthMethod,\n Client,\n ClientErrorExtensions,\n ConnectConfig,\n FileEntryWithStats,\n KeyboardInteractiveCallback,\n ParsedKey,\n ReadStream,\n SFTPWrapper,\n Stats,\n WriteStream,\n} from \"ssh2\";\nconst { Client: SshClientCtor, utils } = ssh2;\nimport type { CapabilitySet } from \"../../../core/CapabilitySet\";\nimport type { TransferSession } from \"../../../core/TransferSession\";\nimport {\n AbortError,\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n ProtocolError,\n TimeoutError,\n ZeroTransferError,\n} from \"../../../errors/ZeroTransferError\";\nimport {\n resolveConnectionProfileSecrets,\n type ResolvedConnectionProfile,\n} from \"../../../profiles/resolveConnectionProfileSecrets\";\nimport type { SecretValue } from \"../../../profiles/SecretSource\";\nimport type { TransferVerificationResult } from \"../../../transfers/TransferJob\";\nimport type {\n ConnectionProfile,\n ListOptions,\n MkdirOptions,\n RemoteEntry,\n RemoteEntryType,\n RemoteStat,\n RemoveOptions,\n RenameOptions,\n RmdirOptions,\n SshKeyboardInteractiveChallenge,\n StatOptions,\n} from \"../../../types/public\";\nimport { basenameRemotePath, joinRemotePath, normalizeRemotePath } from \"../../../utils/path\";\nimport type { TransferProvider } from \"../../Provider\";\nimport type { ProviderFactory } from \"../../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../../RemoteFileSystem\";\n\nconst SFTP_PROVIDER_ID = \"sftp\";\nconst SFTP_DEFAULT_PORT = 22;\nconst SFTP_PROVIDER_CAPABILITIES: CapabilitySet = {\n provider: SFTP_PROVIDER_ID,\n authentication: [\"password\", \"private-key\", \"agent\", \"keyboard-interactive\"],\n list: true,\n stat: true,\n readStream: true,\n writeStream: true,\n serverSideCopy: false,\n serverSideMove: false,\n resumeDownload: true,\n resumeUpload: true,\n checksum: [],\n atomicRename: false,\n chmod: false,\n chown: false,\n symlink: true,\n metadata: [\"accessedAt\", \"group\", \"modifiedAt\", \"owner\", \"permissions\"],\n maxConcurrency: 8,\n notes: [\n \"Initial ssh2-backed SFTP provider with password/private-key/agent authentication, metadata reads, and transfer streams\",\n ],\n};\n\n/** Options used to create an SFTP provider factory. */\nexport interface SftpProviderOptions {\n /** Hash algorithm used before calling ssh2's host verifier, such as `sha256`. */\n hostHash?: ConnectConfig[\"hostHash\"];\n /** Host-key verifier passed directly to ssh2 for advanced callers. */\n hostVerifier?: ConnectConfig[\"hostVerifier\"];\n /** Default SSH handshake timeout in milliseconds when the profile does not provide `timeoutMs`. */\n readyTimeoutMs?: number;\n}\n\n/** Raw SFTP session handles exposed for advanced diagnostics. */\nexport interface SftpRawSession {\n /** Underlying ssh2 client connection. */\n client: Client;\n /** Underlying ssh2 SFTP wrapper. */\n sftp: SFTPWrapper;\n}\n\n/**\n * Creates an SFTP provider factory backed by the mature `ssh2` implementation.\n *\n * @param options - Optional ssh2 host-key verifier and timeout defaults.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n *\n * @example Register and use\n * ```ts\n * import { createSftpProviderFactory, createTransferClient } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createSftpProviderFactory()] });\n *\n * const session = await client.connect({\n * host: \"sftp.example.com\",\n * provider: \"sftp\",\n * username: \"deploy\",\n * ssh: {\n * privateKey: { path: \"./keys/id_ed25519\" },\n * // Optional but recommended for production:\n * pinnedHostKeySha256: \"SHA256:abc123basesixfourpinFromKnownHosts=\",\n * },\n * });\n * ```\n *\n * Host-key verification (`ssh.knownHosts` and/or `ssh.pinnedHostKeySha256`) is\n * optional; without either, the client trusts whatever host key the server\n * presents. Use one for any non-lab deployment.\n */\nexport function createSftpProviderFactory(options: SftpProviderOptions = {}): ProviderFactory {\n validateSftpProviderOptions(options);\n\n return {\n id: SFTP_PROVIDER_ID,\n capabilities: SFTP_PROVIDER_CAPABILITIES,\n create: () => new SftpProvider(options),\n };\n}\n\nclass SftpProvider implements TransferProvider<SftpTransferSession> {\n readonly id = SFTP_PROVIDER_ID;\n readonly capabilities = SFTP_PROVIDER_CAPABILITIES;\n\n constructor(private readonly options: SftpProviderOptions) {}\n\n async connect(profile: ConnectionProfile): Promise<SftpTransferSession> {\n const resolvedProfile = await resolveConnectionProfileSecrets(profile);\n const username = requireTextCredential(resolvedProfile.username, \"username\");\n const authentication = resolveSftpAuthentication(resolvedProfile);\n const client = await connectSshClient(resolvedProfile, this.options, username, authentication);\n\n try {\n const sftp = await openSftpSession(client, resolvedProfile);\n return new SftpTransferSession(client, sftp);\n } catch (error) {\n client.end();\n throw mapSftpError(error, {\n command: \"SFTP\",\n host: resolvedProfile.host,\n });\n }\n }\n}\n\nclass SftpTransferSession implements TransferSession<SftpRawSession> {\n readonly provider = SFTP_PROVIDER_ID;\n readonly capabilities = SFTP_PROVIDER_CAPABILITIES;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(\n private readonly client: Client,\n private readonly sftp: SFTPWrapper,\n ) {\n this.client.on(\"error\", noop);\n this.fs = new SftpFileSystem(sftp);\n this.transfers = new SftpTransferOperations(sftp);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve().then(() => {\n this.client.end();\n });\n }\n\n raw(): SftpRawSession {\n return {\n client: this.client,\n sftp: this.sftp,\n };\n }\n}\n\nclass SftpTransferOperations implements ProviderTransferOperations {\n constructor(private readonly sftp: SFTPWrapper) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const remotePath = normalizeSftpPath(request.endpoint.path);\n\n try {\n const stats = await readSftpStats(this.sftp, remotePath);\n\n if (!stats.isFile()) {\n throw createSftpPathNotFoundError(remotePath, `SFTP path is not a file: ${remotePath}`);\n }\n\n const range = resolveSftpReadRange(stats.size, request.range);\n const result: ProviderTransferReadResult = {\n content: createSftpReadSource(this.sftp, remotePath, range, request),\n totalBytes: range.length,\n };\n\n if (range.offset > 0) {\n result.bytesRead = range.offset;\n }\n\n return result;\n } catch (error) {\n throw mapSftpError(error, { command: \"READ\", path: remotePath });\n }\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const remotePath = normalizeSftpPath(request.endpoint.path);\n const offset = normalizeOptionalByteCount(request.offset, \"offset\", remotePath);\n\n try {\n const bytesTransferred = await writeSftpContent(this.sftp, remotePath, request, offset);\n const result: ProviderTransferWriteResult = {\n bytesTransferred,\n resumed: offset !== undefined && offset > 0,\n totalBytes: request.totalBytes ?? (offset ?? 0) + bytesTransferred,\n verified: request.verification?.verified ?? false,\n };\n\n if (request.verification !== undefined) {\n result.verification = cloneVerification(request.verification);\n }\n\n return result;\n } catch (error) {\n throw mapSftpError(error, { command: \"WRITE\", path: remotePath });\n }\n }\n}\n\nclass SftpFileSystem implements RemoteFileSystem {\n constructor(private readonly sftp: SFTPWrapper) {}\n\n async list(path: string, options: ListOptions = {}): Promise<RemoteEntry[]> {\n throwIfAborted(options.signal, path, \"list\");\n const remotePath = normalizeSftpPath(path);\n\n try {\n const entries = await readSftpDirectory(this.sftp, remotePath);\n return entries\n .filter((entry) => entry.filename !== \".\" && entry.filename !== \"..\")\n .map((entry) => mapSftpDirectoryEntry(remotePath, entry))\n .sort(compareEntries);\n } catch (error) {\n throw mapSftpError(error, { command: \"READDIR\", path: remotePath });\n }\n }\n\n async stat(path: string, options: StatOptions = {}): Promise<RemoteStat> {\n throwIfAborted(options.signal, path, \"stat\");\n const remotePath = normalizeSftpPath(path);\n\n try {\n const stats = await readSftpStats(this.sftp, remotePath);\n return {\n ...mapSftpStats(remotePath, basenameRemotePath(remotePath), stats),\n exists: true,\n };\n } catch (error) {\n throw mapSftpError(error, { command: \"LSTAT\", path: remotePath });\n }\n }\n\n async remove(path: string, options: RemoveOptions = {}): Promise<void> {\n throwIfAborted(options.signal, path, \"remove\");\n const remotePath = normalizeSftpPath(path);\n try {\n await sftpUnlink(this.sftp, remotePath);\n } catch (error) {\n const mapped = mapSftpError(error, { command: \"REMOVE\", path: remotePath });\n if (options.ignoreMissing && mapped instanceof PathNotFoundError) return;\n throw mapped;\n }\n }\n\n async rename(from: string, to: string, options: RenameOptions = {}): Promise<void> {\n throwIfAborted(options.signal, from, \"rename\");\n const fromPath = normalizeSftpPath(from);\n const toPath = normalizeSftpPath(to);\n try {\n await sftpRename(this.sftp, fromPath, toPath);\n } catch (error) {\n throw mapSftpError(error, { command: \"RENAME\", path: fromPath });\n }\n }\n\n async mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n throwIfAborted(options.signal, path, \"mkdir\");\n const remotePath = normalizeSftpPath(path);\n if (!options.recursive) {\n try {\n await sftpMkdir(this.sftp, remotePath);\n } catch (error) {\n throw mapSftpError(error, { command: \"MKDIR\", path: remotePath });\n }\n return;\n }\n const segments = remotePath.split(\"/\").filter((s) => s.length > 0);\n let current = \"\";\n for (const segment of segments) {\n current = `${current}/${segment}`;\n try {\n await sftpMkdir(this.sftp, current);\n } catch (error) {\n // Existing directory is fine for recursive creation; rethrow other failures.\n try {\n const stats = await readSftpStats(this.sftp, current);\n if (stats.isDirectory()) continue;\n } catch {\n // fall through\n }\n throw mapSftpError(error, { command: \"MKDIR\", path: current });\n }\n }\n }\n\n async rmdir(path: string, options: RmdirOptions = {}): Promise<void> {\n throwIfAborted(options.signal, path, \"rmdir\");\n const remotePath = normalizeSftpPath(path);\n if (options.recursive) {\n await this.removeDirectoryRecursive(remotePath);\n return;\n }\n try {\n await sftpRmdir(this.sftp, remotePath);\n } catch (error) {\n const mapped = mapSftpError(error, { command: \"RMDIR\", path: remotePath });\n if (options.ignoreMissing && mapped instanceof PathNotFoundError) return;\n throw mapped;\n }\n }\n\n private async removeDirectoryRecursive(remotePath: string): Promise<void> {\n let entries: FileEntryWithStats[];\n try {\n entries = await readSftpDirectory(this.sftp, remotePath);\n } catch (error) {\n const mapped = mapSftpError(error, { command: \"READDIR\", path: remotePath });\n if (mapped instanceof PathNotFoundError) return;\n throw mapped;\n }\n for (const entry of entries) {\n if (entry.filename === \".\" || entry.filename === \"..\") continue;\n const childPath = `${remotePath.replace(/\\/+$/, \"\")}/${entry.filename}`.replace(/\\/+/g, \"/\");\n const isDir = entry.attrs.isDirectory();\n try {\n if (isDir) {\n await this.removeDirectoryRecursive(childPath);\n } else {\n await sftpUnlink(this.sftp, childPath);\n }\n } catch (error) {\n throw mapSftpError(error, {\n command: isDir ? \"RMDIR\" : \"REMOVE\",\n path: childPath,\n });\n }\n }\n try {\n await sftpRmdir(this.sftp, remotePath);\n } catch (error) {\n throw mapSftpError(error, { command: \"RMDIR\", path: remotePath });\n }\n }\n}\n\ninterface SftpErrorContext {\n command: string;\n host?: string;\n path?: string;\n}\n\ninterface SftpErrorBase {\n cause: unknown;\n command: string;\n host?: string;\n path?: string;\n protocol: \"sftp\";\n sftpCode?: number;\n}\n\ninterface SftpAuthenticationConfig {\n authHandler: NonNullable<ConnectConfig[\"authHandler\"]>;\n}\n\ninterface SftpKnownHostEntry {\n key: ParsedKey;\n patterns: string[];\n}\n\ninterface SftpHostKeyPolicy {\n host: string;\n knownHosts?: SftpKnownHostEntry[];\n pinnedHostKeySha256?: Set<string>;\n port: number;\n}\n\ntype ResolvedSshKnownHosts = NonNullable<ResolvedConnectionProfile[\"ssh\"]>[\"knownHosts\"];\ntype ResolvedSshHostKeyPins = NonNullable<ResolvedConnectionProfile[\"ssh\"]>[\"pinnedHostKeySha256\"];\n\ninterface ResolvedSftpReadRange {\n offset: number;\n length: number;\n}\n\nasync function connectSshClient(\n profile: ResolvedConnectionProfile,\n options: SftpProviderOptions,\n username: string,\n authentication: SftpAuthenticationConfig,\n): Promise<Client> {\n const client = new SshClientCtor();\n let config: ConnectConfig;\n\n try {\n config = await createConnectConfig(profile, options, username, authentication);\n } catch (error) {\n client.end();\n throw mapSftpConnectionError(error, profile.host);\n }\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const fail = (error: unknown) => {\n if (settled) {\n return;\n }\n\n settled = true;\n cleanup();\n client.end();\n reject(mapSftpConnectionError(error, profile.host));\n };\n const handleAbort = () => {\n fail(\n new AbortError({\n details: { operation: \"connect\" },\n host: profile.host,\n message: \"SFTP connection was aborted\",\n protocol: \"sftp\",\n retryable: false,\n }),\n );\n };\n const handleReady = () => {\n settled = true;\n cleanup();\n resolve(client);\n };\n const handleTimeout = () => {\n fail(\n new TimeoutError({\n details: { operation: \"connect\" },\n host: profile.host,\n message: \"SFTP connection timed out\",\n protocol: \"sftp\",\n retryable: true,\n }),\n );\n };\n const cleanup = () => {\n client.off(\"ready\", handleReady);\n client.off(\"error\", fail);\n client.off(\"timeout\", handleTimeout);\n profile.signal?.removeEventListener(\"abort\", handleAbort);\n };\n\n client.once(\"ready\", handleReady);\n client.once(\"error\", fail);\n client.once(\"timeout\", handleTimeout);\n\n if (profile.signal?.aborted === true) {\n handleAbort();\n return;\n }\n\n profile.signal?.addEventListener(\"abort\", handleAbort, { once: true });\n\n try {\n client.connect(config);\n } catch (error) {\n fail(error);\n }\n });\n}\n\nasync function createConnectConfig(\n profile: ResolvedConnectionProfile,\n options: SftpProviderOptions,\n username: string,\n authentication: SftpAuthenticationConfig,\n): Promise<ConnectConfig> {\n const config: ConnectConfig = {\n authHandler: authentication.authHandler,\n host: profile.host,\n port: profile.port ?? SFTP_DEFAULT_PORT,\n username,\n };\n const timeoutMs = profile.timeoutMs ?? options.readyTimeoutMs;\n\n if (timeoutMs !== undefined) {\n config.readyTimeout = timeoutMs;\n config.timeout = timeoutMs;\n }\n\n if (profile.ssh?.algorithms !== undefined) {\n config.algorithms = profile.ssh.algorithms;\n }\n\n const socket = await createSftpSocket(profile, username);\n\n if (socket !== undefined) {\n config.sock = socket;\n }\n\n configureSftpHostKeyVerifier(config, profile, options);\n\n return config;\n}\n\n/**\n * Resolves an optional profile-provided SSH socket before connecting.\n *\n * @param profile - Resolved connection profile containing the optional socket factory.\n * @param username - Resolved username passed to the factory context.\n * @returns Socket-like readable stream for ssh2's `sock` option, when configured.\n */\nasync function createSftpSocket(\n profile: ResolvedConnectionProfile,\n username: string,\n): Promise<ConnectConfig[\"sock\"]> {\n const socketFactory = profile.ssh?.socketFactory;\n\n if (socketFactory === undefined) {\n return undefined;\n }\n\n if (profile.signal?.aborted === true) {\n throw new AbortError({\n details: { operation: \"connect\" },\n host: profile.host,\n message: \"SFTP connection was aborted\",\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n const context = {\n host: profile.host,\n port: profile.port ?? SFTP_DEFAULT_PORT,\n username,\n };\n\n const socket = await socketFactory(\n profile.signal === undefined ? context : { ...context, signal: profile.signal },\n );\n\n if (typeof socket !== \"object\" || socket === null || typeof socket.pipe !== \"function\") {\n throw new ConfigurationError({\n details: { socket: typeof socket },\n message: \"Connection profile ssh.socketFactory must return a socket-like readable stream\",\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n return socket;\n}\n\nfunction configureSftpHostKeyVerifier(\n config: ConnectConfig,\n profile: ResolvedConnectionProfile,\n options: SftpProviderOptions,\n): void {\n const policy = createSftpHostKeyPolicy(profile);\n\n if (policy === undefined) {\n if (options.hostHash !== undefined) config.hostHash = options.hostHash;\n if (options.hostVerifier !== undefined) config.hostVerifier = options.hostVerifier;\n return;\n }\n\n if (options.hostHash !== undefined || options.hostVerifier !== undefined) {\n throw new ConfigurationError({\n details: { provider: SFTP_PROVIDER_ID },\n message:\n \"SFTP profile host-key policies cannot be combined with provider-level hostHash or hostVerifier options\",\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n config.hostVerifier = (key: Buffer) => verifySftpHostKey(policy, key);\n}\n\nfunction createSftpHostKeyPolicy(\n profile: ResolvedConnectionProfile,\n): SftpHostKeyPolicy | undefined {\n const knownHosts = parseKnownHosts(profile.ssh?.knownHosts);\n const pins = normalizeHostKeyPins(profile.ssh?.pinnedHostKeySha256);\n\n if (knownHosts === undefined && pins === undefined) {\n return undefined;\n }\n\n const policy: SftpHostKeyPolicy = {\n host: profile.host,\n port: profile.port ?? SFTP_DEFAULT_PORT,\n };\n\n if (knownHosts !== undefined) policy.knownHosts = knownHosts;\n if (pins !== undefined) policy.pinnedHostKeySha256 = pins;\n\n return policy;\n}\n\nfunction verifySftpHostKey(policy: SftpHostKeyPolicy, key: Buffer): boolean {\n if (\n policy.pinnedHostKeySha256 !== undefined &&\n !policy.pinnedHostKeySha256.has(hashHostKey(key))\n ) {\n return false;\n }\n\n if (policy.knownHosts !== undefined && !matchesKnownHosts(policy, key)) {\n return false;\n }\n\n return true;\n}\n\nfunction parseKnownHosts(source: ResolvedSshKnownHosts): SftpKnownHostEntry[] | undefined {\n if (source === undefined) {\n return undefined;\n }\n\n const values = Array.isArray(source) ? source : [source];\n const entries: SftpKnownHostEntry[] = [];\n\n for (const value of values) {\n const text = Buffer.isBuffer(value) ? value.toString(\"utf8\") : value;\n const lines = text.split(/\\r?\\n/);\n\n lines.forEach((line, index) => {\n const entry = parseKnownHostsLine(line, index + 1);\n\n if (entry !== undefined) {\n entries.push(entry);\n }\n });\n }\n\n return entries;\n}\n\nfunction parseKnownHostsLine(line: string, lineNumber: number): SftpKnownHostEntry | undefined {\n const trimmed = line.trim();\n\n if (trimmed.length === 0 || trimmed.startsWith(\"#\")) {\n return undefined;\n }\n\n const fields = trimmed.split(/\\s+/);\n const offset = fields[0]?.startsWith(\"@\") === true ? 1 : 0;\n const hosts = fields[offset];\n const keyType = fields[offset + 1];\n const keyData = fields[offset + 2];\n\n if (hosts === undefined || keyType === undefined || keyData === undefined) {\n throw createKnownHostsConfigurationError(lineNumber, \"is malformed\");\n }\n\n const key = parseKnownHostPublicKey(`${keyType} ${keyData}`, lineNumber);\n\n return {\n key,\n patterns: hosts.split(\",\").filter((pattern) => pattern.length > 0),\n };\n}\n\nfunction parseKnownHostPublicKey(value: string, lineNumber: number): ParsedKey {\n const parsed = utils.parseKey(value) as unknown;\n\n if (parsed instanceof Error) {\n throw createKnownHostsConfigurationError(lineNumber, parsed.message);\n }\n\n const parsedValues: readonly unknown[] = Array.isArray(parsed) ? parsed : [parsed];\n const parsedKey = parsedValues[0];\n\n if (!isParsedKey(parsedKey)) {\n throw createKnownHostsConfigurationError(lineNumber, \"does not contain a public key\");\n }\n\n return parsedKey;\n}\n\nfunction isParsedKey(value: unknown): value is ParsedKey {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { getPublicSSH?: unknown }).getPublicSSH === \"function\"\n );\n}\n\nfunction matchesKnownHosts(policy: SftpHostKeyPolicy, key: Buffer): boolean {\n return policy.knownHosts?.some((entry) => knownHostEntryMatches(entry, policy, key)) === true;\n}\n\nfunction knownHostEntryMatches(\n entry: SftpKnownHostEntry,\n policy: SftpHostKeyPolicy,\n key: Buffer,\n): boolean {\n const candidates = createKnownHostCandidates(policy.host, policy.port);\n let hostMatched = false;\n\n for (const pattern of entry.patterns) {\n const negated = pattern.startsWith(\"!\");\n const hostPattern = negated ? pattern.slice(1) : pattern;\n const patternMatched = candidates.some((candidate) =>\n knownHostPatternMatches(hostPattern, candidate),\n );\n\n if (negated && patternMatched) {\n return false;\n }\n\n if (patternMatched) {\n hostMatched = true;\n }\n }\n\n return hostMatched && entry.key.getPublicSSH().equals(key);\n}\n\nfunction createKnownHostCandidates(host: string, port: number): string[] {\n const candidates = [host, `[${host}]:${port}`];\n\n return port === SFTP_DEFAULT_PORT ? candidates : [`[${host}]:${port}`, host];\n}\n\nfunction knownHostPatternMatches(pattern: string, candidate: string): boolean {\n if (pattern.startsWith(\"|1|\")) {\n return hashedKnownHostPatternMatches(pattern, candidate);\n }\n\n return wildcardKnownHostPatternToRegExp(pattern).test(candidate);\n}\n\nfunction wildcardKnownHostPatternToRegExp(pattern: string): RegExp {\n const escaped = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\");\n\n return new RegExp(`^${escaped}$`, \"i\");\n}\n\nfunction hashedKnownHostPatternMatches(pattern: string, candidate: string): boolean {\n const [, version, saltText, hashText] = pattern.split(\"|\");\n\n if (version !== \"1\" || saltText === undefined || hashText === undefined) {\n return false;\n }\n\n const salt = Buffer.from(saltText, \"base64\");\n const expected = Buffer.from(hashText, \"base64\");\n const actual = createHmac(\"sha1\", salt).update(candidate).digest();\n\n return expected.byteLength === actual.byteLength && timingSafeEqual(expected, actual);\n}\n\nfunction normalizeHostKeyPins(value: ResolvedSshHostKeyPins): Set<string> | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const pins: readonly string[] = typeof value === \"string\" ? [value] : value;\n\n return new Set(pins.map((pin) => normalizeHostKeyPin(pin)));\n}\n\nfunction normalizeHostKeyPin(value: string): string {\n const trimmed = value.trim();\n const hex = trimmed.replace(/:/g, \"\");\n\n if (hex.length === 64 && /^[a-f0-9]+$/i.test(hex)) {\n return Buffer.from(hex, \"hex\").toString(\"base64\").replace(/=+$/g, \"\");\n }\n\n const bare = trimmed.startsWith(\"SHA256:\") ? trimmed.slice(\"SHA256:\".length) : trimmed;\n\n return Buffer.from(padBase64(bare), \"base64\").toString(\"base64\").replace(/=+$/g, \"\");\n}\n\nfunction hashHostKey(key: Buffer): string {\n return createHash(\"sha256\").update(key).digest(\"base64\").replace(/=+$/g, \"\");\n}\n\nfunction padBase64(value: string): string {\n const remainder = value.length % 4;\n\n return remainder === 0 ? value : `${value}${\"=\".repeat(4 - remainder)}`;\n}\n\nfunction createKnownHostsConfigurationError(\n lineNumber: number,\n reason: string,\n): ConfigurationError {\n return new ConfigurationError({\n details: { lineNumber, provider: SFTP_PROVIDER_ID },\n message: `SFTP known_hosts line ${lineNumber} ${reason}`,\n protocol: \"sftp\",\n retryable: false,\n });\n}\n\nfunction resolveSftpAuthentication(profile: ResolvedConnectionProfile): SftpAuthenticationConfig {\n const agent = profile.ssh?.agent;\n const password = resolveOptionalTextCredential(profile.password, \"password\");\n const privateKey = profile.ssh?.privateKey;\n const passphrase = profile.ssh?.passphrase;\n const keyboardInteractive = profile.ssh?.keyboardInteractive;\n const username = requireTextCredential(profile.username, \"username\");\n const authHandler: AnyAuthMethod[] = [];\n\n if (privateKey !== undefined) {\n const method: AnyAuthMethod = {\n key: privateKey,\n type: \"publickey\",\n username,\n };\n\n if (passphrase !== undefined) method.passphrase = passphrase;\n\n authHandler.push(method);\n }\n\n if (password !== undefined) {\n authHandler.push({\n password,\n type: \"password\",\n username,\n });\n }\n\n if (agent !== undefined) {\n authHandler.push({\n agent,\n type: \"agent\",\n username,\n });\n }\n\n if (keyboardInteractive !== undefined) {\n authHandler.push({\n prompt: (name, instructions, language, prompts, finish) => {\n handleKeyboardInteractiveChallenge(\n {\n instructions,\n language,\n name,\n prompts,\n },\n keyboardInteractive,\n finish,\n );\n },\n type: \"keyboard-interactive\",\n username,\n });\n }\n\n if (authHandler.length === 0) {\n throw new ConfigurationError({\n details: { provider: SFTP_PROVIDER_ID },\n message:\n \"SFTP profiles require a password, ssh.privateKey, ssh.agent, or ssh.keyboardInteractive\",\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n return { authHandler };\n}\n\nfunction handleKeyboardInteractiveChallenge(\n challenge: SshKeyboardInteractiveChallenge,\n handler: NonNullable<NonNullable<ResolvedConnectionProfile[\"ssh\"]>[\"keyboardInteractive\"]>,\n finish: KeyboardInteractiveCallback,\n): void {\n Promise.resolve()\n .then(() => handler(challenge))\n .then((answers) => finish(Array.from(answers)))\n .catch(() => finish([]));\n}\n\nfunction openSftpSession(client: Client, profile: ResolvedConnectionProfile): Promise<SFTPWrapper> {\n return new Promise((resolve, reject) => {\n client.sftp((error, sftp) => {\n if (error !== undefined) {\n reject(\n mapSftpError(error, {\n command: \"SFTP\",\n host: profile.host,\n }),\n );\n return;\n }\n\n resolve(sftp);\n });\n });\n}\n\nfunction readSftpDirectory(sftp: SFTPWrapper, path: string): Promise<FileEntryWithStats[]> {\n return new Promise((resolve, reject) => {\n sftp.readdir(path, (error, entries) => {\n if (error !== undefined) {\n reject(error);\n return;\n }\n\n resolve(entries);\n });\n });\n}\n\nfunction readSftpStats(sftp: SFTPWrapper, path: string): Promise<Stats> {\n return new Promise((resolve, reject) => {\n sftp.lstat(path, (error, stats) => {\n if (error !== undefined) {\n reject(error);\n return;\n }\n\n resolve(stats);\n });\n });\n}\n\nfunction sftpUnlink(sftp: SFTPWrapper, path: string): Promise<void> {\n return new Promise((resolve, reject) => {\n sftp.unlink(path, (error) => {\n if (error !== undefined && error !== null) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nfunction sftpRename(sftp: SFTPWrapper, from: string, to: string): Promise<void> {\n return new Promise((resolve, reject) => {\n sftp.rename(from, to, (error) => {\n if (error !== undefined && error !== null) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nfunction sftpMkdir(sftp: SFTPWrapper, path: string): Promise<void> {\n return new Promise((resolve, reject) => {\n sftp.mkdir(path, (error) => {\n if (error !== undefined && error !== null) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nfunction sftpRmdir(sftp: SFTPWrapper, path: string): Promise<void> {\n return new Promise((resolve, reject) => {\n sftp.rmdir(path, (error) => {\n if (error !== undefined && error !== null) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function* createSftpReadSource(\n sftp: SFTPWrapper,\n path: string,\n range: ResolvedSftpReadRange,\n request: ProviderTransferReadRequest,\n): AsyncGenerator<Uint8Array> {\n if (range.length <= 0) {\n return;\n }\n\n const stream = sftp.createReadStream(path, {\n end: range.offset + range.length - 1,\n start: range.offset,\n }) as ReadStream & AsyncIterable<Buffer>;\n const closeOnAbort = () => stream.destroy();\n\n request.signal?.addEventListener(\"abort\", closeOnAbort, { once: true });\n\n try {\n for await (const chunk of stream) {\n request.throwIfAborted();\n yield new Uint8Array(Buffer.from(chunk));\n }\n } catch (error) {\n throw mapSftpError(error, { command: \"READ\", path });\n } finally {\n request.signal?.removeEventListener(\"abort\", closeOnAbort);\n }\n}\n\nasync function writeSftpContent(\n sftp: SFTPWrapper,\n path: string,\n request: ProviderTransferWriteRequest,\n offset: number | undefined,\n): Promise<number> {\n const stream = createSftpWriteStream(sftp, path, offset);\n const closeOnAbort = () => stream.destroy();\n let bytesTransferred = 0;\n\n request.signal?.addEventListener(\"abort\", closeOnAbort, { once: true });\n\n try {\n for await (const chunk of request.content) {\n request.throwIfAborted();\n await writeSftpChunk(stream, chunk);\n bytesTransferred += chunk.byteLength;\n request.reportProgress(bytesTransferred, request.totalBytes);\n }\n\n await endSftpWriteStream(stream);\n return bytesTransferred;\n } catch (error) {\n stream.destroy();\n throw error;\n } finally {\n request.signal?.removeEventListener(\"abort\", closeOnAbort);\n }\n}\n\nfunction createSftpWriteStream(\n sftp: SFTPWrapper,\n path: string,\n offset: number | undefined,\n): WriteStream {\n if (offset === undefined) {\n return sftp.createWriteStream(path, { flags: \"w\" });\n }\n\n return sftp.createWriteStream(path, { flags: \"r+\", start: offset });\n}\n\nfunction writeSftpChunk(stream: WriteStream, chunk: Uint8Array): Promise<void> {\n if (chunk.byteLength === 0) {\n return Promise.resolve();\n }\n\n return new Promise<void>((resolve, reject) => {\n const cleanup = () => {\n stream.off(\"error\", handleError);\n };\n const handleError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n stream.once(\"error\", handleError);\n stream.write(Buffer.from(chunk), (error?: Error | null) => {\n cleanup();\n\n if (error != null) {\n reject(error);\n return;\n }\n\n resolve();\n });\n });\n}\n\nfunction endSftpWriteStream(stream: WriteStream): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const cleanup = () => {\n stream.off(\"close\", handleClose);\n stream.off(\"error\", handleError);\n };\n const handleClose = () => {\n cleanup();\n resolve();\n };\n const handleError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n stream.once(\"close\", handleClose);\n stream.once(\"error\", handleError);\n stream.end();\n });\n}\n\nfunction resolveSftpReadRange(\n size: number,\n range: ProviderTransferReadRequest[\"range\"],\n): ResolvedSftpReadRange {\n if (range === undefined) {\n return { length: size, offset: 0 };\n }\n\n const requestedOffset = normalizeByteCount(range.offset, \"offset\", \"/\");\n const requestedLength =\n range.length === undefined\n ? size - Math.min(requestedOffset, size)\n : normalizeByteCount(range.length, \"length\", \"/\");\n const offset = Math.min(requestedOffset, size);\n const length = Math.max(0, Math.min(requestedLength, size - offset));\n\n return { length, offset };\n}\n\nfunction normalizeOptionalByteCount(\n value: number | undefined,\n field: string,\n path: string,\n): number | undefined {\n return value === undefined ? undefined : normalizeByteCount(value, field, path);\n}\n\nfunction normalizeByteCount(value: number, field: string, path: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new ConfigurationError({\n details: { field, provider: SFTP_PROVIDER_ID },\n message: `SFTP provider ${field} must be a non-negative number`,\n path,\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n return Math.floor(value);\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n\nfunction mapSftpDirectoryEntry(directory: string, entry: FileEntryWithStats): RemoteEntry {\n return mapSftpStats(joinRemotePath(directory, entry.filename), entry.filename, entry.attrs, {\n longname: entry.longname,\n });\n}\n\nfunction mapSftpStats(\n path: string,\n name: string,\n stats: Stats,\n raw: { longname?: string } = {},\n): RemoteEntry {\n const entry: RemoteEntry = {\n group: String(stats.gid),\n name,\n owner: String(stats.uid),\n path,\n permissions: { raw: formatSftpMode(stats.mode) },\n raw: {\n attrs: serializeSftpStats(stats),\n ...raw,\n },\n type: mapSftpEntryType(stats),\n };\n const accessedAt = sftpSecondsToDate(stats.atime);\n const modifiedAt = sftpSecondsToDate(stats.mtime);\n\n entry.size = stats.size;\n entry.accessedAt = accessedAt;\n entry.modifiedAt = modifiedAt;\n\n return entry;\n}\n\nfunction mapSftpEntryType(stats: Stats): RemoteEntryType {\n if (stats.isFile()) return \"file\";\n if (stats.isDirectory()) return \"directory\";\n if (stats.isSymbolicLink()) return \"symlink\";\n return \"unknown\";\n}\n\nfunction serializeSftpStats(stats: Stats): Record<string, number> {\n return {\n atime: stats.atime,\n gid: stats.gid,\n mode: stats.mode,\n mtime: stats.mtime,\n size: stats.size,\n uid: stats.uid,\n };\n}\n\nfunction sftpSecondsToDate(value: number): Date {\n return new Date(value * 1000);\n}\n\nfunction formatSftpMode(mode: number): string {\n return mode.toString(8).padStart(6, \"0\");\n}\n\nfunction normalizeSftpPath(path: string): string {\n return normalizeRemotePath(path);\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction requireTextCredential(\n value: SecretValue | undefined,\n field: \"password\" | \"username\",\n): string {\n const text = resolveOptionalTextCredential(value, field);\n\n if (text === undefined) {\n throw new ConfigurationError({\n details: { field, provider: SFTP_PROVIDER_ID },\n message: `SFTP profiles require a ${field}`,\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n return text;\n}\n\nfunction resolveOptionalTextCredential(\n value: SecretValue | undefined,\n field: \"password\" | \"username\",\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const text = Buffer.isBuffer(value) ? value.toString(\"utf8\") : value;\n\n if (text.length === 0) {\n throw new ConfigurationError({\n details: { field, provider: SFTP_PROVIDER_ID },\n message: `SFTP profile ${field} must be non-empty`,\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n return text;\n}\n\nfunction validateSftpProviderOptions(options: SftpProviderOptions): void {\n if (\n options.readyTimeoutMs !== undefined &&\n (!Number.isFinite(options.readyTimeoutMs) || options.readyTimeoutMs <= 0)\n ) {\n throw new ConfigurationError({\n details: { readyTimeoutMs: options.readyTimeoutMs },\n message: \"SFTP provider readyTimeoutMs must be a positive finite number\",\n protocol: \"sftp\",\n retryable: false,\n });\n }\n}\n\nfunction createSftpPathNotFoundError(path: string, message: string): PathNotFoundError {\n return new PathNotFoundError({\n details: { provider: SFTP_PROVIDER_ID },\n message,\n path,\n protocol: \"sftp\",\n retryable: false,\n });\n}\n\nfunction throwIfAborted(\n signal: AbortSignal | undefined,\n path: string,\n operation: \"list\" | \"stat\" | \"remove\" | \"rename\" | \"mkdir\" | \"rmdir\",\n): void {\n if (signal?.aborted !== true) {\n return;\n }\n\n throw new AbortError({\n details: { operation },\n message: `SFTP ${operation} was aborted`,\n path,\n protocol: \"sftp\",\n retryable: false,\n });\n}\n\nfunction mapSftpConnectionError(error: unknown, host: string): ZeroTransferError {\n if (error instanceof ZeroTransferError) {\n return error;\n }\n\n if (isSftpAuthenticationError(error)) {\n return new AuthenticationError({\n cause: error,\n host,\n message: \"SFTP authentication failed\",\n protocol: \"sftp\",\n retryable: false,\n });\n }\n\n return new ConnectionError({\n cause: error,\n details: { originalMessage: getErrorMessage(error) },\n host,\n message: `SFTP connection failed: ${getErrorMessage(error)}`,\n protocol: \"sftp\",\n retryable: true,\n });\n}\n\nfunction mapSftpError(error: unknown, context: SftpErrorContext): ZeroTransferError {\n if (error instanceof ZeroTransferError) {\n return error;\n }\n\n const sftpCode = getSftpStatusCode(error);\n const baseDetails = createSftpErrorBase(error, context, sftpCode);\n\n if (sftpCode === 2 || isMissingPathMessage(error)) {\n return new PathNotFoundError({\n ...baseDetails,\n message: `SFTP path not found: ${context.path ?? \"unknown\"}`,\n retryable: false,\n });\n }\n\n if (sftpCode === 3) {\n return new PermissionDeniedError({\n ...baseDetails,\n message: `SFTP permission denied: ${context.path ?? context.command}`,\n retryable: false,\n sftpCode,\n });\n }\n\n return new ProtocolError({\n ...baseDetails,\n details: { originalMessage: getErrorMessage(error) },\n message: `SFTP ${context.command} failed: ${getErrorMessage(error)}`,\n retryable: sftpCode === 6 || sftpCode === 7,\n });\n}\n\nfunction createSftpErrorBase(\n error: unknown,\n context: SftpErrorContext,\n sftpCode: number | undefined,\n): SftpErrorBase {\n const base: SftpErrorBase = {\n cause: error,\n command: context.command,\n protocol: \"sftp\",\n };\n\n if (context.host !== undefined) base.host = context.host;\n if (context.path !== undefined) base.path = context.path;\n if (sftpCode !== undefined) base.sftpCode = sftpCode;\n\n return base;\n}\n\nfunction getSftpStatusCode(error: unknown): number | undefined {\n const code = isRecord(error) ? error.code : undefined;\n\n if (typeof code === \"number\") {\n return code;\n }\n\n return undefined;\n}\n\nfunction isSftpAuthenticationError(error: unknown): boolean {\n if (!isRecord(error)) {\n return false;\n }\n\n const level = (error as ClientErrorExtensions).level;\n const message = getErrorMessage(error).toLowerCase();\n\n return level === \"client-authentication\" || message.includes(\"authentication\");\n}\n\nfunction isMissingPathMessage(error: unknown): boolean {\n return /no such file|not found/i.test(getErrorMessage(error));\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction noop(): void {}\n","/**\n * Shared HTTP transport helpers used by HTTP(S) and WebDAV providers.\n *\n * @module providers/web/httpInternals\n */\nimport { Buffer } from \"node:buffer\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n TimeoutError,\n} from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Fetch implementation accepted by web-family providers. */\nexport type HttpFetch = (input: string, init?: RequestInit) => Promise<Response>;\n\n/** Shared session options carried by HTTP(S)-based providers. */\nexport interface HttpSessionTransport {\n baseUrl: URL;\n fetch: HttpFetch;\n headers: Record<string, string>;\n timeoutMs?: number;\n}\n\n/** Builds an HTTP(S) base URL from a connection profile. */\nexport function buildBaseUrl(\n profile: ConnectionProfile,\n options: { secure: boolean; basePath: string },\n): URL {\n const protocol = options.secure ? \"https:\" : \"http:\";\n const portSegment = profile.port !== undefined ? `:${profile.port}` : \"\";\n const path = options.basePath.length === 0 ? \"/\" : ensureLeadingSlash(options.basePath);\n try {\n return new URL(`${protocol}//${profile.host}${portSegment}${path}`);\n } catch (error) {\n throw new ConfigurationError({\n cause: error,\n details: { host: profile.host, port: profile.port },\n message: \"Invalid host or basePath for HTTP-family provider\",\n retryable: false,\n });\n }\n}\n\n/** Joins a base URL pathname with a normalized remote path. */\nexport function resolveUrl(baseUrl: URL, remotePath: string): URL {\n const trimmedBase = baseUrl.pathname.replace(/\\/+$/, \"\");\n const suffix = remotePath === \"/\" ? \"\" : remotePath;\n const merged = new URL(baseUrl.toString());\n merged.pathname = `${trimmedBase}${suffix}`;\n return merged;\n}\n\n/** Ensures a leading slash on a pathname. */\nexport function ensureLeadingSlash(value: string): string {\n return value.startsWith(\"/\") ? value : `/${value}`;\n}\n\n/** Dispatches a fetch request honoring shared headers, abort, and timeout policy. */\nexport async function dispatchRequest(\n options: HttpSessionTransport,\n url: URL,\n init: RequestInit & { headers?: Record<string, string> },\n): Promise<Response> {\n const headers = { ...options.headers, ...(init.headers ?? {}) };\n const controller = new AbortController();\n const upstreamSignal = init.signal ?? null;\n if (upstreamSignal !== null) {\n if (upstreamSignal.aborted) controller.abort(upstreamSignal.reason);\n else upstreamSignal.addEventListener(\"abort\", () => controller.abort(upstreamSignal.reason));\n }\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"HTTP request timed out\")),\n options.timeoutMs,\n );\n }\n\n try {\n return await options.fetch(url.toString(), {\n ...init,\n headers,\n signal: controller.signal,\n });\n } catch (error) {\n if (controller.signal.aborted && upstreamSignal?.aborted !== true) {\n throw new TimeoutError({\n cause: error,\n details: { timeoutMs: options.timeoutMs, url: url.toString() },\n message: `HTTP request to ${url.toString()} timed out after ${String(options.timeoutMs)}ms`,\n retryable: true,\n });\n }\n throw new ConnectionError({\n cause: error,\n details: { url: url.toString() },\n message: `HTTP request to ${url.toString()} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\n/** Parses a `Content-Range: bytes a-b/total` header. */\nexport function parseContentRangeTotal(value: string): number | undefined {\n const match = /\\/(\\d+)\\s*$/.exec(value);\n if (match === null) return undefined;\n const total = Number.parseInt(match[1] ?? \"\", 10);\n return Number.isFinite(total) ? total : undefined;\n}\n\n/** Resolves the total byte count from a response and optional range offset. */\nexport function parseTotalBytes(\n response: Response,\n rangeOffset: number | undefined,\n): number | undefined {\n if (response.status === 206) {\n const contentRange = response.headers.get(\"content-range\");\n if (contentRange !== null) {\n const total = parseContentRangeTotal(contentRange);\n if (total !== undefined) return total;\n }\n }\n const contentLength = response.headers.get(\"content-length\");\n if (contentLength === null) return undefined;\n const length = Number.parseInt(contentLength, 10);\n if (!Number.isFinite(length) || length < 0) return undefined;\n return rangeOffset !== undefined && rangeOffset > 0 ? length + rangeOffset : length;\n}\n\n/** Formats a `Range: bytes=offset-end` header. */\nexport function formatRangeHeader(offset: number, length: number | undefined): string {\n if (length === undefined) return `bytes=${String(offset)}-`;\n const end = offset + length - 1;\n return `bytes=${String(offset)}-${String(end)}`;\n}\n\n/** Maps an HTTP error status to a typed SDK error. */\nexport function mapResponseError(response: Response, path: string): Error {\n const details = { path, status: response.status, statusText: response.statusText };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `HTTP authentication failed for ${path} (${String(response.status)})`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `HTTP access forbidden for ${path} (${String(response.status)})`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `HTTP path not found: ${path}`,\n retryable: false,\n });\n }\n return new ConnectionError({\n details,\n message: `HTTP request for ${path} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\n/** Converts a Web ReadableStream to an AsyncIterable of Uint8Array. */\nexport async function* webStreamToAsyncIterable(\n body: ReadableStream<Uint8Array>,\n): AsyncIterable<Uint8Array> {\n const reader = body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value !== undefined) yield value;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/** Resolves resolved-secret variants to UTF-8 strings. */\nexport function secretToString(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (value instanceof Uint8Array || Buffer.isBuffer(value)) {\n return Buffer.from(value as Uint8Array).toString(\"utf8\");\n }\n return String(value);\n}\n","/**\n * Dropbox cloud-drive provider.\n *\n * Talks to the Dropbox HTTP API (`api.dropboxapi.com` for RPC, `content.dropboxapi.com`\n * for file content) using a bearer token sourced from the connection profile\n * (`profile.password` resolved as a `SecretSource`). Supports `list` (with\n * pagination via `list_folder/continue`), `stat` (`get_metadata`), `read`\n * (`files/download` with optional `Range`) and single-shot `write`\n * (`files/upload`). Resumable upload sessions are not yet implemented.\n *\n * @module providers/cloud/DropboxProvider\n */\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n formatRangeHeader,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"../web/httpInternals\";\n\nexport type { HttpFetch };\n\nconst DROPBOX_API_BASE = \"https://api.dropboxapi.com\";\nconst DROPBOX_CONTENT_BASE = \"https://content.dropboxapi.com\";\n\nconst DROPBOX_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"dropbox-content-hash\"];\n\n/** Options accepted by {@link createDropboxProviderFactory}. */\nexport interface DropboxProviderOptions {\n /** Provider id to register. Defaults to `\"dropbox\"`. */\n id?: ProviderId;\n /** Override the RPC base URL. Defaults to `https://api.dropboxapi.com`. */\n apiBaseUrl?: string;\n /** Override the content base URL. Defaults to `https://content.dropboxapi.com`. */\n contentBaseUrl?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied to every request before bearer auth. */\n defaultHeaders?: Record<string, string>;\n}\n\n/**\n * Creates a Dropbox provider factory.\n *\n * The bearer token is resolved per-connection from `profile.password`. The\n * `profile.host` field is unused; Dropbox connections are identified solely by\n * their token.\n */\nexport function createDropboxProviderFactory(\n options: DropboxProviderOptions = {},\n): ProviderFactory {\n const id: ProviderId = options.id ?? \"dropbox\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const apiBaseUrl = options.apiBaseUrl ?? DROPBOX_API_BASE;\n const contentBaseUrl = options.contentBaseUrl ?? DROPBOX_CONTENT_BASE;\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply DropboxProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"token\", \"oauth\"],\n checksum: [...DROPBOX_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 4,\n metadata: [\"modifiedAt\", \"uniqueId\"],\n notes: [\n \"Dropbox provider performs single-shot uploads via /2/files/upload; resumable upload sessions are not yet supported.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new DropboxProvider({\n apiBaseUrl,\n capabilities,\n contentBaseUrl,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n fetch: fetchImpl,\n id,\n }),\n id,\n };\n}\n\ninterface DropboxProviderInternalOptions {\n apiBaseUrl: string;\n capabilities: CapabilitySet;\n contentBaseUrl: string;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n}\n\nclass DropboxProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: DropboxProviderInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n if (profile.password === undefined) {\n throw new ConfigurationError({\n message: \"Dropbox provider requires a bearer token via profile.password\",\n retryable: false,\n });\n }\n const token = secretToString(await resolveSecret(profile.password));\n if (token === \"\") {\n throw new ConfigurationError({\n message: \"Dropbox bearer token resolved to an empty string\",\n retryable: false,\n });\n }\n const sessionOptions: DropboxSessionOptions = {\n apiBaseUrl: this.internals.apiBaseUrl,\n capabilities: this.internals.capabilities,\n contentBaseUrl: this.internals.contentBaseUrl,\n defaultHeaders: this.internals.defaultHeaders,\n fetch: this.internals.fetch,\n id: this.internals.id,\n token,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new DropboxSession(sessionOptions);\n }\n}\n\ninterface DropboxSessionOptions {\n apiBaseUrl: string;\n capabilities: CapabilitySet;\n contentBaseUrl: string;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n timeoutMs?: number;\n token: string;\n}\n\nclass DropboxSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: DropboxSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new DropboxFileSystem(options);\n this.transfers = new DropboxTransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass DropboxFileSystem implements RemoteFileSystem {\n constructor(private readonly options: DropboxSessionOptions) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const normalized = normalizeRemotePath(path);\n const apiPath = toDropboxPath(normalized);\n const entries: RemoteEntry[] = [];\n let cursor: string | undefined;\n do {\n const body =\n cursor === undefined\n ? { include_media_info: false, path: apiPath, recursive: false }\n : { cursor };\n const endpoint =\n cursor === undefined ? \"/2/files/list_folder\" : \"/2/files/list_folder/continue\";\n const response = await dropboxRpc(this.options, endpoint, body);\n const parsed = (await response.json()) as DropboxListFolderResponse;\n for (const raw of parsed.entries) {\n const entry = toRemoteEntry(raw, normalized);\n if (entry !== undefined) entries.push(entry);\n }\n cursor = parsed.has_more === true ? parsed.cursor : undefined;\n } while (cursor !== undefined);\n return entries;\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const apiPath = toDropboxPath(normalized);\n const response = await dropboxRpc(this.options, \"/2/files/get_metadata\", {\n include_deleted: false,\n include_has_explicit_shared_members: false,\n include_media_info: false,\n path: apiPath,\n });\n const raw = (await response.json()) as DropboxMetadata;\n const parent = parentDir(normalized);\n const entry = toRemoteEntry(raw, parent);\n if (entry === undefined) {\n throw new PathNotFoundError({\n details: { path: normalized },\n message: `Dropbox returned no metadata for ${normalized}`,\n retryable: false,\n });\n }\n return { ...entry, exists: true };\n }\n}\n\nclass DropboxTransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: DropboxSessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const apiArg = JSON.stringify({ path: toDropboxPath(normalized) });\n const headers: Record<string, string> = {\n \"Dropbox-API-Arg\": apiArg,\n };\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n const url = `${this.options.contentBaseUrl}/2/files/download`;\n const response = await dropboxFetch(this.options, url, \"POST\", {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n });\n if (!response.ok && response.status !== 206) {\n throw mapDropboxResponseError(response, normalized, await safeReadText(response));\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n details: { path: normalized },\n message: `Dropbox download for ${normalized} produced no body`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const hash = readApiResultHeader(response)?.content_hash;\n if (typeof hash === \"string\" && hash.length > 0) result.checksum = hash;\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"Dropbox provider does not yet support resumable upload sessions\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const buffered = await collectChunks(request.content);\n const apiArg = JSON.stringify({\n autorename: false,\n mode: \"overwrite\",\n mute: true,\n path: toDropboxPath(normalized),\n strict_conflict: false,\n });\n const url = `${this.options.contentBaseUrl}/2/files/upload`;\n const response = await dropboxFetch(this.options, url, \"POST\", {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: buffered,\n extraHeaders: {\n \"content-type\": \"application/octet-stream\",\n \"Dropbox-API-Arg\": apiArg,\n },\n });\n if (!response.ok) {\n throw mapDropboxResponseError(response, normalized, await safeReadText(response));\n }\n const meta = (await response.json()) as DropboxFileMetadata;\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n if (typeof meta.content_hash === \"string\" && meta.content_hash.length > 0) {\n result.checksum = meta.content_hash;\n }\n return result;\n }\n}\n\ninterface DropboxFetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function dropboxFetch(\n options: DropboxSessionOptions,\n url: string,\n method: string,\n fetchOptions: DropboxFetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n authorization: `Bearer ${options.token}`,\n };\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) {\n (init as { body: Uint8Array }).body = fetchOptions.body;\n }\n\n const controller = new AbortController();\n const upstream = fetchOptions.signal ?? null;\n if (upstream !== null) {\n if (upstream.aborted) controller.abort(upstream.reason);\n else upstream.addEventListener(\"abort\", () => controller.abort(upstream.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"Dropbox request timed out\")),\n options.timeoutMs,\n );\n }\n try {\n return await options.fetch(url, { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url },\n message: `Dropbox request to ${url} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nasync function dropboxRpc(\n options: DropboxSessionOptions,\n endpoint: string,\n body: Record<string, unknown>,\n): Promise<Response> {\n const url = `${options.apiBaseUrl}${endpoint}`;\n const encoded = new TextEncoder().encode(JSON.stringify(body));\n const response = await dropboxFetch(options, url, \"POST\", {\n body: encoded,\n extraHeaders: { \"content-type\": \"application/json\" },\n });\n if (!response.ok) {\n const text = await safeReadText(response);\n throw mapDropboxResponseError(response, endpoint, text);\n }\n return response;\n}\n\nfunction mapDropboxResponseError(response: Response, contextPath: string, bodyText: string): Error {\n const details = {\n bodyText: bodyText.slice(0, 500),\n path: contextPath,\n status: response.status,\n statusText: response.statusText,\n };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `Dropbox authentication failed for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `Dropbox access forbidden for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 409 && /not_found/.test(bodyText)) {\n return new PathNotFoundError({\n details,\n message: `Dropbox path not found: ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 429) {\n return new ConnectionError({\n details,\n message: `Dropbox rate limit hit for ${contextPath}`,\n retryable: true,\n });\n }\n return new ConnectionError({\n details,\n message: `Dropbox request for ${contextPath} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\ninterface DropboxListFolderResponse {\n entries: DropboxMetadata[];\n cursor: string;\n has_more?: boolean;\n}\n\ninterface DropboxMetadataBase {\n \".tag\": \"file\" | \"folder\" | \"deleted\";\n id?: string;\n name: string;\n path_display?: string;\n path_lower?: string;\n}\n\ninterface DropboxFileMetadata extends DropboxMetadataBase {\n \".tag\": \"file\";\n size?: number;\n client_modified?: string;\n server_modified?: string;\n content_hash?: string;\n rev?: string;\n}\n\ninterface DropboxFolderMetadata extends DropboxMetadataBase {\n \".tag\": \"folder\";\n}\n\ntype DropboxMetadata = DropboxFileMetadata | DropboxFolderMetadata | DropboxMetadataBase;\n\nfunction toRemoteEntry(raw: DropboxMetadata, parentPath: string): RemoteEntry | undefined {\n if (raw[\".tag\"] === \"deleted\") return undefined;\n const displayName = raw.name;\n const path = raw.path_display ?? joinDropboxPath(parentPath, displayName);\n const entry: RemoteEntry = {\n name: basenameRemotePath(path),\n path,\n raw,\n type: raw[\".tag\"] === \"folder\" ? \"directory\" : \"file\",\n };\n if (raw[\".tag\"] === \"file\") {\n const file = raw as DropboxFileMetadata;\n if (typeof file.size === \"number\") entry.size = file.size;\n const modified = file.server_modified ?? file.client_modified;\n if (typeof modified === \"string\") {\n const parsed = new Date(modified);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (typeof file.content_hash === \"string\") entry.uniqueId = file.content_hash;\n else if (typeof file.id === \"string\") entry.uniqueId = file.id;\n } else if (typeof raw.id === \"string\") {\n entry.uniqueId = raw.id;\n }\n return entry;\n}\n\nfunction toDropboxPath(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"\";\n return normalized;\n}\n\nfunction joinDropboxPath(parent: string, name: string): string {\n if (parent === \"\" || parent === \"/\") return `/${name}`;\n return parent.endsWith(\"/\") ? `${parent}${name}` : `${parent}/${name}`;\n}\n\nfunction parentDir(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/\";\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return normalized.slice(0, idx);\n}\n\nasync function safeReadText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\nfunction readApiResultHeader(response: Response): { content_hash?: string } | undefined {\n const header = response.headers.get(\"dropbox-api-result\");\n if (header === null || header === \"\") return undefined;\n try {\n return JSON.parse(header) as { content_hash?: string };\n } catch {\n return undefined;\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n","/**\n * Google Drive cloud-drive provider.\n *\n * Talks to the Google Drive v3 REST API using a bearer token sourced from the\n * connection profile (`profile.password` resolved as a `SecretSource`). Drive\n * is id-addressed rather than path-addressed; the provider maps incoming\n * remote paths to Drive file ids by walking from the configured root folder\n * (`options.rootFolderId`, defaults to the special id `\"root\"`).\n *\n * @module providers/cloud/GoogleDriveProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n formatRangeHeader,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"../web/httpInternals\";\n\nexport type { HttpFetch };\n\nconst GDRIVE_API_BASE = \"https://www.googleapis.com/drive/v3\";\nconst GDRIVE_UPLOAD_BASE = \"https://www.googleapis.com/upload/drive/v3\";\nconst GDRIVE_FOLDER_MIME = \"application/vnd.google-apps.folder\";\n\nconst GDRIVE_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"md5\", \"sha256\", \"crc32c\"];\n\nconst GDRIVE_FILE_FIELDS =\n \"id,name,mimeType,size,modifiedTime,createdTime,md5Checksum,sha256Checksum,parents,trashed\";\nconst GDRIVE_LIST_FIELDS = `nextPageToken,files(${GDRIVE_FILE_FIELDS})`;\n\n/** Options accepted by {@link createGoogleDriveProviderFactory}. */\nexport interface GoogleDriveProviderOptions {\n /** Provider id to register. Defaults to `\"google-drive\"`. */\n id?: ProviderId;\n /** Override the API base URL. Defaults to `https://www.googleapis.com/drive/v3`. */\n apiBaseUrl?: string;\n /** Override the upload base URL. Defaults to `https://www.googleapis.com/upload/drive/v3`. */\n uploadBaseUrl?: string;\n /**\n * Folder id used as the root for path resolution. Defaults to `\"root\"` (the\n * authenticated user's My Drive root). Pass a folder id when the SDK should\n * scope to a shared drive subtree.\n */\n rootFolderId?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied to every request before bearer auth. */\n defaultHeaders?: Record<string, string>;\n}\n\n/**\n * Creates a Google Drive provider factory.\n *\n * The bearer token is resolved per-connection from `profile.password`\n * (typically an OAuth 2 access token). `profile.host` is unused.\n */\nexport function createGoogleDriveProviderFactory(\n options: GoogleDriveProviderOptions = {},\n): ProviderFactory {\n const id: ProviderId = options.id ?? \"google-drive\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const apiBaseUrl = options.apiBaseUrl ?? GDRIVE_API_BASE;\n const uploadBaseUrl = options.uploadBaseUrl ?? GDRIVE_UPLOAD_BASE;\n const rootFolderId = options.rootFolderId ?? \"root\";\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply GoogleDriveProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"token\", \"oauth\"],\n checksum: [...GDRIVE_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 4,\n metadata: [\"modifiedAt\", \"createdAt\", \"mimeType\", \"uniqueId\"],\n notes: [\n \"Google Drive provider performs single-shot multipart uploads via /upload/drive/v3/files; resumable upload sessions are not yet supported.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new GoogleDriveProvider({\n apiBaseUrl,\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n fetch: fetchImpl,\n id,\n rootFolderId,\n uploadBaseUrl,\n }),\n id,\n };\n}\n\ninterface GoogleDriveInternalOptions {\n apiBaseUrl: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n rootFolderId: string;\n uploadBaseUrl: string;\n}\n\nclass GoogleDriveProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: GoogleDriveInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n if (profile.password === undefined) {\n throw new ConfigurationError({\n message: \"Google Drive provider requires a bearer token via profile.password\",\n retryable: false,\n });\n }\n const token = secretToString(await resolveSecret(profile.password));\n if (token === \"\") {\n throw new ConfigurationError({\n message: \"Google Drive bearer token resolved to an empty string\",\n retryable: false,\n });\n }\n const sessionOptions: GoogleDriveSessionOptions = {\n apiBaseUrl: this.internals.apiBaseUrl,\n capabilities: this.internals.capabilities,\n defaultHeaders: this.internals.defaultHeaders,\n fetch: this.internals.fetch,\n id: this.internals.id,\n rootFolderId: this.internals.rootFolderId,\n token,\n uploadBaseUrl: this.internals.uploadBaseUrl,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new GoogleDriveSession(sessionOptions);\n }\n}\n\ninterface GoogleDriveSessionOptions {\n apiBaseUrl: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n rootFolderId: string;\n timeoutMs?: number;\n token: string;\n uploadBaseUrl: string;\n}\n\nclass GoogleDriveSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: GoogleDriveSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n const resolver = new GoogleDrivePathResolver(options);\n this.fs = new GoogleDriveFileSystem(options, resolver);\n this.transfers = new GoogleDriveTransferOperations(options, resolver);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\ninterface DriveFileResource {\n id: string;\n name: string;\n mimeType: string;\n size?: string;\n modifiedTime?: string;\n createdTime?: string;\n md5Checksum?: string;\n sha256Checksum?: string;\n parents?: string[];\n trashed?: boolean;\n}\n\ninterface DriveListResponse {\n files: DriveFileResource[];\n nextPageToken?: string;\n}\n\nclass GoogleDrivePathResolver {\n private readonly cache = new Map<string, DriveFileResource>();\n\n constructor(private readonly options: GoogleDriveSessionOptions) {}\n\n /** Resolves an absolute remote path to the Drive file resource for that node. */\n async resolvePath(path: string): Promise<DriveFileResource> {\n const normalized = normalizeRemotePath(path);\n if (normalized === \"/\" || normalized === \"\") {\n return {\n id: this.options.rootFolderId,\n mimeType: GDRIVE_FOLDER_MIME,\n name: \"\",\n };\n }\n const cached = this.cache.get(normalized);\n if (cached !== undefined) return cached;\n const segments = normalized.split(\"/\").filter((s) => s !== \"\");\n let parent: DriveFileResource = {\n id: this.options.rootFolderId,\n mimeType: GDRIVE_FOLDER_MIME,\n name: \"\",\n };\n let walked = \"\";\n for (const segment of segments) {\n const child = await this.findChild(parent.id, segment);\n if (child === undefined) {\n throw new PathNotFoundError({\n details: { path: normalized },\n message: `Google Drive path not found: ${normalized}`,\n retryable: false,\n });\n }\n walked = `${walked}/${segment}`;\n this.cache.set(walked, child);\n parent = child;\n }\n return parent;\n }\n\n /** Resolves the parent folder id for a path; throws on missing parent. */\n async resolveParentId(path: string): Promise<string> {\n const normalized = normalizeRemotePath(path);\n if (normalized === \"/\" || normalized === \"\") return this.options.rootFolderId;\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return this.options.rootFolderId;\n const parentPath = normalized.slice(0, idx);\n const parent = await this.resolvePath(parentPath);\n return parent.id;\n }\n\n private async findChild(parentId: string, name: string): Promise<DriveFileResource | undefined> {\n const q = `'${escapeDriveQ(parentId)}' in parents and name = '${escapeDriveQ(name)}' and trashed = false`;\n const response = await driveApi(\n this.options,\n \"GET\",\n `/files?${buildSearch({\n fields: GDRIVE_LIST_FIELDS,\n pageSize: \"10\",\n q,\n supportsAllDrives: \"true\",\n includeItemsFromAllDrives: \"true\",\n })}`,\n );\n const parsed = (await response.json()) as DriveListResponse;\n return parsed.files.find((f) => f.name === name);\n }\n}\n\nclass GoogleDriveFileSystem implements RemoteFileSystem {\n constructor(\n private readonly options: GoogleDriveSessionOptions,\n private readonly resolver: GoogleDrivePathResolver,\n ) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const folder = await this.resolver.resolvePath(path);\n if (folder.mimeType !== GDRIVE_FOLDER_MIME && folder.id !== this.options.rootFolderId) {\n throw new PathNotFoundError({\n details: { path },\n message: `Google Drive path is not a folder: ${path}`,\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(path);\n const entries: RemoteEntry[] = [];\n let pageToken: string | undefined;\n do {\n const params: Record<string, string> = {\n fields: GDRIVE_LIST_FIELDS,\n includeItemsFromAllDrives: \"true\",\n pageSize: \"100\",\n q: `'${escapeDriveQ(folder.id)}' in parents and trashed = false`,\n supportsAllDrives: \"true\",\n };\n if (pageToken !== undefined) params[\"pageToken\"] = pageToken;\n const response = await driveApi(this.options, \"GET\", `/files?${buildSearch(params)}`);\n const parsed = (await response.json()) as DriveListResponse;\n for (const file of parsed.files) {\n entries.push(toRemoteEntry(file, normalized));\n }\n pageToken = parsed.nextPageToken;\n } while (pageToken !== undefined);\n return entries;\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const file = await this.resolver.resolvePath(path);\n const normalized = normalizeRemotePath(path);\n const parent = parentDir(normalized);\n const entry = toRemoteEntry(file, parent);\n return { ...entry, exists: true };\n }\n}\n\nclass GoogleDriveTransferOperations implements ProviderTransferOperations {\n constructor(\n private readonly options: GoogleDriveSessionOptions,\n private readonly resolver: GoogleDrivePathResolver,\n ) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const file = await this.resolver.resolvePath(normalized);\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n const params = buildSearch({ alt: \"media\", supportsAllDrives: \"true\" });\n const response = await driveFetch(\n this.options,\n \"GET\",\n `${this.options.apiBaseUrl}/files/${encodeURIComponent(file.id)}?${params}`,\n {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n },\n );\n if (!response.ok && response.status !== 206) {\n throw mapGoogleDriveResponseError(response, normalized, await safeReadText(response));\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n details: { path: normalized },\n message: `Google Drive download for ${normalized} produced no body`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n if (typeof file.md5Checksum === \"string\" && file.md5Checksum.length > 0) {\n result.checksum = file.md5Checksum;\n }\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"Google Drive provider does not yet support resumable upload sessions\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const buffered = await collectChunks(request.content);\n const parentId = await this.resolver.resolveParentId(normalized);\n const name = basenameRemotePath(normalized);\n const existing = await this.findExisting(parentId, name);\n\n const metadata: Record<string, unknown> = { name };\n if (existing === undefined) metadata[\"parents\"] = [parentId];\n\n const boundary = `----zt-boundary-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`;\n const bodyParts: Uint8Array[] = [];\n const enc = new TextEncoder();\n bodyParts.push(\n enc.encode(\n `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${JSON.stringify(metadata)}\\r\\n`,\n ),\n );\n bodyParts.push(enc.encode(`--${boundary}\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n`));\n bodyParts.push(buffered);\n bodyParts.push(enc.encode(`\\r\\n--${boundary}--\\r\\n`));\n const body = concatChunks(bodyParts);\n\n const url =\n existing === undefined\n ? `${this.options.uploadBaseUrl}/files?uploadType=multipart&supportsAllDrives=true&fields=${encodeURIComponent(GDRIVE_FILE_FIELDS)}`\n : `${this.options.uploadBaseUrl}/files/${encodeURIComponent(existing.id)}?uploadType=multipart&supportsAllDrives=true&fields=${encodeURIComponent(GDRIVE_FILE_FIELDS)}`;\n const method = existing === undefined ? \"POST\" : \"PATCH\";\n\n const response = await driveFetch(this.options, method, url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body,\n extraHeaders: { \"content-type\": `multipart/related; boundary=${boundary}` },\n });\n if (!response.ok) {\n throw mapGoogleDriveResponseError(response, normalized, await safeReadText(response));\n }\n const meta = (await response.json()) as DriveFileResource;\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n if (typeof meta.md5Checksum === \"string\" && meta.md5Checksum.length > 0) {\n result.checksum = meta.md5Checksum;\n }\n return result;\n }\n\n private async findExisting(\n parentId: string,\n name: string,\n ): Promise<DriveFileResource | undefined> {\n const q = `'${escapeDriveQ(parentId)}' in parents and name = '${escapeDriveQ(name)}' and trashed = false`;\n const response = await driveApi(\n this.options,\n \"GET\",\n `/files?${buildSearch({\n fields: GDRIVE_LIST_FIELDS,\n includeItemsFromAllDrives: \"true\",\n pageSize: \"10\",\n q,\n supportsAllDrives: \"true\",\n })}`,\n );\n const parsed = (await response.json()) as DriveListResponse;\n return parsed.files.find((f) => f.name === name);\n }\n}\n\ninterface DriveFetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function driveFetch(\n options: GoogleDriveSessionOptions,\n method: string,\n url: string,\n fetchOptions: DriveFetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n authorization: `Bearer ${options.token}`,\n };\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) {\n (init as { body: Uint8Array }).body = fetchOptions.body;\n }\n const controller = new AbortController();\n const upstream = fetchOptions.signal ?? null;\n if (upstream !== null) {\n if (upstream.aborted) controller.abort(upstream.reason);\n else upstream.addEventListener(\"abort\", () => controller.abort(upstream.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"Google Drive request timed out\")),\n options.timeoutMs,\n );\n }\n try {\n return await options.fetch(url, { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url },\n message: `Google Drive request to ${url} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nasync function driveApi(\n options: GoogleDriveSessionOptions,\n method: string,\n apiPath: string,\n): Promise<Response> {\n const url = `${options.apiBaseUrl}${apiPath}`;\n const response = await driveFetch(options, method, url);\n if (!response.ok) {\n const text = await safeReadText(response);\n throw mapGoogleDriveResponseError(response, apiPath, text);\n }\n return response;\n}\n\nfunction mapGoogleDriveResponseError(\n response: Response,\n contextPath: string,\n bodyText: string,\n): Error {\n const details = {\n bodyText: bodyText.slice(0, 500),\n path: contextPath,\n status: response.status,\n statusText: response.statusText,\n };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `Google Drive authentication failed for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `Google Drive access forbidden for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `Google Drive path not found: ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 429) {\n return new ConnectionError({\n details,\n message: `Google Drive rate limit hit for ${contextPath}`,\n retryable: true,\n });\n }\n return new ConnectionError({\n details,\n message: `Google Drive request for ${contextPath} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\nfunction toRemoteEntry(file: DriveFileResource, parent: string): RemoteEntry {\n const path = joinDrivePath(parent, file.name);\n const entry: RemoteEntry = {\n name: file.name,\n path,\n raw: file,\n type: file.mimeType === GDRIVE_FOLDER_MIME ? \"directory\" : \"file\",\n uniqueId: file.id,\n };\n if (typeof file.size === \"string\") {\n const sized = Number(file.size);\n if (Number.isFinite(sized)) entry.size = sized;\n }\n if (typeof file.modifiedTime === \"string\") {\n const parsed = new Date(file.modifiedTime);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (typeof file.createdTime === \"string\") {\n const parsed = new Date(file.createdTime);\n if (!Number.isNaN(parsed.getTime())) entry.createdAt = parsed;\n }\n return entry;\n}\n\nfunction joinDrivePath(parent: string, name: string): string {\n if (parent === \"\" || parent === \"/\") return `/${name}`;\n return parent.endsWith(\"/\") ? `${parent}${name}` : `${parent}/${name}`;\n}\n\nfunction parentDir(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/\";\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return normalized.slice(0, idx);\n}\n\nfunction escapeDriveQ(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\nfunction buildSearch(params: Record<string, string>): string {\n const search = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) search.set(k, v);\n return search.toString();\n}\n\nasync function safeReadText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n return concatChunks(chunks, total);\n}\n\nfunction concatChunks(chunks: Uint8Array[], totalSize?: number): Uint8Array {\n const total = totalSize ?? chunks.reduce((acc, c) => acc + c.byteLength, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\n// `Buffer` is referenced indirectly by the shared `secretToString` helper; this\n// import keeps tree-shaking simple alongside the other web providers.\nvoid Buffer;\n","/**\n * Microsoft OneDrive / SharePoint cloud-drive provider.\n *\n * Talks to the Microsoft Graph v1.0 API. The provider is path-addressed\n * (`/drive/root:/path/to/file`) and uses a bearer token sourced from\n * `profile.password` (resolved as a `SecretSource`). The drive root can be\n * scoped via {@link OneDriveProviderOptions.driveBaseUrl} — the default is\n * `https://graph.microsoft.com/v1.0/me/drive`, which targets the signed-in\n * user's OneDrive. SharePoint document libraries are addressed by overriding\n * `driveBaseUrl` to `https://graph.microsoft.com/v1.0/drives/{driveId}` or\n * `/sites/{siteId}/drives/{driveId}`.\n *\n * @module providers/cloud/OneDriveProvider\n */\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n formatRangeHeader,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"../web/httpInternals\";\n\nexport type { HttpFetch };\n\nconst ONEDRIVE_DRIVE_BASE = \"https://graph.microsoft.com/v1.0/me/drive\";\nconst ONEDRIVE_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"sha1\", \"sha256\", \"quickxorhash\"];\n\n/** Options accepted by {@link createOneDriveProviderFactory}. */\nexport interface OneDriveProviderOptions {\n /** Provider id to register. Defaults to `\"one-drive\"`. */\n id?: ProviderId;\n /**\n * Drive root URL used as the prefix for every Graph call. Defaults to\n * `https://graph.microsoft.com/v1.0/me/drive`. Override with a SharePoint\n * drive URL like `https://graph.microsoft.com/v1.0/drives/{driveId}`.\n */\n driveBaseUrl?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied before bearer auth on every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/**\n * Creates a OneDrive/SharePoint provider factory backed by Microsoft Graph.\n *\n * The bearer token is resolved per-connection from `profile.password`.\n * `profile.host` is unused.\n */\nexport function createOneDriveProviderFactory(\n options: OneDriveProviderOptions = {},\n): ProviderFactory {\n const id: ProviderId = options.id ?? \"one-drive\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const driveBaseUrl = (options.driveBaseUrl ?? ONEDRIVE_DRIVE_BASE).replace(/\\/+$/u, \"\");\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply OneDriveProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"token\", \"oauth\"],\n checksum: [...ONEDRIVE_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 4,\n metadata: [\"modifiedAt\", \"createdAt\", \"uniqueId\"],\n notes: [\n \"OneDrive provider performs single-shot uploads via PUT /content; resumable upload sessions are not yet supported.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new OneDriveProvider({\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n driveBaseUrl,\n fetch: fetchImpl,\n id,\n }),\n id,\n };\n}\n\ninterface OneDriveInternalOptions {\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n driveBaseUrl: string;\n fetch: HttpFetch;\n id: ProviderId;\n}\n\nclass OneDriveProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: OneDriveInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n if (profile.password === undefined) {\n throw new ConfigurationError({\n message: \"OneDrive provider requires a bearer token via profile.password\",\n retryable: false,\n });\n }\n const token = secretToString(await resolveSecret(profile.password));\n if (token === \"\") {\n throw new ConfigurationError({\n message: \"OneDrive bearer token resolved to an empty string\",\n retryable: false,\n });\n }\n const sessionOptions: OneDriveSessionOptions = {\n capabilities: this.internals.capabilities,\n defaultHeaders: this.internals.defaultHeaders,\n driveBaseUrl: this.internals.driveBaseUrl,\n fetch: this.internals.fetch,\n id: this.internals.id,\n token,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new OneDriveSession(sessionOptions);\n }\n}\n\ninterface OneDriveSessionOptions {\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n driveBaseUrl: string;\n fetch: HttpFetch;\n id: ProviderId;\n timeoutMs?: number;\n token: string;\n}\n\nclass OneDriveSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: OneDriveSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new OneDriveFileSystem(options);\n this.transfers = new OneDriveTransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\ninterface DriveItemHashes {\n sha1Hash?: string;\n sha256Hash?: string;\n quickXorHash?: string;\n}\n\ninterface DriveItemFile {\n hashes?: DriveItemHashes;\n mimeType?: string;\n}\n\ninterface DriveItem {\n id: string;\n name: string;\n size?: number;\n lastModifiedDateTime?: string;\n createdDateTime?: string;\n parentReference?: { path?: string };\n file?: DriveItemFile;\n folder?: { childCount?: number };\n eTag?: string;\n}\n\ninterface DriveChildrenResponse {\n value: DriveItem[];\n \"@odata.nextLink\"?: string;\n}\n\nclass OneDriveFileSystem implements RemoteFileSystem {\n constructor(private readonly options: OneDriveSessionOptions) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const normalized = normalizeRemotePath(path);\n const initial = `${this.options.driveBaseUrl}${itemChildrenSegment(normalized)}`;\n const entries: RemoteEntry[] = [];\n let nextUrl: string | undefined = initial;\n while (nextUrl !== undefined) {\n const response = await graphFetch(this.options, \"GET\", nextUrl);\n if (!response.ok) {\n throw mapOneDriveResponseError(response, normalized, await safeReadText(response));\n }\n const parsed = (await response.json()) as DriveChildrenResponse;\n for (const item of parsed.value) {\n entries.push(toRemoteEntry(item, normalized));\n }\n nextUrl = parsed[\"@odata.nextLink\"];\n }\n return entries;\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const url = `${this.options.driveBaseUrl}${itemSegment(normalized)}`;\n const response = await graphFetch(this.options, \"GET\", url);\n if (!response.ok) {\n throw mapOneDriveResponseError(response, normalized, await safeReadText(response));\n }\n const item = (await response.json()) as DriveItem;\n const parent = parentDir(normalized);\n const entry = toRemoteEntry(item, parent);\n return { ...entry, exists: true };\n }\n}\n\nclass OneDriveTransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: OneDriveSessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const url = `${this.options.driveBaseUrl}${itemSegment(normalized)}/content`;\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n // Microsoft Graph 302-redirects /content to a short-lived blob URL; fetch\n // implementations follow redirects by default. We probe item metadata\n // first so the file checksum can be surfaced on the read result.\n const meta = await this.fetchItem(normalized);\n const response = await graphFetch(this.options, \"GET\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n });\n if (!response.ok && response.status !== 206) {\n throw mapOneDriveResponseError(response, normalized, await safeReadText(response));\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n details: { path: normalized },\n message: `OneDrive download for ${normalized} produced no body`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const checksum = preferHash(meta.file?.hashes);\n if (checksum !== undefined) result.checksum = checksum;\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"OneDrive provider does not yet support resumable upload sessions\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const buffered = await collectChunks(request.content);\n const url = `${this.options.driveBaseUrl}${itemSegment(normalized)}/content`;\n const response = await graphFetch(this.options, \"PUT\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: buffered,\n extraHeaders: { \"content-type\": \"application/octet-stream\" },\n });\n if (!response.ok) {\n throw mapOneDriveResponseError(response, normalized, await safeReadText(response));\n }\n const item = (await response.json()) as DriveItem;\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n const checksum = preferHash(item.file?.hashes);\n if (checksum !== undefined) result.checksum = checksum;\n return result;\n }\n\n private async fetchItem(normalized: string): Promise<DriveItem> {\n const url = `${this.options.driveBaseUrl}${itemSegment(normalized)}`;\n const response = await graphFetch(this.options, \"GET\", url);\n if (!response.ok) {\n throw mapOneDriveResponseError(response, normalized, await safeReadText(response));\n }\n return (await response.json()) as DriveItem;\n }\n}\n\ninterface GraphFetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function graphFetch(\n options: OneDriveSessionOptions,\n method: string,\n url: string,\n fetchOptions: GraphFetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n accept: \"application/json\",\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n authorization: `Bearer ${options.token}`,\n };\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) {\n (init as { body: Uint8Array }).body = fetchOptions.body;\n }\n const controller = new AbortController();\n const upstream = fetchOptions.signal ?? null;\n if (upstream !== null) {\n if (upstream.aborted) controller.abort(upstream.reason);\n else upstream.addEventListener(\"abort\", () => controller.abort(upstream.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"OneDrive request timed out\")),\n options.timeoutMs,\n );\n }\n try {\n return await options.fetch(url, { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url },\n message: `OneDrive request to ${url} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nfunction mapOneDriveResponseError(\n response: Response,\n contextPath: string,\n bodyText: string,\n): Error {\n const details = {\n bodyText: bodyText.slice(0, 500),\n path: contextPath,\n status: response.status,\n statusText: response.statusText,\n };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `OneDrive authentication failed for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `OneDrive access forbidden for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `OneDrive path not found: ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 429) {\n return new ConnectionError({\n details,\n message: `OneDrive rate limit hit for ${contextPath}`,\n retryable: true,\n });\n }\n return new ConnectionError({\n details,\n message: `OneDrive request for ${contextPath} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\nfunction toRemoteEntry(item: DriveItem, parent: string): RemoteEntry {\n const path = joinPath(parent, item.name);\n const entry: RemoteEntry = {\n name: item.name,\n path,\n raw: item,\n type: item.folder !== undefined ? \"directory\" : \"file\",\n uniqueId: item.id,\n };\n if (typeof item.size === \"number\") entry.size = item.size;\n if (typeof item.lastModifiedDateTime === \"string\") {\n const parsed = new Date(item.lastModifiedDateTime);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (typeof item.createdDateTime === \"string\") {\n const parsed = new Date(item.createdDateTime);\n if (!Number.isNaN(parsed.getTime())) entry.createdAt = parsed;\n }\n return entry;\n}\n\nfunction preferHash(hashes: DriveItemHashes | undefined): string | undefined {\n if (hashes === undefined) return undefined;\n if (typeof hashes.sha256Hash === \"string\" && hashes.sha256Hash.length > 0) {\n return hashes.sha256Hash;\n }\n if (typeof hashes.sha1Hash === \"string\" && hashes.sha1Hash.length > 0) {\n return hashes.sha1Hash;\n }\n if (typeof hashes.quickXorHash === \"string\" && hashes.quickXorHash.length > 0) {\n return hashes.quickXorHash;\n }\n return undefined;\n}\n\n/** Builds the `/root` or `/root:/encoded/path:` segment for a Graph drive URL. */\nfunction itemSegment(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/root\";\n const trimmed = normalized.replace(/^\\/+/u, \"\");\n return `/root:/${encodeDrivePath(trimmed)}:`;\n}\n\n/** Builds the `/root/children` or `/root:/path:/children` listing segment. */\nfunction itemChildrenSegment(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/root/children\";\n const trimmed = normalized.replace(/^\\/+/u, \"\");\n return `/root:/${encodeDrivePath(trimmed)}:/children`;\n}\n\nfunction encodeDrivePath(value: string): string {\n return value\n .split(\"/\")\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction joinPath(parent: string, name: string): string {\n if (parent === \"\" || parent === \"/\") return `/${name}`;\n return parent.endsWith(\"/\") ? `${parent}${name}` : `${parent}/${name}`;\n}\n\nfunction parentDir(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/\";\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return normalized.slice(0, idx);\n}\n\nasync function safeReadText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n","/**\n * Azure Blob Storage object-store provider.\n *\n * Targets the Azure Blob REST API (`https://{account}.blob.core.windows.net`)\n * and supports listing blobs in a container, reading ranged blob content,\n * single-shot block-blob uploads via `PUT`, and HEAD-based stat. Authentication\n * is via SAS token (appended to every URL) or a pre-resolved bearer token from\n * `profile.password` (`Authorization: Bearer ...` for AAD scenarios).\n *\n * @module providers/cloud/AzureBlobProvider\n */\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n formatRangeHeader,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"../web/httpInternals\";\n\nexport type { HttpFetch };\n\nconst AZURE_BLOB_API_VERSION = \"2023-11-03\";\nconst AZURE_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"md5\"];\n\n/** Options accepted by {@link createAzureBlobProviderFactory}. */\nexport interface AzureBlobProviderOptions {\n /** Provider id to register. Defaults to `\"azure-blob\"`. */\n id?: ProviderId;\n /** Storage account name; combined with `endpoint` when no full URL is supplied. */\n account?: string;\n /** Container name. Required. */\n container: string;\n /**\n * Override the endpoint host. Defaults to\n * `https://{account}.blob.core.windows.net`. Provide for sovereign clouds\n * or Azurite (`http://127.0.0.1:10000/devstoreaccount1`).\n */\n endpoint?: string;\n /** SAS token query string (without leading `?`). Mutually compatible with bearer auth. */\n sasToken?: string;\n /** Override the `x-ms-version` header. */\n apiVersion?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied before bearer auth on every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/** Creates an Azure Blob Storage provider factory. */\nexport function createAzureBlobProviderFactory(options: AzureBlobProviderOptions): ProviderFactory {\n if (typeof options.container !== \"string\" || options.container === \"\") {\n throw new ConfigurationError({\n message: \"AzureBlobProviderOptions.container is required\",\n retryable: false,\n });\n }\n const id: ProviderId = options.id ?? \"azure-blob\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply AzureBlobProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n const endpoint = resolveAzureEndpoint(options);\n const apiVersion = options.apiVersion ?? AZURE_BLOB_API_VERSION;\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"token\", \"oauth\"],\n checksum: [...AZURE_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 4,\n metadata: [\"modifiedAt\", \"uniqueId\"],\n notes: [\n \"Azure Blob provider performs single-shot block-blob uploads via PUT; staged-block + Put Block List uploads are not yet supported.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new AzureBlobProvider({\n apiVersion,\n capabilities,\n container: options.container,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n endpoint,\n fetch: fetchImpl,\n id,\n ...(options.sasToken !== undefined ? { sasToken: options.sasToken } : {}),\n }),\n id,\n };\n}\n\nfunction resolveAzureEndpoint(options: AzureBlobProviderOptions): string {\n if (typeof options.endpoint === \"string\" && options.endpoint !== \"\") {\n return options.endpoint.replace(/\\/+$/u, \"\");\n }\n if (typeof options.account === \"string\" && options.account !== \"\") {\n return `https://${options.account}.blob.core.windows.net`;\n }\n throw new ConfigurationError({\n message: \"AzureBlobProviderOptions requires either `account` or `endpoint`\",\n retryable: false,\n });\n}\n\ninterface AzureBlobInternalOptions {\n apiVersion: string;\n capabilities: CapabilitySet;\n container: string;\n defaultHeaders: Record<string, string>;\n endpoint: string;\n fetch: HttpFetch;\n id: ProviderId;\n sasToken?: string;\n}\n\nclass AzureBlobProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: AzureBlobInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n let bearerToken: string | undefined;\n if (profile.password !== undefined) {\n bearerToken = secretToString(await resolveSecret(profile.password));\n if (bearerToken === \"\") bearerToken = undefined;\n }\n if (bearerToken === undefined && this.internals.sasToken === undefined) {\n throw new ConfigurationError({\n message:\n \"Azure Blob provider requires either a SAS token (via options.sasToken) or a bearer token (via profile.password)\",\n retryable: false,\n });\n }\n const sessionOptions: AzureBlobSessionOptions = {\n apiVersion: this.internals.apiVersion,\n capabilities: this.internals.capabilities,\n container: this.internals.container,\n defaultHeaders: this.internals.defaultHeaders,\n endpoint: this.internals.endpoint,\n fetch: this.internals.fetch,\n id: this.internals.id,\n };\n if (bearerToken !== undefined) sessionOptions.bearerToken = bearerToken;\n if (this.internals.sasToken !== undefined) sessionOptions.sasToken = this.internals.sasToken;\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new AzureBlobSession(sessionOptions);\n }\n}\n\ninterface AzureBlobSessionOptions {\n apiVersion: string;\n bearerToken?: string;\n capabilities: CapabilitySet;\n container: string;\n defaultHeaders: Record<string, string>;\n endpoint: string;\n fetch: HttpFetch;\n id: ProviderId;\n sasToken?: string;\n timeoutMs?: number;\n}\n\nclass AzureBlobSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: AzureBlobSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new AzureBlobFileSystem(options);\n this.transfers = new AzureBlobTransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass AzureBlobFileSystem implements RemoteFileSystem {\n constructor(private readonly options: AzureBlobSessionOptions) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const normalized = normalizeRemotePath(path);\n const prefix = toAzureBlobPrefix(normalized);\n const entries: RemoteEntry[] = [];\n let marker: string | undefined;\n do {\n const params: Record<string, string> = {\n comp: \"list\",\n delimiter: \"/\",\n restype: \"container\",\n };\n if (prefix !== \"\") params[\"prefix\"] = prefix;\n if (marker !== undefined) params[\"marker\"] = marker;\n const url = buildContainerUrl(this.options, params);\n const response = await azureFetch(this.options, \"GET\", url);\n if (!response.ok) {\n throw mapAzureResponseError(response, normalized, await safeReadText(response));\n }\n const xml = await response.text();\n const parsed = parseListBlobsResponse(xml);\n for (const blob of parsed.blobs) {\n if (blob.name.startsWith(prefix)) {\n const entry = blobToEntry(blob, prefix, normalized);\n if (entry !== undefined) entries.push(entry);\n }\n }\n for (const dir of parsed.prefixes) {\n const entry = prefixToEntry(dir, prefix, normalized);\n if (entry !== undefined) entries.push(entry);\n }\n marker = parsed.nextMarker;\n } while (marker !== undefined && marker !== \"\");\n return entries;\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const url = buildBlobUrl(this.options, normalized);\n const response = await azureFetch(this.options, \"HEAD\", url);\n if (!response.ok) {\n throw mapAzureResponseError(response, normalized, await safeReadText(response));\n }\n const sizeHeader = response.headers.get(\"content-length\");\n const size = sizeHeader !== null ? Number(sizeHeader) : undefined;\n const lastModified = response.headers.get(\"last-modified\");\n const etag = response.headers.get(\"etag\") ?? undefined;\n const md5 = response.headers.get(\"content-md5\") ?? undefined;\n const stat: RemoteStat = {\n exists: true,\n name: basenameRemotePath(normalized),\n path: normalized,\n type: \"file\",\n };\n if (typeof size === \"number\" && Number.isFinite(size)) stat.size = size;\n if (lastModified !== null) {\n const parsed = new Date(lastModified);\n if (!Number.isNaN(parsed.getTime())) stat.modifiedAt = parsed;\n }\n if (etag !== undefined) stat.uniqueId = etag;\n else if (md5 !== undefined) stat.uniqueId = md5;\n return stat;\n }\n}\n\nclass AzureBlobTransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: AzureBlobSessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const url = buildBlobUrl(this.options, normalized);\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n const response = await azureFetch(this.options, \"GET\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n });\n if (!response.ok && response.status !== 206) {\n throw mapAzureResponseError(response, normalized, await safeReadText(response));\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n details: { path: normalized },\n message: `Azure Blob download for ${normalized} produced no body`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const md5 = response.headers.get(\"content-md5\");\n if (md5 !== null && md5 !== \"\") result.checksum = md5;\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"Azure Blob provider does not yet support staged-block resumable uploads\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const buffered = await collectChunks(request.content);\n const url = buildBlobUrl(this.options, normalized);\n const response = await azureFetch(this.options, \"PUT\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: buffered,\n extraHeaders: {\n \"content-type\": \"application/octet-stream\",\n \"x-ms-blob-type\": \"BlockBlob\",\n },\n });\n if (!response.ok) {\n throw mapAzureResponseError(response, normalized, await safeReadText(response));\n }\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n const md5 = response.headers.get(\"content-md5\");\n if (md5 !== null && md5 !== \"\") result.checksum = md5;\n return result;\n }\n}\n\ninterface AzureFetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function azureFetch(\n options: AzureBlobSessionOptions,\n method: string,\n url: string,\n fetchOptions: AzureFetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n \"x-ms-version\": options.apiVersion,\n };\n if (options.bearerToken !== undefined) {\n headers[\"authorization\"] = `Bearer ${options.bearerToken}`;\n }\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) {\n (init as { body: Uint8Array }).body = fetchOptions.body;\n }\n const controller = new AbortController();\n const upstream = fetchOptions.signal ?? null;\n if (upstream !== null) {\n if (upstream.aborted) controller.abort(upstream.reason);\n else upstream.addEventListener(\"abort\", () => controller.abort(upstream.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"Azure Blob request timed out\")),\n options.timeoutMs,\n );\n }\n try {\n return await options.fetch(url, { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url },\n message: `Azure Blob request to ${url} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nfunction buildContainerUrl(\n options: AzureBlobSessionOptions,\n params: Record<string, string>,\n): string {\n const search = new URLSearchParams(params);\n appendSas(search, options.sasToken);\n return `${options.endpoint}/${encodeURIComponent(options.container)}?${search.toString()}`;\n}\n\nfunction buildBlobUrl(options: AzureBlobSessionOptions, normalized: string): string {\n const blobPath = normalized.replace(/^\\/+/u, \"\");\n const encoded = blobPath\n .split(\"/\")\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n const base = `${options.endpoint}/${encodeURIComponent(options.container)}/${encoded}`;\n if (options.sasToken !== undefined && options.sasToken !== \"\") {\n return `${base}?${options.sasToken}`;\n }\n return base;\n}\n\nfunction appendSas(search: URLSearchParams, sasToken: string | undefined): void {\n if (sasToken === undefined || sasToken === \"\") return;\n const sas = new URLSearchParams(sasToken);\n for (const [k, v] of sas.entries()) search.set(k, v);\n}\n\ninterface AzureBlobListing {\n blobs: Array<{\n name: string;\n contentLength?: number;\n contentMd5?: string;\n etag?: string;\n lastModified?: string;\n }>;\n prefixes: string[];\n nextMarker?: string;\n}\n\n/**\n * Minimal XML parser for `ListBlobs` responses. The Azure response is\n * deterministic, so we extract the fields we need with regex-driven slicing\n * rather than pulling in a full XML dependency.\n */\nfunction parseListBlobsResponse(xml: string): AzureBlobListing {\n const blobs: AzureBlobListing[\"blobs\"] = [];\n for (const match of xml.matchAll(/<Blob>([\\s\\S]*?)<\\/Blob>/g)) {\n const block = match[1] ?? \"\";\n const name = extractTag(block, \"Name\");\n if (name === undefined) continue;\n const blob: AzureBlobListing[\"blobs\"][number] = { name };\n const length = extractTag(block, \"Content-Length\");\n if (length !== undefined) {\n const parsed = Number(length);\n if (Number.isFinite(parsed)) blob.contentLength = parsed;\n }\n const md5 = extractTag(block, \"Content-MD5\");\n if (md5 !== undefined && md5 !== \"\") blob.contentMd5 = md5;\n const etag = extractTag(block, \"Etag\");\n if (etag !== undefined && etag !== \"\") blob.etag = etag;\n const last = extractTag(block, \"Last-Modified\");\n if (last !== undefined && last !== \"\") blob.lastModified = last;\n blobs.push(blob);\n }\n const prefixes: string[] = [];\n for (const match of xml.matchAll(/<BlobPrefix>([\\s\\S]*?)<\\/BlobPrefix>/g)) {\n const block = match[1] ?? \"\";\n const name = extractTag(block, \"Name\");\n if (name !== undefined) prefixes.push(name);\n }\n const nextMarker = extractTag(xml, \"NextMarker\");\n const result: AzureBlobListing = { blobs, prefixes };\n if (nextMarker !== undefined && nextMarker !== \"\") result.nextMarker = nextMarker;\n return result;\n}\n\nfunction extractTag(block: string, tag: string): string | undefined {\n const re = new RegExp(`<${tag}>([\\\\s\\\\S]*?)</${tag}>`);\n const match = re.exec(block);\n if (match === null) return undefined;\n return decodeXmlText(match[1] ?? \"\");\n}\n\nfunction decodeXmlText(value: string): string {\n return value\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\");\n}\n\nfunction blobToEntry(\n blob: AzureBlobListing[\"blobs\"][number],\n prefix: string,\n parent: string,\n): RemoteEntry | undefined {\n const tail = blob.name.slice(prefix.length);\n if (tail === \"\" || tail.includes(\"/\")) return undefined;\n const entry: RemoteEntry = {\n name: tail,\n path: joinPath(parent, tail),\n raw: blob,\n type: \"file\",\n uniqueId: blob.etag ?? blob.contentMd5 ?? blob.name,\n };\n if (typeof blob.contentLength === \"number\") entry.size = blob.contentLength;\n if (typeof blob.lastModified === \"string\") {\n const parsed = new Date(blob.lastModified);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n return entry;\n}\n\nfunction prefixToEntry(\n prefixedName: string,\n prefix: string,\n parent: string,\n): RemoteEntry | undefined {\n const tail = prefixedName.slice(prefix.length).replace(/\\/+$/u, \"\");\n if (tail === \"\" || tail.includes(\"/\")) return undefined;\n return {\n name: tail,\n path: joinPath(parent, tail),\n type: \"directory\",\n uniqueId: prefixedName,\n };\n}\n\nfunction toAzureBlobPrefix(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"\";\n const trimmed = normalized.replace(/^\\/+/u, \"\");\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\n}\n\nfunction joinPath(parent: string, name: string): string {\n if (parent === \"\" || parent === \"/\") return `/${name}`;\n return parent.endsWith(\"/\") ? `${parent}${name}` : `${parent}/${name}`;\n}\n\nfunction basenameRemotePath(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"\";\n const trimmed = normalized.replace(/\\/+$/u, \"\");\n const idx = trimmed.lastIndexOf(\"/\");\n return idx === -1 ? trimmed : trimmed.slice(idx + 1);\n}\n\nfunction mapAzureResponseError(response: Response, contextPath: string, bodyText: string): Error {\n const details = {\n bodyText: bodyText.slice(0, 500),\n path: contextPath,\n status: response.status,\n statusText: response.statusText,\n };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `Azure Blob authentication failed for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `Azure Blob access forbidden for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `Azure Blob path not found: ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 429) {\n return new ConnectionError({\n details,\n message: `Azure Blob throttled for ${contextPath}`,\n retryable: true,\n });\n }\n return new ConnectionError({\n details,\n message: `Azure Blob request for ${contextPath} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\nasync function safeReadText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n","/**\n * Google Cloud Storage object-store provider.\n *\n * Targets the GCS JSON API (`https://storage.googleapis.com/storage/v1/b/{bucket}/...`)\n * for listing/stat operations and the upload media endpoint\n * (`https://storage.googleapis.com/upload/storage/v1/b/{bucket}/o`) for\n * uploads. Authentication is via OAuth bearer token sourced from\n * `profile.password`.\n *\n * @module providers/cloud/GcsProvider\n */\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n formatRangeHeader,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"../web/httpInternals\";\n\nexport type { HttpFetch };\n\nconst GCS_JSON_API_BASE = \"https://storage.googleapis.com/storage/v1\";\nconst GCS_UPLOAD_API_BASE = \"https://storage.googleapis.com/upload/storage/v1\";\nconst GCS_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"md5\", \"crc32c\"];\n\n/** Options accepted by {@link createGcsProviderFactory}. */\nexport interface GcsProviderOptions {\n /** Provider id to register. Defaults to `\"gcs\"`. */\n id?: ProviderId;\n /** Bucket name. Required. */\n bucket: string;\n /** Override the JSON API base URL. */\n apiBaseUrl?: string;\n /** Override the upload API base URL. */\n uploadBaseUrl?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied before bearer auth on every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/** Creates a Google Cloud Storage provider factory. */\nexport function createGcsProviderFactory(options: GcsProviderOptions): ProviderFactory {\n if (typeof options.bucket !== \"string\" || options.bucket === \"\") {\n throw new ConfigurationError({\n message: \"GcsProviderOptions.bucket is required\",\n retryable: false,\n });\n }\n const id: ProviderId = options.id ?? \"gcs\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply GcsProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n const apiBaseUrl = (options.apiBaseUrl ?? GCS_JSON_API_BASE).replace(/\\/+$/u, \"\");\n const uploadBaseUrl = (options.uploadBaseUrl ?? GCS_UPLOAD_API_BASE).replace(/\\/+$/u, \"\");\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"token\", \"oauth\"],\n checksum: [...GCS_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 4,\n metadata: [\"modifiedAt\", \"createdAt\", \"uniqueId\"],\n notes: [\n \"GCS provider performs single-shot media uploads via /upload?uploadType=media; resumable upload sessions are not yet supported.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new GcsProvider({\n apiBaseUrl,\n bucket: options.bucket,\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n fetch: fetchImpl,\n id,\n uploadBaseUrl,\n }),\n id,\n };\n}\n\ninterface GcsInternalOptions {\n apiBaseUrl: string;\n bucket: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n uploadBaseUrl: string;\n}\n\nclass GcsProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: GcsInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n if (profile.password === undefined) {\n throw new ConfigurationError({\n message: \"GCS provider requires a bearer token via profile.password\",\n retryable: false,\n });\n }\n const token = secretToString(await resolveSecret(profile.password));\n if (token === \"\") {\n throw new ConfigurationError({\n message: \"GCS bearer token resolved to an empty string\",\n retryable: false,\n });\n }\n const sessionOptions: GcsSessionOptions = {\n apiBaseUrl: this.internals.apiBaseUrl,\n bucket: this.internals.bucket,\n capabilities: this.internals.capabilities,\n defaultHeaders: this.internals.defaultHeaders,\n fetch: this.internals.fetch,\n id: this.internals.id,\n token,\n uploadBaseUrl: this.internals.uploadBaseUrl,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new GcsSession(sessionOptions);\n }\n}\n\ninterface GcsSessionOptions {\n apiBaseUrl: string;\n bucket: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n timeoutMs?: number;\n token: string;\n uploadBaseUrl: string;\n}\n\nclass GcsSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: GcsSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new GcsFileSystem(options);\n this.transfers = new GcsTransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\ninterface GcsObject {\n name: string;\n size?: string;\n md5Hash?: string;\n crc32c?: string;\n etag?: string;\n updated?: string;\n timeCreated?: string;\n contentType?: string;\n}\n\ninterface GcsObjectsListResponse {\n items?: GcsObject[];\n prefixes?: string[];\n nextPageToken?: string;\n}\n\nclass GcsFileSystem implements RemoteFileSystem {\n constructor(private readonly options: GcsSessionOptions) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const normalized = normalizeRemotePath(path);\n const prefix = toGcsPrefix(normalized);\n const entries: RemoteEntry[] = [];\n let pageToken: string | undefined;\n do {\n const params: Record<string, string> = { delimiter: \"/\" };\n if (prefix !== \"\") params[\"prefix\"] = prefix;\n if (pageToken !== undefined) params[\"pageToken\"] = pageToken;\n const url = `${this.options.apiBaseUrl}/b/${encodeURIComponent(this.options.bucket)}/o?${buildSearch(params)}`;\n const response = await gcsFetch(this.options, \"GET\", url);\n if (!response.ok) {\n throw mapGcsResponseError(response, normalized, await safeReadText(response));\n }\n const parsed = (await response.json()) as GcsObjectsListResponse;\n for (const item of parsed.items ?? []) {\n const entry = objectToEntry(item, prefix, normalized);\n if (entry !== undefined) entries.push(entry);\n }\n for (const dirPrefix of parsed.prefixes ?? []) {\n const entry = prefixToEntry(dirPrefix, prefix, normalized);\n if (entry !== undefined) entries.push(entry);\n }\n pageToken = parsed.nextPageToken;\n } while (pageToken !== undefined);\n return entries;\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const objectName = toGcsObjectName(normalized);\n const url = `${this.options.apiBaseUrl}/b/${encodeURIComponent(this.options.bucket)}/o/${encodeURIComponent(objectName)}`;\n const response = await gcsFetch(this.options, \"GET\", url);\n if (!response.ok) {\n throw mapGcsResponseError(response, normalized, await safeReadText(response));\n }\n const item = (await response.json()) as GcsObject;\n const parent = parentDir(normalized);\n const entry = objectToEntry(item, toGcsPrefix(parent), parent);\n if (entry === undefined) {\n throw new PathNotFoundError({\n details: { path: normalized },\n message: `GCS path not found: ${normalized}`,\n retryable: false,\n });\n }\n return { ...entry, exists: true };\n }\n}\n\nclass GcsTransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: GcsSessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const objectName = toGcsObjectName(normalized);\n const url = `${this.options.apiBaseUrl}/b/${encodeURIComponent(this.options.bucket)}/o/${encodeURIComponent(objectName)}?alt=media`;\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n const response = await gcsFetch(this.options, \"GET\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n });\n if (!response.ok && response.status !== 206) {\n throw mapGcsResponseError(response, normalized, await safeReadText(response));\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n details: { path: normalized },\n message: `GCS download for ${normalized} produced no body`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const md5 = response.headers.get(\"x-goog-hash\") ?? response.headers.get(\"content-md5\");\n if (md5 !== null && md5 !== \"\") result.checksum = md5;\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"GCS provider does not yet support resumable upload sessions\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const objectName = toGcsObjectName(normalized);\n const buffered = await collectChunks(request.content);\n const url = `${this.options.uploadBaseUrl}/b/${encodeURIComponent(this.options.bucket)}/o?uploadType=media&name=${encodeURIComponent(objectName)}`;\n const response = await gcsFetch(this.options, \"POST\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: buffered,\n extraHeaders: { \"content-type\": \"application/octet-stream\" },\n });\n if (!response.ok) {\n throw mapGcsResponseError(response, normalized, await safeReadText(response));\n }\n const item = (await response.json()) as GcsObject;\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n if (typeof item.md5Hash === \"string\" && item.md5Hash !== \"\") result.checksum = item.md5Hash;\n return result;\n }\n}\n\ninterface GcsFetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function gcsFetch(\n options: GcsSessionOptions,\n method: string,\n url: string,\n fetchOptions: GcsFetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n accept: \"application/json\",\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n authorization: `Bearer ${options.token}`,\n };\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) {\n (init as { body: Uint8Array }).body = fetchOptions.body;\n }\n const controller = new AbortController();\n const upstream = fetchOptions.signal ?? null;\n if (upstream !== null) {\n if (upstream.aborted) controller.abort(upstream.reason);\n else upstream.addEventListener(\"abort\", () => controller.abort(upstream.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"GCS request timed out\")),\n options.timeoutMs,\n );\n }\n try {\n return await options.fetch(url, { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url },\n message: `GCS request to ${url} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nfunction objectToEntry(item: GcsObject, prefix: string, parent: string): RemoteEntry | undefined {\n const tail = item.name.startsWith(prefix) ? item.name.slice(prefix.length) : item.name;\n if (tail === \"\" || tail.includes(\"/\")) return undefined;\n const entry: RemoteEntry = {\n name: tail,\n path: joinPath(parent, tail),\n raw: item,\n type: \"file\",\n uniqueId: item.etag ?? item.md5Hash ?? item.name,\n };\n if (typeof item.size === \"string\") {\n const sized = Number(item.size);\n if (Number.isFinite(sized)) entry.size = sized;\n }\n if (typeof item.updated === \"string\") {\n const parsed = new Date(item.updated);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (typeof item.timeCreated === \"string\") {\n const parsed = new Date(item.timeCreated);\n if (!Number.isNaN(parsed.getTime())) entry.createdAt = parsed;\n }\n return entry;\n}\n\nfunction prefixToEntry(\n prefixedName: string,\n prefix: string,\n parent: string,\n): RemoteEntry | undefined {\n const tail = prefixedName.slice(prefix.length).replace(/\\/+$/u, \"\");\n if (tail === \"\" || tail.includes(\"/\")) return undefined;\n return {\n name: tail,\n path: joinPath(parent, tail),\n type: \"directory\",\n uniqueId: prefixedName,\n };\n}\n\nfunction toGcsPrefix(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"\";\n const trimmed = normalized.replace(/^\\/+/u, \"\");\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\n}\n\nfunction toGcsObjectName(normalized: string): string {\n return normalized.replace(/^\\/+/u, \"\");\n}\n\nfunction parentDir(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/\";\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return normalized.slice(0, idx);\n}\n\nfunction joinPath(parent: string, name: string): string {\n if (parent === \"\" || parent === \"/\") return `/${name}`;\n return parent.endsWith(\"/\") ? `${parent}${name}` : `${parent}/${name}`;\n}\n\nfunction buildSearch(params: Record<string, string>): string {\n const search = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) search.set(k, v);\n return search.toString();\n}\n\nfunction mapGcsResponseError(response: Response, contextPath: string, bodyText: string): Error {\n const details = {\n bodyText: bodyText.slice(0, 500),\n path: contextPath,\n status: response.status,\n statusText: response.statusText,\n };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `GCS authentication failed for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `GCS access forbidden for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `GCS path not found: ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 429) {\n return new ConnectionError({\n details,\n message: `GCS rate limit hit for ${contextPath}`,\n retryable: true,\n });\n }\n return new ConnectionError({\n details,\n message: `GCS request for ${contextPath} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\nasync function safeReadText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n","/**\n * Local file-system provider for deterministic provider contract coverage.\n *\n * @module providers/local/LocalProvider\n */\nimport { createReadStream } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n open,\n readdir,\n readlink,\n rename,\n rm,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { Buffer } from \"node:buffer\";\nimport type { Stats } from \"node:fs\";\nimport type { CapabilitySet } from \"../../core/CapabilitySet\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n ConfigurationError,\n PathNotFoundError,\n PermissionDeniedError,\n} from \"../../errors/ZeroTransferError\";\nimport type { TransferVerificationResult } from \"../../transfers/TransferJob\";\nimport type {\n ConnectionProfile,\n MkdirOptions,\n RemoteEntry,\n RemoteEntryType,\n RemoteStat,\n RemoveOptions,\n RmdirOptions,\n} from \"../../types/public\";\nimport { basenameRemotePath, joinRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\n\nconst LOCAL_PROVIDER_ID = \"local\";\n\nconst LOCAL_PROVIDER_CAPABILITIES: CapabilitySet = {\n provider: LOCAL_PROVIDER_ID,\n authentication: [\"anonymous\"],\n list: true,\n stat: true,\n readStream: true,\n writeStream: true,\n serverSideCopy: false,\n serverSideMove: false,\n resumeDownload: true,\n resumeUpload: true,\n checksum: [],\n atomicRename: false,\n chmod: false,\n chown: false,\n symlink: true,\n metadata: [\"accessedAt\", \"createdAt\", \"modifiedAt\", \"permissions\", \"symlinkTarget\", \"uniqueId\"],\n maxConcurrency: 16,\n notes: [\"Local filesystem provider for tests and local-only workflows\"],\n};\n\n/** Options used to create a local file-system provider factory. */\nexport interface LocalProviderOptions {\n /** Root directory exposed as `/`. When omitted, `profile.host` is treated as the root path. */\n rootPath?: string;\n}\n\n/**\n * Creates a provider factory backed by the local filesystem.\n *\n * Useful for copying files between two remote endpoints via a local staging\n * area, or as the destination for `downloadFile`. The friendly `uploadFile`\n * helper registers a local provider implicitly.\n *\n * @param options - Optional local root path exposed through provider sessions.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n *\n * @example Use a fixed root directory\n * ```ts\n * import { createLocalProviderFactory, createTransferClient } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({\n * providers: [createLocalProviderFactory({ rootPath: \"/var/lib/zt-staging\" })],\n * });\n *\n * const session = await client.connect({ host: \"staging\", provider: \"local\" });\n * const list = await session.fs.list(\"/\");\n * ```\n */\nexport function createLocalProviderFactory(options: LocalProviderOptions = {}): ProviderFactory {\n return {\n id: LOCAL_PROVIDER_ID,\n capabilities: LOCAL_PROVIDER_CAPABILITIES,\n create: () => new LocalProvider(options.rootPath),\n };\n}\n\nclass LocalProvider implements TransferProvider {\n readonly id = LOCAL_PROVIDER_ID;\n readonly capabilities = LOCAL_PROVIDER_CAPABILITIES;\n\n constructor(private readonly configuredRootPath: string | undefined) {}\n\n connect(profile: ConnectionProfile): Promise<TransferSession> {\n return Promise.resolve().then(() => {\n const rootPath = path.resolve(this.configuredRootPath ?? profile.host);\n return new LocalTransferSession(rootPath);\n });\n }\n}\n\nclass LocalTransferSession implements TransferSession {\n readonly provider = LOCAL_PROVIDER_ID;\n readonly capabilities = LOCAL_PROVIDER_CAPABILITIES;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(rootPath: string) {\n this.fs = new LocalFileSystem(rootPath);\n this.transfers = new LocalTransferOperations(rootPath);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass LocalTransferOperations implements ProviderTransferOperations {\n constructor(private readonly rootPath: string) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const remotePath = normalizeLocalProviderPath(request.endpoint.path);\n const entry = await readLocalEntry(this.rootPath, remotePath);\n\n if (entry.type !== \"file\") {\n throw createPathNotFoundError(remotePath, `Local provider path is not a file: ${remotePath}`);\n }\n\n const range = resolveReadRange(entry.size ?? 0, request.range);\n const result: ProviderTransferReadResult = {\n content: createLocalReadSource(resolveLocalPath(this.rootPath, remotePath), range),\n totalBytes: range.length,\n };\n\n if (range.offset > 0) {\n result.bytesRead = range.offset;\n }\n\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const remotePath = normalizeLocalProviderPath(request.endpoint.path);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n const content = await collectTransferContent(request);\n const offset = normalizeOptionalByteCount(request.offset, \"offset\", remotePath);\n\n await ensureLocalParentDirectory(localPath, remotePath);\n await writeLocalContent(localPath, remotePath, content, offset);\n\n const stat = await readLocalEntry(this.rootPath, remotePath);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: content.byteLength,\n resumed: offset !== undefined && offset > 0,\n verified: request.verification?.verified ?? false,\n };\n\n if (stat.size !== undefined) {\n result.totalBytes = stat.size;\n }\n\n if (request.verification !== undefined) {\n result.verification = cloneVerification(request.verification);\n }\n\n return result;\n }\n}\n\nclass LocalFileSystem implements RemoteFileSystem {\n constructor(private readonly rootPath: string) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const remotePath = normalizeLocalProviderPath(path);\n const directory = await this.stat(remotePath);\n\n if (directory.type !== \"directory\") {\n throw createPathNotFoundError(\n remotePath,\n `Local provider path is not a directory: ${remotePath}`,\n );\n }\n\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n const names = await readLocalDirectory(localPath, remotePath);\n const entries = await Promise.all(\n names.map((name) => readLocalEntry(this.rootPath, joinRemotePath(remotePath, name))),\n );\n\n return entries.sort(compareEntries);\n }\n\n async stat(path: string): Promise<RemoteStat> {\n return readLocalEntry(this.rootPath, normalizeLocalProviderPath(path));\n }\n\n async remove(remote: string, options: RemoveOptions = {}): Promise<void> {\n const remotePath = normalizeLocalProviderPath(remote);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n try {\n await unlink(localPath);\n } catch (error) {\n if (options.ignoreMissing && isNodeErrno(error, \"ENOENT\")) return;\n if (isNodeErrno(error, \"ENOENT\")) {\n throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);\n }\n throw error;\n }\n }\n\n async rename(from: string, to: string): Promise<void> {\n const fromRemote = normalizeLocalProviderPath(from);\n const toRemote = normalizeLocalProviderPath(to);\n const fromLocal = resolveLocalPath(this.rootPath, fromRemote);\n const toLocal = resolveLocalPath(this.rootPath, toRemote);\n try {\n await rename(fromLocal, toLocal);\n } catch (error) {\n if (isNodeErrno(error, \"ENOENT\")) {\n throw createPathNotFoundError(fromRemote, `Local path not found: ${fromRemote}`);\n }\n throw error;\n }\n }\n\n async mkdir(remote: string, options: MkdirOptions = {}): Promise<void> {\n const remotePath = normalizeLocalProviderPath(remote);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n await mkdir(localPath, { recursive: options.recursive === true });\n }\n\n async rmdir(remote: string, options: RmdirOptions = {}): Promise<void> {\n const remotePath = normalizeLocalProviderPath(remote);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n try {\n await rm(localPath, { recursive: options.recursive === true, force: false });\n } catch (error) {\n if (isNodeErrno(error, \"ENOENT\")) {\n if (options.ignoreMissing) return;\n throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);\n }\n throw error;\n }\n }\n}\n\nfunction isNodeErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\ninterface ResolvedReadRange {\n offset: number;\n length: number;\n}\n\nfunction resolveReadRange(\n size: number,\n range: ProviderTransferReadRequest[\"range\"],\n): ResolvedReadRange {\n if (range === undefined) {\n return { length: size, offset: 0 };\n }\n\n const requestedOffset = normalizeByteCount(range.offset, \"offset\", \"/\");\n const requestedLength =\n range.length === undefined\n ? size - Math.min(requestedOffset, size)\n : normalizeByteCount(range.length, \"length\", \"/\");\n const offset = Math.min(requestedOffset, size);\n const length = Math.max(0, Math.min(requestedLength, size - offset));\n\n return { length, offset };\n}\n\nasync function* createLocalReadSource(\n localPath: string,\n range: ResolvedReadRange,\n): AsyncGenerator<Uint8Array> {\n if (range.length <= 0) {\n return;\n }\n\n const stream = createReadStream(localPath, {\n end: range.offset + range.length - 1,\n start: range.offset,\n }) as AsyncIterable<Buffer>;\n\n for await (const chunk of stream) {\n yield new Uint8Array(chunk);\n }\n}\n\nasync function collectTransferContent(request: ProviderTransferWriteRequest): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let byteLength = 0;\n\n for await (const chunk of request.content) {\n request.throwIfAborted();\n const clonedChunk = new Uint8Array(chunk);\n chunks.push(clonedChunk);\n byteLength += clonedChunk.byteLength;\n request.reportProgress(byteLength, request.totalBytes);\n }\n\n return concatChunks(chunks, byteLength);\n}\n\nfunction concatChunks(chunks: Uint8Array[], byteLength: number): Uint8Array {\n const content = new Uint8Array(byteLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n content.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return content;\n}\n\nasync function ensureLocalParentDirectory(localPath: string, remotePath: string): Promise<void> {\n try {\n await mkdir(path.dirname(localPath), { recursive: true });\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n}\n\nasync function writeLocalContent(\n localPath: string,\n remotePath: string,\n content: Uint8Array,\n offset: number | undefined,\n): Promise<void> {\n try {\n if (offset === undefined) {\n await writeFile(localPath, content);\n return;\n }\n\n const handle = await openLocalFileForOffsetWrite(localPath);\n\n try {\n await handle.write(content, 0, content.byteLength, offset);\n } finally {\n await handle.close();\n }\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n}\n\nasync function openLocalFileForOffsetWrite(localPath: string) {\n try {\n return await open(localPath, \"r+\");\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return open(localPath, \"w+\");\n }\n\n throw error;\n }\n}\n\nfunction normalizeOptionalByteCount(\n value: number | undefined,\n field: string,\n remotePath: string,\n): number | undefined {\n return value === undefined ? undefined : normalizeByteCount(value, field, remotePath);\n}\n\nfunction normalizeByteCount(value: number, field: string, remotePath: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new ConfigurationError({\n details: { field, provider: LOCAL_PROVIDER_ID },\n message: `Local provider ${field} must be a non-negative number`,\n path: remotePath,\n retryable: false,\n });\n }\n\n return Math.floor(value);\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n\nasync function readLocalDirectory(localPath: string, remotePath: string): Promise<string[]> {\n try {\n return await readdir(localPath);\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n}\n\nasync function readLocalEntry(rootPath: string, remotePath: string): Promise<RemoteStat> {\n const localPath = resolveLocalPath(rootPath, remotePath);\n let stats: Stats;\n\n try {\n stats = await lstat(localPath);\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n\n const entry: RemoteEntry = {\n accessedAt: cloneDate(stats.atime),\n createdAt: cloneDate(stats.birthtime),\n modifiedAt: cloneDate(stats.mtime),\n name: basenameRemotePath(remotePath),\n path: remotePath,\n permissions: { raw: formatMode(stats.mode) },\n size: stats.size,\n type: getLocalEntryType(stats),\n uniqueId: `${stats.dev}:${stats.ino}`,\n };\n\n if (entry.type === \"symlink\") {\n const symlinkTarget = await readSymlinkTarget(localPath);\n\n if (symlinkTarget !== undefined) {\n entry.symlinkTarget = symlinkTarget;\n }\n }\n\n return {\n ...entry,\n exists: true,\n };\n}\n\nasync function readSymlinkTarget(localPath: string): Promise<string | undefined> {\n try {\n return await readlink(localPath);\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeLocalProviderPath(input: string): string {\n const normalized = normalizeRemotePath(input);\n\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n throw new ConfigurationError({\n details: { provider: LOCAL_PROVIDER_ID },\n message: `Local provider path escapes the configured root: ${normalized}`,\n path: normalized,\n retryable: false,\n });\n }\n\n if (normalized === \".\" || normalized === \"/\") {\n return \"/\";\n }\n\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction resolveLocalPath(rootPath: string, remotePath: string): string {\n const normalizedRemotePath = normalizeLocalProviderPath(remotePath);\n\n // If the remote path is already an absolute filesystem path inside rootPath\n // (e.g. friendly upload/download passes the host path as the endpoint path),\n // honour it directly instead of double-prepending rootPath.\n const resolvedRootPath = path.resolve(rootPath);\n const candidateAbsolute = path.resolve(normalizedRemotePath.split(\"/\").join(path.sep));\n if (\n candidateAbsolute === resolvedRootPath ||\n candidateAbsolute.startsWith(resolvedRootPath + path.sep)\n ) {\n return candidateAbsolute;\n }\n\n const relativePath = normalizedRemotePath === \"/\" ? \".\" : normalizedRemotePath.slice(1);\n const resolvedPath = path.resolve(rootPath, relativePath.split(\"/\").join(path.sep));\n const relativeToRoot = path.relative(rootPath, resolvedPath);\n\n if (\n relativeToRoot === \"\" ||\n (!relativeToRoot.startsWith(\"..\") && !path.isAbsolute(relativeToRoot))\n ) {\n return resolvedPath;\n }\n\n throw new ConfigurationError({\n details: { provider: LOCAL_PROVIDER_ID, rootPath },\n message: `Local provider path escapes the configured root: ${normalizedRemotePath}`,\n path: normalizedRemotePath,\n retryable: false,\n });\n}\n\nfunction getLocalEntryType(stats: Stats): RemoteEntryType {\n if (stats.isFile()) return \"file\";\n if (stats.isDirectory()) return \"directory\";\n if (stats.isSymbolicLink()) return \"symlink\";\n return \"unknown\";\n}\n\nfunction formatMode(mode: number): string {\n return (mode & 0o777).toString(8).padStart(3, \"0\");\n}\n\nfunction cloneDate(value: Date): Date {\n return new Date(value.getTime());\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction mapLocalFileSystemError(error: unknown, remotePath: string): Error {\n const code = getErrorCode(error);\n\n if (code === \"ENOENT\" || code === \"ENOTDIR\") {\n return createPathNotFoundError(remotePath, `Local provider path not found: ${remotePath}`);\n }\n\n if (code === \"EACCES\" || code === \"EPERM\") {\n return new PermissionDeniedError({\n cause: error,\n details: { provider: LOCAL_PROVIDER_ID },\n message: `Local provider permission denied: ${remotePath}`,\n path: remotePath,\n retryable: false,\n });\n }\n\n return new ConfigurationError({\n cause: error,\n details: { code, provider: LOCAL_PROVIDER_ID },\n message: `Local provider filesystem operation failed: ${remotePath}`,\n path: remotePath,\n retryable: false,\n });\n}\n\nfunction createPathNotFoundError(path: string, message: string): PathNotFoundError {\n return new PathNotFoundError({\n details: { provider: LOCAL_PROVIDER_ID },\n message,\n path,\n retryable: false,\n });\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : undefined;\n}\n","/**\n * Deterministic in-memory provider for contract and unit tests.\n *\n * @module providers/memory/MemoryProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport type { CapabilitySet } from \"../../core/CapabilitySet\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport { ConfigurationError, PathNotFoundError } from \"../../errors/ZeroTransferError\";\nimport type { TransferVerificationResult } from \"../../transfers/TransferJob\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type { TransferProvider } from \"../Provider\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport type {\n MkdirOptions,\n RemoteEntry,\n RemotePermissions,\n RemoteStat,\n RemoveOptions,\n RmdirOptions,\n} from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\n\nconst MEMORY_PROVIDER_ID = \"memory\";\n\nconst MEMORY_PROVIDER_CAPABILITIES: CapabilitySet = {\n provider: MEMORY_PROVIDER_ID,\n authentication: [\"anonymous\"],\n list: true,\n stat: true,\n readStream: true,\n writeStream: true,\n serverSideCopy: false,\n serverSideMove: false,\n resumeDownload: true,\n resumeUpload: true,\n checksum: [],\n atomicRename: false,\n chmod: false,\n chown: false,\n symlink: true,\n metadata: [\n \"accessedAt\",\n \"createdAt\",\n \"group\",\n \"modifiedAt\",\n \"owner\",\n \"permissions\",\n \"symlinkTarget\",\n \"uniqueId\",\n ],\n maxConcurrency: 32,\n notes: [\"Deterministic in-memory provider for tests and provider contract validation\"],\n};\n\n/** Fixture entry used to seed a memory provider instance. */\nexport interface MemoryProviderEntry extends Omit<RemoteEntry, \"name\"> {\n /** Entry basename. When omitted, it is derived from `path`. */\n name?: string;\n /** Optional byte content for file entries. Strings are encoded as UTF-8. */\n content?: string | Uint8Array;\n}\n\n/** Options used to create a deterministic memory provider factory. */\nexport interface MemoryProviderOptions {\n /** Entries available to sessions created by this provider factory. */\n entries?: Iterable<MemoryProviderEntry>;\n}\n\n/**\n * Creates a provider factory backed by deterministic in-memory fixture entries.\n *\n * @param options - Optional fixture entries to expose through the memory provider.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n */\nexport function createMemoryProviderFactory(options: MemoryProviderOptions = {}): ProviderFactory {\n const state = createMemoryState(options.entries ?? []);\n\n return {\n id: MEMORY_PROVIDER_ID,\n capabilities: MEMORY_PROVIDER_CAPABILITIES,\n create: () => new MemoryProvider(state),\n };\n}\n\nclass MemoryProvider implements TransferProvider {\n readonly id = MEMORY_PROVIDER_ID;\n readonly capabilities = MEMORY_PROVIDER_CAPABILITIES;\n\n constructor(private readonly state: MemoryProviderState) {}\n\n connect(): Promise<TransferSession> {\n return Promise.resolve(new MemoryTransferSession(this.state));\n }\n}\n\nclass MemoryTransferSession implements TransferSession {\n readonly provider = MEMORY_PROVIDER_ID;\n readonly capabilities = MEMORY_PROVIDER_CAPABILITIES;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(state: MemoryProviderState) {\n this.fs = new MemoryFileSystem(state);\n this.transfers = new MemoryTransferOperations(state);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\ninterface MemoryProviderState {\n entries: Map<string, RemoteStat>;\n content: Map<string, Uint8Array>;\n}\n\nclass MemoryFileSystem implements RemoteFileSystem {\n constructor(private readonly state: MemoryProviderState) {}\n\n list(path: string): Promise<RemoteEntry[]> {\n return Promise.resolve().then(() => {\n const normalizedPath = normalizeMemoryPath(path);\n const directory = this.requireEntry(normalizedPath);\n\n if (directory.type !== \"directory\") {\n throw createPathNotFoundError(\n normalizedPath,\n `Memory path is not a directory: ${normalizedPath}`,\n );\n }\n\n return [...this.state.entries.values()]\n .filter(\n (entry) => entry.path !== normalizedPath && getParentPath(entry.path) === normalizedPath,\n )\n .map(cloneRemoteEntry)\n .sort(compareEntries);\n });\n }\n\n stat(path: string): Promise<RemoteStat> {\n return Promise.resolve().then(() =>\n cloneRemoteStat(this.requireEntry(normalizeMemoryPath(path))),\n );\n }\n\n remove(path: string, options: RemoveOptions = {}): Promise<void> {\n return Promise.resolve().then(() => {\n const normalized = normalizeMemoryPath(path);\n const entry = this.state.entries.get(normalized);\n if (entry === undefined) {\n if (options.ignoreMissing) return;\n throw createPathNotFoundError(normalized, `Memory path not found: ${normalized}`);\n }\n if (entry.type === \"directory\") {\n throw createPathNotFoundError(\n normalized,\n `Memory path is a directory; use rmdir: ${normalized}`,\n );\n }\n this.state.entries.delete(normalized);\n this.state.content.delete(normalized);\n });\n }\n\n rename(from: string, to: string): Promise<void> {\n return Promise.resolve().then(() => {\n const fromPath = normalizeMemoryPath(from);\n const toPath = normalizeMemoryPath(to);\n const entry = this.state.entries.get(fromPath);\n if (entry === undefined) {\n throw createPathNotFoundError(fromPath, `Memory path not found: ${fromPath}`);\n }\n ensureParentDirectories(this.state.entries, toPath);\n const moved: RemoteStat = { ...entry, path: toPath, name: basenameRemotePath(toPath) };\n this.state.entries.delete(fromPath);\n this.state.entries.set(toPath, moved);\n const content = this.state.content.get(fromPath);\n if (content !== undefined) {\n this.state.content.delete(fromPath);\n this.state.content.set(toPath, content);\n }\n });\n }\n\n mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n return Promise.resolve().then(() => {\n const normalized = normalizeMemoryPath(path);\n const existing = this.state.entries.get(normalized);\n if (existing !== undefined) {\n if (existing.type === \"directory\" && options.recursive) return;\n throw createInvalidFixtureError(normalized, `Memory path already exists: ${normalized}`);\n }\n if (options.recursive) {\n ensureParentDirectories(this.state.entries, normalized);\n } else {\n const parent = getParentPath(normalized);\n if (parent !== undefined && !this.state.entries.has(parent)) {\n throw createPathNotFoundError(parent, `Memory parent not found: ${parent}`);\n }\n }\n this.state.entries.set(normalized, createDirectoryEntry(normalized));\n });\n }\n\n rmdir(path: string, options: RmdirOptions = {}): Promise<void> {\n return Promise.resolve().then(() => {\n const normalized = normalizeMemoryPath(path);\n const entry = this.state.entries.get(normalized);\n if (entry === undefined) {\n if (options.ignoreMissing) return;\n throw createPathNotFoundError(normalized, `Memory path not found: ${normalized}`);\n }\n if (entry.type !== \"directory\") {\n throw createPathNotFoundError(normalized, `Memory path is not a directory: ${normalized}`);\n }\n const children = [...this.state.entries.values()].filter(\n (child) => child.path !== normalized && getParentPath(child.path) === normalized,\n );\n if (children.length > 0 && !options.recursive) {\n throw createInvalidFixtureError(normalized, `Memory directory not empty: ${normalized}`);\n }\n const stack = [...children];\n while (stack.length > 0) {\n const next = stack.pop();\n if (!next) continue;\n if (next.type === \"directory\") {\n for (const grand of this.state.entries.values()) {\n if (grand.path !== next.path && getParentPath(grand.path) === next.path) {\n stack.push(grand);\n }\n }\n }\n this.state.entries.delete(next.path);\n this.state.content.delete(next.path);\n }\n this.state.entries.delete(normalized);\n });\n }\n\n private requireEntry(path: string): RemoteStat {\n const entry = this.state.entries.get(path);\n\n if (entry === undefined) {\n throw createPathNotFoundError(path, `Memory path not found: ${path}`);\n }\n\n return entry;\n }\n}\n\nclass MemoryTransferOperations implements ProviderTransferOperations {\n constructor(private readonly state: MemoryProviderState) {}\n\n read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n return Promise.resolve().then(() => {\n request.throwIfAborted();\n const path = normalizeMemoryPath(request.endpoint.path);\n const entry = requireFileEntry(this.state, path);\n const content = this.state.content.get(path) ?? new Uint8Array(entry.size ?? 0);\n const range = resolveByteRange(content.byteLength, request.range);\n const chunk = content.slice(range.offset, range.offset + range.length);\n const result: ProviderTransferReadResult = {\n content: createMemoryContentSource(chunk),\n totalBytes: chunk.byteLength,\n };\n\n if (range.offset > 0) {\n result.bytesRead = range.offset;\n }\n\n return result;\n });\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const path = normalizeMemoryPath(request.endpoint.path);\n const existing = this.state.entries.get(path);\n\n if (existing?.type === \"directory\") {\n throw createInvalidFixtureError(path, `Memory path is a directory: ${path}`);\n }\n\n const writtenContent = await collectTransferContent(request);\n const offset = normalizeOptionalByteCount(request.offset, \"offset\");\n const previousContent = this.state.content.get(path) ?? new Uint8Array(0);\n const content =\n offset === undefined\n ? writtenContent\n : mergeContentAtOffset(previousContent, writtenContent, offset);\n\n ensureParentDirectories(this.state.entries, path);\n this.state.entries.set(path, createWrittenFileEntry(path, content.byteLength));\n this.state.content.set(path, content);\n\n const result: ProviderTransferWriteResult = {\n bytesTransferred: writtenContent.byteLength,\n resumed: offset !== undefined && offset > 0,\n totalBytes: content.byteLength,\n verified: request.verification?.verified ?? false,\n };\n\n if (request.verification !== undefined) {\n result.verification = cloneVerification(request.verification);\n }\n\n return result;\n }\n}\n\nfunction createMemoryState(entries: Iterable<MemoryProviderEntry>): MemoryProviderState {\n const state: MemoryProviderState = {\n content: new Map(),\n entries: new Map([[\"/\", createDirectoryEntry(\"/\")]]),\n };\n\n for (const input of entries) {\n const entry = createMemoryEntry(input);\n const content = createMemoryContent(input, entry);\n\n if (entry.path === \"/\" && entry.type !== \"directory\") {\n throw createInvalidFixtureError(entry.path, \"Memory provider root must be a directory\");\n }\n\n ensureParentDirectories(state.entries, entry.path);\n state.entries.set(entry.path, entry);\n\n if (content !== undefined) {\n state.content.set(entry.path, content);\n }\n }\n\n return state;\n}\n\nfunction createMemoryEntry(input: MemoryProviderEntry): RemoteStat {\n const path = normalizeMemoryPath(input.path);\n const entry: RemoteEntry = {\n name: input.name ?? basenameRemotePath(path),\n path,\n type: input.type,\n };\n\n copyOptionalEntryFields(entry, input);\n\n const content = normalizeMemoryContent(input.content);\n\n if (content !== undefined) {\n entry.size = content.byteLength;\n }\n\n return {\n ...entry,\n exists: true,\n };\n}\n\nfunction createMemoryContent(\n input: MemoryProviderEntry,\n entry: RemoteStat,\n): Uint8Array | undefined {\n const content = normalizeMemoryContent(input.content);\n\n if (content !== undefined) {\n if (entry.type !== \"file\") {\n throw createInvalidFixtureError(\n entry.path,\n `Memory fixture content requires a file: ${entry.path}`,\n );\n }\n\n return content;\n }\n\n if (entry.type === \"file\") {\n return new Uint8Array(entry.size ?? 0);\n }\n\n return undefined;\n}\n\nfunction normalizeMemoryContent(content: string | Uint8Array | undefined): Uint8Array | undefined {\n if (content === undefined) {\n return undefined;\n }\n\n return typeof content === \"string\" ? Buffer.from(content) : new Uint8Array(content);\n}\n\nfunction createWrittenFileEntry(path: string, size: number): RemoteStat {\n return {\n exists: true,\n modifiedAt: new Date(),\n name: basenameRemotePath(path),\n path,\n size,\n type: \"file\",\n };\n}\n\nfunction createDirectoryEntry(path: string): RemoteStat {\n return {\n exists: true,\n name: basenameRemotePath(path),\n path,\n type: \"directory\",\n };\n}\n\nfunction ensureParentDirectories(state: Map<string, RemoteStat>, path: string): void {\n for (const parentPath of getAncestorPaths(path)) {\n const parent = state.get(parentPath);\n\n if (parent !== undefined && parent.type !== \"directory\") {\n throw createInvalidFixtureError(\n parentPath,\n `Memory fixture parent is not a directory: ${parentPath}`,\n );\n }\n\n if (parent === undefined) {\n state.set(parentPath, createDirectoryEntry(parentPath));\n }\n }\n}\n\nfunction normalizeMemoryPath(path: string): string {\n const normalized = normalizeRemotePath(path);\n\n if (normalized === \".\" || normalized === \"/\") {\n return \"/\";\n }\n\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction getAncestorPaths(path: string): string[] {\n const ancestors: string[] = [];\n let parentPath = getParentPath(path);\n\n while (parentPath !== undefined && parentPath !== \"/\") {\n ancestors.unshift(parentPath);\n parentPath = getParentPath(parentPath);\n }\n\n return ancestors;\n}\n\nfunction getParentPath(path: string): string | undefined {\n if (path === \"/\") {\n return undefined;\n }\n\n const parentEnd = path.lastIndexOf(\"/\");\n return parentEnd <= 0 ? \"/\" : path.slice(0, parentEnd);\n}\n\nfunction requireFileEntry(state: MemoryProviderState, path: string): RemoteStat {\n const entry = state.entries.get(path);\n\n if (entry === undefined) {\n throw createPathNotFoundError(path, `Memory path not found: ${path}`);\n }\n\n if (entry.type !== \"file\") {\n throw createPathNotFoundError(path, `Memory path is not a file: ${path}`);\n }\n\n return entry;\n}\n\nfunction resolveByteRange(\n size: number,\n range: ProviderTransferReadRequest[\"range\"],\n): { offset: number; length: number } {\n if (range === undefined) {\n return { length: size, offset: 0 };\n }\n\n const requestedOffset = normalizeByteCount(range.offset, \"offset\");\n const requestedLength =\n range.length === undefined\n ? size - Math.min(requestedOffset, size)\n : normalizeByteCount(range.length, \"length\");\n const offset = Math.min(requestedOffset, size);\n const length = Math.max(0, Math.min(requestedLength, size - offset));\n\n return { length, offset };\n}\n\nasync function collectTransferContent(request: ProviderTransferWriteRequest): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let byteLength = 0;\n\n for await (const chunk of request.content) {\n request.throwIfAborted();\n const clonedChunk = new Uint8Array(chunk);\n chunks.push(clonedChunk);\n byteLength += clonedChunk.byteLength;\n request.reportProgress(byteLength, request.totalBytes);\n }\n\n return concatChunks(chunks, byteLength);\n}\n\nfunction concatChunks(chunks: Uint8Array[], byteLength: number): Uint8Array {\n const content = new Uint8Array(byteLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n content.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return content;\n}\n\nfunction mergeContentAtOffset(\n previousContent: Uint8Array,\n writtenContent: Uint8Array,\n offset: number,\n): Uint8Array {\n const content = new Uint8Array(\n Math.max(previousContent.byteLength, offset + writtenContent.byteLength),\n );\n content.set(previousContent);\n content.set(writtenContent, offset);\n return content;\n}\n\nasync function* createMemoryContentSource(content: Uint8Array): AsyncGenerator<Uint8Array> {\n await Promise.resolve();\n yield new Uint8Array(content);\n}\n\nfunction normalizeOptionalByteCount(value: number | undefined, field: string): number | undefined {\n return value === undefined ? undefined : normalizeByteCount(value, field);\n}\n\nfunction normalizeByteCount(value: number, field: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw createInvalidFixtureError(\"/\", `Memory provider ${field} must be a non-negative number`);\n }\n\n return Math.floor(value);\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n\nfunction cloneRemoteEntry(entry: RemoteEntry): RemoteEntry {\n const clone: RemoteEntry = {\n name: entry.name,\n path: entry.path,\n type: entry.type,\n };\n\n copyOptionalEntryFields(clone, entry);\n return clone;\n}\n\nfunction cloneRemoteStat(entry: RemoteStat): RemoteStat {\n return {\n ...cloneRemoteEntry(entry),\n exists: true,\n };\n}\n\nfunction copyOptionalEntryFields(target: RemoteEntry, source: Partial<RemoteEntry>): void {\n if (source.size !== undefined) target.size = source.size;\n if (source.modifiedAt !== undefined) target.modifiedAt = cloneDate(source.modifiedAt);\n if (source.createdAt !== undefined) target.createdAt = cloneDate(source.createdAt);\n if (source.accessedAt !== undefined) target.accessedAt = cloneDate(source.accessedAt);\n if (source.permissions !== undefined) target.permissions = clonePermissions(source.permissions);\n if (source.owner !== undefined) target.owner = source.owner;\n if (source.group !== undefined) target.group = source.group;\n if (source.symlinkTarget !== undefined) target.symlinkTarget = source.symlinkTarget;\n if (source.uniqueId !== undefined) target.uniqueId = source.uniqueId;\n if (source.raw !== undefined) target.raw = source.raw;\n}\n\nfunction cloneDate(value: Date): Date {\n return new Date(value.getTime());\n}\n\nfunction clonePermissions(permissions: RemotePermissions): RemotePermissions {\n return { ...permissions };\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction createPathNotFoundError(path: string, message: string): PathNotFoundError {\n return new PathNotFoundError({\n details: { provider: MEMORY_PROVIDER_ID },\n message,\n path,\n retryable: false,\n });\n}\n\nfunction createInvalidFixtureError(path: string, message: string): ConfigurationError {\n return new ConfigurationError({\n details: { provider: MEMORY_PROVIDER_ID },\n message,\n path,\n retryable: false,\n });\n}\n","/**\n * HTTP(S) read-only provider.\n *\n * Connects to a remote web origin and exposes downloads via standard `GET` with\n * `Range` resume support and metadata via `HEAD`. The provider is intentionally\n * read-only — uploads should target a `webdav` or `s3` provider once those land.\n *\n * @module providers/web/HttpProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n ConfigurationError,\n ConnectionError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteResult,\n TransferDataSource,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n buildBaseUrl,\n dispatchRequest,\n formatRangeHeader,\n mapResponseError,\n parseTotalBytes,\n resolveUrl,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n type HttpSessionTransport,\n} from \"./httpInternals\";\n\nexport type { HttpFetch };\n\n/** Options accepted by {@link createHttpProviderFactory}. */\nexport interface HttpProviderOptions {\n /** Provider id to register. Defaults to `\"http\"`. Set to `\"https\"` for the HTTPS variant. */\n id?: ProviderId;\n /** Whether the provider should treat connections as TLS-only. Defaults to `true` when `id === \"https\"`. */\n secure?: boolean;\n /** Base URL prefix prepended to relative endpoint paths. Defaults to `\"\"`. */\n basePath?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied to every request. */\n defaultHeaders?: Record<string, string>;\n}\n\nconst HTTP_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"etag\"];\n\n/**\n * Creates a provider factory backed by HTTP(S) GET/HEAD.\n *\n * @param options - Optional provider configuration.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n */\nexport function createHttpProviderFactory(options: HttpProviderOptions = {}): ProviderFactory {\n const id: ProviderId = options.id ?? \"http\";\n const secure = options.secure ?? id === \"https\";\n const basePath = options.basePath ?? \"\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply HttpProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"anonymous\", \"password\", \"token\"],\n checksum: [...HTTP_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: false,\n maxConcurrency: 8,\n metadata: [\"modifiedAt\", \"mimeType\", \"uniqueId\"],\n notes: [\"Read-only HTTP(S) provider. Uploads are not supported.\"],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: false,\n };\n\n return {\n capabilities,\n create: () =>\n new HttpProvider({\n basePath,\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n fetch: fetchImpl,\n id,\n secure,\n }),\n id,\n };\n}\n\ninterface HttpProviderInternalOptions {\n basePath: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n secure: boolean;\n}\n\nclass HttpProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: HttpProviderInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n const headers = { ...this.internals.defaultHeaders };\n if (profile.username !== undefined) {\n const username = await resolveSecret(profile.username);\n const password = profile.password !== undefined ? await resolveSecret(profile.password) : \"\";\n const usernameText = secretToString(username);\n const passwordText = secretToString(password);\n headers[\"Authorization\"] =\n `Basic ${Buffer.from(`${usernameText}:${passwordText}`).toString(\"base64\")}`;\n }\n\n const baseUrl = buildSessionBaseUrl(profile, this.internals);\n const sessionOptions: HttpSessionOptions = {\n baseUrl,\n capabilities: this.internals.capabilities,\n fetch: this.internals.fetch,\n headers,\n id: this.internals.id,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n const session = new HttpTransferSession(sessionOptions);\n return session;\n }\n}\n\ninterface HttpSessionOptions extends HttpSessionTransport {\n capabilities: CapabilitySet;\n id: ProviderId;\n}\n\nclass HttpTransferSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(private readonly options: HttpSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new HttpFileSystem(options);\n this.transfers = new HttpTransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass HttpFileSystem implements RemoteFileSystem {\n constructor(private readonly options: HttpSessionOptions) {}\n\n list(): Promise<RemoteEntry[]> {\n return Promise.reject(\n new UnsupportedFeatureError({\n message: \"HTTP provider does not support directory listing\",\n retryable: false,\n }),\n );\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const url = resolveUrl(this.options.baseUrl, normalized);\n const response = await dispatchRequest(this.options, url, {\n method: \"HEAD\",\n });\n if (!response.ok) {\n throw mapResponseError(response, normalized);\n }\n return responseToStat(response, normalized);\n }\n}\n\nclass HttpTransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: HttpSessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const url = resolveUrl(this.options.baseUrl, normalized);\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"Range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n\n const requestInit: RequestInit & { headers?: Record<string, string> } = {\n headers,\n method: \"GET\",\n };\n if (request.signal !== undefined) requestInit.signal = request.signal;\n const response = await dispatchRequest(this.options, url, requestInit);\n\n if (!response.ok && response.status !== 206) {\n throw mapResponseError(response, normalized);\n }\n\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n message: `HTTP response had no body for ${url.toString()}`,\n retryable: true,\n });\n }\n\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const etag = response.headers.get(\"etag\");\n if (etag !== null) result.checksum = etag;\n\n return result;\n }\n\n write(): Promise<ProviderTransferWriteResult> {\n return Promise.reject(\n new UnsupportedFeatureError({\n message: \"HTTP provider is read-only; uploads are not supported\",\n retryable: false,\n }),\n );\n }\n}\n\nfunction buildSessionBaseUrl(\n profile: ConnectionProfile,\n internals: HttpProviderInternalOptions,\n): URL {\n return buildBaseUrl(profile, { basePath: internals.basePath, secure: internals.secure });\n}\n\nfunction responseToStat(response: Response, normalizedPath: string): RemoteStat {\n const stat: RemoteStat = {\n exists: true,\n name: basenameRemotePath(normalizedPath),\n path: normalizedPath,\n type: \"file\",\n };\n const contentLength = response.headers.get(\"content-length\");\n if (contentLength !== null) {\n const size = Number.parseInt(contentLength, 10);\n if (Number.isFinite(size) && size >= 0) stat.size = size;\n }\n const lastModified = response.headers.get(\"last-modified\");\n if (lastModified !== null) {\n const parsed = new Date(lastModified);\n if (!Number.isNaN(parsed.getTime())) stat.modifiedAt = parsed;\n }\n const etag = response.headers.get(\"etag\");\n if (etag !== null) stat.uniqueId = etag;\n return stat;\n}\n\n// Placeholder export so TypeScript treats the module import as side-effect free.\nexport type { TransferDataSource };\n","/**\n * WebDAV provider.\n *\n * Wraps a WebDAV-capable HTTP server with `PROPFIND` listings/stat, `GET`\n * downloads (with `Range` resume), and `PUT` uploads. Built on top of the\n * shared HTTP transport helpers used by {@link createHttpProviderFactory}.\n *\n * @module providers/web/WebDavProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n ConfigurationError,\n ConnectionError,\n ProtocolError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n buildBaseUrl,\n dispatchRequest,\n formatRangeHeader,\n mapResponseError,\n parseTotalBytes,\n resolveUrl,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n type HttpSessionTransport,\n} from \"./httpInternals\";\n\nexport type { HttpFetch };\n\n/** Options accepted by {@link createWebDavProviderFactory}. */\nexport interface WebDavProviderOptions {\n /** Provider id to register. Defaults to `\"webdav\"`. */\n id?: ProviderId;\n /** Whether the transport is TLS. Defaults to `false`; set `true` or use https `port`. */\n secure?: boolean;\n /** Path prefix prepended to remote paths. Defaults to `\"\"`. */\n basePath?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied to every request. */\n defaultHeaders?: Record<string, string>;\n}\n\nconst WEBDAV_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"etag\"];\n\n/**\n * Creates a WebDAV provider factory.\n *\n * @param options - Optional provider configuration.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n */\nexport function createWebDavProviderFactory(options: WebDavProviderOptions = {}): ProviderFactory {\n const id: ProviderId = options.id ?? \"webdav\";\n const secure = options.secure ?? false;\n const basePath = options.basePath ?? \"\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply WebDavProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"anonymous\", \"password\", \"token\"],\n checksum: [...WEBDAV_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 8,\n metadata: [\"modifiedAt\", \"mimeType\", \"uniqueId\"],\n notes: [\"WebDAV provider buffers PUT bodies in memory; chunked uploads are not yet supported.\"],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new WebDavProvider({\n basePath,\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n fetch: fetchImpl,\n id,\n secure,\n }),\n id,\n };\n}\n\ninterface WebDavProviderInternalOptions {\n basePath: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n secure: boolean;\n}\n\nclass WebDavProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: WebDavProviderInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n const headers = { ...this.internals.defaultHeaders };\n if (profile.username !== undefined) {\n const username = await resolveSecret(profile.username);\n const password = profile.password !== undefined ? await resolveSecret(profile.password) : \"\";\n const usernameText = secretToString(username);\n const passwordText = secretToString(password);\n headers[\"Authorization\"] = `Basic ${Buffer.from(`${usernameText}:${passwordText}`).toString(\n \"base64\",\n )}`;\n }\n\n const baseUrl = buildBaseUrl(profile, {\n basePath: this.internals.basePath,\n secure: this.internals.secure,\n });\n const sessionOptions: WebDavSessionOptions = {\n baseUrl,\n capabilities: this.internals.capabilities,\n fetch: this.internals.fetch,\n headers,\n id: this.internals.id,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new WebDavSession(sessionOptions);\n }\n}\n\ninterface WebDavSessionOptions extends HttpSessionTransport {\n capabilities: CapabilitySet;\n id: ProviderId;\n}\n\nclass WebDavSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: WebDavSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new WebDavFileSystem(options);\n this.transfers = new WebDavTransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass WebDavFileSystem implements RemoteFileSystem {\n constructor(private readonly options: WebDavSessionOptions) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const normalized = normalizeRemotePath(path);\n const url = resolveUrl(this.options.baseUrl, normalized);\n const response = await dispatchRequest(this.options, url, {\n headers: { Depth: \"1\", \"Content-Type\": \"application/xml\" },\n method: \"PROPFIND\",\n });\n if (!response.ok && response.status !== 207) {\n throw mapResponseError(response, normalized);\n }\n const body = await response.text();\n const entries = parsePropfindResponses(body, this.options.baseUrl);\n return entries\n .filter((entry) => entry.path !== normalized && entry.path !== `${normalized}/`)\n .map((entry) => normalizeEntry(entry, normalized));\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const url = resolveUrl(this.options.baseUrl, normalized);\n const response = await dispatchRequest(this.options, url, {\n headers: { Depth: \"0\", \"Content-Type\": \"application/xml\" },\n method: \"PROPFIND\",\n });\n if (!response.ok && response.status !== 207) {\n throw mapResponseError(response, normalized);\n }\n const body = await response.text();\n const entries = parsePropfindResponses(body, this.options.baseUrl);\n const target =\n entries.find((entry) => entry.path === normalized || entry.path === `${normalized}/`) ??\n entries[0];\n if (target === undefined) {\n throw new ProtocolError({\n details: { path: normalized },\n message: \"WebDAV PROPFIND returned no responses\",\n retryable: false,\n });\n }\n const entry = normalizeEntry(target, parentOf(normalized));\n const stat: RemoteStat = {\n exists: true,\n name: entry.name,\n path: normalized,\n type: entry.type,\n };\n if (entry.size !== undefined) stat.size = entry.size;\n if (entry.modifiedAt !== undefined) stat.modifiedAt = entry.modifiedAt;\n if (entry.uniqueId !== undefined) stat.uniqueId = entry.uniqueId;\n return stat;\n }\n}\n\nclass WebDavTransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: WebDavSessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const url = resolveUrl(this.options.baseUrl, normalized);\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"Range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n\n const init: RequestInit & { headers?: Record<string, string> } = {\n headers,\n method: \"GET\",\n };\n if (request.signal !== undefined) init.signal = request.signal;\n const response = await dispatchRequest(this.options, url, init);\n\n if (!response.ok && response.status !== 206) {\n throw mapResponseError(response, normalized);\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n message: `WebDAV response had no body for ${url.toString()}`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const etag = response.headers.get(\"etag\");\n if (etag !== null) result.checksum = etag;\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"WebDAV provider does not support resumable uploads\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const url = resolveUrl(this.options.baseUrl, normalized);\n\n const buffered = await collectChunks(request.content);\n const headers: Record<string, string> = {\n \"Content-Length\": String(buffered.byteLength),\n \"Content-Type\": \"application/octet-stream\",\n };\n\n const init: RequestInit & { headers?: Record<string, string> } = {\n body: buffered,\n headers,\n method: \"PUT\",\n };\n if (request.signal !== undefined) init.signal = request.signal;\n const response = await dispatchRequest(this.options, url, init);\n if (!response.ok) {\n throw mapResponseError(response, normalized);\n }\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n const etag = response.headers.get(\"etag\");\n if (etag !== null) result.checksum = etag;\n return result;\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\ninterface PropfindEntry {\n path: string;\n type: \"file\" | \"directory\";\n size?: number;\n modifiedAt?: Date;\n uniqueId?: string;\n}\n\nfunction parsePropfindResponses(xml: string, baseUrl: URL): PropfindEntry[] {\n const entries: PropfindEntry[] = [];\n const responseRegex =\n /<(?:[a-zA-Z0-9-]+:)?response\\b[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9-]+:)?response>/gi;\n let match: RegExpExecArray | null;\n while ((match = responseRegex.exec(xml)) !== null) {\n const inner = match[1] ?? \"\";\n const href = extractTag(inner, \"href\");\n if (href === undefined) continue;\n const path = decodeHref(href, baseUrl);\n const propBlock = extractTag(inner, \"prop\") ?? inner;\n const isCollection = /<(?:[a-zA-Z0-9-]+:)?collection\\b/i.test(propBlock);\n const sizeText = extractTag(propBlock, \"getcontentlength\");\n const modifiedText = extractTag(propBlock, \"getlastmodified\");\n const etag = extractTag(propBlock, \"getetag\");\n const entry: PropfindEntry = {\n path,\n type: isCollection ? \"directory\" : \"file\",\n };\n if (sizeText !== undefined) {\n const size = Number.parseInt(sizeText.trim(), 10);\n if (Number.isFinite(size) && size >= 0) entry.size = size;\n }\n if (modifiedText !== undefined) {\n const parsed = new Date(modifiedText.trim());\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (etag !== undefined) entry.uniqueId = etag.trim();\n entries.push(entry);\n }\n return entries;\n}\n\nfunction extractTag(xml: string, localName: string): string | undefined {\n const pattern = new RegExp(\n `<(?:[a-zA-Z0-9-]+:)?${localName}\\\\b[^>]*?(?:/>|>([\\\\s\\\\S]*?)</(?:[a-zA-Z0-9-]+:)?${localName}>)`,\n \"i\",\n );\n const match = pattern.exec(xml);\n if (match === null) return undefined;\n return match[1] ?? \"\";\n}\n\nfunction decodeHref(rawHref: string, baseUrl: URL): string {\n const decoded = decodeURIComponent(rawHref.trim());\n let pathname = decoded;\n if (/^https?:\\/\\//i.test(decoded)) {\n try {\n pathname = new URL(decoded).pathname;\n } catch {\n pathname = decoded;\n }\n }\n const basePathname = baseUrl.pathname.replace(/\\/+$/, \"\");\n if (basePathname.length > 0 && pathname.startsWith(basePathname)) {\n pathname = pathname.slice(basePathname.length);\n }\n if (!pathname.startsWith(\"/\")) pathname = `/${pathname}`;\n if (pathname.length > 1 && pathname.endsWith(\"/\")) pathname = pathname.slice(0, -1);\n return pathname;\n}\n\nfunction normalizeEntry(entry: PropfindEntry, parentPath: string): RemoteEntry {\n const trimmed = entry.path.endsWith(\"/\") ? entry.path.slice(0, -1) : entry.path;\n const name = basenameRemotePath(trimmed === \"\" ? \"/\" : trimmed);\n const result: RemoteEntry = {\n name: name === \"\" ? trimmed : name,\n path: trimmed === \"\" ? \"/\" : trimmed,\n type: entry.type,\n };\n if (entry.size !== undefined) result.size = entry.size;\n if (entry.modifiedAt !== undefined) result.modifiedAt = entry.modifiedAt;\n if (entry.uniqueId !== undefined) result.uniqueId = entry.uniqueId;\n void parentPath;\n return result;\n}\n\nfunction parentOf(path: string): string {\n if (path === \"/\" || path === \"\") return \"/\";\n const idx = path.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return path.slice(0, idx);\n}\n","/**\n * AWS SigV4 request signer used by the S3-compatible provider.\n *\n * Produces an `Authorization` header (and `x-amz-content-sha256` / `x-amz-date`\n * headers) that conform to AWS Signature Version 4. Only the subset required\n * by the S3 REST API surface is implemented.\n *\n * @module providers/web/awsSigv4\n */\nimport { createHash, createHmac } from \"node:crypto\";\n\n/** Inputs for {@link signSigV4}. */\nexport interface SigV4Input {\n /** HTTP method, upper-case (e.g. `\"GET\"`, `\"PUT\"`, `\"HEAD\"`). */\n method: string;\n /** Fully resolved request URL. */\n url: URL;\n /** Header bag the signer should sign and augment. Mutated in place. */\n headers: Record<string, string>;\n /** AWS region (e.g. `\"us-east-1\"`). */\n region: string;\n /** AWS service identifier (e.g. `\"s3\"`). */\n service: string;\n /** AWS access key id. */\n accessKeyId: string;\n /** AWS secret access key. */\n secretAccessKey: string;\n /** Optional STS session token. */\n sessionToken?: string;\n /** Body bytes used to compute the payload hash. Defaults to empty. */\n body?: Uint8Array;\n /** Override SigV4 timestamp; primarily useful in tests. */\n now?: Date;\n}\n\nconst UNSIGNED_PAYLOAD = \"UNSIGNED-PAYLOAD\";\n\n/** Signs `input.headers` with SigV4 and returns the canonical string for diagnostics. */\nexport function signSigV4(input: SigV4Input): { authorization: string; signedHeaders: string } {\n const now = input.now ?? new Date();\n const amzDate = formatAmzDate(now);\n const dateStamp = amzDate.slice(0, 8);\n const payloadHash =\n input.body !== undefined ? sha256Hex(input.body) : sha256Hex(new Uint8Array());\n\n input.headers[\"host\"] = input.url.host;\n input.headers[\"x-amz-date\"] = amzDate;\n input.headers[\"x-amz-content-sha256\"] = payloadHash;\n if (input.sessionToken !== undefined) {\n input.headers[\"x-amz-security-token\"] = input.sessionToken;\n }\n\n const canonicalUri = canonicalizePath(input.url.pathname);\n const canonicalQuery = canonicalizeQuery(input.url.searchParams);\n const lowerHeaders: Array<[string, string]> = Object.entries(input.headers)\n .map<[string, string]>(([name, value]) => [\n name.toLowerCase(),\n value.trim().replace(/\\s+/g, \" \"),\n ])\n .sort((entryA, entryB) => (entryA[0] < entryB[0] ? -1 : entryA[0] > entryB[0] ? 1 : 0));\n const canonicalHeaders = lowerHeaders.map(([n, v]) => `${n}:${v}\\n`).join(\"\");\n const signedHeaders = lowerHeaders.map(([n]) => n).join(\";\");\n\n const canonicalRequest = [\n input.method.toUpperCase(),\n canonicalUri,\n canonicalQuery,\n canonicalHeaders,\n signedHeaders,\n payloadHash,\n ].join(\"\\n\");\n\n const credentialScope = `${dateStamp}/${input.region}/${input.service}/aws4_request`;\n const stringToSign = [\n \"AWS4-HMAC-SHA256\",\n amzDate,\n credentialScope,\n sha256Hex(Buffer.from(canonicalRequest, \"utf8\")),\n ].join(\"\\n\");\n\n const kDate = hmac(`AWS4${input.secretAccessKey}`, dateStamp);\n const kRegion = hmac(kDate, input.region);\n const kService = hmac(kRegion, input.service);\n const kSigning = hmac(kService, \"aws4_request\");\n const signature = hmacHex(kSigning, stringToSign);\n\n const authorization = `AWS4-HMAC-SHA256 Credential=${input.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;\n input.headers[\"authorization\"] = authorization;\n return { authorization, signedHeaders };\n}\n\n/** Marker payload value used when signing GET-style requests without a body hash. */\nexport const SIGV4_UNSIGNED_PAYLOAD = UNSIGNED_PAYLOAD;\n\nfunction formatAmzDate(now: Date): string {\n const iso = now.toISOString();\n return `${iso.slice(0, 4)}${iso.slice(5, 7)}${iso.slice(8, 10)}T${iso.slice(11, 13)}${iso.slice(14, 16)}${iso.slice(17, 19)}Z`;\n}\n\nfunction canonicalizePath(pathname: string): string {\n if (pathname.length === 0) return \"/\";\n return pathname\n .split(\"/\")\n .map((segment) => encodeRfc3986(decodeURIComponent(segment)))\n .join(\"/\");\n}\n\nfunction canonicalizeQuery(params: URLSearchParams): string {\n const entries: Array<[string, string]> = [];\n params.forEach((value, key) => {\n entries.push([key, value]);\n });\n entries.sort(([ka, va], [kb, vb]) =>\n ka === kb ? (va < vb ? -1 : va > vb ? 1 : 0) : ka < kb ? -1 : 1,\n );\n return entries.map(([key, value]) => `${encodeRfc3986(key)}=${encodeRfc3986(value)}`).join(\"&\");\n}\n\nfunction encodeRfc3986(value: string): string {\n return encodeURIComponent(value).replace(\n /[!'()*]/g,\n (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n\nfunction sha256Hex(data: Uint8Array): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\nfunction hmac(key: string | Buffer, data: string): Buffer {\n return createHmac(\"sha256\", key).update(data, \"utf8\").digest();\n}\n\nfunction hmacHex(key: Buffer, data: string): string {\n return createHmac(\"sha256\", key).update(data, \"utf8\").digest(\"hex\");\n}\n","/**\n * S3-compatible provider.\n *\n * Talks to S3-compatible REST endpoints (AWS S3, MinIO, R2, Backblaze B2 S3\n * compatibility, Wasabi, etc.) with SigV4 signing. Supports `list` (ListObjectsV2),\n * `stat` (HEAD object), `read` (GET with optional `Range`), and single-shot `write`\n * (PUT object). Multipart upload remains a future capability.\n *\n * @module providers/web/S3Provider\n */\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n ConfigurationError,\n ConnectionError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret, type SecretSource } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport { signSigV4 } from \"./awsSigv4\";\nimport {\n formatRangeHeader,\n mapResponseError,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"./httpInternals\";\n\nexport type { HttpFetch };\n\n/** Options accepted by {@link createS3ProviderFactory}. */\nexport interface S3ProviderOptions {\n /** Provider id to register. Defaults to `\"s3\"`. */\n id?: ProviderId;\n /** Required bucket name; can be overridden per connection via `profile.host`. */\n bucket?: string;\n /** AWS region. Defaults to `\"us-east-1\"`. */\n region?: string;\n /** Service identifier for SigV4. Defaults to `\"s3\"`. */\n service?: string;\n /** Custom endpoint base URL (e.g. MinIO, R2). Defaults to `https://s3.<region>.amazonaws.com`. */\n endpoint?: string;\n /** Whether to use path-style URLs (`endpoint/bucket/key`). Defaults to `true`. */\n pathStyle?: boolean;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied to every request before signing. */\n defaultHeaders?: Record<string, string>;\n /** Optional STS session token applied to every request. */\n sessionToken?: SecretSource;\n /** Multipart upload tuning. Disabled by default; enable for objects above ~5 GiB or when streaming. */\n multipart?: S3MultipartOptions;\n}\n\n/** Multipart upload tuning for the S3 provider. */\nexport interface S3MultipartOptions {\n /** Enable multipart upload. Defaults to `false`. */\n enabled?: boolean;\n /** Object size threshold in bytes above which multipart is used. Defaults to 8 MiB. */\n thresholdBytes?: number;\n /** Target part size in bytes. Must be ≥ 5 MiB except for the final part. Defaults to 8 MiB. */\n partSizeBytes?: number;\n /**\n * Optional persistent store enabling cross-process resume of incomplete\n * multipart uploads. When provided, in-flight `uploadId` plus uploaded part\n * etags are checkpointed after every part; on retry the upload reuses the\n * stored state and skips the bytes already transferred.\n */\n resumeStore?: S3MultipartResumeStore;\n}\n\n/** Resume key identifying an in-flight multipart upload. */\nexport interface S3MultipartResumeKey {\n bucket: string;\n jobId: string;\n path: string;\n}\n\n/** Persisted multipart-upload checkpoint. */\nexport interface S3MultipartCheckpoint {\n uploadId: string;\n /** Parts already accepted by S3, in upload order. */\n parts: ReadonlyArray<S3MultipartPart>;\n}\n\n/** Single part recorded in a multipart-upload checkpoint. */\nexport interface S3MultipartPart {\n partNumber: number;\n etag: string;\n /** Cumulative byte offset reached after this part (exclusive). */\n byteEnd: number;\n}\n\n/**\n * Persistence contract for resuming partial multipart uploads across\n * processes or retries. Implementations may be synchronous or asynchronous;\n * `clear` is invoked once the multipart upload completes successfully (or is\n * explicitly aborted).\n */\nexport interface S3MultipartResumeStore {\n load(\n key: S3MultipartResumeKey,\n ): Promise<S3MultipartCheckpoint | undefined> | S3MultipartCheckpoint | undefined;\n save(key: S3MultipartResumeKey, checkpoint: S3MultipartCheckpoint): Promise<void> | void;\n clear(key: S3MultipartResumeKey): Promise<void> | void;\n}\n\n/** Creates an in-memory {@link S3MultipartResumeStore}. */\nexport function createMemoryS3MultipartResumeStore(): S3MultipartResumeStore {\n const map = new Map<string, S3MultipartCheckpoint>();\n const stringify = (key: S3MultipartResumeKey): string =>\n `${key.bucket}\\u0000${key.jobId}\\u0000${key.path}`;\n return {\n clear: (key) => {\n map.delete(stringify(key));\n },\n load: (key) => map.get(stringify(key)),\n save: (key, checkpoint) => {\n map.set(stringify(key), checkpoint);\n },\n };\n}\n\nconst DEFAULT_MULTIPART_PART_SIZE = 8 * 1024 * 1024;\nconst DEFAULT_MULTIPART_THRESHOLD = 8 * 1024 * 1024;\n\nconst S3_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"etag\"];\n\n/**\n * Creates an S3-compatible provider factory.\n *\n * Credentials must be supplied via the connection profile: `username` is the\n * access key id and `password` is the secret access key. `profile.host` may\n * be set to the bucket name (taking precedence over `options.bucket`).\n *\n * Works with AWS S3 and any S3-compatible API (MinIO, Cloudflare R2,\n * Backblaze B2, DigitalOcean Spaces, Wasabi, etc.) via `options.endpoint`.\n *\n * @example AWS S3\n * ```ts\n * import { createS3ProviderFactory, createTransferClient } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createS3ProviderFactory()] });\n *\n * const session = await client.connect({\n * host: \"my-bucket\",\n * provider: \"s3\",\n * username: process.env.AWS_ACCESS_KEY_ID,\n * password: { env: \"AWS_SECRET_ACCESS_KEY\" },\n * s3: { region: \"us-east-1\" },\n * });\n * ```\n *\n * @example MinIO / R2 / S3-compatible endpoint\n * ```ts\n * const client = createTransferClient({\n * providers: [createS3ProviderFactory({\n * endpoint: \"https://minio.internal:9000\",\n * pathStyle: true,\n * })],\n * });\n * ```\n */\nexport function createS3ProviderFactory(options: S3ProviderOptions = {}): ProviderFactory {\n const id: ProviderId = options.id ?? \"s3\";\n const region = options.region ?? \"us-east-1\";\n const service = options.service ?? \"s3\";\n const pathStyle = options.pathStyle ?? true;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const endpoint = options.endpoint ?? `https://s3.${region}.amazonaws.com`;\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply S3ProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n let endpointUrl: URL;\n try {\n endpointUrl = new URL(endpoint);\n } catch (error) {\n throw new ConfigurationError({\n cause: error,\n details: { endpoint },\n message: \"S3 provider received an invalid endpoint URL\",\n retryable: false,\n });\n }\n\n const multipartEnabled = options.multipart?.enabled ?? false;\n const multipart: ResolvedMultipartOptions = {\n enabled: multipartEnabled,\n partSizeBytes: options.multipart?.partSizeBytes ?? DEFAULT_MULTIPART_PART_SIZE,\n thresholdBytes: options.multipart?.thresholdBytes ?? DEFAULT_MULTIPART_THRESHOLD,\n ...(options.multipart?.resumeStore !== undefined\n ? { resumeStore: options.multipart.resumeStore }\n : {}),\n };\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"password\", \"token\"],\n checksum: [...S3_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 16,\n metadata: [\"modifiedAt\", \"mimeType\", \"uniqueId\"],\n notes: multipartEnabled\n ? [\n `S3 multipart upload enabled (partSize=${String(multipart.partSizeBytes)}B, threshold=${String(multipart.thresholdBytes)}B).`,\n ]\n : [\n \"S3 provider performs single-shot PUT uploads; pass multipart.enabled to stream large objects.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: multipartEnabled,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new S3Provider({\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n endpointUrl,\n fetch: fetchImpl,\n id,\n multipart,\n pathStyle,\n region,\n service,\n ...(options.bucket !== undefined ? { bucket: options.bucket } : {}),\n ...(options.sessionToken !== undefined ? { sessionToken: options.sessionToken } : {}),\n }),\n id,\n };\n}\n\ninterface ResolvedMultipartOptions {\n enabled: boolean;\n partSizeBytes: number;\n thresholdBytes: number;\n resumeStore?: S3MultipartResumeStore;\n}\n\ninterface S3ProviderInternalOptions {\n bucket?: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n endpointUrl: URL;\n fetch: HttpFetch;\n id: ProviderId;\n multipart: ResolvedMultipartOptions;\n pathStyle: boolean;\n region: string;\n service: string;\n sessionToken?: SecretSource;\n}\n\nclass S3Provider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: S3ProviderInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n if (profile.username === undefined || profile.password === undefined) {\n throw new ConfigurationError({\n message: \"S3 provider requires username (access key id) and password (secret access key)\",\n retryable: false,\n });\n }\n const accessKeyId = secretToString(await resolveSecret(profile.username));\n const secretAccessKey = secretToString(await resolveSecret(profile.password));\n const sessionToken =\n this.internals.sessionToken !== undefined\n ? secretToString(await resolveSecret(this.internals.sessionToken))\n : undefined;\n\n const bucket =\n profile.host !== undefined && profile.host !== \"\" ? profile.host : this.internals.bucket;\n if (bucket === undefined || bucket === \"\") {\n throw new ConfigurationError({\n message:\n \"S3 provider requires a bucket via S3ProviderOptions.bucket or ConnectionProfile.host\",\n retryable: false,\n });\n }\n\n const sessionOptions: S3SessionOptions = {\n accessKeyId,\n bucket,\n capabilities: this.internals.capabilities,\n defaultHeaders: this.internals.defaultHeaders,\n endpointUrl: this.internals.endpointUrl,\n fetch: this.internals.fetch,\n id: this.internals.id,\n multipart: this.internals.multipart,\n pathStyle: this.internals.pathStyle,\n region: this.internals.region,\n secretAccessKey,\n service: this.internals.service,\n };\n if (sessionToken !== undefined) sessionOptions.sessionToken = sessionToken;\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new S3Session(sessionOptions);\n }\n}\n\ninterface S3SessionOptions {\n accessKeyId: string;\n bucket: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n endpointUrl: URL;\n fetch: HttpFetch;\n id: ProviderId;\n multipart: ResolvedMultipartOptions;\n pathStyle: boolean;\n region: string;\n secretAccessKey: string;\n service: string;\n sessionToken?: string;\n timeoutMs?: number;\n}\n\nclass S3Session implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: S3SessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n this.fs = new S3FileSystem(options);\n this.transfers = new S3TransferOperations(options);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass S3FileSystem implements RemoteFileSystem {\n constructor(private readonly options: S3SessionOptions) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const normalized = normalizeRemotePath(path);\n const prefix = normalized === \"/\" ? \"\" : `${normalized.slice(1)}/`;\n const url = buildBucketUrl(this.options);\n url.searchParams.set(\"list-type\", \"2\");\n url.searchParams.set(\"delimiter\", \"/\");\n if (prefix.length > 0) url.searchParams.set(\"prefix\", prefix);\n\n const response = await s3Fetch(this.options, \"GET\", url);\n if (!response.ok) throw mapResponseError(response, normalized);\n const body = await response.text();\n return parseListObjectsV2(body, prefix);\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const normalized = normalizeRemotePath(path);\n const url = buildObjectUrl(this.options, normalized);\n const response = await s3Fetch(this.options, \"HEAD\", url);\n if (!response.ok) throw mapResponseError(response, normalized);\n const stat: RemoteStat = {\n exists: true,\n name: basenameRemotePath(normalized),\n path: normalized,\n type: \"file\",\n };\n const contentLength = response.headers.get(\"content-length\");\n if (contentLength !== null) {\n const size = Number.parseInt(contentLength, 10);\n if (Number.isFinite(size) && size >= 0) stat.size = size;\n }\n const lastModified = response.headers.get(\"last-modified\");\n if (lastModified !== null) {\n const parsed = new Date(lastModified);\n if (!Number.isNaN(parsed.getTime())) stat.modifiedAt = parsed;\n }\n const etag = response.headers.get(\"etag\");\n if (etag !== null) stat.uniqueId = etag;\n return stat;\n }\n}\n\nclass S3TransferOperations implements ProviderTransferOperations {\n constructor(private readonly options: S3SessionOptions) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const url = buildObjectUrl(this.options, normalized);\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n const response = await s3Fetch(this.options, \"GET\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n });\n if (!response.ok && response.status !== 206) {\n throw mapResponseError(response, normalized);\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n message: `S3 response had no body for ${url.toString()}`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n const etag = response.headers.get(\"etag\");\n if (etag !== null) result.checksum = etag;\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const multipart = this.options.multipart;\n const offset = request.offset ?? 0;\n if (offset > 0) {\n if (!multipart.enabled || multipart.resumeStore === undefined) {\n throw new UnsupportedFeatureError({\n details: { offset },\n message:\n \"S3 provider requires multipart.enabled and multipart.resumeStore to resume an upload\",\n retryable: false,\n });\n }\n return this.writeMultipart(request, normalized, offset);\n }\n if (multipart.enabled) {\n return this.writeMultipart(request, normalized, 0);\n }\n return this.writeSingleShot(request, normalized);\n }\n\n private async writeSingleShot(\n request: ProviderTransferWriteRequest,\n normalized: string,\n ): Promise<ProviderTransferWriteResult> {\n const url = buildObjectUrl(this.options, normalized);\n const buffered = await collectChunks(request.content);\n const response = await s3Fetch(this.options, \"PUT\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: buffered,\n extraHeaders: { \"content-type\": \"application/octet-stream\" },\n });\n if (!response.ok) throw mapResponseError(response, normalized);\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n const etag = response.headers.get(\"etag\");\n if (etag !== null) result.checksum = etag;\n return result;\n }\n\n private async writeMultipart(\n request: ProviderTransferWriteRequest,\n normalized: string,\n requestedOffset: number,\n ): Promise<ProviderTransferWriteResult> {\n const multipart = this.options.multipart;\n const partSize = multipart.partSizeBytes;\n const objectUrl = buildObjectUrl(this.options, normalized);\n const resumeStore = multipart.resumeStore;\n const resumeKey: S3MultipartResumeKey = {\n bucket: this.options.bucket,\n jobId: request.job.id,\n path: normalized,\n };\n\n // Look up a checkpoint when a resume store is configured.\n let existing: S3MultipartCheckpoint | undefined;\n if (resumeStore !== undefined) {\n existing = (await resumeStore.load(resumeKey)) ?? undefined;\n }\n if (requestedOffset > 0) {\n if (existing === undefined) {\n throw new UnsupportedFeatureError({\n details: { offset: requestedOffset },\n message: \"S3 provider has no resume checkpoint for this transfer\",\n retryable: false,\n });\n }\n const lastByteEnd = existing.parts[existing.parts.length - 1]?.byteEnd ?? 0;\n if (lastByteEnd !== requestedOffset) {\n throw new UnsupportedFeatureError({\n details: { checkpointOffset: lastByteEnd, requestedOffset },\n message: \"S3 resume offset does not match the stored multipart checkpoint\",\n retryable: false,\n });\n }\n }\n\n const iterator = request.content[Symbol.asyncIterator]();\n\n // When resuming, we trust the caller has already advanced the source past\n // `requestedOffset`. When starting fresh, buffer up to `thresholdBytes` so\n // small payloads can fall back to single-shot PUT.\n const initialBuffer: Uint8Array[] = [];\n let initialSize = 0;\n if (existing === undefined) {\n while (initialSize <= multipart.thresholdBytes) {\n const next = await iterator.next();\n if (next.done === true) break;\n const chunk = next.value;\n if (chunk.byteLength === 0) continue;\n initialBuffer.push(chunk);\n initialSize += chunk.byteLength;\n }\n if (initialSize <= multipart.thresholdBytes) {\n const buffered = concat(initialBuffer, initialSize);\n return this.singleShotFromBuffer(request, normalized, buffered);\n }\n }\n\n // Establish (or reuse) the upload id.\n let uploadId: string;\n if (existing !== undefined) {\n uploadId = existing.uploadId;\n } else {\n const initiateUrl = new URL(objectUrl.toString());\n initiateUrl.searchParams.set(\"uploads\", \"\");\n const initiateResponse = await s3Fetch(this.options, \"POST\", initiateUrl, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: { \"content-type\": \"application/octet-stream\" },\n });\n if (!initiateResponse.ok) throw mapResponseError(initiateResponse, normalized);\n const initiateBody = await initiateResponse.text();\n const initiated = innerText(initiateBody, \"UploadId\");\n if (initiated === undefined || initiated === \"\") {\n throw new ConnectionError({\n message: \"S3 CreateMultipartUpload returned no UploadId\",\n retryable: true,\n });\n }\n uploadId = initiated;\n if (resumeStore !== undefined) {\n await resumeStore.save(resumeKey, { parts: [], uploadId });\n }\n }\n\n const parts: S3MultipartPart[] = existing !== undefined ? [...existing.parts] : [];\n const startedBytes = parts.length > 0 ? (parts[parts.length - 1]?.byteEnd ?? 0) : 0;\n let bytesTransferred = startedBytes;\n let partNumber = parts.length + 1;\n let buffer: Uint8Array[] = [];\n let bufferSize = 0;\n if (existing === undefined) {\n const trailing = concat(initialBuffer, initialSize);\n buffer = [trailing];\n bufferSize = trailing.byteLength;\n }\n\n const flushPart = async (final: boolean): Promise<void> => {\n while (bufferSize >= partSize || (final && bufferSize > 0)) {\n const take = final ? bufferSize : partSize;\n const partBytes = sliceFromBuffers(buffer, take);\n buffer = partBytes.remaining;\n bufferSize -= partBytes.bytes.byteLength;\n const partUrl = new URL(objectUrl.toString());\n partUrl.searchParams.set(\"partNumber\", String(partNumber));\n partUrl.searchParams.set(\"uploadId\", uploadId);\n const partResponse = await s3Fetch(this.options, \"PUT\", partUrl, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: partBytes.bytes,\n });\n if (!partResponse.ok) {\n throw mapResponseError(partResponse, normalized);\n }\n const partEtag = partResponse.headers.get(\"etag\");\n if (partEtag === null) {\n throw new ConnectionError({\n message: `S3 UploadPart returned no ETag for part ${String(partNumber)}`,\n retryable: true,\n });\n }\n bytesTransferred += partBytes.bytes.byteLength;\n parts.push({ byteEnd: bytesTransferred, etag: partEtag, partNumber });\n if (resumeStore !== undefined) {\n await resumeStore.save(resumeKey, { parts: [...parts], uploadId });\n }\n request.reportProgress(bytesTransferred, undefined);\n partNumber += 1;\n }\n };\n\n try {\n await flushPart(false);\n while (true) {\n request.throwIfAborted();\n const next = await iterator.next();\n if (next.done === true) break;\n if (next.value.byteLength === 0) continue;\n buffer.push(next.value);\n bufferSize += next.value.byteLength;\n await flushPart(false);\n }\n await flushPart(true);\n } catch (error) {\n // When a resume store is wired the checkpoint is preserved so a future\n // retry can pick up where this one left off; otherwise we must clean up\n // the orphaned multipart upload immediately.\n if (resumeStore === undefined) {\n await abortMultipart(this.options, objectUrl, uploadId).catch(() => undefined);\n }\n throw error;\n }\n\n if (parts.length === 0) {\n if (resumeStore !== undefined) await resumeStore.clear(resumeKey);\n await abortMultipart(this.options, objectUrl, uploadId).catch(() => undefined);\n throw new ConnectionError({\n message: \"S3 multipart upload completed with zero parts\",\n retryable: false,\n });\n }\n\n const completeUrl = new URL(objectUrl.toString());\n completeUrl.searchParams.set(\"uploadId\", uploadId);\n const xmlBody = buildCompleteMultipartBody(parts);\n const completeResponse = await s3Fetch(this.options, \"POST\", completeUrl, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: new TextEncoder().encode(xmlBody),\n extraHeaders: { \"content-type\": \"application/xml\" },\n });\n if (!completeResponse.ok) {\n if (resumeStore === undefined) {\n await abortMultipart(this.options, objectUrl, uploadId).catch(() => undefined);\n }\n throw mapResponseError(completeResponse, normalized);\n }\n if (resumeStore !== undefined) await resumeStore.clear(resumeKey);\n const completeBody = await completeResponse.text();\n const finalEtag = innerText(completeBody, \"ETag\");\n const result: ProviderTransferWriteResult = {\n bytesTransferred,\n totalBytes: bytesTransferred,\n };\n if (finalEtag !== undefined) result.checksum = finalEtag;\n return result;\n }\n\n private async singleShotFromBuffer(\n request: ProviderTransferWriteRequest,\n normalized: string,\n buffered: Uint8Array,\n ): Promise<ProviderTransferWriteResult> {\n const url = buildObjectUrl(this.options, normalized);\n const response = await s3Fetch(this.options, \"PUT\", url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body: buffered,\n extraHeaders: { \"content-type\": \"application/octet-stream\" },\n });\n if (!response.ok) throw mapResponseError(response, normalized);\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n const etag = response.headers.get(\"etag\");\n if (etag !== null) result.checksum = etag;\n return result;\n }\n}\n\ninterface S3FetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function s3Fetch(\n options: S3SessionOptions,\n method: string,\n url: URL,\n fetchOptions: S3FetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n };\n if (fetchOptions.body !== undefined) {\n headers[\"content-length\"] = String(fetchOptions.body.byteLength);\n }\n signSigV4({\n accessKeyId: options.accessKeyId,\n headers,\n method,\n region: options.region,\n secretAccessKey: options.secretAccessKey,\n service: options.service,\n url,\n ...(fetchOptions.body !== undefined ? { body: fetchOptions.body } : {}),\n ...(options.sessionToken !== undefined ? { sessionToken: options.sessionToken } : {}),\n });\n\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) (init as { body: Uint8Array }).body = fetchOptions.body;\n if (fetchOptions.signal !== undefined) init.signal = fetchOptions.signal;\n\n const controller = new AbortController();\n const upstreamSignal = init.signal ?? null;\n if (upstreamSignal !== null) {\n if (upstreamSignal.aborted) controller.abort(upstreamSignal.reason);\n else upstreamSignal.addEventListener(\"abort\", () => controller.abort(upstreamSignal.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"S3 request timed out\")),\n options.timeoutMs,\n );\n }\n\n try {\n return await options.fetch(url.toString(), { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url: url.toString() },\n message: `S3 request to ${url.toString()} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nfunction buildBucketUrl(options: S3SessionOptions): URL {\n const url = new URL(options.endpointUrl.toString());\n if (options.pathStyle) {\n url.pathname = `/${options.bucket}/`;\n } else {\n url.host = `${options.bucket}.${options.endpointUrl.host}`;\n url.pathname = \"/\";\n }\n return url;\n}\n\nfunction buildObjectUrl(options: S3SessionOptions, normalizedPath: string): URL {\n const key = normalizedPath === \"/\" ? \"\" : normalizedPath.slice(1);\n const url = buildBucketUrl(options);\n if (options.pathStyle) {\n url.pathname = `/${options.bucket}/${key}`;\n } else {\n url.pathname = `/${key}`;\n }\n return url;\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\nfunction concat(chunks: Uint8Array[], totalSize: number): Uint8Array {\n const out = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\nfunction sliceFromBuffers(\n buffers: Uint8Array[],\n size: number,\n): { bytes: Uint8Array; remaining: Uint8Array[] } {\n const out = new Uint8Array(size);\n let offset = 0;\n let i = 0;\n while (offset < size && i < buffers.length) {\n const chunk = buffers[i];\n if (chunk === undefined) {\n i += 1;\n continue;\n }\n const remaining = size - offset;\n if (chunk.byteLength <= remaining) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n i += 1;\n } else {\n out.set(chunk.subarray(0, remaining), offset);\n const leftover = chunk.subarray(remaining);\n const next = buffers.slice(i + 1);\n next.unshift(leftover);\n return { bytes: out, remaining: next };\n }\n }\n return { bytes: out.subarray(0, offset), remaining: buffers.slice(i) };\n}\n\nasync function abortMultipart(\n options: S3SessionOptions,\n objectUrl: URL,\n uploadId: string,\n): Promise<void> {\n const url = new URL(objectUrl.toString());\n url.searchParams.set(\"uploadId\", uploadId);\n await s3Fetch(options, \"DELETE\", url);\n}\n\nfunction buildCompleteMultipartBody(\n parts: ReadonlyArray<{ partNumber: number; etag: string }>,\n): string {\n const partsXml = parts\n .map(\n (part) =>\n `<Part><PartNumber>${String(part.partNumber)}</PartNumber><ETag>${escapeXml(part.etag)}</ETag></Part>`,\n )\n .join(\"\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?><CompleteMultipartUpload>${partsXml}</CompleteMultipartUpload>`;\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction parseListObjectsV2(xml: string, prefix: string): RemoteEntry[] {\n const entries: RemoteEntry[] = [];\n const contentRegex = /<Contents\\b[^>]*>([\\s\\S]*?)<\\/Contents>/g;\n let match: RegExpExecArray | null;\n while ((match = contentRegex.exec(xml)) !== null) {\n const inner = match[1] ?? \"\";\n const key = innerText(inner, \"Key\");\n if (key === undefined || key === prefix) continue;\n const size = innerText(inner, \"Size\");\n const lastModified = innerText(inner, \"LastModified\");\n const etag = innerText(inner, \"ETag\");\n const relative = key.startsWith(prefix) ? key.slice(prefix.length) : key;\n if (relative === \"\") continue;\n const path = `/${key}`;\n const entry: RemoteEntry = {\n name: basenameRemotePath(path),\n path,\n type: \"file\",\n };\n if (size !== undefined) {\n const bytes = Number.parseInt(size, 10);\n if (Number.isFinite(bytes) && bytes >= 0) entry.size = bytes;\n }\n if (lastModified !== undefined) {\n const parsed = new Date(lastModified);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (etag !== undefined) entry.uniqueId = etag;\n entries.push(entry);\n }\n\n const prefixRegex = /<CommonPrefixes\\b[^>]*>([\\s\\S]*?)<\\/CommonPrefixes>/g;\n while ((match = prefixRegex.exec(xml)) !== null) {\n const inner = match[1] ?? \"\";\n const subPrefix = innerText(inner, \"Prefix\");\n if (subPrefix === undefined) continue;\n const trimmed = subPrefix.endsWith(\"/\") ? subPrefix.slice(0, -1) : subPrefix;\n const path = `/${trimmed}`;\n entries.push({\n name: basenameRemotePath(path),\n path,\n type: \"directory\",\n });\n }\n return entries;\n}\n\nfunction innerText(xml: string, tag: string): string | undefined {\n const pattern = new RegExp(`<${tag}\\\\b[^>]*?(?:/>|>([\\\\s\\\\S]*?)</${tag}>)`, \"i\");\n const match = pattern.exec(xml);\n if (match === null) return undefined;\n return (match[1] ?? \"\").trim();\n}\n","/**\n * Built-in provider capability matrix.\n *\n * Aggregates the {@link CapabilitySet} advertised by every shipped provider\n * factory so applications, docs, and diagnostics can compare features across\n * providers without instantiating each one. The S3 entry is captured twice —\n * once with multipart upload disabled (default) and once with multipart\n * upload enabled — because that flag flips `resumeUpload`.\n *\n * @module providers/capabilityMatrix\n */\nimport type { CapabilitySet } from \"../core/CapabilitySet\";\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { createFtpProviderFactory, createFtpsProviderFactory } from \"./classic/ftp\";\nimport { createSftpProviderFactory } from \"./classic/sftp\";\nimport {\n createAzureBlobProviderFactory,\n createDropboxProviderFactory,\n createGcsProviderFactory,\n createGoogleDriveProviderFactory,\n createOneDriveProviderFactory,\n} from \"./cloud\";\nimport { createLocalProviderFactory } from \"./local\";\nimport { createMemoryProviderFactory } from \"./memory\";\nimport {\n createHttpProviderFactory,\n createS3ProviderFactory,\n createWebDavProviderFactory,\n} from \"./web\";\n\n/** Identifier for an entry in {@link getBuiltinCapabilityMatrix}. */\nexport type BuiltinProviderMatrixId = ProviderId | \"s3:multipart\";\n\n/** Single entry in the built-in capability matrix. */\nexport interface BuiltinCapabilityMatrixEntry {\n /** Stable matrix identifier (provider id, or `s3:multipart` for the multipart variant). */\n id: BuiltinProviderMatrixId;\n /** Human-readable label, suitable for documentation tables. */\n label: string;\n /** Capability snapshot advertised by the provider factory. */\n capabilities: CapabilitySet;\n}\n\nconst noopFetch: typeof fetch = () => Promise.reject(new Error(\"capabilityMatrix: fetch unused\"));\n\n/**\n * Returns the capability matrix for every shipped provider factory.\n *\n * Each call constructs a fresh factory snapshot, so the result reflects the\n * current build (including any future new metadata or notes). Web providers\n * are constructed with a no-op fetch since capability advertisement does not\n * require a live transport.\n */\nexport function getBuiltinCapabilityMatrix(): BuiltinCapabilityMatrixEntry[] {\n return [\n {\n capabilities: createLocalProviderFactory().capabilities,\n id: \"local\",\n label: \"Local file system\",\n },\n {\n capabilities: createMemoryProviderFactory().capabilities,\n id: \"memory\",\n label: \"In-memory (test fixture)\",\n },\n {\n capabilities: createFtpProviderFactory().capabilities,\n id: \"ftp\",\n label: \"FTP\",\n },\n {\n capabilities: createFtpsProviderFactory().capabilities,\n id: \"ftps\",\n label: \"FTPS\",\n },\n {\n capabilities: createSftpProviderFactory().capabilities,\n id: \"sftp\",\n label: \"SFTP\",\n },\n {\n capabilities: createHttpProviderFactory({ fetch: noopFetch }).capabilities,\n id: \"http\",\n label: \"HTTP/HTTPS (read-only)\",\n },\n {\n capabilities: createWebDavProviderFactory({ fetch: noopFetch }).capabilities,\n id: \"webdav\",\n label: \"WebDAV\",\n },\n {\n capabilities: createS3ProviderFactory({ fetch: noopFetch }).capabilities,\n id: \"s3\",\n label: \"S3-compatible (single-shot uploads)\",\n },\n {\n capabilities: createS3ProviderFactory({\n fetch: noopFetch,\n multipart: { enabled: true },\n }).capabilities,\n id: \"s3:multipart\",\n label: \"S3-compatible (multipart uploads)\",\n },\n {\n capabilities: createDropboxProviderFactory({ fetch: noopFetch }).capabilities,\n id: \"dropbox\",\n label: \"Dropbox\",\n },\n {\n capabilities: createGoogleDriveProviderFactory({ fetch: noopFetch }).capabilities,\n id: \"google-drive\",\n label: \"Google Drive\",\n },\n {\n capabilities: createOneDriveProviderFactory({ fetch: noopFetch }).capabilities,\n id: \"one-drive\",\n label: \"OneDrive / SharePoint\",\n },\n {\n capabilities: createAzureBlobProviderFactory({\n container: \"capability-matrix\",\n endpoint: \"https://example.blob.core.windows.net\",\n fetch: noopFetch,\n sasToken: \"sv=ignored\",\n }).capabilities,\n id: \"azure-blob\",\n label: \"Azure Blob Storage\",\n },\n {\n capabilities: createGcsProviderFactory({\n bucket: \"capability-matrix\",\n fetch: noopFetch,\n }).capabilities,\n id: \"gcs\",\n label: \"Google Cloud Storage\",\n },\n ];\n}\n\n/**\n * Renders the matrix returned by {@link getBuiltinCapabilityMatrix} as a\n * GitHub-flavored Markdown table covering the most commonly-compared\n * capability flags.\n */\nexport function formatCapabilityMatrixMarkdown(\n matrix: ReadonlyArray<BuiltinCapabilityMatrixEntry> = getBuiltinCapabilityMatrix(),\n): string {\n const header =\n \"| Provider | list | stat | read | write | resume↓ | resume↑ | server-side copy/move | checksums | auth |\";\n const divider = \"| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\";\n const rows = matrix.map((entry) => {\n const c = entry.capabilities;\n const yesNo = (value: boolean): string => (value ? \"✅\" : \"❌\");\n const sideways = `${yesNo(c.serverSideCopy)} / ${yesNo(c.serverSideMove)}`;\n const checksums = c.checksum.length === 0 ? \"—\" : c.checksum.join(\", \");\n const auth = c.authentication.length === 0 ? \"—\" : c.authentication.join(\", \");\n return `| ${entry.label} | ${yesNo(c.list)} | ${yesNo(c.stat)} | ${yesNo(c.readStream)} | ${yesNo(c.writeStream)} | ${yesNo(c.resumeDownload)} | ${yesNo(c.resumeUpload)} | ${sideways} | ${checksums} | ${auth} |`;\n });\n return [header, divider, ...rows].join(\"\\n\");\n}\n","/**\n * OAuth bearer-token helpers for cloud-drive and object-storage providers.\n *\n * Cloud providers in this SDK accept a bearer token via `profile.password`,\n * which is resolved as a {@link SecretSource}. Long-lived access tokens are\n * rare in OAuth flows; instead, applications hold a refresh token (or use a\n * client-credentials grant) and exchange it for short-lived access tokens.\n *\n * {@link createOAuthTokenSecretSource} adapts an arbitrary refresh callback\n * into a `SecretProvider` (one of the accepted `SecretSource` shapes) that\n * caches the most recent access token until its expiry approaches, then\n * silently re-runs the refresh callback. The cache honours an optional\n * `skewMs` margin so tokens are renewed before they expire on the wire.\n *\n * @module profiles/OAuthTokenSource\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { SecretProvider } from \"./SecretSource\";\n\n/** Token material returned by {@link OAuthRefreshCallback}. */\nexport interface OAuthAccessToken {\n /** Access token value. Required. */\n accessToken: string;\n /**\n * Lifetime in seconds (`expires_in`-style). When provided, the helper caches\n * the token until `now + (expiresInSeconds - skewSeconds)`.\n */\n expiresInSeconds?: number;\n /** Absolute expiry. Wins over `expiresInSeconds` when both are provided. */\n expiresAt?: Date;\n}\n\n/** Refresh callback invoked when no valid cached token is available. */\nexport type OAuthRefreshCallback = () => OAuthAccessToken | Promise<OAuthAccessToken>;\n\n/** Options accepted by {@link createOAuthTokenSecretSource}. */\nexport interface OAuthTokenSecretSourceOptions {\n /**\n * Safety margin (in milliseconds) subtracted from the token's expiry to\n * trigger a refresh before the wire deadline. Defaults to `60_000` (60s).\n */\n skewMs?: number;\n /** Clock used to evaluate expiry. Defaults to `Date.now`. */\n now?: () => number;\n}\n\ninterface CachedToken {\n accessToken: string;\n /** Absolute expiry in epoch milliseconds, or `undefined` for non-expiring tokens. */\n expiresAtMs: number | undefined;\n}\n\n/**\n * Builds a {@link SecretProvider} that exchanges a refresh callback for\n * cached, auto-renewing access tokens.\n *\n * The returned function can be passed directly as `profile.password` for any\n * provider that accepts bearer tokens (Dropbox, Google Drive, OneDrive, GCS,\n * Azure Blob via AAD).\n *\n * @example\n * ```ts\n * const password = createOAuthTokenSecretSource(async () => {\n * const res = await fetch(\"https://example.com/oauth/token\", { ... });\n * const body = (await res.json()) as { access_token: string; expires_in: number };\n * return { accessToken: body.access_token, expiresInSeconds: body.expires_in };\n * });\n * const session = await factory.create().connect({ host: \"\", protocol: \"ftp\", password });\n * ```\n */\nexport function createOAuthTokenSecretSource(\n refresh: OAuthRefreshCallback,\n options: OAuthTokenSecretSourceOptions = {},\n): SecretProvider {\n if (typeof refresh !== \"function\") {\n throw new ConfigurationError({\n message: \"createOAuthTokenSecretSource requires a refresh callback\",\n retryable: false,\n });\n }\n const skewMs = options.skewMs ?? 60_000;\n const now = options.now ?? (() => Date.now());\n if (skewMs < 0) {\n throw new ConfigurationError({\n message: \"OAuthTokenSecretSourceOptions.skewMs must be non-negative\",\n retryable: false,\n });\n }\n\n let cache: CachedToken | undefined;\n let pending: Promise<CachedToken> | undefined;\n\n const renew = async (): Promise<CachedToken> => {\n const result = await refresh();\n if (typeof result.accessToken !== \"string\" || result.accessToken === \"\") {\n throw new ConfigurationError({\n message: \"OAuth refresh callback returned an empty access token\",\n retryable: false,\n });\n }\n let expiresAtMs: number | undefined;\n if (result.expiresAt !== undefined) {\n const ts = result.expiresAt.getTime();\n if (Number.isFinite(ts)) expiresAtMs = ts;\n } else if (typeof result.expiresInSeconds === \"number\") {\n if (!Number.isFinite(result.expiresInSeconds) || result.expiresInSeconds <= 0) {\n throw new ConfigurationError({\n message: \"OAuth refresh callback returned a non-positive expiresInSeconds\",\n retryable: false,\n });\n }\n expiresAtMs = now() + result.expiresInSeconds * 1000;\n }\n const cached: CachedToken = { accessToken: result.accessToken, expiresAtMs };\n cache = cached;\n return cached;\n };\n\n return async () => {\n const current = cache;\n if (current !== undefined && isFresh(current, skewMs, now)) {\n return current.accessToken;\n }\n if (pending === undefined) {\n pending = renew().finally(() => {\n pending = undefined;\n });\n }\n const refreshed = await pending;\n return refreshed.accessToken;\n };\n}\n\nfunction isFresh(token: CachedToken, skewMs: number, now: () => number): boolean {\n if (token.expiresAtMs === undefined) return true;\n return token.expiresAtMs - skewMs > now();\n}\n","/**\n * OpenSSH `known_hosts` parsing helpers used by SFTP profile imports and host-key verification.\n *\n * @module profiles/importers/KnownHostsParser\n */\nimport { Buffer } from \"node:buffer\";\nimport { createHmac } from \"node:crypto\";\n\n/** Marker prefixing a known_hosts line (`@cert-authority` or `@revoked`). */\nexport type KnownHostsMarker = \"cert-authority\" | \"revoked\";\n\n/** Parsed entry from an OpenSSH `known_hosts` file. */\nexport interface KnownHostsEntry {\n /** Optional line marker (`@cert-authority` or `@revoked`). */\n marker?: KnownHostsMarker;\n /** Raw, comma-separated host patterns. Negation patterns retain their leading `!`. */\n hostPatterns: readonly string[];\n /** Hashed-salt component for `|1|salt|hash` entries. Mutually exclusive with plain patterns. */\n hashedSalt?: string;\n /** Hashed-hash component for `|1|salt|hash` entries. Mutually exclusive with plain patterns. */\n hashedHash?: string;\n /** SSH key algorithm identifier (e.g. `ssh-ed25519`, `ecdsa-sha2-nistp256`). */\n keyType: string;\n /** Base64-encoded public key blob. */\n keyBase64: string;\n /** Trailing comment text, if any. */\n comment?: string;\n /** Original line text without trailing newline. */\n raw: string;\n}\n\n/**\n * Parses OpenSSH `known_hosts` content into structured entries. Comment and blank lines are skipped.\n * Lines that cannot be parsed are silently dropped so callers can tolerate hand-edited files.\n *\n * @param text - Raw `known_hosts` file contents.\n * @returns Parsed entries in source order.\n */\nexport function parseKnownHosts(text: string): KnownHostsEntry[] {\n const entries: KnownHostsEntry[] = [];\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) continue;\n const entry = parseKnownHostsLine(line);\n if (entry !== undefined) entries.push(entry);\n }\n return entries;\n}\n\nfunction parseKnownHostsLine(line: string): KnownHostsEntry | undefined {\n const tokens = line.trim().split(/\\s+/);\n if (tokens.length < 3) return undefined;\n let index = 0;\n let marker: KnownHostsMarker | undefined;\n const first = tokens[index];\n if (first === \"@cert-authority\" || first === \"@revoked\") {\n marker = first === \"@cert-authority\" ? \"cert-authority\" : \"revoked\";\n index += 1;\n }\n const hostField = tokens[index];\n const keyType = tokens[index + 1];\n const keyBase64 = tokens[index + 2];\n if (hostField === undefined || keyType === undefined || keyBase64 === undefined) return undefined;\n const commentTokens = tokens.slice(index + 3);\n const comment = commentTokens.length > 0 ? commentTokens.join(\" \") : undefined;\n\n let hostPatterns: readonly string[] = [];\n let hashedSalt: string | undefined;\n let hashedHash: string | undefined;\n if (hostField.startsWith(\"|1|\")) {\n const parts = hostField.split(\"|\");\n if (parts.length < 4) return undefined;\n hashedSalt = parts[2];\n hashedHash = parts[3];\n } else {\n hostPatterns = hostField.split(\",\").filter((token) => token !== \"\");\n }\n\n const entry: KnownHostsEntry = {\n hostPatterns,\n keyBase64,\n keyType,\n raw: line,\n };\n if (marker !== undefined) entry.marker = marker;\n if (comment !== undefined) entry.comment = comment;\n if (hashedSalt !== undefined) entry.hashedSalt = hashedSalt;\n if (hashedHash !== undefined) entry.hashedHash = hashedHash;\n return entry;\n}\n\n/** Default OpenSSH port used when matching host patterns without an explicit `[host]:port`. */\nconst DEFAULT_SSH_PORT = 22;\n\n/**\n * Returns true when the given host (and optional port) matches the entry's host patterns.\n * Hashed entries use HMAC-SHA1 verification per OpenSSH semantics.\n *\n * @param entry - Parsed `known_hosts` entry to test.\n * @param host - Hostname or IP literal to match.\n * @param port - Optional connection port. Defaults to {@link DEFAULT_SSH_PORT}.\n * @returns Whether the entry matches and is not negated.\n */\nexport function matchKnownHostsEntry(\n entry: KnownHostsEntry,\n host: string,\n port: number = DEFAULT_SSH_PORT,\n): boolean {\n if (entry.hashedSalt !== undefined && entry.hashedHash !== undefined) {\n return matchesHashedEntry(entry.hashedSalt, entry.hashedHash, host, port);\n }\n let matched = false;\n for (const pattern of entry.hostPatterns) {\n if (pattern.startsWith(\"!\")) {\n const negated = pattern.slice(1);\n if (matchesPlainPattern(negated, host, port)) return false;\n continue;\n }\n if (matchesPlainPattern(pattern, host, port)) matched = true;\n }\n return matched;\n}\n\n/**\n * Filters parsed entries down to those that match the given host/port. Negations are honored.\n *\n * @param entries - Entries returned by {@link parseKnownHosts}.\n * @param host - Hostname or IP literal to match.\n * @param port - Optional connection port. Defaults to {@link DEFAULT_SSH_PORT}.\n * @returns Matching entries in source order.\n */\nexport function matchKnownHosts(\n entries: readonly KnownHostsEntry[],\n host: string,\n port: number = DEFAULT_SSH_PORT,\n): KnownHostsEntry[] {\n return entries.filter((entry) => matchKnownHostsEntry(entry, host, port));\n}\n\nfunction matchesPlainPattern(pattern: string, host: string, port: number): boolean {\n const portMatch = pattern.match(/^\\[(.+)\\]:(\\d+)$/);\n if (portMatch) {\n const [, hostPattern, portText] = portMatch;\n if (hostPattern === undefined || portText === undefined) return false;\n const expectedPort = Number.parseInt(portText, 10);\n if (Number.isNaN(expectedPort) || expectedPort !== port) return false;\n return globMatch(hostPattern, host);\n }\n return port === DEFAULT_SSH_PORT && globMatch(pattern, host);\n}\n\nfunction globMatch(pattern: string, value: string): boolean {\n const regex = new RegExp(\n `^${pattern\n .replace(/[.+^${}()|\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")}$`,\n \"i\",\n );\n return regex.test(value);\n}\n\nfunction matchesHashedEntry(salt: string, hash: string, host: string, port: number): boolean {\n const saltBuffer = Buffer.from(salt, \"base64\");\n if (saltBuffer.length === 0) return false;\n const candidates = port === DEFAULT_SSH_PORT ? [host] : [`[${host}]:${String(port)}`, host];\n for (const candidate of candidates) {\n const expected = createHmac(\"sha1\", saltBuffer).update(candidate).digest(\"base64\");\n if (expected === hash) return true;\n }\n return false;\n}\n","/**\n * OpenSSH `ssh_config` parser and {@link ConnectionProfile} importer.\n *\n * Supports the directives most commonly used by SFTP profiles: `HostName`, `Port`, `User`,\n * `IdentityFile`, `UserKnownHostsFile`, `ProxyJump`, `ConnectTimeout`, plus the SSH algorithm\n * controls (`KexAlgorithms`, `Ciphers`, `MACs`, `HostKeyAlgorithms`).\n *\n * @module profiles/importers/OpenSshConfigImporter\n */\nimport { ConfigurationError } from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Parsed `Host` block from an OpenSSH config file. */\nexport interface OpenSshConfigEntry {\n /** Host patterns declared on the `Host` line. */\n patterns: readonly string[];\n /** Lower-cased directive name to ordered values. Multi-valued directives (e.g. `IdentityFile`) preserve order. */\n options: Readonly<Record<string, readonly string[]>>;\n}\n\n/**\n * Parses OpenSSH `ssh_config` text into structured `Host` blocks.\n *\n * The parser is intentionally permissive: unknown directives are retained and `Match` blocks are skipped.\n *\n * @param text - Contents of the `ssh_config` file.\n * @returns Parsed `Host` entries in source order.\n */\nexport function parseOpenSshConfig(text: string): OpenSshConfigEntry[] {\n const entries: OpenSshConfigEntry[] = [];\n let current: { patterns: string[]; options: Record<string, string[]> } | undefined;\n let skipping = false;\n const lines = text.split(/\\r?\\n/);\n for (const rawLine of lines) {\n const line = rawLine.replace(/#.*$/, \"\").trim();\n if (line === \"\") continue;\n const match = line.match(/^([A-Za-z][A-Za-z0-9_-]*)\\s*=?\\s*(.*)$/);\n if (!match) continue;\n const [, keywordRaw, valueRaw] = match;\n if (keywordRaw === undefined || valueRaw === undefined) continue;\n const keyword = keywordRaw.toLowerCase();\n const value = valueRaw.trim();\n if (keyword === \"host\") {\n if (current !== undefined) entries.push(current);\n current = { options: {}, patterns: tokenizeValues(value) };\n skipping = false;\n continue;\n }\n if (keyword === \"match\") {\n if (current !== undefined) entries.push(current);\n current = undefined;\n skipping = true;\n continue;\n }\n if (skipping || current === undefined) continue;\n const values = tokenizeValues(value);\n const existing = current.options[keyword];\n if (existing === undefined) {\n current.options[keyword] = [...values];\n } else {\n existing.push(...values);\n }\n }\n if (current !== undefined) entries.push(current);\n return entries;\n}\n\nfunction tokenizeValues(value: string): string[] {\n if (value === \"\") return [];\n const tokens: string[] = [];\n const regex = /\"([^\"]*)\"|(\\S+)/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(value)) !== null) {\n tokens.push(match[1] ?? match[2] ?? \"\");\n }\n return tokens;\n}\n\n/**\n * Resolved set of directives for a given host alias. Values from later-declared blocks are\n * merged after earlier ones so wildcard fallbacks (e.g. `Host *`) only fill gaps.\n */\nexport interface ResolvedOpenSshHost {\n /** Host alias the lookup was performed against. */\n alias: string;\n /** Per-directive ordered values, keyed by lower-cased directive name. */\n options: Readonly<Record<string, readonly string[]>>;\n /** Source entries that contributed to the resolved set, in match order. */\n matched: readonly OpenSshConfigEntry[];\n}\n\n/**\n * Resolves the merged option set for an OpenSSH host alias.\n *\n * @param entries - Parsed entries from {@link parseOpenSshConfig}.\n * @param alias - Host alias to resolve.\n * @returns Merged directive set with the matching entries.\n */\nexport function resolveOpenSshHost(\n entries: readonly OpenSshConfigEntry[],\n alias: string,\n): ResolvedOpenSshHost {\n const merged: Record<string, string[]> = {};\n const matched: OpenSshConfigEntry[] = [];\n for (const entry of entries) {\n if (!entryMatchesAlias(entry, alias)) continue;\n matched.push(entry);\n for (const [key, values] of Object.entries(entry.options)) {\n if (merged[key] === undefined) merged[key] = [...values];\n }\n }\n return { alias, matched, options: merged };\n}\n\nfunction entryMatchesAlias(entry: OpenSshConfigEntry, alias: string): boolean {\n let matched = false;\n for (const pattern of entry.patterns) {\n if (pattern.startsWith(\"!\")) {\n if (globMatch(pattern.slice(1), alias)) return false;\n continue;\n }\n if (globMatch(pattern, alias)) matched = true;\n }\n return matched;\n}\n\nfunction globMatch(pattern: string, value: string): boolean {\n const regex = new RegExp(\n `^${pattern\n .replace(/[.+^${}()|\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")}$`,\n \"i\",\n );\n return regex.test(value);\n}\n\n/** Options accepted by {@link importOpenSshConfig}. */\nexport interface ImportOpenSshConfigOptions {\n /** Raw `ssh_config` text. Either this or {@link entries} must be provided. */\n text?: string;\n /** Pre-parsed entries from {@link parseOpenSshConfig}. */\n entries?: readonly OpenSshConfigEntry[];\n /** Host alias to import. */\n alias: string;\n}\n\n/** Result of {@link importOpenSshConfig}. */\nexport interface ImportOpenSshConfigResult {\n /** Generated SFTP connection profile. */\n profile: ConnectionProfile;\n /** Resolved directive set used to build the profile. */\n resolved: ResolvedOpenSshHost;\n /** Identity file paths declared in the config, in declaration order. */\n identityFiles: readonly string[];\n /** Optional `ProxyJump` value preserved from the config. */\n proxyJump?: string;\n}\n\n/**\n * Builds a {@link ConnectionProfile} for the given SSH alias from `ssh_config` text or pre-parsed entries.\n *\n * @param options - Import options.\n * @returns Importer result with the generated profile and supporting metadata.\n * @throws {@link ConfigurationError} When neither text nor entries is supplied.\n */\nexport function importOpenSshConfig(\n options: ImportOpenSshConfigOptions,\n): ImportOpenSshConfigResult {\n const { alias } = options;\n const entries =\n options.entries ?? (options.text !== undefined ? parseOpenSshConfig(options.text) : undefined);\n if (entries === undefined) {\n throw new ConfigurationError({\n code: \"openssh_config_input_missing\",\n message: \"importOpenSshConfig requires either text or pre-parsed entries.\",\n retryable: false,\n });\n }\n const resolved = resolveOpenSshHost(entries, alias);\n const optionsMap = resolved.options;\n\n const host = first(optionsMap, \"hostname\") ?? alias;\n const portText = first(optionsMap, \"port\");\n const port = portText !== undefined ? safeInt(portText) : undefined;\n const user = first(optionsMap, \"user\");\n const identityFiles = optionsMap[\"identityfile\"] ?? [];\n const knownHostsFiles = optionsMap[\"userknownhostsfile\"] ?? [];\n const connectTimeoutText = first(optionsMap, \"connecttimeout\");\n const proxyJump = first(optionsMap, \"proxyjump\");\n const kex = optionsMap[\"kexalgorithms\"] ?? [];\n const ciphers = optionsMap[\"ciphers\"] ?? [];\n const macs = optionsMap[\"macs\"] ?? [];\n const serverHostKey = optionsMap[\"hostkeyalgorithms\"] ?? [];\n\n const profile: ConnectionProfile = { host, provider: \"sftp\" };\n if (port !== undefined) profile.port = port;\n if (user !== undefined) profile.username = { value: user };\n if (connectTimeoutText !== undefined) {\n const seconds = safeInt(connectTimeoutText);\n if (seconds !== undefined) profile.timeoutMs = seconds * 1000;\n }\n\n const ssh: NonNullable<ConnectionProfile[\"ssh\"]> = {};\n if (identityFiles.length > 0) {\n const firstKey = identityFiles[0];\n if (firstKey !== undefined) ssh.privateKey = { path: expandHome(firstKey) };\n }\n if (knownHostsFiles.length > 0) {\n ssh.knownHosts = knownHostsFiles.map((path) => ({ path: expandHome(path) }));\n }\n const algorithms: Record<string, string[]> = {};\n if (kex.length > 0) algorithms[\"kex\"] = expandAlgorithms(kex);\n if (ciphers.length > 0) algorithms[\"cipher\"] = expandAlgorithms(ciphers);\n if (macs.length > 0) algorithms[\"hmac\"] = expandAlgorithms(macs);\n if (serverHostKey.length > 0) algorithms[\"serverHostKey\"] = expandAlgorithms(serverHostKey);\n if (Object.keys(algorithms).length > 0) {\n ssh.algorithms = algorithms;\n }\n if (Object.keys(ssh).length > 0) profile.ssh = ssh;\n\n const result: ImportOpenSshConfigResult = {\n identityFiles: identityFiles.map(expandHome),\n profile,\n resolved,\n };\n if (proxyJump !== undefined) result.proxyJump = proxyJump;\n return result;\n}\n\nfunction first(\n options: Readonly<Record<string, readonly string[]>>,\n key: string,\n): string | undefined {\n const values = options[key];\n return values !== undefined && values.length > 0 ? values[0] : undefined;\n}\n\nfunction safeInt(text: string): number | undefined {\n const value = Number.parseInt(text, 10);\n return Number.isFinite(value) ? value : undefined;\n}\n\nfunction expandHome(path: string): string {\n if (!path.startsWith(\"~\")) return path;\n const home = process.env[\"HOME\"] ?? process.env[\"USERPROFILE\"];\n if (home === undefined) return path;\n if (path === \"~\") return home;\n if (path.startsWith(\"~/\") || path.startsWith(\"~\\\\\")) return `${home}${path.slice(1)}`;\n return path;\n}\n\nfunction expandAlgorithms(values: readonly string[]): string[] {\n const out: string[] = [];\n for (const value of values) {\n for (const part of value.split(\",\")) {\n const trimmed = part.trim();\n if (trimmed !== \"\") out.push(trimmed);\n }\n }\n return out;\n}\n","/**\n * FileZilla `sitemanager.xml` importer.\n *\n * Walks FileZilla's nested folder/server hierarchy and emits {@link ConnectionProfile} entries\n * for each saved site. The importer ignores cloud providers and other entries it cannot map\n * to a {@link RemoteProtocol}.\n *\n * @module profiles/importers/FileZillaImporter\n */\nimport { Buffer } from \"node:buffer\";\nimport { ConfigurationError } from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Imported FileZilla site with the folder hierarchy that contained it. */\nexport interface FileZillaSite {\n /** Site display name. */\n name: string;\n /** Ordered folder names leading to the site (top-level first). Empty for root sites. */\n folder: readonly string[];\n /** Generated connection profile. */\n profile: ConnectionProfile;\n /** Encoded password value retained from the file, if any. */\n password?: string;\n /** Logon type code preserved from the file (`0`=anonymous, `1`=normal, etc.). */\n logonType?: number;\n}\n\n/** Result returned by {@link importFileZillaSites}. */\nexport interface ImportFileZillaSitesResult {\n /** Sites successfully mapped to a connection profile. */\n sites: readonly FileZillaSite[];\n /** Sites that were skipped because their protocol is not supported. */\n skipped: readonly { name: string; folder: readonly string[]; protocol?: number }[];\n}\n\n/**\n * Parses FileZilla `sitemanager.xml` text and returns generated profiles.\n *\n * @param xml - Contents of `sitemanager.xml`.\n * @returns Imported sites and any skipped entries.\n * @throws {@link ConfigurationError} When the XML root cannot be located.\n */\nexport function importFileZillaSites(xml: string): ImportFileZillaSitesResult {\n const events = tokenizeXml(xml);\n if (events.length === 0) {\n throw new ConfigurationError({\n code: \"filezilla_xml_empty\",\n message: \"FileZilla sitemanager XML is empty.\",\n retryable: false,\n });\n }\n const sites: FileZillaSite[] = [];\n const skipped: { name: string; folder: readonly string[]; protocol?: number }[] = [];\n const folderStack: string[] = [];\n const folderNamePending: boolean[] = [];\n let inServer = false;\n let serverFields: Record<string, string> = {};\n let serverPasswordEncoding: string | undefined;\n let activeTag: string | undefined;\n let captureFolderName = false;\n\n for (const event of events) {\n if (event.kind === \"open\") {\n if (event.name === \"Folder\") {\n folderStack.push(\"\");\n folderNamePending.push(true);\n continue;\n }\n if (event.name === \"Server\") {\n inServer = true;\n serverFields = {};\n serverPasswordEncoding = undefined;\n continue;\n }\n activeTag = event.name;\n if (event.name === \"Pass\" && inServer) {\n serverPasswordEncoding = event.attributes[\"encoding\"];\n }\n if (event.name === \"Name\" && !inServer && folderNamePending.length > 0) {\n captureFolderName = true;\n }\n continue;\n }\n if (event.kind === \"text\") {\n if (captureFolderName) {\n const top = folderStack.length - 1;\n if (top >= 0) folderStack[top] = event.text.trim();\n captureFolderName = false;\n continue;\n }\n if (inServer && activeTag !== undefined) {\n serverFields[activeTag] = (serverFields[activeTag] ?? \"\") + event.text;\n }\n continue;\n }\n if (event.kind === \"close\") {\n if (event.name === \"Folder\") {\n folderStack.pop();\n folderNamePending.pop();\n continue;\n }\n if (event.name === \"Server\") {\n const folder = folderStack.filter((segment) => segment !== \"\");\n const result = buildSiteFromFields(serverFields, serverPasswordEncoding);\n if (result.kind === \"site\") {\n sites.push({ ...result.site, folder });\n } else {\n skipped.push({\n folder,\n name: result.name,\n ...(result.protocol !== undefined ? { protocol: result.protocol } : {}),\n });\n }\n inServer = false;\n serverFields = {};\n serverPasswordEncoding = undefined;\n activeTag = undefined;\n continue;\n }\n if (activeTag === event.name) activeTag = undefined;\n }\n }\n return { sites, skipped };\n}\n\ninterface BuiltSite {\n kind: \"site\";\n site: Omit<FileZillaSite, \"folder\">;\n}\n\ninterface SkippedSite {\n kind: \"skipped\";\n name: string;\n protocol?: number;\n}\n\nfunction buildSiteFromFields(\n fields: Record<string, string>,\n passwordEncoding: string | undefined,\n): BuiltSite | SkippedSite {\n const name = (fields[\"Name\"] ?? fields[\"Host\"] ?? \"Untitled\").trim();\n const host = (fields[\"Host\"] ?? \"\").trim();\n if (host === \"\") return { kind: \"skipped\", name };\n const protocolText = fields[\"Protocol\"];\n const protocol = protocolText !== undefined ? Number.parseInt(protocolText.trim(), 10) : 0;\n const mapped = mapFileZillaProtocol(protocol);\n if (mapped === undefined) {\n return Number.isFinite(protocol)\n ? { kind: \"skipped\", name, protocol }\n : { kind: \"skipped\", name };\n }\n const profile: ConnectionProfile = { host, provider: mapped.provider };\n if (mapped.secure !== undefined) profile.secure = mapped.secure;\n const portText = fields[\"Port\"];\n if (portText !== undefined) {\n const port = Number.parseInt(portText.trim(), 10);\n if (Number.isFinite(port)) profile.port = port;\n }\n const user = fields[\"User\"]?.trim();\n if (user !== undefined && user !== \"\") profile.username = { value: user };\n\n let password: string | undefined;\n const rawPass = fields[\"Pass\"];\n if (rawPass !== undefined && rawPass !== \"\") {\n if (passwordEncoding === \"base64\") {\n password = Buffer.from(rawPass, \"base64\").toString(\"utf8\");\n } else {\n password = rawPass;\n }\n if (password !== undefined && password !== \"\") profile.password = { value: password };\n }\n\n const site: Omit<FileZillaSite, \"folder\"> = { name, profile };\n if (password !== undefined) site.password = password;\n const logonText = fields[\"Logontype\"];\n if (logonText !== undefined) {\n const logonType = Number.parseInt(logonText.trim(), 10);\n if (Number.isFinite(logonType)) site.logonType = logonType;\n }\n return { kind: \"site\", site };\n}\n\nfunction mapFileZillaProtocol(\n code: number,\n): { provider: NonNullable<ConnectionProfile[\"provider\"]>; secure?: boolean } | undefined {\n switch (code) {\n case 0:\n return { provider: \"ftp\" };\n case 1:\n return { provider: \"sftp\" };\n case 4:\n return { provider: \"ftps\", secure: true };\n case 5:\n return { provider: \"ftps\", secure: true };\n case 6:\n return { provider: \"ftp\", secure: false };\n default:\n return undefined;\n }\n}\n\ninterface XmlOpenEvent {\n kind: \"open\";\n name: string;\n attributes: Record<string, string>;\n selfClosing: boolean;\n}\ninterface XmlCloseEvent {\n kind: \"close\";\n name: string;\n}\ninterface XmlTextEvent {\n kind: \"text\";\n text: string;\n}\ntype XmlEvent = XmlOpenEvent | XmlCloseEvent | XmlTextEvent;\n\nfunction tokenizeXml(xml: string): XmlEvent[] {\n const events: XmlEvent[] = [];\n let index = 0;\n const length = xml.length;\n while (index < length) {\n const lt = xml.indexOf(\"<\", index);\n if (lt === -1) {\n const text = xml.slice(index);\n if (text.trim() !== \"\") events.push({ kind: \"text\", text: decodeEntities(text) });\n break;\n }\n if (lt > index) {\n const text = xml.slice(index, lt);\n if (text.trim() !== \"\") events.push({ kind: \"text\", text: decodeEntities(text) });\n }\n if (xml.startsWith(\"<!--\", lt)) {\n const end = xml.indexOf(\"-->\", lt + 4);\n index = end === -1 ? length : end + 3;\n continue;\n }\n if (xml.startsWith(\"<![CDATA[\", lt)) {\n const end = xml.indexOf(\"]]>\", lt + 9);\n const cdataEnd = end === -1 ? length : end;\n events.push({ kind: \"text\", text: xml.slice(lt + 9, cdataEnd) });\n index = end === -1 ? length : end + 3;\n continue;\n }\n if (xml[lt + 1] === \"?\" || xml[lt + 1] === \"!\") {\n const gt = xml.indexOf(\">\", lt + 1);\n index = gt === -1 ? length : gt + 1;\n continue;\n }\n const gt = xml.indexOf(\">\", lt + 1);\n if (gt === -1) break;\n const tagBody = xml.slice(lt + 1, gt);\n if (tagBody.startsWith(\"/\")) {\n events.push({ kind: \"close\", name: tagBody.slice(1).trim() });\n } else {\n const selfClosing = tagBody.endsWith(\"/\");\n const body = selfClosing ? tagBody.slice(0, -1) : tagBody;\n const { name, attributes } = parseTagBody(body.trim());\n events.push({ attributes, kind: \"open\", name, selfClosing });\n if (selfClosing) events.push({ kind: \"close\", name });\n }\n index = gt + 1;\n }\n return events;\n}\n\nfunction parseTagBody(body: string): { name: string; attributes: Record<string, string> } {\n const match = body.match(/^([A-Za-z_:][\\w:.-]*)\\s*(.*)$/);\n if (!match) return { attributes: {}, name: body };\n const name = match[1] ?? \"\";\n const rest = match[2] ?? \"\";\n const attributes: Record<string, string> = {};\n const attrRegex = /([A-Za-z_:][\\w:.-]*)\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/g;\n let attrMatch: RegExpExecArray | null;\n while ((attrMatch = attrRegex.exec(rest)) !== null) {\n const key = attrMatch[1];\n const value = attrMatch[3] ?? attrMatch[4] ?? \"\";\n if (key !== undefined) attributes[key] = decodeEntities(value);\n }\n return { attributes, name };\n}\n\nfunction decodeEntities(text: string): string {\n return text\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\");\n}\n","/**\n * WinSCP `WinSCP.ini` importer.\n *\n * Parses the INI session sections produced by WinSCP and emits {@link ConnectionProfile} entries.\n * Sessions whose `FSProtocol` cannot be mapped to a classic provider are skipped.\n *\n * @module profiles/importers/WinScpImporter\n */\nimport { ConfigurationError } from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Imported WinSCP session entry. */\nexport interface WinScpSession {\n /** Decoded session name (URL-decoded path under the `Sessions\\\\` namespace). */\n name: string;\n /** Hierarchical path segments derived from the session name (folders separated by `/`). */\n folder: readonly string[];\n /** Generated connection profile. */\n profile: ConnectionProfile;\n /** Raw FSProtocol code preserved from the file. */\n fsProtocol?: number;\n /** Raw Ftps code preserved from the file (`0`=none, `1`=implicit, `2`/`3`=explicit). */\n ftps?: number;\n}\n\n/** Result of {@link importWinScpSessions}. */\nexport interface ImportWinScpSessionsResult {\n /** Successfully mapped sessions. */\n sessions: readonly WinScpSession[];\n /** Sessions skipped because their protocol is not supported. */\n skipped: readonly { name: string; folder: readonly string[]; fsProtocol?: number }[];\n}\n\n/**\n * Parses WinSCP `WinSCP.ini` text and returns generated profiles.\n *\n * @param ini - Contents of the WinSCP configuration file.\n * @returns Imported sessions and any skipped entries.\n * @throws {@link ConfigurationError} When no session sections are found.\n */\nexport function importWinScpSessions(ini: string): ImportWinScpSessionsResult {\n const sections = parseIni(ini);\n const sessionSections = sections.filter((section) => section.name.startsWith(\"Sessions\\\\\"));\n if (sessionSections.length === 0) {\n throw new ConfigurationError({\n code: \"winscp_ini_no_sessions\",\n message: \"WinSCP INI does not contain any [Sessions\\\\...] sections.\",\n retryable: false,\n });\n }\n const sessions: WinScpSession[] = [];\n const skipped: { name: string; folder: readonly string[]; fsProtocol?: number }[] = [];\n for (const section of sessionSections) {\n const decodedPath = decodeSessionPath(section.name.slice(\"Sessions\\\\\".length));\n const segments = decodedPath.split(\"/\").filter((segment) => segment !== \"\");\n const name = segments[segments.length - 1] ?? decodedPath;\n const folder = segments.slice(0, -1);\n const built = buildSessionProfile(name, section.values);\n if (built.kind === \"session\") {\n sessions.push({ ...built.session, folder });\n } else {\n skipped.push({\n folder,\n name,\n ...(built.fsProtocol !== undefined ? { fsProtocol: built.fsProtocol } : {}),\n });\n }\n }\n return { sessions, skipped };\n}\n\ninterface BuiltSession {\n kind: \"session\";\n session: Omit<WinScpSession, \"folder\">;\n}\ninterface SkippedSession {\n kind: \"skipped\";\n fsProtocol?: number;\n}\n\nfunction buildSessionProfile(\n name: string,\n values: Readonly<Record<string, string>>,\n): BuiltSession | SkippedSession {\n const host = values[\"HostName\"]?.trim();\n if (host === undefined || host === \"\") return { kind: \"skipped\" };\n const fsProtocolText = values[\"FSProtocol\"];\n const fsProtocol = fsProtocolText !== undefined ? Number.parseInt(fsProtocolText, 10) : 1;\n const ftpsText = values[\"Ftps\"];\n const ftps = ftpsText !== undefined ? Number.parseInt(ftpsText, 10) : 0;\n const mapped = mapWinScpProtocol(fsProtocol, ftps);\n if (mapped === undefined) {\n return Number.isFinite(fsProtocol) ? { fsProtocol, kind: \"skipped\" } : { kind: \"skipped\" };\n }\n\n const profile: ConnectionProfile = { host, provider: mapped.provider };\n if (mapped.secure !== undefined) profile.secure = mapped.secure;\n const portText = values[\"PortNumber\"];\n if (portText !== undefined) {\n const port = Number.parseInt(portText, 10);\n if (Number.isFinite(port)) profile.port = port;\n }\n const user = values[\"UserName\"]?.trim();\n if (user !== undefined && user !== \"\") profile.username = { value: user };\n\n if (mapped.provider === \"sftp\") {\n const ssh: NonNullable<ConnectionProfile[\"ssh\"]> = {};\n const keyPath = values[\"PublicKeyFile\"]?.trim();\n if (keyPath !== undefined && keyPath !== \"\") ssh.privateKey = { path: keyPath };\n if (Object.keys(ssh).length > 0) profile.ssh = ssh;\n }\n\n const session: Omit<WinScpSession, \"folder\"> = { name, profile };\n if (Number.isFinite(fsProtocol)) session.fsProtocol = fsProtocol;\n if (Number.isFinite(ftps) && ftps !== 0) session.ftps = ftps;\n return { kind: \"session\", session };\n}\n\nfunction mapWinScpProtocol(\n fsProtocol: number,\n ftps: number,\n): { provider: NonNullable<ConnectionProfile[\"provider\"]>; secure?: boolean } | undefined {\n switch (fsProtocol) {\n case 0:\n case 1:\n case 2:\n return { provider: \"sftp\" };\n case 5:\n return ftps === 0 ? { provider: \"ftp\" } : { provider: \"ftps\", secure: ftps === 1 };\n default:\n return undefined;\n }\n}\n\ninterface IniSection {\n name: string;\n values: Record<string, string>;\n}\n\nfunction parseIni(text: string): IniSection[] {\n const sections: IniSection[] = [];\n let current: IniSection | undefined;\n const lines = text.split(/\\r?\\n/);\n for (const rawLine of lines) {\n const line = rawLine.replace(/^\\s*[#;].*$/, \"\").trim();\n if (line === \"\") continue;\n const sectionMatch = line.match(/^\\[(.+)\\]$/);\n if (sectionMatch && sectionMatch[1] !== undefined) {\n current = { name: sectionMatch[1], values: {} };\n sections.push(current);\n continue;\n }\n if (current === undefined) continue;\n const eq = line.indexOf(\"=\");\n if (eq === -1) continue;\n const key = line.slice(0, eq).trim();\n const value = line.slice(eq + 1).trim();\n if (key !== \"\") current.values[key] = value;\n }\n return sections;\n}\n\nfunction decodeSessionPath(name: string): string {\n // WinSCP encodes special characters in session names (e.g. spaces as %20, backslashes as %5C).\n try {\n return decodeURIComponent(name);\n } catch {\n return name;\n }\n}\n","/**\n * Protocol error factory helpers.\n *\n * This module translates raw FTP status replies into typed ZeroTransfer errors so\n * adapters can keep protocol parsing separate from application-facing failures.\n *\n * @module errors/errorFactory\n */\nimport {\n AuthenticationError,\n ConnectionError,\n PathAlreadyExistsError,\n PathNotFoundError,\n PermissionDeniedError,\n ProtocolError,\n TransferError,\n type SpecializedErrorDetails,\n type ZeroTransferError,\n} from \"./ZeroTransferError\";\nimport type { RemoteProtocol } from \"../types/public\";\n\n/**\n * Input used to map an FTP reply into a structured ZeroTransfer error.\n */\nexport interface FtpReplyErrorInput {\n /** Numeric FTP response code returned by the server. */\n ftpCode: number;\n /** Server-provided response message. */\n message: string;\n /** FTP command that produced the response, if known. */\n command?: string;\n /** Remote path involved in the command, if any. */\n path?: string;\n /** Protocol variant used by the adapter. */\n protocol?: RemoteProtocol;\n /** Original lower-level failure that accompanied the reply. */\n cause?: unknown;\n}\n\n/**\n * Maps an FTP reply into the closest typed ZeroTransfer error.\n *\n * @param input - FTP code, message, and optional operation context.\n * @returns A structured error subclass with stable code and retryability metadata.\n */\nexport function errorFromFtpReply(input: FtpReplyErrorInput): ZeroTransferError {\n const details: SpecializedErrorDetails = {\n ftpCode: input.ftpCode,\n message: input.message,\n protocol: input.protocol ?? \"ftp\",\n retryable: false,\n };\n\n if (input.command !== undefined) details.command = input.command;\n if (input.path !== undefined) details.path = input.path;\n if (input.cause !== undefined) details.cause = input.cause;\n\n if (input.ftpCode === 530) {\n return new AuthenticationError(details);\n }\n\n if (input.ftpCode === 421) {\n return new ConnectionError({\n ...details,\n retryable: true,\n });\n }\n\n if (input.ftpCode === 550) {\n return mapFtp550(details);\n }\n\n if ([450, 451, 452].includes(input.ftpCode)) {\n return new TransferError({\n ...details,\n retryable: true,\n });\n }\n\n if (input.ftpCode >= 400 && input.ftpCode < 500) {\n return new ConnectionError({\n ...details,\n retryable: true,\n });\n }\n\n return new ProtocolError(details);\n}\n\n/**\n * Maps ambiguous FTP 550 replies to the most specific path or permission error.\n *\n * @param details - Shared error details derived from the original reply.\n * @returns A typed path or permission error.\n */\nfunction mapFtp550(details: SpecializedErrorDetails): ZeroTransferError {\n const lowerMessage = details.message.toLowerCase();\n\n if (lowerMessage.includes(\"already\") || lowerMessage.includes(\"exists\")) {\n return new PathAlreadyExistsError(details);\n }\n\n if (\n lowerMessage.includes(\"not found\") ||\n lowerMessage.includes(\"no such\") ||\n lowerMessage.includes(\"unavailable\")\n ) {\n return new PathNotFoundError(details);\n }\n\n return new PermissionDeniedError(details);\n}\n","/**\n * Transfer plan and dry-run primitives.\n *\n * @module transfers/TransferPlan\n */\nimport type { TransferEndpoint, TransferJob, TransferOperation } from \"./TransferJob\";\n\n/** Non-executing plan action used to explain an intentionally skipped step. */\nexport type TransferPlanAction = TransferOperation | \"skip\";\n\n/** Step inside a transfer plan. */\nexport interface TransferPlanStep {\n /** Stable step identifier within the plan. */\n id: string;\n /** Action the step would perform. */\n action: TransferPlanAction;\n /** Source endpoint when the action reads data. */\n source?: TransferEndpoint;\n /** Destination endpoint when the action writes data. */\n destination?: TransferEndpoint;\n /** Expected bytes affected by the step when known. */\n expectedBytes?: number;\n /** Whether this step may remove or replace data. */\n destructive?: boolean;\n /** Human-readable reason for planned or skipped work. */\n reason?: string;\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Input used to create a transfer plan. */\nexport interface TransferPlanInput {\n /** Stable plan identifier. */\n id: string;\n /** Planned steps in execution order. */\n steps: TransferPlanStep[];\n /** Whether the plan is informational only. Defaults to `true`. */\n dryRun?: boolean;\n /** Clock used for deterministic tests. Defaults to `new Date()`. */\n now?: () => Date;\n /** Non-fatal plan warnings. */\n warnings?: string[];\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Provider-neutral transfer plan. */\nexport interface TransferPlan {\n /** Stable plan identifier. */\n id: string;\n /** Whether this plan should be treated as a dry run. */\n dryRun: boolean;\n /** Time the plan was created. */\n createdAt: Date;\n /** Planned steps in execution order. */\n steps: TransferPlanStep[];\n /** Non-fatal plan warnings. */\n warnings: string[];\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Summary of a transfer plan. */\nexport interface TransferPlanSummary {\n /** Total number of steps. */\n totalSteps: number;\n /** Number of executable steps. */\n executableSteps: number;\n /** Number of skipped steps. */\n skippedSteps: number;\n /** Number of destructive steps. */\n destructiveSteps: number;\n /** Sum of expected bytes for steps that provide sizes. */\n totalExpectedBytes: number;\n /** Counts grouped by action. */\n actions: Record<string, number>;\n}\n\n/** Creates a transfer plan from dry-run planning input. */\nexport function createTransferPlan(input: TransferPlanInput): TransferPlan {\n const plan: TransferPlan = {\n createdAt: input.now?.() ?? new Date(),\n dryRun: input.dryRun ?? true,\n id: input.id,\n steps: input.steps.map(clonePlanStep),\n warnings: [...(input.warnings ?? [])],\n };\n\n if (input.metadata !== undefined) {\n plan.metadata = { ...input.metadata };\n }\n\n return plan;\n}\n\n/** Summarizes a transfer plan for diagnostics, previews, and tests. */\nexport function summarizeTransferPlan(plan: TransferPlan): TransferPlanSummary {\n const actions: Record<string, number> = {};\n let destructiveSteps = 0;\n let executableSteps = 0;\n let skippedSteps = 0;\n let totalExpectedBytes = 0;\n\n for (const step of plan.steps) {\n actions[step.action] = (actions[step.action] ?? 0) + 1;\n destructiveSteps += step.destructive === true ? 1 : 0;\n skippedSteps += step.action === \"skip\" ? 1 : 0;\n executableSteps += step.action === \"skip\" ? 0 : 1;\n totalExpectedBytes += step.expectedBytes ?? 0;\n }\n\n return {\n actions,\n destructiveSteps,\n executableSteps,\n skippedSteps,\n totalExpectedBytes,\n totalSteps: plan.steps.length,\n };\n}\n\n/** Converts executable plan steps into transfer jobs while preserving order. */\nexport function createTransferJobsFromPlan(plan: TransferPlan): TransferJob[] {\n return plan.steps.flatMap((step) => {\n if (step.action === \"skip\") {\n return [];\n }\n\n const job: TransferJob = {\n id: `${plan.id}:${step.id}`,\n operation: step.action,\n };\n\n if (step.source !== undefined) job.source = cloneEndpoint(step.source);\n if (step.destination !== undefined) job.destination = cloneEndpoint(step.destination);\n if (step.expectedBytes !== undefined) job.totalBytes = step.expectedBytes;\n if (step.metadata !== undefined) job.metadata = { ...step.metadata };\n\n return [job];\n });\n}\n\nfunction clonePlanStep(step: TransferPlanStep): TransferPlanStep {\n const clone: TransferPlanStep = {\n action: step.action,\n id: step.id,\n };\n\n if (step.source !== undefined) clone.source = cloneEndpoint(step.source);\n if (step.destination !== undefined) clone.destination = cloneEndpoint(step.destination);\n if (step.expectedBytes !== undefined) clone.expectedBytes = step.expectedBytes;\n if (step.destructive !== undefined) clone.destructive = step.destructive;\n if (step.reason !== undefined) clone.reason = step.reason;\n if (step.metadata !== undefined) clone.metadata = { ...step.metadata };\n\n return clone;\n}\n\nfunction cloneEndpoint(endpoint: TransferEndpoint): TransferEndpoint {\n const clone: TransferEndpoint = { path: endpoint.path };\n\n if (endpoint.provider !== undefined) {\n clone.provider = endpoint.provider;\n }\n\n return clone;\n}\n","/**\n * Transfer queue primitives built on top of {@link TransferEngine}.\n *\n * @module transfers/TransferQueue\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferProgressEvent } from \"../types/public\";\nimport {\n TransferEngine,\n type TransferEngineExecuteOptions,\n type TransferExecutor,\n type TransferRetryPolicy,\n} from \"./TransferEngine\";\nimport type {\n TransferBandwidthLimit,\n TransferJob,\n TransferReceipt,\n TransferTimeoutPolicy,\n} from \"./TransferJob\";\n\n/** Queue item lifecycle state. */\nexport type TransferQueueItemStatus = \"queued\" | \"running\" | \"completed\" | \"failed\" | \"canceled\";\n\n/** Resolver used when jobs do not provide an executor at enqueue time. */\nexport type TransferQueueExecutorResolver = (job: TransferJob) => TransferExecutor;\n\n/** Options used to create a transfer queue. */\nexport interface TransferQueueOptions {\n /** Transfer engine used to execute queued jobs. Defaults to a new engine. */\n engine?: TransferEngine;\n /** Maximum jobs to execute at the same time. Defaults to `1`. */\n concurrency?: number;\n /** Default executor used for jobs that do not provide one directly. */\n executor?: TransferExecutor;\n /** Dynamic executor resolver used when no per-job executor or default executor exists. */\n resolveExecutor?: TransferQueueExecutorResolver;\n /** Retry policy passed to engine executions. */\n retry?: TransferRetryPolicy;\n /** Timeout policy passed to engine executions. */\n timeout?: TransferTimeoutPolicy;\n /** Optional throughput limit shape passed to transfer executors. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Progress observer shared across queued jobs. */\n onProgress?: (event: TransferProgressEvent) => void;\n /** Completion observer for successful jobs. */\n onReceipt?: (receipt: TransferReceipt) => void;\n /** Failure observer for failed jobs. */\n onError?: (item: TransferQueueItem, error: unknown) => void;\n}\n\n/** Options used when draining a queue. */\nexport interface TransferQueueRunOptions {\n /** Abort signal used to cancel running jobs during this drain. */\n signal?: AbortSignal;\n /** Retry policy override for this drain. */\n retry?: TransferRetryPolicy;\n /** Timeout policy override for this drain. */\n timeout?: TransferTimeoutPolicy;\n /** Bandwidth limit override for this drain. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Progress observer override for this drain. */\n onProgress?: (event: TransferProgressEvent) => void;\n}\n\n/** Enqueued transfer job state. */\nexport interface TransferQueueItem {\n /** Queued job identifier. */\n id: string;\n /** Original transfer job. */\n job: TransferJob;\n /** Current queue status. */\n status: TransferQueueItemStatus;\n /** Successful transfer receipt when completed. */\n receipt?: TransferReceipt;\n /** Failure or cancellation reason when available. */\n error?: unknown;\n}\n\ninterface InternalTransferQueueItem extends TransferQueueItem {\n controller: AbortController;\n executor?: TransferExecutor;\n}\n\n/** Summary returned after a queue drain. */\nexport interface TransferQueueSummary {\n /** Number of items currently known to the queue. */\n total: number;\n /** Number of successfully completed jobs. */\n completed: number;\n /** Number of failed jobs. */\n failed: number;\n /** Number of canceled jobs. */\n canceled: number;\n /** Number of jobs still queued because the queue was paused. */\n queued: number;\n /** Number of jobs currently running. */\n running: number;\n /** Successful receipts in queue order. */\n receipts: TransferReceipt[];\n /** Failed queue items in queue order. */\n failures: TransferQueueItem[];\n}\n\n/** Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries. */\nexport class TransferQueue {\n private readonly engine: TransferEngine;\n private readonly items: InternalTransferQueueItem[] = [];\n private readonly defaultExecutor: TransferExecutor | undefined;\n private readonly resolveExecutor: TransferQueueExecutorResolver | undefined;\n private readonly retry: TransferRetryPolicy | undefined;\n private readonly timeout: TransferTimeoutPolicy | undefined;\n private readonly bandwidthLimit: TransferBandwidthLimit | undefined;\n private readonly onProgress: ((event: TransferProgressEvent) => void) | undefined;\n private readonly onReceipt: ((receipt: TransferReceipt) => void) | undefined;\n private readonly onError: ((item: TransferQueueItem, error: unknown) => void) | undefined;\n private concurrency: number;\n private paused = false;\n\n /**\n * Creates a transfer queue.\n *\n * @param options - Queue engine, concurrency, executor, and observer options.\n */\n constructor(options: TransferQueueOptions = {}) {\n this.engine = options.engine ?? new TransferEngine();\n this.concurrency = normalizeConcurrency(options.concurrency);\n this.defaultExecutor = options.executor;\n this.resolveExecutor = options.resolveExecutor;\n this.retry = options.retry;\n this.timeout = options.timeout;\n this.bandwidthLimit = options.bandwidthLimit;\n this.onProgress = options.onProgress;\n this.onReceipt = options.onReceipt;\n this.onError = options.onError;\n }\n\n /** Adds a transfer job to the queue. */\n add(job: TransferJob, executor?: TransferExecutor): TransferQueueItem {\n if (this.items.some((item) => item.id === job.id)) {\n throw new ConfigurationError({\n details: { jobId: job.id },\n message: `Transfer queue already contains job: ${job.id}`,\n retryable: false,\n });\n }\n\n const item: InternalTransferQueueItem = {\n controller: new AbortController(),\n id: job.id,\n job: cloneTransferJob(job),\n status: \"queued\",\n };\n\n if (executor !== undefined) {\n item.executor = executor;\n }\n\n this.items.push(item);\n return toPublicItem(item);\n }\n\n /** Pauses dispatch of new queued jobs. Running jobs are allowed to finish. */\n pause(): void {\n this.paused = true;\n }\n\n /** Resumes dispatch of queued jobs on the next `run()` call. */\n resume(): void {\n this.paused = false;\n }\n\n /** Updates queue concurrency for subsequent drains. */\n setConcurrency(concurrency: number): void {\n this.concurrency = normalizeConcurrency(concurrency);\n }\n\n /** Cancels a queued or running job. */\n cancel(jobId: string): boolean {\n const item = this.items.find((candidate) => candidate.id === jobId);\n\n if (\n item === undefined ||\n item.status === \"completed\" ||\n item.status === \"failed\" ||\n item.status === \"canceled\"\n ) {\n return false;\n }\n\n item.controller.abort();\n\n if (item.status === \"queued\") {\n item.status = \"canceled\";\n }\n\n return true;\n }\n\n /** Returns a queued item snapshot by id. */\n get(jobId: string): TransferQueueItem | undefined {\n const item = this.items.find((candidate) => candidate.id === jobId);\n return item === undefined ? undefined : toPublicItem(item);\n }\n\n /** Lists queue item snapshots in insertion order. */\n list(): TransferQueueItem[] {\n return this.items.map(toPublicItem);\n }\n\n /** Drains currently queued jobs until complete, failed, canceled, or paused. */\n async run(options: TransferQueueRunOptions = {}): Promise<TransferQueueSummary> {\n const workerCount = Math.max(1, Math.min(this.concurrency, this.countDispatchableItems()));\n const workers = Array.from({ length: workerCount }, () => this.runWorker(options));\n\n await Promise.all(workers);\n return this.summarize();\n }\n\n /** Returns a queue summary without executing more work. */\n summarize(): TransferQueueSummary {\n const publicItems = this.items.map(toPublicItem);\n\n return {\n canceled: publicItems.filter((item) => item.status === \"canceled\").length,\n completed: publicItems.filter((item) => item.status === \"completed\").length,\n failed: publicItems.filter((item) => item.status === \"failed\").length,\n failures: publicItems.filter((item) => item.status === \"failed\"),\n queued: publicItems.filter((item) => item.status === \"queued\").length,\n receipts: publicItems\n .filter(\n (item): item is TransferQueueItem & { receipt: TransferReceipt } =>\n item.receipt !== undefined,\n )\n .map((item) => item.receipt),\n running: publicItems.filter((item) => item.status === \"running\").length,\n total: publicItems.length,\n };\n }\n\n private async runWorker(options: TransferQueueRunOptions): Promise<void> {\n for (;;) {\n const item = this.nextQueuedItem();\n\n if (item === undefined) {\n return;\n }\n\n await this.runItem(item, options);\n }\n }\n\n private nextQueuedItem(): InternalTransferQueueItem | undefined {\n if (this.paused) {\n return undefined;\n }\n\n const item = this.items.find((candidate) => candidate.status === \"queued\");\n\n if (item !== undefined) {\n item.status = item.controller.signal.aborted ? \"canceled\" : \"running\";\n }\n\n return item?.status === \"running\" ? item : undefined;\n }\n\n private async runItem(\n item: InternalTransferQueueItem,\n options: TransferQueueRunOptions,\n ): Promise<void> {\n const abortListener = createAbortForwarder(options.signal, item.controller);\n\n try {\n const executeOptions: TransferEngineExecuteOptions = {\n signal: item.controller.signal,\n };\n const onProgress = options.onProgress ?? this.onProgress;\n const retry = options.retry ?? this.retry;\n const timeout = options.timeout ?? this.timeout;\n const bandwidthLimit = options.bandwidthLimit ?? this.bandwidthLimit;\n\n if (onProgress !== undefined) {\n executeOptions.onProgress = onProgress;\n }\n\n if (retry !== undefined) {\n executeOptions.retry = retry;\n }\n\n if (timeout !== undefined) {\n executeOptions.timeout = timeout;\n }\n\n if (bandwidthLimit !== undefined) {\n executeOptions.bandwidthLimit = bandwidthLimit;\n }\n\n const receipt = await this.engine.execute(\n item.job,\n this.requireExecutor(item),\n executeOptions,\n );\n\n item.receipt = receipt;\n item.status = \"completed\";\n this.onReceipt?.(receipt);\n } catch (error) {\n item.error = error;\n item.status = item.controller.signal.aborted ? \"canceled\" : \"failed\";\n\n if (item.status === \"failed\") {\n this.onError?.(toPublicItem(item), error);\n }\n } finally {\n abortListener.dispose();\n }\n }\n\n private requireExecutor(item: InternalTransferQueueItem): TransferExecutor {\n const executor = item.executor ?? this.defaultExecutor ?? this.resolveExecutor?.(item.job);\n\n if (executor === undefined) {\n throw new ConfigurationError({\n details: { jobId: item.job.id },\n message: `Transfer queue job has no executor: ${item.job.id}`,\n retryable: false,\n });\n }\n\n return executor;\n }\n\n private countDispatchableItems(): number {\n return this.items.filter((item) => item.status === \"queued\" && !item.controller.signal.aborted)\n .length;\n }\n}\n\nfunction normalizeConcurrency(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value)) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction createAbortForwarder(\n source: AbortSignal | undefined,\n target: AbortController,\n): { dispose(): void } {\n if (source === undefined) {\n return { dispose: () => undefined };\n }\n\n const abort = (): void => target.abort();\n\n if (source.aborted) {\n abort();\n return { dispose: () => undefined };\n }\n\n source.addEventListener(\"abort\", abort, { once: true });\n\n return {\n dispose: () => source.removeEventListener(\"abort\", abort),\n };\n}\n\nfunction toPublicItem(item: InternalTransferQueueItem): TransferQueueItem {\n const snapshot: TransferQueueItem = {\n id: item.id,\n job: cloneTransferJob(item.job),\n status: item.status,\n };\n\n if (item.receipt !== undefined) snapshot.receipt = item.receipt;\n if (item.error !== undefined) snapshot.error = item.error;\n\n return snapshot;\n}\n\nfunction cloneTransferJob(job: TransferJob): TransferJob {\n const clone: TransferJob = {\n id: job.id,\n operation: job.operation,\n };\n\n if (job.source !== undefined) clone.source = { ...job.source };\n if (job.destination !== undefined) clone.destination = { ...job.destination };\n if (job.totalBytes !== undefined) clone.totalBytes = job.totalBytes;\n if (job.resumed !== undefined) clone.resumed = job.resumed;\n if (job.metadata !== undefined) clone.metadata = { ...job.metadata };\n\n return clone;\n}\n","/**\n * Browser-friendly directory navigation helpers for file-manager UIs.\n *\n * Wraps a {@link RemoteFileSystem} with stateful current-directory tracking,\n * breadcrumb generation, and pure sort/filter utilities so consumers can render\n * directory views without re-implementing common navigation glue.\n *\n * @module sync/createRemoteBrowser\n */\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry } from \"../types/public\";\nimport { normalizeRemotePath } from \"../utils/path\";\n\n/** Sort key supported by {@link sortRemoteEntries}. */\nexport type RemoteEntrySortKey = \"name\" | \"size\" | \"modifiedAt\" | \"type\";\n\n/** Sort direction supported by {@link sortRemoteEntries}. */\nexport type RemoteEntrySortOrder = \"asc\" | \"desc\";\n\n/** Crumb describing one segment in the current path. */\nexport interface RemoteBreadcrumb {\n /** Display name. `\"\"` is replaced with `\"/\"` for the root crumb. */\n name: string;\n /** Absolute path the crumb resolves to. */\n path: string;\n}\n\n/** Filter callback applied to a directory listing. */\nexport type RemoteBrowserFilter = (entry: RemoteEntry) => boolean;\n\n/** Options accepted by {@link createRemoteBrowser}. */\nexport interface CreateRemoteBrowserOptions {\n /** Remote file system to browse. */\n fs: RemoteFileSystem;\n /** Initial path. Defaults to `\"/\"`. */\n initialPath?: string;\n /** Sort key applied to listings. Defaults to `\"name\"`. */\n sortKey?: RemoteEntrySortKey;\n /** Sort order applied to listings. Defaults to `\"asc\"`. */\n sortOrder?: RemoteEntrySortOrder;\n /** Whether dotfile entries (names starting with `.`) are included. Defaults to `true`. */\n showHidden?: boolean;\n /** Optional filter applied after sort/hidden filtering. */\n filter?: RemoteBrowserFilter;\n}\n\n/** Snapshot returned by browser navigation methods. */\nexport interface RemoteBrowserSnapshot {\n /** Current absolute path. */\n path: string;\n /** Directory entries after sorting and filtering. */\n entries: RemoteEntry[];\n /** Breadcrumb trail leading from `/` to {@link path}. */\n breadcrumbs: RemoteBreadcrumb[];\n}\n\n/** Stateful directory browser returned by {@link createRemoteBrowser}. */\nexport interface RemoteBrowser {\n /** Current absolute path. */\n readonly path: string;\n /** Last loaded sorted/filtered entries. */\n readonly entries: readonly RemoteEntry[];\n /** Reload the current directory and return the latest snapshot. */\n refresh(): Promise<RemoteBrowserSnapshot>;\n /** Navigate to the supplied absolute or relative path. */\n navigate(target: string): Promise<RemoteBrowserSnapshot>;\n /** Descend into the supplied directory entry. Throws when the entry is not a directory. */\n open(entry: RemoteEntry): Promise<RemoteBrowserSnapshot>;\n /** Move to the parent directory; no-op when already at the root. */\n up(): Promise<RemoteBrowserSnapshot>;\n /** Compute breadcrumbs for the current path without re-listing. */\n breadcrumbs(): RemoteBreadcrumb[];\n /** Update the sort key. The next refresh re-sorts the cached entries. */\n setSort(key: RemoteEntrySortKey, order?: RemoteEntrySortOrder): void;\n /** Toggle hidden-entry visibility. The next refresh re-applies the filter. */\n setShowHidden(showHidden: boolean): void;\n}\n\n/**\n * Returns the parent directory of a remote path, or `\"/\"` for root inputs.\n *\n * @param input - Remote path to inspect.\n * @returns The parent path normalized to an absolute form.\n */\nexport function parentRemotePath(input: string): string {\n const normalized = normalizeRemotePath(input);\n if (normalized === \"/\") return \"/\";\n const parts = normalized.split(\"/\").filter(Boolean);\n parts.pop();\n if (parts.length === 0) return \"/\";\n return `/${parts.join(\"/\")}`;\n}\n\n/**\n * Builds breadcrumbs from `/` down to the supplied path.\n *\n * @param input - Absolute remote path.\n * @returns Ordered crumbs starting with the root.\n */\nexport function buildRemoteBreadcrumbs(input: string): RemoteBreadcrumb[] {\n const normalized = normalizeRemotePath(input);\n const crumbs: RemoteBreadcrumb[] = [{ name: \"/\", path: \"/\" }];\n if (normalized === \"/\") return crumbs;\n\n const parts = normalized.split(\"/\").filter(Boolean);\n let cursor = \"\";\n for (const part of parts) {\n cursor += `/${part}`;\n crumbs.push({ name: part, path: cursor });\n }\n return crumbs;\n}\n\n/**\n * Returns a copy of the supplied entries sorted by the requested key. Directories\n * are grouped before files within ascending sorts, matching common file-manager UX.\n *\n * @param entries - Entries to sort.\n * @param key - Sort key.\n * @param order - Sort order.\n * @returns Sorted copy of the entries.\n */\nexport function sortRemoteEntries(\n entries: readonly RemoteEntry[],\n key: RemoteEntrySortKey = \"name\",\n order: RemoteEntrySortOrder = \"asc\",\n): RemoteEntry[] {\n const direction = order === \"asc\" ? 1 : -1;\n return [...entries].sort((left, right) => {\n if (key !== \"type\") {\n const leftIsDir = left.type === \"directory\";\n const rightIsDir = right.type === \"directory\";\n if (leftIsDir !== rightIsDir) return leftIsDir ? -1 : 1;\n }\n\n const compared = compareEntriesByKey(left, right, key);\n if (compared !== 0) return compared * direction;\n return compareNames(left, right);\n });\n}\n\n/**\n * Filters entries using the optional predicate plus an optional hidden-file rule.\n *\n * @param entries - Entries to filter.\n * @param options - Filtering controls.\n * @returns Entries matching the supplied rules.\n */\nexport function filterRemoteEntries(\n entries: readonly RemoteEntry[],\n options: { filter?: RemoteBrowserFilter; showHidden?: boolean } = {},\n): RemoteEntry[] {\n const showHidden = options.showHidden ?? true;\n const filter = options.filter;\n return entries.filter((entry) => {\n if (!showHidden && entry.name.startsWith(\".\")) return false;\n if (filter !== undefined && !filter(entry)) return false;\n return true;\n });\n}\n\n/**\n * Creates a stateful directory browser around a remote file system.\n *\n * The returned browser caches the most recent listing and applies sort/filter\n * settings on each refresh. Navigation methods return a snapshot so UI layers can\n * render synchronously without re-reading state.\n *\n * @param options - Browser configuration.\n * @returns Stateful browser bound to the supplied file system.\n */\nexport function createRemoteBrowser(options: CreateRemoteBrowserOptions): RemoteBrowser {\n const { fs } = options;\n let currentPath = normalizeRemotePath(options.initialPath ?? \"/\");\n let cachedEntries: RemoteEntry[] = [];\n let sortKey: RemoteEntrySortKey = options.sortKey ?? \"name\";\n let sortOrder: RemoteEntrySortOrder = options.sortOrder ?? \"asc\";\n let showHidden = options.showHidden ?? true;\n const filter = options.filter;\n\n async function loadCurrent(): Promise<RemoteBrowserSnapshot> {\n const raw = await fs.list(currentPath);\n const projected = projectEntries(raw);\n cachedEntries = projected;\n return snapshot();\n }\n\n function projectEntries(raw: readonly RemoteEntry[]): RemoteEntry[] {\n const filterOptions: { filter?: RemoteBrowserFilter; showHidden: boolean } = { showHidden };\n if (filter !== undefined) filterOptions.filter = filter;\n const filtered = filterRemoteEntries(raw, filterOptions);\n return sortRemoteEntries(filtered, sortKey, sortOrder);\n }\n\n function snapshot(): RemoteBrowserSnapshot {\n return {\n breadcrumbs: buildRemoteBreadcrumbs(currentPath),\n entries: [...cachedEntries],\n path: currentPath,\n };\n }\n\n async function navigate(target: string): Promise<RemoteBrowserSnapshot> {\n currentPath = resolveTarget(currentPath, target);\n return loadCurrent();\n }\n\n async function open(entry: RemoteEntry): Promise<RemoteBrowserSnapshot> {\n if (entry.type !== \"directory\") {\n throw new TypeError(`Cannot open non-directory entry \"${entry.path}\" (type: ${entry.type})`);\n }\n return navigate(entry.path);\n }\n\n return {\n breadcrumbs: () => buildRemoteBreadcrumbs(currentPath),\n get entries() {\n return cachedEntries;\n },\n navigate,\n open,\n get path() {\n return currentPath;\n },\n refresh: loadCurrent,\n setShowHidden(value: boolean) {\n showHidden = value;\n },\n setSort(key: RemoteEntrySortKey, order: RemoteEntrySortOrder = sortOrder) {\n sortKey = key;\n sortOrder = order;\n },\n up: () => navigate(parentRemotePath(currentPath)),\n };\n}\n\nfunction resolveTarget(currentPath: string, target: string): string {\n if (target.startsWith(\"/\")) return normalizeRemotePath(target);\n if (target === \"\" || target === \".\") return currentPath;\n if (target === \"..\") return parentRemotePath(currentPath);\n const base = currentPath === \"/\" ? \"\" : currentPath;\n return normalizeRemotePath(`${base}/${target}`);\n}\n\nfunction compareEntriesByKey(\n left: RemoteEntry,\n right: RemoteEntry,\n key: RemoteEntrySortKey,\n): number {\n switch (key) {\n case \"size\":\n return (left.size ?? 0) - (right.size ?? 0);\n case \"modifiedAt\": {\n const leftTime = left.modifiedAt?.getTime() ?? 0;\n const rightTime = right.modifiedAt?.getTime() ?? 0;\n return leftTime - rightTime;\n }\n case \"type\":\n return left.type.localeCompare(right.type);\n case \"name\":\n default:\n return compareNames(left, right);\n }\n}\n\nfunction compareNames(left: RemoteEntry, right: RemoteEntry): number {\n return left.name.localeCompare(right.name, undefined, { numeric: true, sensitivity: \"base\" });\n}\n","/**\n * Sync planning primitives that build a {@link TransferPlan} from a remote-tree diff.\n *\n * @module sync/createSyncPlan\n */\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport {\n createTransferPlan,\n type TransferPlan,\n type TransferPlanStep,\n} from \"../transfers/TransferPlan\";\nimport { joinRemotePath, normalizeRemotePath } from \"../utils/path\";\nimport type { RemoteTreeDiff, RemoteTreeDiffEntry } from \"./diffRemoteTrees\";\n\n/** Sync direction used by {@link createSyncPlan}. */\nexport type SyncDirection = \"source-to-destination\" | \"destination-to-source\";\n\n/** How {@link createSyncPlan} reacts to entries that exist only on the destination. */\nexport type SyncDeletePolicy =\n /** Never delete destination entries that are missing on the source. */\n | \"never\"\n /** Plan destination deletions when running source-to-destination sync. */\n | \"mirror\"\n /** Plan destination deletions only when paired with a same-path file on the source. */\n | \"replace-only\";\n\n/** How {@link createSyncPlan} reacts to entries flagged as modified on both sides. */\nexport type SyncConflictPolicy =\n /** Overwrite the destination with the source. */\n | \"overwrite\"\n /** Overwrite the source with the destination. */\n | \"prefer-destination\"\n /** Skip conflicting entries with a `skip` step. */\n | \"skip\"\n /** Fail planning with a {@link ConfigurationError} when a conflict is encountered. */\n | \"error\";\n\n/** Endpoint shape supplied to {@link createSyncPlan}. */\nexport interface SyncEndpointInput {\n /** Provider that owns the endpoint when known. */\n provider?: ProviderId;\n /** Root path on the provider being synced. */\n rootPath: string;\n}\n\n/** Options accepted by {@link createSyncPlan}. */\nexport interface CreateSyncPlanOptions {\n /** Stable plan identifier. */\n id: string;\n /** Diff produced by {@link diffRemoteTrees} or an equivalent source. */\n diff: RemoteTreeDiff;\n /** Source-side endpoint that produced the diff. */\n source: SyncEndpointInput;\n /** Destination-side endpoint that produced the diff. */\n destination: SyncEndpointInput;\n /** Sync direction. Defaults to `\"source-to-destination\"`. */\n direction?: SyncDirection;\n /** Delete policy. Defaults to `\"never\"`. */\n deletePolicy?: SyncDeletePolicy;\n /** Conflict policy. Defaults to `\"overwrite\"`. */\n conflictPolicy?: SyncConflictPolicy;\n /** Whether to plan upload/download steps for directories. Defaults to `false`. */\n includeDirectoryActions?: boolean;\n /** Whether the plan is informational only. Defaults to `true`. */\n dryRun?: boolean;\n /** Clock used for deterministic tests. Defaults to `new Date()`. */\n now?: () => Date;\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Builds a {@link TransferPlan} that reconciles two remote subtrees.\n *\n * Plan steps are derived from a {@link RemoteTreeDiff}; the function does not perform\n * any I/O. Direction, delete policy, and conflict policy control which entries\n * become executable transfers and which become `skip` steps.\n *\n * @param options - Inputs and policies that shape the plan.\n * @returns Transfer plan ready for `createTransferJobsFromPlan` or queue execution.\n * @throws {@link ConfigurationError} When `conflictPolicy: \"error\"` encounters a conflict.\n */\nexport function createSyncPlan(options: CreateSyncPlanOptions): TransferPlan {\n const direction: SyncDirection = options.direction ?? \"source-to-destination\";\n const deletePolicy: SyncDeletePolicy = options.deletePolicy ?? \"never\";\n const conflictPolicy: SyncConflictPolicy = options.conflictPolicy ?? \"overwrite\";\n const includeDirectoryActions = options.includeDirectoryActions ?? false;\n const sourceRoot = normalizeRemotePath(options.source.rootPath);\n const destinationRoot = normalizeRemotePath(options.destination.rootPath);\n const warnings: string[] = [];\n const steps: TransferPlanStep[] = [];\n\n for (const entry of options.diff.entries) {\n const context: PlanEntryContext = {\n conflictPolicy,\n deletePolicy,\n destinationRoot,\n direction,\n entry,\n includeDirectoryActions,\n sourceRoot,\n warnings,\n };\n if (options.source.provider !== undefined) context.sourceProvider = options.source.provider;\n if (options.destination.provider !== undefined) {\n context.destinationProvider = options.destination.provider;\n }\n const step = planEntry(context);\n\n if (step !== undefined) steps.push(step);\n }\n\n const planInput: Parameters<typeof createTransferPlan>[0] = {\n id: options.id,\n steps,\n warnings,\n };\n if (options.dryRun !== undefined) planInput.dryRun = options.dryRun;\n if (options.now !== undefined) planInput.now = options.now;\n if (options.metadata !== undefined) planInput.metadata = options.metadata;\n\n return createTransferPlan(planInput);\n}\n\ninterface PlanEntryContext {\n conflictPolicy: SyncConflictPolicy;\n deletePolicy: SyncDeletePolicy;\n destinationProvider?: ProviderId;\n destinationRoot: string;\n direction: SyncDirection;\n entry: RemoteTreeDiffEntry;\n includeDirectoryActions: boolean;\n sourceProvider?: ProviderId;\n sourceRoot: string;\n warnings: string[];\n}\n\nfunction planEntry(context: PlanEntryContext): TransferPlanStep | undefined {\n const { entry } = context;\n const isDirectory = isDirectoryEntry(entry);\n\n if (isDirectory && !context.includeDirectoryActions) {\n return undefined;\n }\n\n switch (entry.status) {\n case \"added\":\n return planAdded(context);\n case \"removed\":\n return planRemoved(context);\n case \"modified\":\n return planModified(context);\n case \"unchanged\":\n return planUnchanged(context);\n default:\n // Unreachable when callers pass a normalized RemoteTreeDiff.\n return undefined;\n }\n}\n\nfunction planAdded(context: PlanEntryContext): TransferPlanStep {\n if (context.direction === \"source-to-destination\") {\n return createCopyStep(context, \"source\", \"destination\", expectedBytesFor(context.entry));\n }\n\n // Direction is destination-to-source: source-only entries should be deleted.\n if (context.deletePolicy === \"never\") {\n return createSkipStep(context, \"Source-only entry preserved by delete policy\");\n }\n\n return createDeleteStep(context, \"source\");\n}\n\nfunction planRemoved(context: PlanEntryContext): TransferPlanStep {\n if (context.direction === \"destination-to-source\") {\n return createCopyStep(context, \"destination\", \"source\", expectedBytesFor(context.entry));\n }\n\n // Direction is source-to-destination: destination-only entries.\n if (context.deletePolicy === \"never\") {\n return createSkipStep(context, \"Destination-only entry preserved by delete policy\");\n }\n\n if (context.deletePolicy === \"replace-only\") {\n return createSkipStep(\n context,\n \"Destination-only entry preserved (no source replacement available)\",\n );\n }\n\n return createDeleteStep(context, \"destination\");\n}\n\nfunction planModified(context: PlanEntryContext): TransferPlanStep {\n switch (context.conflictPolicy) {\n case \"overwrite\":\n return createCopyStep(context, \"source\", \"destination\", expectedBytesFor(context.entry), {\n destructive: true,\n });\n case \"prefer-destination\":\n return createCopyStep(context, \"destination\", \"source\", expectedBytesFor(context.entry), {\n destructive: true,\n });\n case \"skip\":\n return createSkipStep(context, `Conflict skipped: ${context.entry.reasons.join(\",\")}`);\n case \"error\":\n throw new ConfigurationError({\n details: {\n path: context.entry.path,\n reasons: context.entry.reasons,\n },\n message: `Sync plan conflict at ${context.entry.path} with reasons: ${context.entry.reasons.join(\", \")}`,\n retryable: false,\n });\n default:\n return createSkipStep(context, \"Conflict skipped\");\n }\n}\n\nfunction planUnchanged(context: PlanEntryContext): TransferPlanStep {\n return createSkipStep(context, \"Entry already in sync\");\n}\n\nfunction createCopyStep(\n context: PlanEntryContext,\n fromSide: \"source\" | \"destination\",\n toSide: \"source\" | \"destination\",\n expectedBytes: number | undefined,\n overrides: Partial<TransferPlanStep> = {},\n): TransferPlanStep {\n const step: TransferPlanStep = {\n action: \"copy\",\n id: makeStepId(context.entry, `copy-${fromSide}-to-${toSide}`),\n reason: describeReasons(context.entry, `Copy ${fromSide} to ${toSide}`),\n };\n\n step.source = endpointFor(context, fromSide);\n step.destination = endpointFor(context, toSide);\n if (expectedBytes !== undefined) step.expectedBytes = expectedBytes;\n if (overrides.destructive === true) step.destructive = true;\n if (overrides.metadata !== undefined) step.metadata = { ...overrides.metadata };\n\n return step;\n}\n\nfunction createDeleteStep(\n context: PlanEntryContext,\n side: \"source\" | \"destination\",\n): TransferPlanStep {\n return {\n action: \"delete\",\n destination: endpointFor(context, side),\n destructive: true,\n id: makeStepId(context.entry, `delete-${side}`),\n reason: `Delete ${side} entry not present on the other side`,\n };\n}\n\nfunction createSkipStep(context: PlanEntryContext, reason: string): TransferPlanStep {\n return {\n action: \"skip\",\n id: makeStepId(context.entry, \"skip\"),\n reason,\n source: endpointFor(context, \"source\"),\n destination: endpointFor(context, \"destination\"),\n };\n}\n\nfunction endpointFor(\n context: PlanEntryContext,\n side: \"source\" | \"destination\",\n): NonNullable<TransferPlanStep[\"source\"]> {\n const root = side === \"source\" ? context.sourceRoot : context.destinationRoot;\n const provider = side === \"source\" ? context.sourceProvider : context.destinationProvider;\n const endpoint: NonNullable<TransferPlanStep[\"source\"]> = {\n path: joinRootAndRelative(root, context.entry.path),\n };\n if (provider !== undefined) endpoint.provider = provider;\n return endpoint;\n}\n\nfunction joinRootAndRelative(rootPath: string, relativePath: string): string {\n if (rootPath === \"/\") return relativePath;\n if (relativePath === \"/\") return rootPath;\n return joinRemotePath(rootPath, relativePath);\n}\n\nfunction makeStepId(entry: RemoteTreeDiffEntry, suffix: string): string {\n return `${entry.path}#${suffix}`;\n}\n\nfunction describeReasons(entry: RemoteTreeDiffEntry, prefix: string): string {\n if (entry.reasons.length === 0) return prefix;\n return `${prefix} (${entry.reasons.join(\",\")})`;\n}\n\nfunction expectedBytesFor(entry: RemoteTreeDiffEntry): number | undefined {\n return entry.source?.size ?? entry.destination?.size;\n}\n\nfunction isDirectoryEntry(entry: RemoteTreeDiffEntry): boolean {\n return entry.source?.type === \"directory\" || entry.destination?.type === \"directory\";\n}\n","/**\n * Atomic deploy planning helpers.\n *\n * Produces a structured plan that stages a release under `<liveRoot>/<releasesDir>/<releaseId>`,\n * activates it via rename or symlink swap, and prunes older releases beyond a retain count.\n *\n * The plan is provider-neutral and execution-free: callers wire the upload {@link TransferPlan}\n * through the transfer engine and execute the activate/prune steps using their provider's\n * filesystem mutation primitives (rename, symlink, delete).\n *\n * @module sync/createAtomicDeployPlan\n */\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferPlan } from \"../transfers/TransferPlan\";\nimport { joinRemotePath, normalizeRemotePath } from \"../utils/path\";\nimport { createSyncPlan, type SyncEndpointInput } from \"./createSyncPlan\";\nimport type { RemoteTreeDiff } from \"./diffRemoteTrees\";\n\n/** Activation strategy used to swap a staged release into place. */\nexport type AtomicDeployStrategy =\n /** Rename `<liveRoot>` aside, then rename the staging path to `<liveRoot>`. */\n | \"rename\"\n /** Update a symlink at `<liveRoot>` to point at the staging path. */\n | \"symlink\";\n\n/** Operation kind for an activation step. */\nexport type AtomicDeployActivateOperation = \"rename\" | \"symlink\" | \"delete\";\n\n/** Kind of activation step described by the plan. */\nexport interface AtomicDeployActivateStep {\n /** Stable identifier within the activation list. */\n id: string;\n /** Operation the step would perform. */\n operation: AtomicDeployActivateOperation;\n /** Source path the operation reads or moves from. */\n fromPath?: string;\n /** Destination path the operation writes to. */\n toPath: string;\n /** Provider identifier that owns the affected paths when known. */\n provider?: ProviderId;\n /** Whether the step replaces or removes data. */\n destructive?: boolean;\n /** Human-readable description for previews and logs. */\n reason: string;\n}\n\n/** Pruning step describing an old release directory marked for deletion. */\nexport interface AtomicDeployPruneStep {\n /** Stable identifier within the prune list. */\n id: string;\n /** Absolute release directory path to delete. */\n path: string;\n /** Provider identifier that owns the path when known. */\n provider?: ProviderId;\n /** Reason the release was selected for pruning. */\n reason: string;\n}\n\n/** Result returned by {@link createAtomicDeployPlan}. */\nexport interface AtomicDeployPlan {\n /** Stable plan identifier. */\n id: string;\n /** Release identifier embedded into the staging path. */\n releaseId: string;\n /** Activation strategy chosen for the swap. */\n strategy: AtomicDeployStrategy;\n /** Provider identifier for the live destination when known. */\n provider?: ProviderId;\n /** Live target path the release activates onto. */\n livePath: string;\n /** Staging directory the upload populates. */\n stagingPath: string;\n /** Releases root directory under which staging and prior releases live. */\n releasesRoot: string;\n /** Optional backup path used by the rename strategy. */\n backupPath?: string;\n /** Upload plan that populates the staging directory. */\n uploadPlan: TransferPlan;\n /** Activation steps that swap staging into the live path. */\n activate: AtomicDeployActivateStep[];\n /** Prune steps that remove older releases beyond {@link retain}. */\n prune: AtomicDeployPruneStep[];\n /** Number of releases to retain (including the new release). */\n retain: number;\n /** Time the plan was created. */\n createdAt: Date;\n /** Non-fatal plan warnings. */\n warnings: string[];\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Options accepted by {@link createAtomicDeployPlan}. */\nexport interface CreateAtomicDeployPlanOptions {\n /** Stable plan identifier. */\n id: string;\n /** Diff describing source vs. staging contents (typically diffed against an empty staging directory). */\n diff: RemoteTreeDiff;\n /** Source-side endpoint feeding the release. */\n source: SyncEndpointInput;\n /** Live destination endpoint the release activates onto. */\n destination: SyncEndpointInput;\n /** Activation strategy. Defaults to `\"rename\"`. */\n strategy?: AtomicDeployStrategy;\n /** Release identifier. Defaults to a timestamp derived from {@link now}. */\n releaseId?: string;\n /** Releases directory name under the destination root. Defaults to `\".releases\"`. */\n releasesDirectory?: string;\n /** Number of releases to retain after the new release, including the new one. Defaults to `3`. */\n retain?: number;\n /** Existing release directory paths under the releases root that may be pruned. */\n existingReleases?: string[];\n /** Whether the plan is informational only. Defaults to `true`. */\n dryRun?: boolean;\n /** Clock used for deterministic tests. Defaults to `new Date()`. */\n now?: () => Date;\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\nconst DEFAULT_RELEASES_DIRECTORY = \".releases\";\nconst DEFAULT_RETAIN = 3;\n\n/**\n * Builds an {@link AtomicDeployPlan} that stages a release, swaps it live, and prunes old releases.\n *\n * @param options - Inputs and policies that shape the deploy.\n * @returns Structured deploy plan ready for execution by the calling host.\n * @throws {@link ConfigurationError} When `retain` is less than `1` or the destination root is empty.\n */\nexport function createAtomicDeployPlan(options: CreateAtomicDeployPlanOptions): AtomicDeployPlan {\n const retain = options.retain ?? DEFAULT_RETAIN;\n if (retain < 1) {\n throw new ConfigurationError({\n details: { retain },\n message: \"Atomic deploy retain count must be at least 1\",\n retryable: false,\n });\n }\n\n const livePath = normalizeRemotePath(options.destination.rootPath);\n if (livePath === \"/\") {\n throw new ConfigurationError({\n message: \"Atomic deploy destination rootPath must not be the filesystem root\",\n retryable: false,\n });\n }\n\n const strategy: AtomicDeployStrategy = options.strategy ?? \"rename\";\n const now = options.now?.() ?? new Date();\n const releaseId = options.releaseId ?? defaultReleaseId(now);\n const releasesRoot = joinRemotePath(\n livePath,\n options.releasesDirectory ?? DEFAULT_RELEASES_DIRECTORY,\n );\n const stagingPath = joinRemotePath(releasesRoot, releaseId);\n const backupPath =\n strategy === \"rename\" ? joinRemotePath(releasesRoot, `${releaseId}.previous`) : undefined;\n const provider = options.destination.provider ?? options.source.provider;\n const warnings: string[] = [];\n\n const uploadPlan = createSyncPlan({\n conflictPolicy: \"overwrite\",\n deletePolicy: \"never\",\n destination: {\n ...(options.destination.provider !== undefined\n ? { provider: options.destination.provider }\n : {}),\n rootPath: stagingPath,\n },\n diff: options.diff,\n direction: \"source-to-destination\",\n dryRun: options.dryRun ?? true,\n id: `${options.id}/upload`,\n includeDirectoryActions: false,\n ...(options.now !== undefined ? { now: options.now } : {}),\n source: options.source,\n });\n\n const activate = buildActivateSteps({\n backupPath,\n livePath,\n planId: options.id,\n provider,\n stagingPath,\n strategy,\n });\n\n const prune = buildPruneSteps({\n existingReleases: options.existingReleases ?? [],\n planId: options.id,\n provider,\n releaseId,\n releasesRoot,\n retain,\n });\n\n const plan: AtomicDeployPlan = {\n activate,\n createdAt: now,\n id: options.id,\n livePath,\n prune,\n releaseId,\n releasesRoot,\n retain,\n stagingPath,\n strategy,\n uploadPlan,\n warnings,\n };\n if (provider !== undefined) plan.provider = provider;\n if (backupPath !== undefined) plan.backupPath = backupPath;\n if (options.metadata !== undefined) plan.metadata = { ...options.metadata };\n return plan;\n}\n\ninterface BuildActivateContext {\n backupPath: string | undefined;\n livePath: string;\n planId: string;\n provider: ProviderId | undefined;\n stagingPath: string;\n strategy: AtomicDeployStrategy;\n}\n\nfunction buildActivateSteps(context: BuildActivateContext): AtomicDeployActivateStep[] {\n if (context.strategy === \"symlink\") {\n const step: AtomicDeployActivateStep = {\n destructive: true,\n fromPath: context.stagingPath,\n id: `${context.planId}/activate/symlink`,\n operation: \"symlink\",\n reason: \"Update live symlink to point at the new release\",\n toPath: context.livePath,\n };\n if (context.provider !== undefined) step.provider = context.provider;\n return [step];\n }\n\n const steps: AtomicDeployActivateStep[] = [];\n if (context.backupPath !== undefined) {\n const backup: AtomicDeployActivateStep = {\n destructive: true,\n fromPath: context.livePath,\n id: `${context.planId}/activate/backup`,\n operation: \"rename\",\n reason: \"Rename current live path aside as a release backup\",\n toPath: context.backupPath,\n };\n if (context.provider !== undefined) backup.provider = context.provider;\n steps.push(backup);\n }\n\n const promote: AtomicDeployActivateStep = {\n destructive: true,\n fromPath: context.stagingPath,\n id: `${context.planId}/activate/promote`,\n operation: \"rename\",\n reason: \"Promote the staged release to the live path\",\n toPath: context.livePath,\n };\n if (context.provider !== undefined) promote.provider = context.provider;\n steps.push(promote);\n return steps;\n}\n\ninterface BuildPruneContext {\n existingReleases: string[];\n planId: string;\n provider: ProviderId | undefined;\n releaseId: string;\n releasesRoot: string;\n retain: number;\n}\n\nfunction buildPruneSteps(context: BuildPruneContext): AtomicDeployPruneStep[] {\n if (context.existingReleases.length === 0) return [];\n\n const normalizedRoot = normalizeRemotePath(context.releasesRoot);\n const newReleasePath = joinRemotePath(normalizedRoot, context.releaseId);\n const candidates = [...new Set(context.existingReleases.map((path) => normalizeRemotePath(path)))]\n .filter((path) => path !== newReleasePath)\n .sort();\n\n const releasesToRetain = Math.max(0, context.retain - 1);\n if (candidates.length <= releasesToRetain) return [];\n\n const toPrune = candidates.slice(0, candidates.length - releasesToRetain);\n return toPrune.map((path, index) => {\n const step: AtomicDeployPruneStep = {\n id: `${context.planId}/prune/${index}`,\n path,\n reason: \"Older release exceeds retain window\",\n };\n if (context.provider !== undefined) step.provider = context.provider;\n return step;\n });\n}\n\nfunction defaultReleaseId(now: Date): string {\n // ISO timestamp with characters safe for filesystem path segments (no `:` or `.`).\n return now.toISOString().replace(/[:.]/g, \"-\");\n}\n","/**\n * Recursive remote-tree traversal helpers.\n *\n * @module sync/walkRemoteTree\n */\nimport { AbortError } from \"../errors/ZeroTransferError\";\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry } from \"../types/public\";\nimport { joinRemotePath, normalizeRemotePath } from \"../utils/path\";\n\n/** Filter callback applied to each visited entry. Returning `false` skips the entry. */\nexport type RemoteTreeFilter = (entry: RemoteEntry) => boolean;\n\n/** Options accepted by {@link walkRemoteTree}. */\nexport interface WalkRemoteTreeOptions {\n /** Whether to descend into subdirectories. Defaults to `true`. */\n recursive?: boolean;\n /** Maximum traversal depth. `0` walks only the root listing. Unbounded by default. */\n maxDepth?: number;\n /** Whether to include directory entries in the output. Defaults to `true`. */\n includeDirectories?: boolean;\n /** Whether to include file entries in the output. Defaults to `true`. */\n includeFiles?: boolean;\n /** Whether to follow symlinks during traversal. Defaults to `false`. */\n followSymlinks?: boolean;\n /** Optional filter applied before yielding and before descending into directories. */\n filter?: RemoteTreeFilter;\n /** Optional abort signal that interrupts traversal between listings. */\n signal?: AbortSignal;\n}\n\n/** Walk record yielded by {@link walkRemoteTree}. */\nexport interface RemoteTreeEntry {\n /** Visited remote entry. */\n entry: RemoteEntry;\n /** Zero-based depth relative to the traversal root. */\n depth: number;\n /** Normalized parent directory path. */\n parentPath: string;\n}\n\n/**\n * Walks a remote file system depth-first, yielding entries in a stable order.\n *\n * Listings are sorted by entry path within each directory so output is deterministic\n * across providers. Errors thrown by `fs.list()` propagate; callers can supply a\n * filter to skip directories that should not be traversed.\n *\n * @param fs - Remote file system used for listings.\n * @param rootPath - Root directory to walk.\n * @param options - Optional traversal controls.\n * @returns Async generator emitting {@link RemoteTreeEntry} records.\n * @throws {@link AbortError} When the supplied abort signal is cancelled mid-walk.\n */\nexport async function* walkRemoteTree(\n fs: RemoteFileSystem,\n rootPath: string,\n options: WalkRemoteTreeOptions = {},\n): AsyncGenerator<RemoteTreeEntry> {\n const recursive = options.recursive ?? true;\n const includeDirectories = options.includeDirectories ?? true;\n const includeFiles = options.includeFiles ?? true;\n const followSymlinks = options.followSymlinks ?? false;\n const root = normalizeRemotePath(rootPath);\n const normalized: NormalizedWalkOptions = {\n followSymlinks,\n includeDirectories,\n includeFiles,\n recursive,\n };\n if (options.maxDepth !== undefined) normalized.maxDepth = options.maxDepth;\n if (options.filter !== undefined) normalized.filter = options.filter;\n if (options.signal !== undefined) normalized.signal = options.signal;\n\n yield* walkDirectory(fs, root, 0, normalized);\n}\n\ninterface NormalizedWalkOptions {\n recursive: boolean;\n includeDirectories: boolean;\n includeFiles: boolean;\n followSymlinks: boolean;\n maxDepth?: number;\n filter?: RemoteTreeFilter;\n signal?: AbortSignal;\n}\n\nasync function* walkDirectory(\n fs: RemoteFileSystem,\n path: string,\n depth: number,\n options: NormalizedWalkOptions,\n): AsyncGenerator<RemoteTreeEntry> {\n throwIfAborted(options.signal);\n const entries = await fs.list(path);\n const sorted = [...entries].sort(compareEntries);\n\n for (const entry of sorted) {\n if (options.filter !== undefined && !options.filter(entry)) continue;\n\n if (matchesEntryKind(entry, options.includeDirectories, options.includeFiles)) {\n yield { depth, entry, parentPath: path };\n }\n\n if (\n options.recursive &&\n canDescendInto(entry, options.followSymlinks) &&\n (options.maxDepth === undefined || depth < options.maxDepth)\n ) {\n yield* walkDirectory(fs, ensureDescendPath(entry, path), depth + 1, options);\n }\n }\n}\n\nfunction matchesEntryKind(\n entry: RemoteEntry,\n includeDirectories: boolean,\n includeFiles: boolean,\n): boolean {\n if (entry.type === \"directory\") return includeDirectories;\n if (entry.type === \"file\") return includeFiles;\n return true;\n}\n\nfunction canDescendInto(entry: RemoteEntry, followSymlinks: boolean): boolean {\n if (entry.type === \"directory\") return true;\n return followSymlinks && entry.type === \"symlink\";\n}\n\nfunction ensureDescendPath(entry: RemoteEntry, parentPath: string): string {\n if (entry.path !== \"\" && entry.path !== entry.name) {\n return normalizeRemotePath(entry.path);\n }\n\n return joinRemotePath(parentPath, entry.name);\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n if (left.path < right.path) return -1;\n if (left.path > right.path) return 1;\n return 0;\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw new AbortError({\n message: \"Remote tree walk aborted\",\n retryable: false,\n });\n }\n}\n","/**\n * Directory diffing primitives that compare two remote trees.\n *\n * @module sync/diffRemoteTrees\n */\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry } from \"../types/public\";\nimport { normalizeRemotePath } from \"../utils/path\";\nimport {\n walkRemoteTree,\n type RemoteTreeFilter,\n type WalkRemoteTreeOptions,\n} from \"./walkRemoteTree\";\n\n/** Outcome category for an entry across the two compared trees. */\nexport type RemoteTreeDiffStatus = \"added\" | \"removed\" | \"modified\" | \"unchanged\";\n\n/** Reason an entry is considered modified. */\nexport type RemoteTreeDiffReason = \"type\" | \"size\" | \"modifiedAt\" | \"checksum\";\n\n/** Single diff record produced by {@link diffRemoteTrees}. */\nexport interface RemoteTreeDiffEntry {\n /** Path relative to the traversal root, beginning with `/`. */\n path: string;\n /** Outcome category for this entry. */\n status: RemoteTreeDiffStatus;\n /** Reasons the entry is considered modified. Empty for unchanged/added/removed records. */\n reasons: RemoteTreeDiffReason[];\n /** Source-side entry, when present. */\n source?: RemoteEntry;\n /** Destination-side entry, when present. */\n destination?: RemoteEntry;\n}\n\n/** Compact summary of a diff result. */\nexport interface RemoteTreeDiffSummary {\n /** Number of entries present only on the source side. */\n added: number;\n /** Number of entries present only on the destination side. */\n removed: number;\n /** Number of entries present on both sides whose contents differ. */\n modified: number;\n /** Number of entries present on both sides with identical contents. */\n unchanged: number;\n /** Total entries inspected across both sides. */\n total: number;\n}\n\n/** Result returned by {@link diffRemoteTrees}. */\nexport interface RemoteTreeDiff {\n /** Diff records sorted by path. */\n entries: RemoteTreeDiffEntry[];\n /** Compact counts for the diff. */\n summary: RemoteTreeDiffSummary;\n}\n\n/** Options accepted by {@link diffRemoteTrees}. */\nexport interface DiffRemoteTreesOptions {\n /** Optional traversal controls applied to both sides. */\n walk?: Pick<\n WalkRemoteTreeOptions,\n \"filter\" | \"followSymlinks\" | \"includeDirectories\" | \"includeFiles\" | \"maxDepth\" | \"recursive\"\n >;\n /** Filter applied only to the source side. Overrides `walk.filter` when set. */\n sourceFilter?: RemoteTreeFilter;\n /** Filter applied only to the destination side. Overrides `walk.filter` when set. */\n destinationFilter?: RemoteTreeFilter;\n /** Whether unchanged entries are included in `entries`. Defaults to `false`. */\n includeUnchanged?: boolean;\n /** Tolerance in milliseconds when comparing modification timestamps. Defaults to `1000`. */\n modifiedAtToleranceMs?: number;\n /** Whether modification timestamps participate in the comparison. Defaults to `true`. */\n compareModifiedAt?: boolean;\n /** Whether sizes participate in the comparison. Defaults to `true`. */\n compareSize?: boolean;\n /** Whether to require matching `uniqueId` checksums when both entries expose one. Defaults to `false`. */\n compareUniqueId?: boolean;\n /** Optional abort signal threaded through both walks. */\n signal?: AbortSignal;\n}\n\n/**\n * Compares two remote subtrees and produces an entry-level diff.\n *\n * Source and destination paths are walked independently; entries are then aligned by\n * the relative path from each tree root. Directory equality is structural — directories\n * are equal when their relative paths match and the entry types agree.\n *\n * @param source - Source-side remote file system.\n * @param sourcePath - Source-side root path being compared.\n * @param destination - Destination-side remote file system.\n * @param destinationPath - Destination-side root path being compared.\n * @param options - Optional comparison controls.\n * @returns Diff result containing entries and a summary.\n */\nexport async function diffRemoteTrees(\n source: RemoteFileSystem,\n sourcePath: string,\n destination: RemoteFileSystem,\n destinationPath: string,\n options: DiffRemoteTreesOptions = {},\n): Promise<RemoteTreeDiff> {\n const includeUnchanged = options.includeUnchanged ?? false;\n const sourceRoot = normalizeRemotePath(sourcePath);\n const destinationRoot = normalizeRemotePath(destinationPath);\n const sourceWalk = createWalkOptions(options, options.sourceFilter);\n const destinationWalk = createWalkOptions(options, options.destinationFilter);\n\n const [sourceEntries, destinationEntries] = await Promise.all([\n collectEntries(source, sourceRoot, sourceWalk),\n collectEntries(destination, destinationRoot, destinationWalk),\n ]);\n\n const aligned = alignEntries(sourceEntries, destinationEntries);\n const entries: RemoteTreeDiffEntry[] = [];\n const summary: RemoteTreeDiffSummary = {\n added: 0,\n modified: 0,\n removed: 0,\n total: 0,\n unchanged: 0,\n };\n\n for (const { path, source: sourceEntry, destination: destinationEntry } of aligned) {\n summary.total += 1;\n const reasons: RemoteTreeDiffReason[] = [];\n let status: RemoteTreeDiffStatus;\n\n if (sourceEntry !== undefined && destinationEntry === undefined) {\n status = \"added\";\n summary.added += 1;\n } else if (sourceEntry === undefined && destinationEntry !== undefined) {\n status = \"removed\";\n summary.removed += 1;\n } else if (sourceEntry !== undefined && destinationEntry !== undefined) {\n const computedReasons = compareEntries(sourceEntry, destinationEntry, options);\n\n if (computedReasons.length === 0) {\n status = \"unchanged\";\n summary.unchanged += 1;\n } else {\n status = \"modified\";\n reasons.push(...computedReasons);\n summary.modified += 1;\n }\n } else {\n // Both entries undefined cannot happen because alignEntries only emits aligned pairs.\n continue;\n }\n\n if (status === \"unchanged\" && !includeUnchanged) continue;\n\n const record: RemoteTreeDiffEntry = { path, reasons, status };\n if (sourceEntry !== undefined) record.source = sourceEntry;\n if (destinationEntry !== undefined) record.destination = destinationEntry;\n entries.push(record);\n }\n\n entries.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n\n return { entries, summary };\n}\n\nfunction createWalkOptions(\n options: DiffRemoteTreesOptions,\n filter: RemoteTreeFilter | undefined,\n): WalkRemoteTreeOptions {\n const walk = options.walk ?? {};\n const merged: WalkRemoteTreeOptions = {};\n\n if (walk.recursive !== undefined) merged.recursive = walk.recursive;\n if (walk.maxDepth !== undefined) merged.maxDepth = walk.maxDepth;\n if (walk.includeDirectories !== undefined) merged.includeDirectories = walk.includeDirectories;\n if (walk.includeFiles !== undefined) merged.includeFiles = walk.includeFiles;\n if (walk.followSymlinks !== undefined) merged.followSymlinks = walk.followSymlinks;\n const resolvedFilter = filter ?? walk.filter;\n if (resolvedFilter !== undefined) merged.filter = resolvedFilter;\n if (options.signal !== undefined) merged.signal = options.signal;\n\n return merged;\n}\n\ninterface CollectedEntry {\n relativePath: string;\n entry: RemoteEntry;\n}\n\nasync function collectEntries(\n fs: RemoteFileSystem,\n rootPath: string,\n walkOptions: WalkRemoteTreeOptions,\n): Promise<Map<string, RemoteEntry>> {\n const map = new Map<string, RemoteEntry>();\n\n for await (const record of walkRemoteTree(fs, rootPath, walkOptions)) {\n const collected = toCollectedEntry(record.entry, rootPath);\n if (collected !== undefined) map.set(collected.relativePath, collected.entry);\n }\n\n return map;\n}\n\nfunction toCollectedEntry(entry: RemoteEntry, rootPath: string): CollectedEntry | undefined {\n const root = normalizeRemotePath(rootPath);\n const path = normalizeRemotePath(entry.path);\n\n if (path === root) return undefined;\n if (root === \"/\") return { entry, relativePath: path };\n if (path.startsWith(`${root}/`)) {\n return { entry, relativePath: path.slice(root.length) };\n }\n\n return undefined;\n}\n\ninterface AlignedPair {\n path: string;\n source?: RemoteEntry;\n destination?: RemoteEntry;\n}\n\nfunction alignEntries(\n sourceEntries: Map<string, RemoteEntry>,\n destinationEntries: Map<string, RemoteEntry>,\n): AlignedPair[] {\n const paths = new Set<string>([...sourceEntries.keys(), ...destinationEntries.keys()]);\n const aligned: AlignedPair[] = [];\n\n for (const path of paths) {\n const pair: AlignedPair = { path };\n const source = sourceEntries.get(path);\n const destination = destinationEntries.get(path);\n\n if (source !== undefined) pair.source = source;\n if (destination !== undefined) pair.destination = destination;\n aligned.push(pair);\n }\n\n return aligned;\n}\n\nfunction compareEntries(\n source: RemoteEntry,\n destination: RemoteEntry,\n options: DiffRemoteTreesOptions,\n): RemoteTreeDiffReason[] {\n const reasons: RemoteTreeDiffReason[] = [];\n const compareSize = options.compareSize ?? true;\n const compareModifiedAt = options.compareModifiedAt ?? true;\n const compareUniqueId = options.compareUniqueId ?? false;\n const tolerance = options.modifiedAtToleranceMs ?? 1000;\n\n if (source.type !== destination.type) {\n reasons.push(\"type\");\n }\n\n if (compareSize && isSizeRelevant(source, destination) && source.size !== destination.size) {\n reasons.push(\"size\");\n }\n\n if (compareModifiedAt && isModifiedAtDifferent(source, destination, tolerance)) {\n reasons.push(\"modifiedAt\");\n }\n\n if (\n compareUniqueId &&\n source.uniqueId !== undefined &&\n destination.uniqueId !== undefined &&\n source.uniqueId !== destination.uniqueId\n ) {\n reasons.push(\"checksum\");\n }\n\n return reasons;\n}\n\nfunction isSizeRelevant(source: RemoteEntry, destination: RemoteEntry): boolean {\n if (source.type !== \"file\" || destination.type !== \"file\") return false;\n return source.size !== undefined && destination.size !== undefined;\n}\n\nfunction isModifiedAtDifferent(\n source: RemoteEntry,\n destination: RemoteEntry,\n toleranceMs: number,\n): boolean {\n if (source.modifiedAt === undefined || destination.modifiedAt === undefined) return false;\n const delta = Math.abs(source.modifiedAt.getTime() - destination.modifiedAt.getTime());\n return delta > toleranceMs;\n}\n","/**\n * Remote manifest read/write/compare helpers.\n *\n * A manifest is a serializable snapshot of a remote subtree produced by walking\n * the live tree once and persisting the result. Manifests can be diffed against\n * each other to detect drift without re-listing both sides.\n *\n * @module sync/manifest\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { ProviderId } from \"../core/ProviderId\";\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry, RemoteEntryType } from \"../types/public\";\nimport { normalizeRemotePath } from \"../utils/path\";\nimport type {\n RemoteTreeDiff,\n RemoteTreeDiffEntry,\n RemoteTreeDiffReason,\n RemoteTreeDiffStatus,\n RemoteTreeDiffSummary,\n} from \"./diffRemoteTrees\";\nimport {\n walkRemoteTree,\n type RemoteTreeFilter,\n type WalkRemoteTreeOptions,\n} from \"./walkRemoteTree\";\n\n/** Schema version for the manifest payload. Bumped on incompatible format changes. */\nexport const REMOTE_MANIFEST_FORMAT_VERSION = 1;\n\n/** Manifest entry recorded for each visited remote node. */\nexport interface RemoteManifestEntry {\n /** Path relative to {@link RemoteManifest.root}, beginning with `/`. */\n path: string;\n /** Entry kind. */\n type: RemoteEntryType;\n /** Entry size in bytes when known. */\n size?: number;\n /** Last modification time as an ISO 8601 timestamp when known. */\n modifiedAt?: string;\n /** Protocol-specific stable identity when available. */\n uniqueId?: string;\n /** Target path for symbolic links when known. */\n symlinkTarget?: string;\n}\n\n/** Persisted snapshot of a remote subtree. */\nexport interface RemoteManifest {\n /** Schema version. Must equal {@link REMOTE_MANIFEST_FORMAT_VERSION}. */\n formatVersion: number;\n /** ISO 8601 timestamp recording when the manifest was generated. */\n generatedAt: string;\n /** Normalized absolute root path the manifest snapshot is anchored to. */\n root: string;\n /** Optional provider identifier the snapshot was captured from. */\n provider?: ProviderId;\n /** Manifest entries sorted by path. */\n entries: RemoteManifestEntry[];\n}\n\n/** Options accepted by {@link createRemoteManifest}. */\nexport interface CreateRemoteManifestOptions {\n /** Optional traversal controls forwarded to {@link walkRemoteTree}. */\n walk?: Pick<\n WalkRemoteTreeOptions,\n \"filter\" | \"followSymlinks\" | \"includeDirectories\" | \"includeFiles\" | \"maxDepth\" | \"recursive\"\n >;\n /** Filter applied during traversal. Overrides `walk.filter` when provided. */\n filter?: RemoteTreeFilter;\n /** Provider identifier embedded into the manifest header. */\n provider?: ProviderId;\n /** Clock used to stamp `generatedAt`. Defaults to `Date.now`. */\n now?: () => Date;\n /** Optional abort signal threaded through the walk. */\n signal?: AbortSignal;\n}\n\n/** Options accepted by {@link compareRemoteManifests}. */\nexport interface CompareRemoteManifestsOptions {\n /** Whether unchanged entries are included in the result. Defaults to `false`. */\n includeUnchanged?: boolean;\n /** Tolerance in milliseconds applied to `modifiedAt` comparisons. Defaults to `1000`. */\n modifiedAtToleranceMs?: number;\n /** Whether modification timestamps participate in the comparison. Defaults to `true`. */\n compareModifiedAt?: boolean;\n /** Whether sizes participate in the comparison. Defaults to `true`. */\n compareSize?: boolean;\n /** Whether to require matching `uniqueId` checksums when both entries expose one. Defaults to `false`. */\n compareUniqueId?: boolean;\n}\n\n/**\n * Walks a remote subtree and produces a serializable manifest snapshot.\n *\n * @param fs - Remote file system to capture.\n * @param rootPath - Root path the manifest is anchored to.\n * @param options - Optional capture controls.\n * @returns Manifest snapshot suitable for serialization or comparison.\n */\nexport async function createRemoteManifest(\n fs: RemoteFileSystem,\n rootPath: string,\n options: CreateRemoteManifestOptions = {},\n): Promise<RemoteManifest> {\n const root = normalizeRemotePath(rootPath);\n const walkOptions: WalkRemoteTreeOptions = { ...(options.walk ?? {}) };\n const resolvedFilter = options.filter ?? options.walk?.filter;\n if (resolvedFilter !== undefined) walkOptions.filter = resolvedFilter;\n if (options.signal !== undefined) walkOptions.signal = options.signal;\n\n const entries: RemoteManifestEntry[] = [];\n\n for await (const record of walkRemoteTree(fs, root, walkOptions)) {\n const relativePath = relativeFromRoot(record.entry.path, root);\n if (relativePath === undefined) continue;\n entries.push(toManifestEntry(record.entry, relativePath));\n }\n\n entries.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n\n const generatedAt = (options.now?.() ?? new Date()).toISOString();\n const manifest: RemoteManifest = {\n entries,\n formatVersion: REMOTE_MANIFEST_FORMAT_VERSION,\n generatedAt,\n root,\n };\n if (options.provider !== undefined) manifest.provider = options.provider;\n return manifest;\n}\n\n/**\n * Serializes a manifest to a JSON string suitable for persistence.\n *\n * @param manifest - Manifest snapshot to serialize.\n * @param indent - Optional indentation passed to `JSON.stringify`. Defaults to `2`.\n * @returns Stable JSON representation of the manifest.\n */\nexport function serializeRemoteManifest(manifest: RemoteManifest, indent: number = 2): string {\n return JSON.stringify(manifest, undefined, indent);\n}\n\n/**\n * Parses a JSON-encoded manifest, validating the schema version and entry shape.\n *\n * @param text - JSON payload produced by {@link serializeRemoteManifest}.\n * @returns Parsed manifest snapshot.\n * @throws {@link ConfigurationError} When the payload is invalid or has an unsupported version.\n */\nexport function parseRemoteManifest(text: string): RemoteManifest {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n throw new ConfigurationError({\n cause: error,\n message: \"Failed to parse remote manifest payload as JSON\",\n retryable: false,\n });\n }\n\n if (parsed === null || typeof parsed !== \"object\") {\n throw new ConfigurationError({\n message: \"Remote manifest payload must be a JSON object\",\n retryable: false,\n });\n }\n\n const candidate = parsed as Partial<RemoteManifest> & Record<string, unknown>;\n if (candidate.formatVersion !== REMOTE_MANIFEST_FORMAT_VERSION) {\n throw new ConfigurationError({\n details: {\n expected: REMOTE_MANIFEST_FORMAT_VERSION,\n received: candidate.formatVersion,\n },\n message: `Unsupported remote manifest formatVersion: ${String(candidate.formatVersion)}`,\n retryable: false,\n });\n }\n\n if (typeof candidate.root !== \"string\" || candidate.root.length === 0) {\n throw new ConfigurationError({\n message: \"Remote manifest root must be a non-empty string\",\n retryable: false,\n });\n }\n\n if (typeof candidate.generatedAt !== \"string\") {\n throw new ConfigurationError({\n message: \"Remote manifest generatedAt must be an ISO timestamp string\",\n retryable: false,\n });\n }\n\n if (!Array.isArray(candidate.entries)) {\n throw new ConfigurationError({\n message: \"Remote manifest entries must be an array\",\n retryable: false,\n });\n }\n\n const entries = candidate.entries.map((entry, index) => normalizeManifestEntry(entry, index));\n const manifest: RemoteManifest = {\n entries,\n formatVersion: REMOTE_MANIFEST_FORMAT_VERSION,\n generatedAt: candidate.generatedAt,\n root: normalizeRemotePath(candidate.root),\n };\n if (typeof candidate.provider === \"string\") manifest.provider = candidate.provider;\n return manifest;\n}\n\n/**\n * Compares two manifests and produces an entry-level diff.\n *\n * The comparison is performed on the relative-path keys recorded inside each manifest;\n * the absolute roots may differ between snapshots (e.g. captured against `/site` on the\n * source and `/var/www/site` on the destination).\n *\n * @param source - Source-side manifest snapshot.\n * @param destination - Destination-side manifest snapshot.\n * @param options - Optional comparison controls.\n * @returns Diff result mirroring {@link RemoteTreeDiff}.\n */\nexport function compareRemoteManifests(\n source: RemoteManifest,\n destination: RemoteManifest,\n options: CompareRemoteManifestsOptions = {},\n): RemoteTreeDiff {\n const includeUnchanged = options.includeUnchanged ?? false;\n const sourceMap = indexEntries(source);\n const destinationMap = indexEntries(destination);\n const paths = new Set<string>([...sourceMap.keys(), ...destinationMap.keys()]);\n\n const entries: RemoteTreeDiffEntry[] = [];\n const summary: RemoteTreeDiffSummary = {\n added: 0,\n modified: 0,\n removed: 0,\n total: 0,\n unchanged: 0,\n };\n\n for (const path of paths) {\n summary.total += 1;\n const sourceEntry = sourceMap.get(path);\n const destinationEntry = destinationMap.get(path);\n const reasons: RemoteTreeDiffReason[] = [];\n let status: RemoteTreeDiffStatus;\n\n if (sourceEntry !== undefined && destinationEntry === undefined) {\n status = \"added\";\n summary.added += 1;\n } else if (sourceEntry === undefined && destinationEntry !== undefined) {\n status = \"removed\";\n summary.removed += 1;\n } else if (sourceEntry !== undefined && destinationEntry !== undefined) {\n const computed = compareManifestEntries(sourceEntry, destinationEntry, options);\n if (computed.length === 0) {\n status = \"unchanged\";\n summary.unchanged += 1;\n } else {\n status = \"modified\";\n reasons.push(...computed);\n summary.modified += 1;\n }\n } else {\n continue;\n }\n\n if (status === \"unchanged\" && !includeUnchanged) continue;\n\n const record: RemoteTreeDiffEntry = { path, reasons, status };\n if (sourceEntry !== undefined) {\n record.source = manifestEntryToRemote(sourceEntry, source.root);\n }\n if (destinationEntry !== undefined) {\n record.destination = manifestEntryToRemote(destinationEntry, destination.root);\n }\n entries.push(record);\n }\n\n entries.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n return { entries, summary };\n}\n\nfunction relativeFromRoot(entryPath: string, root: string): string | undefined {\n const path = normalizeRemotePath(entryPath);\n if (path === root) return undefined;\n if (root === \"/\") return path;\n if (path.startsWith(`${root}/`)) return path.slice(root.length);\n return undefined;\n}\n\nfunction toManifestEntry(entry: RemoteEntry, relativePath: string): RemoteManifestEntry {\n const manifestEntry: RemoteManifestEntry = {\n path: relativePath,\n type: entry.type,\n };\n if (entry.size !== undefined) manifestEntry.size = entry.size;\n if (entry.modifiedAt !== undefined) manifestEntry.modifiedAt = entry.modifiedAt.toISOString();\n if (entry.uniqueId !== undefined) manifestEntry.uniqueId = entry.uniqueId;\n if (entry.symlinkTarget !== undefined) manifestEntry.symlinkTarget = entry.symlinkTarget;\n return manifestEntry;\n}\n\nfunction normalizeManifestEntry(value: unknown, index: number): RemoteManifestEntry {\n if (value === null || typeof value !== \"object\") {\n throw new ConfigurationError({\n details: { index },\n message: `Remote manifest entry at index ${index} must be an object`,\n retryable: false,\n });\n }\n\n const candidate = value as Partial<RemoteManifestEntry> & Record<string, unknown>;\n if (typeof candidate.path !== \"string\" || candidate.path.length === 0) {\n throw new ConfigurationError({\n details: { index },\n message: `Remote manifest entry at index ${index} must have a non-empty path`,\n retryable: false,\n });\n }\n if (!isRemoteEntryType(candidate.type)) {\n throw new ConfigurationError({\n details: { index, received: candidate.type },\n message: `Remote manifest entry at index ${index} has an invalid type`,\n retryable: false,\n });\n }\n\n const entry: RemoteManifestEntry = {\n path: candidate.path,\n type: candidate.type,\n };\n if (typeof candidate.size === \"number\") entry.size = candidate.size;\n if (typeof candidate.modifiedAt === \"string\") entry.modifiedAt = candidate.modifiedAt;\n if (typeof candidate.uniqueId === \"string\") entry.uniqueId = candidate.uniqueId;\n if (typeof candidate.symlinkTarget === \"string\") entry.symlinkTarget = candidate.symlinkTarget;\n return entry;\n}\n\nfunction isRemoteEntryType(value: unknown): value is RemoteEntryType {\n return value === \"file\" || value === \"directory\" || value === \"symlink\" || value === \"unknown\";\n}\n\nfunction indexEntries(manifest: RemoteManifest): Map<string, RemoteManifestEntry> {\n const map = new Map<string, RemoteManifestEntry>();\n for (const entry of manifest.entries) map.set(entry.path, entry);\n return map;\n}\n\nfunction manifestEntryToRemote(entry: RemoteManifestEntry, root: string): RemoteEntry {\n const absolutePath = root === \"/\" ? entry.path : `${root}${entry.path}`;\n const remote: RemoteEntry = {\n name: deriveName(entry.path),\n path: absolutePath,\n type: entry.type,\n };\n if (entry.size !== undefined) remote.size = entry.size;\n if (entry.modifiedAt !== undefined) {\n const parsed = new Date(entry.modifiedAt);\n if (!Number.isNaN(parsed.getTime())) remote.modifiedAt = parsed;\n }\n if (entry.uniqueId !== undefined) remote.uniqueId = entry.uniqueId;\n if (entry.symlinkTarget !== undefined) remote.symlinkTarget = entry.symlinkTarget;\n return remote;\n}\n\nfunction deriveName(path: string): string {\n const segments = path.split(\"/\").filter(Boolean);\n return segments.length === 0 ? \"/\" : (segments[segments.length - 1] ?? \"/\");\n}\n\nfunction compareManifestEntries(\n source: RemoteManifestEntry,\n destination: RemoteManifestEntry,\n options: CompareRemoteManifestsOptions,\n): RemoteTreeDiffReason[] {\n const reasons: RemoteTreeDiffReason[] = [];\n const compareSize = options.compareSize ?? true;\n const compareModifiedAt = options.compareModifiedAt ?? true;\n const compareUniqueId = options.compareUniqueId ?? false;\n const tolerance = options.modifiedAtToleranceMs ?? 1000;\n\n if (source.type !== destination.type) reasons.push(\"type\");\n\n if (\n compareSize &&\n source.type === \"file\" &&\n destination.type === \"file\" &&\n source.size !== undefined &&\n destination.size !== undefined &&\n source.size !== destination.size\n ) {\n reasons.push(\"size\");\n }\n\n if (compareModifiedAt && isModifiedAtDifferent(source, destination, tolerance)) {\n reasons.push(\"modifiedAt\");\n }\n\n if (\n compareUniqueId &&\n source.uniqueId !== undefined &&\n destination.uniqueId !== undefined &&\n source.uniqueId !== destination.uniqueId\n ) {\n reasons.push(\"checksum\");\n }\n\n return reasons;\n}\n\nfunction isModifiedAtDifferent(\n source: RemoteManifestEntry,\n destination: RemoteManifestEntry,\n toleranceMs: number,\n): boolean {\n if (source.modifiedAt === undefined || destination.modifiedAt === undefined) return false;\n const sourceTime = Date.parse(source.modifiedAt);\n const destinationTime = Date.parse(destination.modifiedAt);\n if (Number.isNaN(sourceTime) || Number.isNaN(destinationTime)) return false;\n return Math.abs(sourceTime - destinationTime) > toleranceMs;\n}\n"],"mappings":";AASA,SAAS,oBAAoB;;;ACyCtB,IAAM,oBAAN,cAAgC,MAAM;AAAA;AAAA,EAElC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOT,YAAY,SAAmC;AAC7C,UAAM,QAAQ,SAAS,QAAQ,UAAU,SAAY,SAAY,EAAE,OAAO,QAAQ,MAAM,CAAC;AACzF,SAAK,OAAO,WAAW;AACvB,SAAK,OAAO,QAAQ;AACpB,SAAK,YAAY,QAAQ;AAEzB,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAkC;AAChC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AASA,SAAS,gBAAgB,SAAkC,MAAwC;AACjG,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,QAAQ,QAAQ;AAAA,EACxB;AACF;AAGO,IAAM,kBAAN,cAA8B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,gCAAgC,CAAC;AAAA,EAClE;AACF;AAGO,IAAM,sBAAN,cAAkC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,oCAAoC,CAAC;AAAA,EACtE;AACF;AAGO,IAAM,qBAAN,cAAiC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,mCAAmC,CAAC;AAAA,EACrE;AACF;AAGO,IAAM,oBAAN,cAAgC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,8BAA8B,CAAC;AAAA,EAChE;AACF;AAGO,IAAM,yBAAN,cAAqC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM5D,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,mCAAmC,CAAC;AAAA,EACrE;AACF;AAGO,IAAM,wBAAN,cAAoC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3D,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,iCAAiC,CAAC;AAAA,EACnE;AACF;AAGO,IAAM,eAAN,cAA2B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,uBAAuB,CAAC;AAAA,EACzD;AACF;AAGO,IAAM,aAAN,cAAyB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,uBAAuB,CAAC;AAAA,EACzD;AACF;AAGO,IAAM,gBAAN,cAA4B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,8BAA8B,CAAC;AAAA,EAChE;AACF;AAGO,IAAM,aAAN,cAAyB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,2BAA2B,CAAC;AAAA,EAC7D;AACF;AAGO,IAAM,gBAAN,cAA4B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,8BAA8B,CAAC;AAAA,EAChE;AACF;AAGO,IAAM,oBAAN,cAAgC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,kCAAkC,CAAC;AAAA,EACpE;AACF;AAGO,IAAM,0BAAN,cAAsC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7D,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,mCAAmC,CAAC;AAAA,EACrE;AACF;AAGO,IAAM,qBAAN,cAAiC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxD,YAAY,SAAkC;AAC5C,UAAM,gBAAgB,SAAS,mCAAmC,CAAC;AAAA,EACrE;AACF;;;ACxNO,IAAM,aAA2C;AAAA,EACtD,QAAQ;AAAA,EAAC;AAAA,EACT,QAAQ;AAAA,EAAC;AAAA,EACT,OAAO;AAAA,EAAC;AAAA,EACR,OAAO;AAAA,EAAC;AAAA,EACR,QAAQ;AAAA,EAAC;AACX;AAUO,SAAS,QAAQ,QAA4B,OAAiB,QAA8B;AACjG,QAAM,SAAS,OAAO,KAAK;AAE3B,MAAI,WAAW,QAAW;AACxB;AAAA,EACF;AAEA,QAAM,YAAuB;AAAA,IAC3B,GAAG;AAAA,IACH;AAAA,EACF;AAEA,SAAO,WAAW,UAAU,OAAO;AACrC;;;ACpGA,SAAS,UAAAA,eAAc;;;ACEhB,IAAM,uBAAuB,CAAC,OAAO,QAAQ,MAAM;AAqCnD,SAAS,oBACd,YACiC;AACjC,SACE,OAAO,eAAe,YAAY,qBAAqB,SAAS,UAA+B;AAEnG;AAQO,SAAS,kBAAkB,WAAsD;AACtF,SAAO,UAAU,YAAY,UAAU;AACzC;;;ADjDA,IAAM,eAAe,oBAAI,IAAI,CAAC,SAAS,WAAW,WAAW,SAAS,CAAC;AAEvE,IAAM,gCAAgC;AAEtC,IAAM,4BAA4B;AAS3B,SAAS,0BAA0B,SAA+C;AACvF,MAAI,kBAAkB,OAAO,MAAM,QAAW;AAC5C,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,KAAK,KAAK,EAAE,WAAW,GAAG;AACpC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,SAAS,UAAa,CAAC,YAAY,QAAQ,IAAI,GAAG;AAC5D,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,MAAM,QAAQ,KAAK;AAAA,MAC9B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,cAAc,UAAa,CAAC,uBAAuB,QAAQ,SAAS,GAAG;AACjF,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,WAAW,QAAQ,UAAU;AAAA,MACxC,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,QAAQ,QAAW;AAC7B,uBAAmB,QAAQ,GAAG;AAAA,EAChC;AAEA,MAAI,QAAQ,QAAQ,QAAW;AAC7B,uBAAmB,QAAQ,GAAG;AAAA,EAChC;AAEA,SAAO;AACT;AAQA,SAAS,mBAAmB,SAA2B;AACrD,8BAA4B,QAAQ,mBAAmB;AAEvD,MAAI,QAAQ,eAAe,QAAW;AACpC,0BAAsB,QAAQ,UAAU;AAAA,EAC1C;AAEA,MAAI,QAAQ,UAAU,QAAW;AAC/B,2BAAuB,QAAQ,KAAK;AAAA,EACtC;AAEA,MACE,QAAQ,wBAAwB,UAChC,OAAO,QAAQ,wBAAwB,YACvC;AACA,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,qBAAqB,OAAO,QAAQ,oBAAoB;AAAA,MACnE,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,kBAAkB,UAAa,OAAO,QAAQ,kBAAkB,YAAY;AACtF,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,eAAe,OAAO,QAAQ,cAAc;AAAA,MACvD,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;AAQA,SAAS,sBAAsB,OAAuC;AACpE,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,UAAM,yBAAyB,KAAK;AAAA,EACtC;AAEA,QAAM,aAAa;AAEnB,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,QAAI,SAAS,QAAW;AACtB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,UAAI,CAAC,sBAAsB,IAAI,GAAG;AAChC,cAAM,yBAAyB,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC;AAAA,MACjD;AAEA;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG;AACpE,YAAM,yBAAyB,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC;AAAA,IACjD;AAEA,UAAM,iBAAiB;AAEvB,eAAW,CAAC,WAAW,aAAa,KAAK,OAAO,QAAQ,cAAc,GAAG;AACvE,UAAI,CAAC,CAAC,UAAU,WAAW,QAAQ,EAAE,SAAS,SAAS,GAAG;AACxD,cAAM,yBAAyB,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC;AAAA,MACjD;AAEA,UACE,OAAO,kBAAkB,aACxB,CAAC,MAAM,QAAQ,aAAa,KAAK,CAAC,sBAAsB,aAAa,IACtE;AACA,cAAM,yBAAyB,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,OAAqC;AAClE,SAAO,MAAM,SAAS,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,YAAY,KAAK,SAAS,CAAC;AAC9F;AAQA,SAAS,uBAAuB,OAAkC;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,MAAM,KAAK,EAAE,SAAS,GAAG;AAC3B;AAAA,IACF;AAAA,EACF,WACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAsC,kBAAkB,cAChE,OAAQ,MAA6B,SAAS,YAC9C;AACA;AAAA,EACF;AAEA,QAAM,IAAI,mBAAmB;AAAA,IAC3B,SAAS,EAAE,OAAO,OAAO,MAAM;AAAA,IAC/B,SAAS;AAAA,IACT,WAAW;AAAA,EACb,CAAC;AACH;AAQA,SAAS,mBAAmB,SAA2B;AACrD,MAAI,QAAQ,eAAe,UAAa,QAAQ,WAAW,KAAK,EAAE,WAAW,GAAG;AAC9E,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,uBAAuB,UAAa,OAAO,QAAQ,uBAAuB,WAAW;AAC/F,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,oBAAoB,QAAQ,mBAAmB;AAAA,MAC1D,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,qBAAmB,QAAQ,YAAY,YAAY;AACnD,qBAAmB,QAAQ,YAAY,YAAY;AACnD,+BAA6B,QAAQ,oBAAoB;AAC3D;AAQA,SAAS,6BAA6B,OAAiD;AACrF,MAAI,UAAU,QAAW;AACvB;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAE1D,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,6BAA6B,KAAK;AAAA,EAC1C;AAEA,aAAW,eAAe,cAAc;AACtC,QAAI,OAAO,gBAAgB,YAAY,CAAC,oBAAoB,WAAW,GAAG;AACxE,YAAM,6BAA6B,KAAK;AAAA,IAC1C;AAAA,EACF;AACF;AAQA,SAAS,4BAA4B,OAAgD;AACnF,MAAI,UAAU,QAAW;AACvB;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAE1D,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,yBAAyB,KAAK;AAAA,EACtC;AAEA,aAAW,eAAe,cAAc;AACtC,QAAI,OAAO,gBAAgB,YAAY,CAAC,8BAA8B,WAAW,GAAG;AAClF,YAAM,yBAAyB,KAAK;AAAA,IACtC;AAAA,EACF;AACF;AAQA,SAAS,oBAAoB,OAAwB;AACnD,QAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,MAAM,EAAE;AAChD,SAAO,WAAW,WAAW,iCAAiC,eAAe,KAAK,UAAU;AAC9F;AAQA,SAAS,8BAA8B,OAAwB;AAC7D,QAAM,UAAU,MAAM,KAAK;AAE3B,MAAI,oBAAoB,OAAO,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,QAAQ,WAAW,SAAS,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI;AAC/E,QAAM,SAAS,UAAU,IAAI;AAE7B,MAAI,CAAC,uBAAuB,KAAK,MAAM,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAOC,QAAO,KAAK,QAAQ,QAAQ,EAAE,eAAe;AAAA,EACtD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,UAAU,OAAuB;AACxC,QAAM,YAAY,MAAM,SAAS;AAEjC,SAAO,cAAc,IAAI,QAAQ,GAAG,KAAK,GAAG,IAAI,OAAO,IAAI,SAAS,CAAC;AACvE;AAQA,SAAS,6BAA6B,OAAoC;AACxE,SAAO,IAAI,mBAAmB;AAAA,IAC5B,SAAS,EAAE,sBAAsB,MAAM;AAAA,IACvC,SACE;AAAA,IACF,WAAW;AAAA,EACb,CAAC;AACH;AAQA,SAAS,yBAAyB,OAAoC;AACpE,SAAO,IAAI,mBAAmB;AAAA,IAC5B,SAAS,EAAE,qBAAqB,MAAM;AAAA,IACtC,SACE;AAAA,IACF,WAAW;AAAA,EACb,CAAC;AACH;AAQA,SAAS,yBAAyB,OAAoC;AACpE,SAAO,IAAI,mBAAmB;AAAA,IAC5B,SAAS,EAAE,YAAY,MAAM;AAAA,IAC7B,SAAS;AAAA,IACT,WAAW;AAAA,EACb,CAAC;AACH;AASA,SAAS,mBAAmB,OAAiC,OAAqB;AAChF,MAAI,UAAU,QAAW;AACvB;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,IAAI,KAAK,GAAG;AAC5B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,CAAC,KAAK,GAAG,MAAM;AAAA,MAC1B,SAAS,0BAA0B,KAAK;AAAA,MACxC,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,OAAO,UAAU,KAAK,KAAK,SAAS,KAAK,SAAS;AAC3D;AAEA,SAAS,uBAAuB,OAAwB;AACtD,SAAO,OAAO,SAAS,KAAK,KAAK,QAAQ;AAC3C;;;AExWO,IAAM,mBAAN,MAAuB;AAAA,EACX,YAAY,oBAAI,IAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlE,YAAY,YAAuC,CAAC,GAAG;AACrD,eAAW,YAAY,WAAW;AAChC,WAAK,SAAS,QAAQ;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,UAAiC;AACxC,QAAI,KAAK,UAAU,IAAI,SAAS,EAAE,GAAG;AACnC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS,EAAE,UAAU,SAAS,GAAG;AAAA,QACjC,SAAS,aAAa,SAAS,EAAE;AAAA,QACjC,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,SAAK,UAAU,IAAI,SAAS,IAAI,QAAQ;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,YAAiC;AAC1C,WAAO,KAAK,UAAU,OAAO,UAAU;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,YAAiC;AACnC,WAAO,KAAK,UAAU,IAAI,UAAU;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,YAAqD;AACvD,WAAO,KAAK,UAAU,IAAI,UAAU;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAQ,YAAyC;AAC/C,UAAM,WAAW,KAAK,IAAI,UAAU;AAEpC,QAAI,aAAa,QAAW;AAC1B,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,UAAU,WAAW;AAAA,QAChC,SAAS,aAAa,UAAU;AAAA,QAChC,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB,YAAmD;AACjE,WAAO,KAAK,IAAI,UAAU,GAAG;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBAAoB,YAAuC;AACzD,WAAO,KAAK,QAAQ,UAAU,EAAE;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAA0B;AACxB,WAAO,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAoC;AAClC,WAAO,KAAK,KAAK,EAAE,IAAI,CAAC,aAAa,SAAS,YAAY;AAAA,EAC5D;AACF;;;ACtGO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAEjB;AAAA,EAEQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,UAAiC,CAAC,GAAG;AAC/C,SAAK,WAAW,QAAQ,YAAY,IAAI,iBAAiB;AACzD,SAAK,SAAS,QAAQ,UAAU;AAEhC,eAAW,YAAY,QAAQ,aAAa,CAAC,GAAG;AAC9C,WAAK,SAAS,SAAS,QAAQ;AAAA,IACjC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBAAiB,UAAiC;AAChD,SAAK,SAAS,SAAS,QAAQ;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAY,YAAiC;AAC3C,WAAO,KAAK,SAAS,IAAI,UAAU;AAAA,EACrC;AAAA,EAMA,gBAAgB,YAA0D;AACxE,QAAI,eAAe,QAAW;AAC5B,aAAO,KAAK,SAAS,iBAAiB;AAAA,IACxC;AAEA,WAAO,KAAK,SAAS,oBAAoB,UAAU;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,SAAsD;AAClE,UAAM,eAAe,0BAA0B,OAAO;AACtD,UAAM,aAAa,kBAAkB,YAAY;AAEjD,QAAI,eAAe,QAAW;AAC5B,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,kBAAkB,KAAK,SAAS,QAAQ,UAAU;AACxD,UAAM,WAAW,gBAAgB,OAAO;AACxC,UAAM,oBAAuC;AAAA,MAC3C,GAAG;AAAA,MACH,UAAU;AAAA,IACZ;AAEA,QAAI,kBAAkB,aAAa,UAAa,oBAAoB,UAAU,GAAG;AAC/E,wBAAkB,WAAW;AAAA,IAC/B;AAEA,YAAQ,KAAK,QAAQ,QAAQ,uBAAuB,mBAAmB,UAAU,CAAC;AAElF,WAAO,SAAS,QAAQ,iBAAiB;AAAA,EAC3C;AACF;AAEA,SAAS,uBACP,SACA,YACgB;AAChB,QAAM,SAAyB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM,QAAQ;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAEA,MAAI,oBAAoB,UAAU,GAAG;AACnC,WAAO,WAAW;AAAA,EACpB;AAEA,SAAO;AACT;;;ACjFO,SAAS,qBAAqB,UAAiC,CAAC,GAAmB;AACxF,SAAO,IAAI,eAAe,OAAO;AACnC;;;APIO,IAAM,eAAN,MAAM,sBAAqB,aAAa;AAAA;AAAA,EAE7C,OAAgB,uBAAuB;AAAA;AAAA,EAG9B;AAAA,EAEQ;AAAA,EACA;AAAA,EACT,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,YAAY,UAA+B,CAAC,GAAG;AAC7C,UAAM;AACN,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,SAAS,QAAQ,UAAU;AAChC,SAAK,UAAU,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAO,UAA+B,CAAC,GAAiB;AAC7D,WAAO,IAAI,cAAa,OAAO;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,QACX,SACA,UAA+B,CAAC,GACT;AACvB,UAAM,gBAAqC,EAAE,GAAG,QAAQ;AAExD,QAAI,QAAQ,WAAW,QAAW;AAChC,oBAAc,SAAS,QAAQ;AAAA,IACjC;AAEA,QAAI,QAAQ,aAAa,QAAW;AAClC,oBAAc,WAAW,QAAQ;AAAA,IACnC,WAAW,oBAAoB,QAAQ,QAAQ,GAAG;AAChD,oBAAc,WAAW,QAAQ;AAAA,IACnC;AAEA,UAAM,SAAS,IAAI,cAAa,aAAa;AAC7C,UAAM,OAAO,QAAQ,OAAO;AAC5B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,SAA2C;AACvD,UAAM,UAAU,KAAK,eAAe;AACpC,UAAM,WACJ,QAAQ,aACP,oBAAoB,QAAQ,QAAQ,IAAI,QAAQ,WAAW,KAAK;AACnE,YAAQ,KAAK,QAAQ,QAAQ;AAAA,MAC3B,WAAW;AAAA,MACX,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AACD,UAAM,QAAQ,QAAQ;AAAA,MACpB,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AACD,SAAK,YAAY;AACjB,SAAK,KAAK,WAAW;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAA4B;AAChC,QAAI,KAAK,YAAY,UAAa,KAAK,WAAW;AAChD,YAAM,KAAK,QAAQ,WAAW;AAAA,IAChC;AAEA,SAAK,YAAY;AACjB,SAAK,KAAK,YAAY;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAA4C;AAC1C,WAAO;AAAA,MACL,cAAc,KAAK,YAAY;AAAA,MAC/B,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAKC,OAAc,SAA+C;AACtE,WAAO,KAAK,eAAe,EAAE,KAAKA,OAAM,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAKA,OAAc,SAA4C;AACnE,WAAO,KAAK,eAAe,EAAE,KAAKA,OAAM,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,iBAAoC;AAC1C,QAAI,KAAK,YAAY,QAAW;AAC9B,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,OAAO,KAAK,SAAS,YAAY,CAAC;AAAA,QAC3C,UAAU,KAAK;AAAA,QACf,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,WAAO,KAAK;AAAA,EACd;AACF;;;AQzNA,SAAS,YAAY,WAAW,mBAAmB;;;ACoC5C,SAAS,wBACd,OACA,UAAoC,CAAC,GACN;AAC/B,MAAI,UAAU,OAAW,QAAO;AAEhC,QAAM,iBAAiB,cAAc,MAAM,cAAc;AACzD,QAAM,aAAa,eAAe,MAAM,YAAY,cAAc;AAClE,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,QAAQ,QAAQ,SAAS;AAE/B,MAAI,SAAS;AACb,MAAI,eAAe,IAAI;AAEvB,WAAS,SAAe;AACtB,UAAM,UAAU,IAAI;AACpB,UAAM,YAAY,KAAK,IAAI,GAAG,UAAU,YAAY;AAEpD,QAAI,YAAY,GAAG;AACjB,eAAS,KAAK,IAAI,YAAY,SAAU,YAAY,MAAQ,cAAc;AAC1E,qBAAe;AAAA,IACjB;AAAA,EACF;AAEA,iBAAe,QAAQ,OAAe,QAAqC;AACzE,QAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS,EAAE,MAAM;AAAA,QACjB,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,QAAI,UAAU,EAAG;AAEjB,QAAI,YAAY;AAEhB,WAAO,YAAY,GAAG;AACpB,qBAAe,MAAM;AACrB,aAAO;AAEP,UAAI,UAAU,WAAW;AACvB,kBAAU;AACV;AAAA,MACF;AAEA,UAAI,UAAU,YAAY;AAGxB,cAAM,UAAU;AAChB,iBAAS;AACT,qBAAa;AACb,cAAMC,UAAS,KAAK,KAAM,KAAK,IAAI,WAAW,UAAU,IAAI,iBAAkB,GAAI;AAClF,cAAM,MAAMA,SAAQ,MAAM;AAC1B;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,IAAI,WAAW,UAAU,IAAI;AAClD,YAAM,SAAS,KAAK,IAAI,GAAG,KAAK,KAAM,UAAU,iBAAkB,GAAI,CAAC;AACvE,YAAM,MAAM,QAAQ,MAAM;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,gBAAgB,QAAQ;AAC/C;AAaO,SAAS,qBACd,QACA,UACA,QAC2B;AAC3B,MAAI,aAAa,OAAW,QAAO;AAEnC,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,GAAG,mBAAmB;AACzC,uBAAiB,SAAS,QAAQ;AAChC,uBAAe,MAAM;AACrB,YAAI,MAAM,aAAa,GAAG;AACxB,gBAAM,SAAS,QAAQ,MAAM,YAAY,MAAM;AAAA,QACjD;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAAuB;AAC5C,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACzC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,gBAAgB,MAAM;AAAA,MACjC,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,OAA2B,gBAAgC;AACjF,MAAI,UAAU,OAAW,QAAO;AAEhC,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACzC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,YAAY,MAAM;AAAA,MAC7B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,QAAuC;AAC7D,MAAI,QAAQ,YAAY,MAAM;AAC5B,UAAM,IAAI,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;AAEA,SAAS,aAAa,SAAiB,QAAqC;AAC1E,MAAI,WAAW,EAAG,QAAO,QAAQ,QAAQ;AAEzC,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,QAAQ,WAAW,MAAM;AAC7B,cAAQ;AACR,cAAQ;AAAA,IACV,GAAG,OAAO;AAEV,UAAM,UAAU,MAAM;AACpB,cAAQ;AACR;AAAA,QACE,IAAI,WAAW;AAAA,UACb,SAAS;AAAA,UACT,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AAEA,aAAS,UAAgB;AACvB,mBAAa,KAAK;AAClB,cAAQ,oBAAoB,SAAS,OAAO;AAAA,IAC9C;AAEA,QAAI,WAAW,QAAW;AACxB,UAAI,OAAO,SAAS;AAClB,gBAAQ;AACR;AAAA,MACF;AACA,aAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IAC1D;AAAA,EACF,CAAC;AACH;;;ACnJO,SAAS,+BACd,SACkB;AAClB,SAAO,OAAO,YAAY;AACxB,UAAM,EAAE,IAAI,IAAI;AAEhB,QAAI,CAAC,qBAAqB,IAAI,SAAS,GAAG;AACxC,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,OAAO,IAAI,IAAI,WAAW,IAAI,UAAU;AAAA,QACnD,SAAS,qEAAqE,IAAI,SAAS;AAAA,QAC3F,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,gBAAgB,KAAK,QAAQ;AAC5C,UAAM,cAAc,gBAAgB,KAAK,aAAa;AACtD,UAAM,gBAAgB,QAAQ,eAAe,EAAE,UAAU,QAAQ,KAAK,MAAM,SAAS,CAAC;AACtF,UAAM,qBAAqB,QAAQ,eAAe;AAAA,MAChD,UAAU;AAAA,MACV;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AACD,UAAM,kBAAkB,0BAA0B,eAAe,QAAQ,UAAU,GAAG;AACtF,UAAM,uBAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,YAAQ,eAAe;AACvB,UAAM,aAAa,MAAM,gBAAgB,KAAK,kBAAkB,SAAS,MAAM,CAAC;AAChF,YAAQ,eAAe;AACvB,UAAM,sBAAsB,uBAAuB,YAAY,SAAS,QAAQ,QAAQ;AACxF,UAAM,cAAc,MAAM,qBAAqB;AAAA,MAC7C,mBAAmB,SAAS,aAAa,mBAAmB;AAAA,IAC9D;AAEA,WAAO,4BAA4B,YAAY,aAAa,GAAG;AAAA,EACjE;AACF;AAEA,SAAS,uBACP,YACA,SACA,SAC4B;AAC5B,QAAM,WAAW,wBAAwB,QAAQ,gBAAgB,OAAO;AAExE,MAAI,aAAa,OAAW,QAAO;AAEnC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,qBAAqB,WAAW,SAAS,UAAU,QAAQ,MAAM;AAAA,EAC5E;AACF;AAEA,SAAS,qBAAqB,WAAuC;AACnE,SAAO,cAAc,UAAU,cAAc,cAAc,cAAc;AAC3E;AAEA,SAAS,gBAAgB,KAAkB,MAAsD;AAC/F,QAAM,WAAW,SAAS,WAAW,IAAI,SAAS,IAAI;AAEtD,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,IAAI,IAAI,WAAW,IAAI,WAAW,KAAK;AAAA,MACzD,SAAS,2BAA2B,IAAI,cAAc,IAAI,EAAE;AAAA,MAC5D,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,0BACP,SACA,UACA,MACA,KAC4B;AAC5B,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,wBAAwB;AAAA,MAChC,SAAS,EAAE,UAAU,cAAc,QAAQ,GAAG,OAAO,IAAI,IAAI,WAAW,IAAI,WAAW,KAAK;AAAA,MAC5F,SAAS,oCAAoC,IAAI,cAAc,SAAS,IAAI;AAAA,MAC5E,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,cAAc,QAAW;AACnC,UAAM,IAAI,wBAAwB;AAAA,MAChC,SAAS;AAAA,QACP,UAAU,cAAc,QAAQ;AAAA,QAChC,OAAO,IAAI;AAAA,QACX,WAAW,IAAI;AAAA,QACf,UAAU,QAAQ;AAAA,QAClB;AAAA,MACF;AAAA,MACA,SAAS,yDAAyD,QAAQ,QAAQ;AAAA,MAClF,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,QAAQ;AACjB;AAEA,SAAS,kBACP,SACA,UAC6B;AAC7B,QAAM,UAAuC;AAAA,IAC3C,SAAS,QAAQ;AAAA,IACjB,UAAU,cAAc,QAAQ;AAAA,IAChC,KAAK,QAAQ;AAAA,IACb,gBAAgB,CAAC,kBAAkB,eACjC,QAAQ,eAAe,kBAAkB,UAAU;AAAA,IACrD,gBAAgB,MAAM,QAAQ,eAAe;AAAA,EAC/C;AAEA,MAAI,QAAQ,WAAW,OAAW,SAAQ,SAAS,QAAQ;AAC3D,MAAI,QAAQ,mBAAmB,QAAW;AACxC,YAAQ,iBAAiB,EAAE,GAAG,QAAQ,eAAe;AAAA,EACvD;AAEA,SAAO;AACT;AAEA,SAAS,mBACP,SACA,UACA,YAC8B;AAC9B,QAAM,UAAwC;AAAA,IAC5C,SAAS,QAAQ;AAAA,IACjB,SAAS,WAAW;AAAA,IACpB,UAAU,cAAc,QAAQ;AAAA,IAChC,KAAK,QAAQ;AAAA,IACb,gBAAgB,CAAC,kBAAkBC,gBACjC,QAAQ,eAAe,kBAAkBA,WAAU;AAAA,IACrD,gBAAgB,MAAM,QAAQ,eAAe;AAAA,EAC/C;AACA,QAAM,aAAa,WAAW,cAAc,QAAQ,IAAI;AAExD,MAAI,QAAQ,WAAW,OAAW,SAAQ,SAAS,QAAQ;AAC3D,MAAI,QAAQ,mBAAmB,QAAW;AACxC,YAAQ,iBAAiB,EAAE,GAAG,QAAQ,eAAe;AAAA,EACvD;AACA,MAAI,eAAe,OAAW,SAAQ,aAAa;AACnD,MAAI,QAAQ,IAAI,YAAY,KAAM,SAAQ,SAAS,WAAW,aAAa;AAC3E,MAAI,WAAW,iBAAiB,QAAW;AACzC,YAAQ,eAAe,kBAAkB,WAAW,YAAY;AAAA,EAClE;AAEA,SAAO;AACT;AAEA,SAAS,4BACP,YACA,aACA,KACyB;AACzB,QAAM,SAAkC;AAAA,IACtC,kBAAkB,YAAY;AAAA,EAChC;AACA,QAAM,aAAa,YAAY,cAAc,WAAW,cAAc,IAAI;AAC1E,QAAM,WAAW,CAAC,GAAI,WAAW,YAAY,CAAC,GAAI,GAAI,YAAY,YAAY,CAAC,CAAE;AAEjF,MAAI,eAAe,OAAW,QAAO,aAAa;AAClD,MAAI,YAAY,YAAY,OAAW,QAAO,UAAU,YAAY;AACpE,MAAI,YAAY,aAAa,OAAW,QAAO,WAAW,YAAY;AACtE,MAAI,YAAY,aAAa,OAAW,QAAO,WAAW,YAAY;AAAA,WAC7D,WAAW,aAAa,OAAW,QAAO,WAAW,WAAW;AACzE,MAAI,YAAY,iBAAiB,QAAW;AAC1C,WAAO,eAAe,kBAAkB,YAAY,YAAY;AAAA,EAClE,WAAW,WAAW,iBAAiB,QAAW;AAChD,WAAO,eAAe,kBAAkB,WAAW,YAAY;AAAA,EACjE;AACA,MAAI,SAAS,SAAS,EAAG,QAAO,WAAW;AAE3C,SAAO;AACT;AAEA,SAAS,cAAc,UAA8C;AACnE,QAAM,QAA0B,EAAE,MAAM,SAAS,KAAK;AAEtD,MAAI,SAAS,aAAa,OAAW,OAAM,WAAW,SAAS;AAE/D,SAAO;AACT;AAEA,SAAS,kBAAkB,cAAsE;AAC/F,QAAM,QAAoC,EAAE,UAAU,aAAa,SAAS;AAE5E,MAAI,aAAa,WAAW,OAAW,OAAM,SAAS,aAAa;AACnE,MAAI,aAAa,aAAa,OAAW,OAAM,WAAW,aAAa;AACvE,MAAI,aAAa,qBAAqB,QAAW;AAC/C,UAAM,mBAAmB,aAAa;AAAA,EACxC;AACA,MAAI,aAAa,mBAAmB,OAAW,OAAM,iBAAiB,aAAa;AACnF,MAAI,aAAa,YAAY,OAAW,OAAM,UAAU,EAAE,GAAG,aAAa,QAAQ;AAElF,SAAO;AACT;;;ACpNO,SAAS,qBAAqB,OAA4C;AAC/E,QAAM,aAAa,KAAK,IAAI,GAAG,MAAM,YAAY,QAAQ,IAAI,MAAM,UAAU,QAAQ,CAAC;AACtF,QAAM,SAAyB;AAAA,IAC7B,iBAAiB,MAAM;AAAA,IACvB,kBAAkB,MAAM;AAAA,IACxB,WAAW,MAAM;AAAA,IACjB,aAAa,MAAM;AAAA,IACnB;AAAA,IACA,uBAAuB,wBAAwB,MAAM,kBAAkB,UAAU;AAAA,IACjF,SAAS,MAAM,WAAW;AAAA,IAC1B,UAAU,MAAM,YAAY;AAAA,EAC9B;AAEA,MAAI,MAAM,eAAe,OAAW,QAAO,aAAa,MAAM;AAC9D,MAAI,MAAM,aAAa,OAAW,QAAO,WAAW,MAAM;AAE1D,SAAO;AACT;AAQO,SAAS,oBAAoB,OAAkD;AACpF,QAAM,MAAM,MAAM,OAAO,oBAAI,KAAK;AAClC,QAAM,YAAY,KAAK,IAAI,GAAG,IAAI,QAAQ,IAAI,MAAM,UAAU,QAAQ,CAAC;AACvE,QAAM,QAA+B;AAAA,IACnC,YAAY,MAAM;AAAA,IAClB,kBAAkB,MAAM;AAAA,IACxB,WAAW,MAAM;AAAA,IACjB;AAAA,IACA,gBAAgB,wBAAwB,MAAM,kBAAkB,SAAS;AAAA,EAC3E;AAEA,MAAI,MAAM,eAAe,QAAW;AAClC,UAAM,aAAa,MAAM;AACzB,UAAM,UAAU,MAAM,aAAa,IAAK,MAAM,mBAAmB,MAAM,aAAc,MAAM;AAAA,EAC7F;AAEA,SAAO;AACT;AASA,SAAS,wBAAwB,OAAe,YAA4B;AAC1E,MAAI,cAAc,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,aAAa;AAC/B;;;ACzBO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,UAAiC,CAAC,GAAG;AAC/C,SAAK,MAAM,QAAQ,QAAQ,MAAM,oBAAI,KAAK;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QACJ,KACA,UACA,UAAwC,CAAC,GACf;AAC1B,UAAM,cAAc,qBAAqB,QAAQ,OAAO,WAAW;AACnE,UAAM,WAA8B,CAAC;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,aAAa,iBAAiB,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACxE,QAAI,yBAAyB;AAE7B,QAAI;AACF,eAAS,gBAAgB,GAAG,iBAAiB,aAAa,iBAAiB,GAAG;AAC5E,aAAK,eAAe,WAAW,QAAQ,GAAG;AAE1C,cAAM,mBAAmB,KAAK,IAAI;AAClC,cAAM,UAAU,KAAK;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX,CAAC,qBAAqB;AACpB,qCAAyB;AAAA,UAC3B;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,SAAS,MAAM,YAAY,UAAU,SAAS,WAAW,QAAQ,GAAG;AAC1E,kBAAQ,eAAe;AACvB,mCAAyB,OAAO;AAEhC,gBAAM,cAAc,KAAK,IAAI;AAC7B,mBAAS;AAAA,YACP,cAAc,eAAe,kBAAkB,aAAa,OAAO,gBAAgB;AAAA,UACrF;AAEA,iBAAO,cAAc,KAAK,QAAQ,UAAU,WAAW,WAAW;AAAA,QACpE,SAAS,OAAO;AACd,gBAAM,cAAc,KAAK,IAAI;AAC7B,gBAAM,UAAU;AAAA,YACd;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,eAAe,KAAK;AAAA,UACtB;AACA,mBAAS,KAAK,OAAO;AAErB,cAAI,iBAAiB,cAAc,iBAAiB,cAAc;AAChE,kBAAM;AAAA,UACR;AAEA,gBAAM,aAAyC,EAAE,SAAS,eAAe,OAAO,IAAI;AACpF,gBAAM,cACJ,gBAAgB,gBACf,QAAQ,OAAO,cAAc,UAAU,KAAK,YAAY,KAAK;AAEhE,cAAI,aAAa;AACf,oBAAQ,OAAO,UAAU,UAAU;AACnC;AAAA,UACF;AAEA,gBAAM,sBAAsB,KAAK,OAAO,QAAQ;AAAA,QAClD;AAAA,MACF;AAEA,YAAM,sBAAsB,KAAK,QAAW,QAAQ;AAAA,IACtD,UAAE;AACA,iBAAW,QAAQ;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,uBACN,KACA,SACA,WACA,SACA,QACA,wBAC0B;AAC1B,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA;AAAA,MACA,gBAAgB,CAAC,kBAAkB,eAAe;AAChD,aAAK,eAAe,QAAQ,GAAG;AAC/B,+BAAuB,gBAAgB;AACvC,cAAM,gBAAgB;AAAA,UACpB;AAAA,UACA,KAAK,KAAK,IAAI;AAAA,UACd;AAAA,UACA,YAAY,IAAI;AAAA,QAClB;AACA,cAAM,qBAAqB,cAAc,IAAI;AAC7C,cAAM,QAAQ;AAAA,UACZ,uBAAuB,SACnB,gBACA,EAAE,GAAG,eAAe,YAAY,mBAAmB;AAAA,QACzD;AACA,gBAAQ,aAAa,KAAK;AAC1B,eAAO;AAAA,MACT;AAAA,MACA,gBAAgB,MAAM,KAAK,eAAe,QAAQ,GAAG;AAAA,IACvD;AAEA,QAAI,WAAW,QAAW;AACxB,cAAQ,SAAS;AAAA,IACnB;AAEA,QAAI,QAAQ,mBAAmB,QAAW;AACxC,cAAQ,iBAAiB,EAAE,GAAG,QAAQ,eAAe;AAAA,IACvD;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,QAAiC,KAAwB;AAC9E,QAAI,QAAQ,YAAY,MAAM;AAC5B,UAAI,OAAO,kBAAkB,mBAAmB;AAC9C,cAAM,OAAO;AAAA,MACf;AAEA,YAAM,IAAI,WAAW;AAAA,QACnB,SAAS,EAAE,OAAO,IAAI,IAAI,WAAW,IAAI,UAAU;AAAA,QACnD,SAAS,yBAAyB,IAAI,EAAE;AAAA,QACxC,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAOA,SAAS,iBACP,cACA,SACA,KACY;AACZ,QAAM,YAAY,mBAAmB,SAAS,SAAS;AAEvD,MAAI,iBAAiB,UAAa,cAAc,QAAW;AACzD,WAAO,EAAE,SAAS,MAAM,OAAU;AAAA,EACpC;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,kBAAkB,MAAY,WAAW,MAAM,cAAc,MAAM;AACzE,QAAM,gBACJ,cAAc,SACV,SACA,WAAW,MAAM;AACf,eAAW;AAAA,MACT,IAAI,aAAa;AAAA,QACf,SAAS,EAAE,OAAO,IAAI,IAAI,WAAW,IAAI,WAAW,UAAU;AAAA,QAC9D,SAAS,gCAAgC,SAAS,OAAO,IAAI,EAAE;AAAA,QAC/D,WAAW,SAAS,aAAa;AAAA,MACnC,CAAC;AAAA,IACH;AAAA,EACF,GAAG,SAAS;AAElB,MAAI,cAAc,YAAY,MAAM;AAClC,oBAAgB;AAAA,EAClB,OAAO;AACL,kBAAc,iBAAiB,SAAS,iBAAiB,EAAE,MAAM,KAAK,CAAC;AAAA,EACzE;AAEA,SAAO;AAAA,IACL,SAAS,MAAM;AACb,UAAI,kBAAkB,QAAW;AAC/B,qBAAa,aAAa;AAAA,MAC5B;AACA,oBAAc,oBAAoB,SAAS,eAAe;AAAA,IAC5D;AAAA,IACA,QAAQ,WAAW;AAAA,EACrB;AACF;AAEA,SAAS,mBAAmB,OAA+C;AACzE,MAAI,UAAU,UAAa,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AAChE,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,eAAe,YACb,UACA,SACA,QACA,KACkC;AAClC,MAAI,WAAW,QAAW;AACxB,WAAO,SAAS,OAAO;AAAA,EACzB;AAEA,SAAO,QAAQ,KAAK,CAAC,SAAS,OAAO,GAAG,kBAAkB,QAAQ,GAAG,CAAC,CAAC;AACzE;AAEA,SAAS,kBACP,QACA,KACkC;AAClC,SAAO,IAAI,QAAQ,CAAC,GAAG,WAAW;AAChC,UAAM,cAAc,MAAY;AAC9B,UAAI,OAAO,kBAAkB,mBAAmB;AAC9C,eAAO,OAAO,MAAM;AACpB;AAAA,MACF;AAEA;AAAA,QACE,IAAI,WAAW;AAAA,UACb,SAAS,EAAE,OAAO,IAAI,IAAI,WAAW,IAAI,UAAU;AAAA,UACnD,SAAS,yBAAyB,IAAI,EAAE;AAAA,UACxC,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,OAAO,SAAS;AAClB,kBAAY;AACZ;AAAA,IACF;AAEA,WAAO,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,EAC9D,CAAC;AACH;AAEA,SAAS,qBAAqB,OAAmC;AAC/D,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC;AAEA,SAAS,cACP,SACA,WACA,aACA,kBACA,OACiB;AACjB,QAAM,SAA0B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,KAAK,IAAI,GAAG,YAAY,QAAQ,IAAI,UAAU,QAAQ,CAAC;AAAA,IACnE;AAAA,EACF;AAEA,MAAI,UAAU,QAAW;AACvB,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO;AACT;AAEA,SAAS,cACP,KACA,QACA,UACA,WACA,aACiB;AACjB,QAAM,aAAa,KAAK,IAAI,GAAG,YAAY,QAAQ,IAAI,UAAU,QAAQ,CAAC;AAC1E,QAAM,eAAe,4BAA4B,MAAM;AACvD,QAAM,UAA2B;AAAA,IAC/B;AAAA,IACA,uBAAuBC,yBAAwB,OAAO,kBAAkB,UAAU;AAAA,IAClF,kBAAkB,OAAO;AAAA,IACzB;AAAA,IACA;AAAA,IACA,OAAO,IAAI;AAAA,IACX,WAAW,IAAI;AAAA,IACf,SAAS,OAAO,WAAW,IAAI,WAAW;AAAA,IAC1C;AAAA,IACA,YAAY,IAAI;AAAA,IAChB,UAAU,cAAc,YAAY,OAAO,YAAY;AAAA,IACvD,UAAU,CAAC,GAAI,OAAO,YAAY,CAAC,CAAE;AAAA,EACvC;AAEA,MAAI,IAAI,WAAW,OAAW,SAAQ,SAAS,EAAE,GAAG,IAAI,OAAO;AAC/D,MAAI,IAAI,gBAAgB,OAAW,SAAQ,cAAc,EAAE,GAAG,IAAI,YAAY;AAC9E,MAAI,OAAO,eAAe,OAAW,SAAQ,aAAa,OAAO;AAAA,WACxD,IAAI,eAAe,OAAW,SAAQ,aAAa,IAAI;AAChE,MAAI,OAAO,aAAa,OAAW,SAAQ,WAAW,OAAO;AAAA,WACpD,cAAc,aAAa,OAAW,SAAQ,WAAW,aAAa;AAC/E,MAAI,iBAAiB,OAAW,SAAQ,eAAe;AACvD,MAAI,IAAI,aAAa,OAAW,SAAQ,WAAW,EAAE,GAAG,IAAI,SAAS;AAErE,SAAO;AACT;AAEA,SAAS,4BACP,QACwC;AACxC,QAAM,eAAe,OAAO;AAE5B,MAAI,iBAAiB,QAAW;AAC9B,UAAMC,cAAyC,EAAE,UAAU,aAAa,SAAS;AAEjF,QAAI,aAAa,WAAW,OAAW,CAAAA,YAAW,SAAS,aAAa;AACxE,QAAI,aAAa,aAAa,OAAW,CAAAA,YAAW,WAAW,aAAa;AAC5E,QAAI,aAAa,qBAAqB,QAAW;AAC/C,MAAAA,YAAW,mBAAmB,aAAa;AAAA,IAC7C;AACA,QAAI,aAAa,mBAAmB;AAClC,MAAAA,YAAW,iBAAiB,aAAa;AAC3C,QAAI,aAAa,YAAY,OAAW,CAAAA,YAAW,UAAU,EAAE,GAAG,aAAa,QAAQ;AAEvF,WAAOA;AAAA,EACT;AAEA,MAAI,OAAO,aAAa,UAAa,OAAO,aAAa,QAAW;AAClE,WAAO;AAAA,EACT;AAEA,QAAM,aAAyC,EAAE,UAAU,OAAO,YAAY,MAAM;AAEpF,MAAI,OAAO,aAAa,QAAW;AACjC,eAAW,WAAW,OAAO;AAAA,EAC/B;AAEA,SAAO;AACT;AAEA,SAAS,sBACP,KACA,OACA,UACe;AACf,SAAO,IAAI,cAAc;AAAA,IACvB,OAAO;AAAA,IACP,SAAS;AAAA,MACP;AAAA,MACA,OAAO,IAAI;AAAA,MACX,WAAW,IAAI;AAAA,IACjB;AAAA,IACA,SAAS,wBAAwB,IAAI,EAAE;AAAA,IACvC,WAAW,YAAY,KAAK;AAAA,EAC9B,CAAC;AACH;AAEA,SAAS,eAAe,OAAsC;AAC5D,MAAI,iBAAiB,mBAAmB;AACtC,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,WAAW,MAAM;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,OAAO,KAAK;AAAA,IACrB,MAAM;AAAA,EACR;AACF;AAEA,SAAS,YAAY,OAAyB;AAC5C,SAAO,iBAAiB,qBAAqB,MAAM;AACrD;AAEA,SAASD,yBAAwB,OAAe,YAA4B;AAC1E,MAAI,cAAc,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,aAAa;AAC/B;;;ACvaA,eAAsB,SAAS,SAAoD;AACjF,QAAM,EAAE,QAAQ,MAAM,IAAI;AAE1B,MAAI,MAAM,YAAY,OAAO;AAC3B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,SAAS,MAAM,GAAG;AAAA,MAC7B,SAAS,cAAc,MAAM,EAAE;AAAA,MAC/B,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB,MAAM,OAAO,QAAQ,MAAM,OAAO,OAAO;AAE/D,MAAI;AACJ,MAAI;AACF,yBAAqB,MAAM,OAAO,QAAQ,MAAM,YAAY,OAAO;AACnE,UAAM,SAAS,QAAQ,UAAU,IAAI,eAAe;AACpD,UAAM,MAAM,eAAe,OAAO,eAAe,oBAAoB,OAAO;AAC5E,UAAM,WAAW,oBAAI,IAA6B;AAAA,MAChD,CAAC,UAAU,aAAa;AAAA,MACxB,CAAC,eAAe,kBAAkB;AAAA,IACpC,CAAC;AACD,UAAM,WAAW,+BAA+B;AAAA,MAC9C,gBAAgB,CAAC,EAAE,KAAK,MAAM,SAAS,IAAI,IAAI;AAAA,IACjD,CAAC;AAED,WAAO,MAAM,OAAO,QAAQ,KAAK,UAAU,oBAAoB,OAAO,CAAC;AAAA,EACzE,UAAE;AACA,QAAI,uBAAuB,QAAW;AACpC,YAAM,mBAAmB,WAAW;AAAA,IACtC;AACA,UAAM,cAAc,WAAW;AAAA,EACjC;AACF;AAEA,SAAS,eACP,OACA,eACA,oBACA,SACa;AACb,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,SAA2B;AAAA,IAC/B,MAAM,MAAM,OAAO;AAAA,IACnB,UAAU,cAAc;AAAA,EAC1B;AACA,QAAM,cAAgC;AAAA,IACpC,MAAM,MAAM,YAAY;AAAA,IACxB,UAAU,mBAAmB;AAAA,EAC/B;AAEA,QAAM,eAAwC,EAAE,SAAS,MAAM,GAAG;AAClE,MAAI,MAAM,SAAS,OAAW,cAAa,WAAW,IAAI,MAAM;AAChE,MAAI,MAAM,aAAa,OAAW,QAAO,OAAO,cAAc,MAAM,QAAQ;AAC5E,MAAI,QAAQ,aAAa,OAAW,QAAO,OAAO,cAAc,QAAQ,QAAQ;AAEhF,QAAM,MAAmB;AAAA,IACvB;AAAA,IACA,IAAI,QAAQ,SAAS,aAAa,OAAO,QAAQ,GAAG;AAAA,IACpD;AAAA,IACA;AAAA,EACF;AAEA,MAAI,OAAO,KAAK,YAAY,EAAE,SAAS,GAAG;AACxC,QAAI,WAAW;AAAA,EACjB;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,OAAiB,KAAuC;AAC5E,QAAM,aAAa,MAAM,KAAK,oBAAI,KAAK,GAAG,QAAQ;AAClD,SAAO,SAAS,MAAM,EAAE,IAAI,UAAU,SAAS,EAAE,CAAC;AACpD;AAEA,SAAS,oBAAoB,SAAwD;AACnF,QAAM,UAAwC,CAAC;AAC/C,MAAI,QAAQ,WAAW,OAAW,SAAQ,SAAS,QAAQ;AAC3D,MAAI,QAAQ,UAAU,OAAW,SAAQ,QAAQ,QAAQ;AACzD,MAAI,QAAQ,eAAe,OAAW,SAAQ,aAAa,QAAQ;AACnE,MAAI,QAAQ,YAAY,OAAW,SAAQ,UAAU,QAAQ;AAC7D,MAAI,QAAQ,mBAAmB,OAAW,SAAQ,iBAAiB,QAAQ;AAC3E,SAAO;AACT;;;AL/GA,IAAM,gBAAmC,EAAE,MAAM,SAAS,UAAU,QAAQ;AA+CrE,SAAS,WAAW,SAAsD;AAC/E,QAAM,EAAE,QAAQ,aAAa,WAAW,SAAS,WAAW,GAAG,KAAK,IAAI;AACxE,QAAM,QAAQ,WAAW;AAAA,IACvB,aAAa,EAAE,MAAM,YAAY,MAAM,SAAS,YAAY,QAAQ;AAAA,IACpE,IAAI,WAAW,UAAU,mBAAmB,WAAW,YAAY,IAAI,CAAC;AAAA,IACxE,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,EAAE,MAAM,aAAa,SAAS,GAAG,SAAS,cAAc;AAAA,EAClE,CAAC;AACD,SAAO,SAAS,EAAE,QAAQ,OAAO,GAAG,KAAK,CAAC;AAC5C;AA6CO,SAAS,aAAa,SAAwD;AACnF,QAAM,EAAE,QAAQ,WAAW,SAAS,WAAW,QAAQ,GAAG,KAAK,IAAI;AACnE,QAAM,QAAQ,WAAW;AAAA,IACvB,aAAa,EAAE,MAAM,aAAa,SAAS,GAAG,SAAS,cAAc;AAAA,IACrE,IAAI,WAAW,YAAY,mBAAmB,OAAO,MAAM,SAAS,CAAC;AAAA,IACrE,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,EAAE,MAAM,OAAO,MAAM,SAAS,OAAO,QAAQ;AAAA,EACvD,CAAC;AACD,SAAO,SAAS,EAAE,QAAQ,OAAO,GAAG,KAAK,CAAC;AAC5C;AAgDO,SAAS,YAAY,SAAuD;AACjF,QAAM,EAAE,QAAQ,aAAa,SAAS,WAAW,QAAQ,GAAG,KAAK,IAAI;AACrE,QAAM,QAAQ,WAAW;AAAA,IACvB,aAAa,EAAE,MAAM,YAAY,MAAM,SAAS,YAAY,QAAQ;AAAA,IACpE,IAAI,WAAW,QAAQ,mBAAmB,OAAO,MAAM,YAAY,IAAI,CAAC;AAAA,IACxE,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,EAAE,MAAM,OAAO,MAAM,SAAS,OAAO,QAAQ;AAAA,EACvD,CAAC;AACD,SAAO,SAAS,EAAE,QAAQ,OAAO,GAAG,KAAK,CAAC;AAC5C;AAUA,SAAS,WAAW,OAAkC;AACpD,QAAM,QAAkB;AAAA,IACtB,aAAa,MAAM;AAAA,IACnB,IAAI,MAAM;AAAA,IACV,WAAW,MAAM;AAAA,IACjB,QAAQ,MAAM;AAAA,EAChB;AACA,MAAI,MAAM,SAAS,OAAW,OAAM,OAAO,MAAM;AACjD,SAAO;AACT;AAEA,SAAS,aAAa,WAA2B;AAC/C,SAAO,WAAW,SAAS,IAAI,YAAY,YAAY,SAAS;AAClE;AAEA,SAAS,mBAAmB,QAAgB,aAA6B;AACvE,SAAO,GAAG,MAAM,KAAK,WAAW;AAClC;;;AM/NO,IAAM,WAAW;AAExB,IAAM,wBAAwB;AAC9B,IAAM,yBAAyB;AAQxB,SAAS,eAAe,KAAsB;AACnD,SAAO,sBAAsB,KAAK,IAAI,QAAQ,SAAS,EAAE,CAAC;AAC5D;AAQO,SAAS,cAAc,SAAyB;AACrD,SAAO,QAAQ,QAAQ,wBAAwB,CAAC,YAAY,gBAAwB;AAClF,WAAO,GAAG,YAAY,YAAY,CAAC,IAAI,QAAQ;AAAA,EACjD,CAAC;AACH;AAQO,SAAS,YAAY,OAAyB;AACnD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,cAAc,KAAK;AAAA,EAC5B;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,YAAY,IAAI,CAAC;AAAA,EAC9C;AAEA,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,WAAO,aAAa,KAAgC;AAAA,EACtD;AAEA,SAAO;AACT;AAQO,SAAS,aAAa,OAAyD;AACpF,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAC1C,UAAI,eAAe,GAAG,GAAG;AACvB,eAAO,CAAC,KAAK,QAAQ;AAAA,MACvB;AAEA,aAAO,CAAC,KAAK,YAAY,KAAK,CAAC;AAAA,IACjC,CAAC;AAAA,EACH;AACF;;;ACrEA,SAAS,UAAAE,eAAc;AACvB,SAAS,gBAAgB;AA6DzB,eAAsB,cACpB,QACA,UAAgC,CAAC,GACX;AACtB,MAAI,cAAc,MAAM,GAAG;AACzB,WAAO,iBAAiB,MAAM;AAAA,EAChC;AAEA,MAAI,OAAO,WAAW,YAAY;AAChC,WAAO,iBAAiB,MAAM,OAAO,CAAC;AAAA,EACxC;AAEA,MAAI,oBAAoB,MAAM,GAAG;AAC/B,WAAO,iBAAiB,OAAO,KAAK;AAAA,EACtC;AAEA,MAAI,kBAAkB,MAAM,GAAG;AAC7B,UAAM,SAAS,QAAQ,OAAO,QAAQ,KAAK,OAAO,GAAG;AAErD,QAAI,UAAU,QAAW;AACvB,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,wBAAwB,MAAM,GAAG;AACnC,UAAM,SAAS,QAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS;AAE3D,QAAI,UAAU,QAAW;AACvB,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAOC,QAAO,KAAK,OAAO,QAAQ;AAAA,EACpC;AAEA,MAAI,mBAAmB,MAAM,GAAG;AAC9B,UAAM,aAAa,QAAQ,YAAY;AACvC,UAAM,QAAQ,MAAM,WAAW,OAAO,IAAI;AAE1C,QAAI,OAAO,aAAa,UAAU;AAChC,aAAOA,QAAO,KAAK,KAAK;AAAA,IAC1B;AAEA,WAAO,MAAM,SAAS,OAAO,YAAY,MAAM;AAAA,EACjD;AAEA,QAAM,+BAA+B,6BAA6B,UAAU,SAAS;AACvF;AAQO,SAAS,mBAAmB,QAA6C;AAC9E,MAAI,cAAc,MAAM,KAAK,OAAO,WAAW,YAAY;AACzD,WAAO;AAAA,EACT;AAEA,MAAI,oBAAoB,MAAM,EAAG,QAAO,EAAE,OAAO,SAAS;AAC1D,MAAI,kBAAkB,MAAM,EAAG,QAAO,EAAE,KAAK,SAAS;AACtD,MAAI,wBAAwB,MAAM,EAAG,QAAO,EAAE,WAAW,SAAS;AAClE,MAAI,mBAAmB,MAAM,EAAG,QAAO,EAAE,UAAU,OAAO,UAAU,MAAM,SAAS;AAEnF,SAAO;AACT;AAEA,SAAS,cAAc,OAAsC;AAC3D,SAAO,OAAO,UAAU,YAAYA,QAAO,SAAS,KAAK;AAC3D;AAEA,SAAS,oBAAoB,OAA4C;AACvE,SAAO,SAAS,KAAK,KAAK,WAAW,SAAS,cAAc,MAAM,KAAK;AACzE;AAEA,SAAS,kBAAkB,OAA0C;AACnE,SAAO,SAAS,KAAK,KAAK,OAAO,MAAM,QAAQ;AACjD;AAEA,SAAS,wBAAwB,OAAgD;AAC/E,SAAO,SAAS,KAAK,KAAK,OAAO,MAAM,cAAc;AACvD;AAEA,SAAS,mBAAmB,OAA2C;AACrE,SAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AAClD;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,iBAAiB,OAAiC;AACzD,SAAOA,QAAO,SAAS,KAAK,IAAIA,QAAO,KAAK,KAAK,IAAI;AACvD;AAEA,SAAS,+BACP,SACA,YACA,YACoB;AACpB,SAAO,IAAI,mBAAmB;AAAA,IAC5B,SAAS,EAAE,YAAY,WAAW;AAAA,IAClC;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACH;;;ACvKO,SAAS,wBAAwB,SAAqD;AAC3F,QAAM,EAAE,QAAQ,UAAU,QAAQ,KAAK,KAAK,UAAU,GAAG,KAAK,IAAI;AAClE,QAAM,WAAW,aAAa,IAAI;AAElC,MAAI,aAAa,OAAW,UAAS,WAAW,mBAAmB,QAAQ;AAC3E,MAAI,aAAa,OAAW,UAAS,WAAW,mBAAmB,QAAQ;AAC3E,MAAI,QAAQ,OAAW,UAAS,MAAM,iBAAiB,GAAG;AAC1D,MAAI,QAAQ,OAAW,UAAS,MAAM,iBAAiB,GAAG;AAC1D,MAAI,WAAW,OAAW,UAAS,SAAS;AAC5C,MAAI,WAAW,OAAW,UAAS,SAAS;AAE5C,SAAO;AACT;AAQA,SAAS,iBAAiB,SAA8C;AACtE,QAAM,EAAE,OAAO,qBAAqB,YAAY,YAAY,YAAY,eAAe,GAAG,KAAK,IAC7F;AACF,QAAM,WAAW,aAAa,IAAI;AAElC,MAAI,UAAU,OAAW,UAAS,QAAQ;AAC1C,MAAI,eAAe,OAAW,UAAS,aAAa,mBAAmB,UAAU;AACjF,MAAI,eAAe,OAAW,UAAS,aAAa,mBAAmB,UAAU;AACjF,MAAI,eAAe,OAAW,UAAS,aAAa,0BAA0B,UAAU;AACxF,MAAI,wBAAwB,OAAW,UAAS,sBAAsB;AACtE,MAAI,kBAAkB,OAAW,UAAS,gBAAgB;AAE1D,SAAO;AACT;AAQA,SAAS,0BAA0B,QAAwD;AACzF,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,OAAO,IAAI,CAAC,SAAS,mBAAmB,IAAI,CAAC;AAAA,EACtD;AAEA,SAAO,mBAAmB,MAAM;AAClC;AAQA,SAAS,iBAAiB,SAA8C;AACtE,QAAM,EAAE,IAAI,MAAM,qBAAqB,KAAK,YAAY,KAAK,GAAG,KAAK,IAAI;AACzE,QAAM,WAAW,aAAa,IAAI;AAElC,MAAI,OAAO,OAAW,UAAS,KAAK,sBAAsB,EAAE;AAC5D,MAAI,SAAS,OAAW,UAAS,OAAO,mBAAmB,IAAI;AAC/D,MAAI,QAAQ,OAAW,UAAS,MAAM,mBAAmB,GAAG;AAC5D,MAAI,eAAe,OAAW,UAAS,aAAa,mBAAmB,UAAU;AACjF,MAAI,QAAQ,OAAW,UAAS,MAAM,mBAAmB,GAAG;AAC5D,MAAI,wBAAwB,OAAW,UAAS,sBAAsB;AAEtE,SAAO;AACT;AAQA,SAAS,sBAAsB,QAAkC;AAC/D,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,OAAO,IAAI,CAAC,SAAS,mBAAmB,IAAI,CAAC;AAAA,EACtD;AAEA,SAAO,mBAAmB,MAAM;AAClC;;;ACrEO,SAAS,2BAA2B,QAA2C;AACpF,QAAM,eAAe,OAAO,gBAAgB;AAC5C,SAAO;AAAA,IACL,WAAW,aAAa,IAAI,CAAC,WAAW,EAAE,cAAc,OAAO,IAAI,MAAM,SAAS,EAAE;AAAA,EACtF;AACF;AAsDA,eAAsB,yBACpB,SACsC;AACtC,QAAM,MAAM,QAAQ,QAAQ,MAAM,YAAY,IAAI;AAClD,QAAM,YAAY,QAAQ,cAAc;AACxC,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,aAAa,KAAK,IAAI,GAAG,QAAQ,cAAc,CAAC;AACtD,QAAM,kBAAkB,wBAAwB,QAAQ,OAAO;AAE/D,QAAM,SAAsC;AAAA,IAC1C,MAAM,QAAQ,QAAQ;AAAA,IACtB,IAAI;AAAA,IACJ;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,OAAO,QAAQ,QAAQ,OAAO;AAC5D,WAAO,QAAQ,YAAY,IAAI,IAAI;AACnC,WAAO,WAAW,QAAQ;AAC1B,WAAO,eAAe,QAAQ;AAC9B,QAAI;AACF,UAAI,WAAW;AACb,cAAM,YAAY,IAAI;AACtB,cAAM,UAAU,MAAM,QAAQ,GAAG,KAAK,QAAQ;AAC9C,eAAO,QAAQ,SAAS,IAAI,IAAI;AAChC,eAAO,SAAS,QAAQ,MAAM,GAAG,UAAU;AAAA,MAC7C;AACA,aAAO,KAAK;AAAA,IACd,UAAE;AACA,YAAM,kBAAkB,IAAI;AAC5B,YAAM,QAAQ,WAAW;AACzB,aAAO,QAAQ,eAAe,IAAI,IAAI;AAAA,IACxC;AAAA,EACF,SAAS,OAAO;AACd,WAAO,QAAQ,yBAAyB,KAAK;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,OAIhC;AACA,MAAI,iBAAiB,OAAO;AAC1B,UAAM,UAA6D,EAAE,SAAS,MAAM,QAAQ;AAC5F,QAAI,MAAM,SAAS,QAAS,SAAQ,OAAO,MAAM;AACjD,UAAM,OAAQ,MAA6B;AAC3C,QAAI,OAAO,SAAS,SAAU,SAAQ,OAAO;AAC7C,WAAO;AAAA,EACT;AACA,SAAO,EAAE,SAAS,OAAO,KAAK,EAAE;AAClC;;;ACxIA,SAAS,UAAAC,eAAc;AACvB,SAAS,kBAAkB,YAAyB;AACpD;AAAA,EACE,WAAW;AAAA,OAIN;;;ACiDP,eAAsB,gCACpB,SACA,UAAgC,CAAC,GACG;AACpC,QAAM,EAAE,UAAU,KAAK,KAAK,UAAU,GAAG,KAAK,IAAI;AAClD,QAAM,WAAsC,EAAE,GAAG,KAAK;AAEtD,MAAI,aAAa,QAAW;AAC1B,aAAS,WAAW,MAAM,cAAc,UAAU,OAAO;AAAA,EAC3D;AAEA,MAAI,aAAa,QAAW;AAC1B,aAAS,WAAW,MAAM,cAAc,UAAU,OAAO;AAAA,EAC3D;AAEA,MAAI,QAAQ,QAAW;AACrB,aAAS,MAAM,MAAM,kBAAkB,KAAK,OAAO;AAAA,EACrD;AAEA,MAAI,QAAQ,QAAW;AACrB,aAAS,MAAM,MAAM,kBAAkB,KAAK,OAAO;AAAA,EACrD;AAEA,SAAO;AACT;AASA,eAAe,kBACb,SACA,SAC6B;AAC7B,QAAM,EAAE,YAAY,YAAY,YAAY,GAAG,KAAK,IAAI;AACxD,QAAM,WAA+B,EAAE,GAAG,KAAK;AAE/C,MAAI,eAAe,OAAW,UAAS,aAAa,MAAM,cAAc,YAAY,OAAO;AAC3F,MAAI,eAAe,OAAW,UAAS,aAAa,MAAM,cAAc,YAAY,OAAO;AAC3F,MAAI,eAAe;AACjB,aAAS,aAAa,MAAM,wBAAwB,YAAY,OAAO;AAEzE,SAAO;AACT;AASA,eAAe,wBACb,QACA,SACsC;AACtC,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,QAAQ,IAAI,OAAO,IAAI,CAAC,SAAS,cAAc,MAAM,OAAO,CAAC,CAAC;AAAA,EACvE;AAEA,SAAO,cAAc,QAAQ,OAAO;AACtC;AASA,eAAe,kBACb,SACA,SAC6B;AAC7B,QAAM,EAAE,IAAI,MAAM,KAAK,YAAY,KAAK,GAAG,KAAK,IAAI;AACpD,QAAM,WAA+B,EAAE,GAAG,KAAK;AAE/C,MAAI,OAAO,OAAW,UAAS,KAAK,MAAM,uBAAuB,IAAI,OAAO;AAC5E,MAAI,SAAS,OAAW,UAAS,OAAO,MAAM,cAAc,MAAM,OAAO;AACzE,MAAI,QAAQ,OAAW,UAAS,MAAM,MAAM,cAAc,KAAK,OAAO;AACtE,MAAI,eAAe,OAAW,UAAS,aAAa,MAAM,cAAc,YAAY,OAAO;AAC3F,MAAI,QAAQ,OAAW,UAAS,MAAM,MAAM,cAAc,KAAK,OAAO;AAEtE,SAAO;AACT;AASA,eAAe,uBACb,QACA,SACsC;AACtC,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,QAAQ,IAAI,OAAO,IAAI,CAAC,SAAS,cAAc,MAAM,OAAO,CAAC,CAAC;AAAA,EACvE;AAEA,SAAO,cAAc,QAAQ,OAAO;AACtC;;;AC3JA,IAAM,8BAA8B;AAU7B,SAAS,sBAAsB,OAAe,QAAQ,QAAgB;AAC3E,MAAI,4BAA4B,KAAK,KAAK,GAAG;AAC3C,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,cAAc,KAAK;AAAA,MAC5B,WAAW;AAAA,MACX,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AASO,SAAS,oBAAoB,OAAuB;AACzD,wBAAsB,KAAK;AAE3B,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,QAAMC,cAAa,MAAM,WAAW,GAAG;AACvC,QAAM,WAAqB,CAAC;AAE5B,aAAW,WAAW,MAAM,MAAM,QAAQ,GAAG;AAC3C,QAAI,QAAQ,WAAW,KAAK,YAAY,KAAK;AAC3C;AAAA,IACF;AAEA,QAAI,YAAY,MAAM;AACpB,UAAI,SAAS,SAAS,KAAK,SAAS,SAAS,SAAS,CAAC,MAAM,MAAM;AACjE,iBAAS,IAAI;AAAA,MACf,WAAW,CAACA,aAAY;AACtB,iBAAS,KAAK,OAAO;AAAA,MACvB;AACA;AAAA,IACF;AAEA,aAAS,KAAK,OAAO;AAAA,EACvB;AAEA,QAAM,aAAa,SAAS,KAAK,GAAG;AAEpC,MAAIA,aAAY;AACd,WAAO,WAAW,SAAS,IAAI,IAAI,UAAU,KAAK;AAAA,EACpD;AAEA,SAAO,WAAW,SAAS,IAAI,aAAa;AAC9C;AASO,SAAS,kBAAkB,UAA4B;AAC5D,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,SAAS,KAAK,GAAG,CAAC;AAC/C;AASO,SAAS,mBAAmB,OAAuB;AACxD,QAAM,aAAa,oBAAoB,KAAK;AAC5C,QAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,SAAO,MAAM,MAAM,SAAS,CAAC,KAAK;AACpC;;;AC3FA,IAAM,mBAAmB,IAAI;AAAA,EAC3B,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE;AAAA,IACnF,CAAC,OAAO,UAAU,CAAC,OAAO,KAAK;AAAA,EACjC;AACF;AAUO,SAAS,cAAc,OAAe,YAAY,KAAoB;AAC3E,SAAO,MACJ,MAAM,OAAO,EACb,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,EAC5B,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,IAAI,CAAC,SAAS,cAAc,MAAM,SAAS,CAAC,EAC5C,OAAO,CAAC,UAAU,MAAM,SAAS,OAAO,MAAM,SAAS,IAAI;AAChE;AAcO,SAAS,cAAc,OAAe,YAAY,KAAK,MAAM,oBAAI,KAAK,GAAkB;AAC7F,SAAO,MACJ,MAAM,OAAO,EACb,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,EAC5B,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,CAAC,KAAK,YAAY,EAAE,WAAW,QAAQ,CAAC,EAC5E,IAAI,CAAC,SAAS,kBAAkB,MAAM,WAAW,GAAG,CAAC,EACrD,OAAO,CAAC,UAAU,MAAM,SAAS,OAAO,MAAM,SAAS,IAAI;AAChE;AAWO,SAAS,kBAAkB,MAAc,YAAY,KAAK,MAAM,oBAAI,KAAK,GAAgB;AAC9F,QAAM,QACJ,sGAAsG;AAAA,IACpG;AAAA,EACF;AAEF,MAAI,UAAU,MAAM;AAClB,UAAM,IAAI,WAAW;AAAA,MACnB,SAAS,EAAE,KAAK;AAAA,MAChB,SAAS,6BAA6B,IAAI;AAAA,MAC1C,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,CAAC,EAAE,OAAO,IAAI,OAAO,OAAO,UAAU,WAAW,SAAS,YAAY,OAAO,IAAI;AACvF,QAAM,EAAE,MAAM,cAAc,IAAI,kBAAkB,SAAS,IAAI;AAC/D,QAAM,QAAqB;AAAA,IACzB;AAAA,IACA,MAAM,eAAe,WAAW,IAAI;AAAA,IACpC,aAAa,EAAE,KAAK,KAAK;AAAA,IACzB,KAAK,EAAE,KAAK;AAAA,IACZ,MAAM,gBAAgB,IAAI;AAAA,EAC5B;AACA,QAAM,aAAa,uBAAuB,WAAW,SAAS,YAAY,GAAG;AAE7E,MAAI,UAAU,OAAW,OAAM,QAAQ;AACvC,MAAI,UAAU,OAAW,OAAM,QAAQ;AACvC,MAAI,aAAa,OAAW,OAAM,OAAO,OAAO,QAAQ;AACxD,MAAI,eAAe,OAAW,OAAM,aAAa;AACjD,MAAI,kBAAkB,OAAW,OAAM,gBAAgB;AAEvD,SAAO;AACT;AAUO,SAAS,cAAc,MAAc,YAAY,KAAkB;AACxE,QAAM,iBAAiB,KAAK,QAAQ,GAAG;AAEvC,MAAI,kBAAkB,KAAK,mBAAmB,KAAK,SAAS,GAAG;AAC7D,UAAM,IAAI,WAAW;AAAA,MACnB,SAAS,wBAAwB,IAAI;AAAA,MACrC,WAAW;AAAA,MACX,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,KAAK,MAAM,GAAG,cAAc;AAC7C,QAAM,OAAO,KAAK,MAAM,iBAAiB,CAAC;AAC1C,QAAM,QAAQ,WAAW,QAAQ;AACjC,QAAM,OAAO,YAAY,MAAM,IAAI,MAAM,CAAC;AAC1C,QAAM,aAAa,mBAAmB,MAAM,IAAI,QAAQ,CAAC;AACzD,QAAM,WAAW,MAAM,IAAI,MAAM;AACjC,QAAM,cAAc,MAAM,IAAI,MAAM;AACpC,QAAM,WAAW,MAAM,IAAI,QAAQ;AAEnC,QAAM,QAAqB;AAAA,IACzB;AAAA,IACA,MAAM,eAAe,WAAW,IAAI;AAAA,IACpC,KAAK;AAAA,MACH,OAAO,OAAO,YAAY,KAAK;AAAA,MAC/B;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,MAAI,aAAa,OAAW,OAAM,OAAO,OAAO,QAAQ;AACxD,MAAI,eAAe,OAAW,OAAM,aAAa;AACjD,MAAI,gBAAgB,OAAW,OAAM,cAAc,EAAE,KAAK,YAAY;AACtE,MAAI,aAAa,OAAW,OAAM,WAAW;AAE7C,SAAO;AACT;AAQO,SAAS,mBAAmB,OAA6C;AAC9E,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,+DAA+D,KAAK,KAAK;AAEhG,MAAI,mBAAmB,MAAM;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,EAAE,MAAM,OAAO,KAAK,MAAM,QAAQ,QAAQ,cAAc,GAAG,IAAI;AACtE,QAAM,wBAAwB,YAAY,OAAO,GAAG,GAAG;AAEvD,SAAO,IAAI;AAAA,IACT,KAAK;AAAA,MACH,OAAO,IAAI;AAAA,MACX,OAAO,KAAK,IAAI;AAAA,MAChB,OAAO,GAAG;AAAA,MACV,OAAO,IAAI;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,OAAO,qBAAqB;AAAA,IAC9B;AAAA,EACF;AACF;AAQA,SAAS,WAAW,OAAoC;AACtD,QAAM,QAAQ,oBAAI,IAAoB;AAEtC,aAAW,QAAQ,MAAM,MAAM,GAAG,GAAG;AACnC,QAAI,KAAK,WAAW,GAAG;AACrB;AAAA,IACF;AAEA,UAAM,iBAAiB,KAAK,QAAQ,GAAG;AAEvC,QAAI,kBAAkB,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,IAAI,KAAK,MAAM,GAAG,cAAc,EAAE,YAAY,GAAG,KAAK,MAAM,iBAAiB,CAAC,CAAC;AAAA,EACvF;AAEA,SAAO;AACT;AAQA,SAAS,YAAY,OAA4C;AAC/D,UAAQ,OAAO,YAAY,GAAG;AAAA,IAC5B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAQA,SAAS,gBAAgB,MAA+B;AACtD,UAAQ,KAAK,CAAC,GAAG;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAWA,SAAS,uBACP,WACA,SACA,YACA,KACkB;AAClB,MAAI,cAAc,UAAa,YAAY,UAAa,eAAe,QAAW;AAChF,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,iBAAiB,IAAI,UAAU,YAAY,CAAC;AAC1D,QAAM,MAAM,OAAO,OAAO;AAE1B,MAAI,UAAU,UAAa,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,KAAK,MAAM,IAAI;AACxE,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,KAAK,UAAU,GAAG;AAC9B,WAAO,IAAI,KAAK,KAAK,IAAI,OAAO,UAAU,GAAG,OAAO,GAAG,CAAC;AAAA,EAC1D;AAEA,QAAM,YAAY,sBAAsB,KAAK,UAAU;AAEvD,MAAI,cAAc,MAAM;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,EAAE,UAAU,UAAU,IAAI;AACjC,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,SAAS,OAAO,UAAU;AAEhC,MAAI,OAAO,MAAM,SAAS,IAAI;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,IAAI,KAAK,KAAK,IAAI,IAAI,eAAe,GAAG,OAAO,KAAK,MAAM,MAAM,CAAC;AAC1E;AASA,SAAS,kBACP,SACA,MAIA;AACA,QAAM,OAAO,WAAW;AAExB,MAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,WAAO,EAAE,KAAK;AAAA,EAChB;AAEA,QAAM,YAAY;AAClB,QAAM,iBAAiB,KAAK,QAAQ,SAAS;AAE7C,MAAI,iBAAiB,GAAG;AACtB,WAAO,EAAE,KAAK;AAAA,EAChB;AAEA,SAAO;AAAA,IACL,MAAM,KAAK,MAAM,GAAG,cAAc;AAAA,IAClC,eAAe,KAAK,MAAM,iBAAiB,UAAU,MAAM;AAAA,EAC7D;AACF;;;ACjRA,IAAM,mBAAmB;AAKlB,IAAM,oBAAN,MAAwB;AAAA,EACrB,SAAS;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASR,KAAK,OAAuC;AAC1C,SAAK,UAAU,MAAM,SAAS;AAC9B,UAAM,WAAW,KAAK,OAAO,MAAM,OAAO;AAC1C,SAAK,SAAS,SAAS,IAAI,KAAK;AAEhC,UAAM,YAA2B,CAAC;AAElC,eAAW,WAAW,UAAU;AAC9B,YAAM,WAAW,KAAK,YAAY,OAAO;AAEzC,UAAI,aAAa,QAAW;AAC1B,kBAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAc;AACZ,SAAK,SAAS;AACd,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,qBAA8B;AAC5B,WAAO,KAAK,oBAAoB,UAAa,KAAK,OAAO,SAAS;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,YAAY,SAA0C;AAC5D,UAAM,YAAY,iBAAiB,KAAK,OAAO;AAE/C,QAAI,cAAc,MAAM;AACtB,UAAI,KAAK,oBAAoB,QAAW;AACtC,aAAK,gBAAgB,MAAM,KAAK,OAAO;AACvC,aAAK,gBAAgB,SAAS,KAAK,OAAO;AAC1C,eAAO;AAAA,MACT;AAEA,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO;AAAA,MACT;AAEA,YAAM,IAAI,WAAW;AAAA,QACnB,SAAS,gCAAgC,OAAO;AAAA,QAChD,WAAW;AAAA,QACX,SAAS;AAAA,UACP;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,OAAO,UAAU,CAAC,CAAE;AACjC,UAAM,YAAY,UAAU,CAAC;AAC7B,UAAM,UAAU,UAAU,CAAC;AAE3B,QAAI,KAAK,oBAAoB,QAAW;AACtC,WAAK,gBAAgB,MAAM,KAAK,mBAAmB,SAAS,KAAK,gBAAgB,IAAI,CAAC;AACtF,WAAK,gBAAgB,SAAS,KAAK,OAAO;AAE1C,UAAI,SAAS,KAAK,gBAAgB,QAAQ,cAAc,KAAK;AAC3D,cAAM,YAAY,KAAK;AACvB,aAAK,kBAAkB;AACvB,eAAO,cAAc,UAAU,MAAM,UAAU,OAAO,UAAU,QAAQ;AAAA,MAC1E;AAEA,aAAO;AAAA,IACT;AAEA,QAAI,cAAc,KAAK;AACrB,WAAK,kBAAkB;AAAA,QACrB;AAAA,QACA,OAAO,CAAC,OAAO;AAAA,QACf,UAAU,CAAC,OAAO;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AAEA,WAAO,cAAc,MAAM,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC;AAAA,EACjD;AACF;AAkCA,SAAS,cAAc,MAAc,OAAiB,UAAiC;AACrF,QAAM,SAAS,eAAe,IAAI;AAElC,SAAO;AAAA,IACL;AAAA,IACA,SAAS,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,IACA,KAAK,SAAS,KAAK,IAAI;AAAA,IACvB;AAAA,IACA,aAAa,WAAW;AAAA,IACxB,YAAY,WAAW;AAAA,IACvB,cAAc,WAAW;AAAA,IACzB,kBAAkB,WAAW;AAAA,IAC7B,kBAAkB,WAAW;AAAA,EAC/B;AACF;AAQA,SAAS,eAAe,MAAiC;AACvD,MAAI,QAAQ,OAAO,OAAO,IAAK,QAAO;AACtC,MAAI,QAAQ,OAAO,OAAO,IAAK,QAAO;AACtC,MAAI,QAAQ,OAAO,OAAO,IAAK,QAAO;AACtC,MAAI,QAAQ,OAAO,OAAO,IAAK,QAAO;AACtC,SAAO;AACT;AASA,SAAS,mBAAmB,SAAiB,MAAsB;AACjE,QAAM,WAAW,OAAO,IAAI;AAE5B,MAAI,QAAQ,WAAW,GAAG,QAAQ,GAAG,KAAK,QAAQ,WAAW,GAAG,QAAQ,GAAG,GAAG;AAC5E,WAAO,QAAQ,MAAM,CAAC;AAAA,EACxB;AAEA,SAAO;AACT;;;AJ1LA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,6BAA6B;AACnC,IAAM,gCAAwD;AAE9D,IAAM,4BAA4B,6BAA6B,iBAAiB;AAAA,EAC9E;AACF,CAAC;AAED,IAAM,6BAA6B,6BAA6B,kBAAkB;AAAA,EAChF;AACF,CAAC;AASD,SAAS,6BAA6B,UAA6B,OAAgC;AACjG,SAAO;AAAA,IACL;AAAA,IACA,gBACE,aAAa,mBACT,CAAC,aAAa,YAAY,oBAAoB,IAC9C,CAAC,aAAa,UAAU;AAAA,IAC9B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,UAAU,CAAC;AAAA,IACX,cAAc;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA,IACT,UAAU,CAAC,cAAc,eAAe,UAAU;AAAA,IAClD,gBAAgB;AAAA,IAChB;AAAA,EACF;AACF;AAqFO,SAAS,yBAAyB,UAA8B,CAAC,GAAoB;AAC1F,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ,MACN,IAAI,YAAY;AAAA,MACd,cAAc;AAAA,MACd,aAAa,QAAQ,eAAe;AAAA,MACpC,qBAAqB,QAAQ,uBAAuB;AAAA,MACpD,YAAY;AAAA,IACd,CAAC;AAAA,EACL;AACF;AA0CO,SAAS,0BAA0B,UAA+B,CAAC,GAAoB;AAC5F,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,cACJ,QAAQ,gBAAgB,SAAS,aAAa,6BAA6B;AAE7E,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ,MACN,IAAI,YAAY;AAAA,MACd,cAAc;AAAA,MACd;AAAA,MACA,qBAAqB,QAAQ,uBAAuB;AAAA,MACpD,YAAY;AAAA,MACZ,UAAU;AAAA,QACR,gBAAgB,QAAQ,kBAAkB;AAAA,QAC1C;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACL;AACF;AAGA,IAAM,cAAN,MAA8C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW5C,YAA6B,QAAkC;AAAlC;AAC3B,SAAK,KAAK,OAAO;AACjB,SAAK,eAAe,OAAO;AAAA,EAC7B;AAAA,EAH6B;AAAA;AAAA,EATpB;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBT,MAAM,QAAQ,SAAsD;AAClE,UAAM,kBAAkB,MAAM,gCAAgC,OAAO;AACrE,UAAM,OAAO,gBAAgB,QAAQ,KAAK,OAAO;AACjD,UAAM,iBAAoC;AAAA,MACxC,MAAM,gBAAgB;AAAA,MACtB,qBAAqB,KAAK,OAAO;AAAA,MACjC;AAAA,MACA,YAAY,KAAK,OAAO;AAAA,IAC1B;AAEA,QAAI,KAAK,OAAO,aAAa,QAAW;AACtC,YAAM,uBAAuB,4BAA4B,eAAe;AAExE,qBAAe,WAAW;AAAA,QACxB,GAAG,KAAK,OAAO;AAAA,QACf,GAAI,yBAAyB,SAAY,CAAC,IAAI,EAAE,qBAAqB;AAAA,QACrE,YAAY,2BAA2B,eAAe;AAAA,MACxD;AAAA,IACF;AAEA,QAAI,gBAAgB,WAAW,QAAW;AACxC,qBAAe,SAAS,gBAAgB;AAAA,IAC1C;AAEA,QAAI,gBAAgB,cAAc,QAAW;AAC3C,qBAAe,YAAY,gBAAgB;AAAA,IAC7C;AAEA,UAAM,UAAU,MAAM,qBAAqB,QAAQ,cAAc;AAEjE,QAAI;AACF,YAAM;AAAA,QACJ;AAAA,QACA,gBAAgB,aAAa,SACzB,cACA,eAAe,gBAAgB,QAAQ;AAAA,QAC3C,gBAAgB,aAAa,SACzB,eACA,eAAe,gBAAgB,QAAQ;AAAA,QAC3C,gBAAgB;AAAA,MAClB;AACA,aAAO,IAAI,mBAAmB,SAAS,KAAK,YAAY;AAAA,IAC1D,SAAS,OAAO;AACd,cAAQ,MAAM;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAGA,IAAM,qBAAN,MAAoD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBlD,YACmB,SACjB,cACA;AAFiB;AAGjB,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe;AACpB,SAAK,KAAK,IAAI,cAAc,OAAO;AACnC,SAAK,YAAY,IAAI,sBAAsB,OAAO;AAAA,EACpD;AAAA,EAPmB;AAAA;AAAA,EAfV;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAmBT,MAAM,aAA4B;AAChC,QAAI;AACF,YAAM,KAAK,QAAQ,YAAY,MAAM;AAAA,IACvC,QAAQ;AAAA,IAER,UAAE;AACA,WAAK,QAAQ,MAAM;AAAA,IACrB;AAAA,EACF;AACF;AAEA,IAAM,wBAAN,MAAkE;AAAA,EAChE,YAA6B,SAA+B;AAA/B;AAAA,EAAgC;AAAA,EAAhC;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,iBAAiB,QAAQ,SAAS,IAAI;AACzD,UAAM,QAAQ,iBAAiB,QAAQ,KAAK;AAE5C,UAAM,iBAAiB,KAAK,SAAS,UAAU,UAAU;AACzD,UAAM,iBAAiB,MAAM;AAAA,MAC3B,KAAK;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB;AAAA,MACA;AAAA,QACE,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,YAAQ,eAAe;AACvB,UAAM,SAAqC;AAAA,MACzC,SAAS;AAAA,QACP,KAAK;AAAA,QACL;AAAA,QACA,QAAQ,UAAU;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,QAAW;AAC9B,aAAO,aAAa,MAAM;AAAA,IAC5B;AAEA,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,YAAY,MAAM;AAAA,IAC3B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,UAAM,aAAa,iBAAiB,QAAQ,SAAS,IAAI;AACzD,UAAM,SAAS,2BAA2B,QAAQ,QAAQ,UAAU,UAAU;AAE9E,UAAM,iBAAiB,KAAK,SAAS,UAAU,UAAU;AACzD,UAAM,mBAAmB,MAAM;AAAA,MAC7B,KAAK;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB;AAAA,MACA;AAAA,MACA,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACvC;AAEA,UAAM,SAAsC;AAAA,MAC1C;AAAA,MACA,SAAS,WAAW,UAAa,SAAS;AAAA,MAC1C,YAAY,QAAQ,eAAe,UAAU,KAAK;AAAA,MAClD,UAAU,QAAQ,cAAc,YAAY;AAAA,IAC9C;AAEA,QAAI,QAAQ,iBAAiB,QAAW;AACtC,aAAO,eAAeC,mBAAkB,QAAQ,YAAY;AAAA,IAC9D;AAEA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,gBAAN,MAAgD;AAAA,EAC9C,YAA6B,SAA+B;AAA/B;AAAA,EAAgC;AAAA,EAAhC;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,iBAAiBA,KAAI;AACxC,UAAM,iBAAiB,KAAK,SAAS,UAAU,UAAU;AACzD,UAAM,UAAU,MAAM,qBAAqB,KAAK,SAAS,UAAU;AACnE,WAAO,QAAQ,KAAK,cAAc;AAAA,EACpC;AAAA,EAEA,MAAM,KAAKA,OAAmC;AAC5C,UAAM,aAAa,iBAAiBA,KAAI;AACxC,UAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,QAAQ,UAAU,EAAE;AACpE,+BAA2B,UAAU,QAAQ,YAAY,KAAK,QAAQ,UAAU;AAEhF,UAAM,WAAW,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,KAAK,aAAa;AAE7E,QAAI,aAAa,QAAW;AAC1B,YAAM;AAAA,QACJ;AAAA,QACA,GAAG,KAAK,QAAQ,WAAW,YAAY,CAAC;AAAA,QACxC;AAAA,QACA,KAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAEA,UAAM,QAAQ,cAAc,UAAU,cAAc,UAAU,KAAK,GAAG;AAEtE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,mBAAmB,UAAU;AAAA,MACnC,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAOA,OAAc,UAAyB,CAAC,GAAkB;AACrE,UAAM,aAAa,iBAAiBA,KAAI;AACxC,UAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,QAAQ,UAAU,EAAE;AACpE,QAAI,SAAS,WAAY;AACzB,QAAI,SAAS,SAAS,OAAO,QAAQ,cAAe;AACpD,+BAA2B,UAAU,QAAQ,YAAY,KAAK,QAAQ,UAAU;AAAA,EAClF;AAAA,EAEA,MAAM,OAAO,MAAc,IAA2B;AACpD,UAAM,WAAW,iBAAiB,IAAI;AACtC,UAAM,SAAS,iBAAiB,EAAE;AAClC,UAAM,OAAO,MAAM,KAAK,QAAQ,YAAY,QAAQ,QAAQ,EAAE;AAC9D,QAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,YAAY;AAC1C,iCAA2B,MAAM,QAAQ,UAAU,KAAK,QAAQ,UAAU;AAAA,IAC5E;AACA,UAAM,iBAAiB,KAAK,SAAS,QAAQ,MAAM,IAAI,MAAM;AAAA,EAC/D;AAAA,EAEA,MAAM,MAAMA,OAAc,UAAwB,CAAC,GAAkB;AACnE,UAAM,aAAa,iBAAiBA,KAAI;AACxC,QAAI,CAAC,QAAQ,WAAW;AACtB,YAAM,iBAAiB,KAAK,SAAS,OAAO,UAAU,IAAI,UAAU;AACpE;AAAA,IACF;AACA,UAAM,WAAW,WAAW,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AACjE,QAAI,UAAU;AACd,eAAW,WAAW,UAAU;AAC9B,gBAAU,GAAG,OAAO,IAAI,OAAO;AAC/B,YAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,OAAO,OAAO,EAAE;AAChE,UAAI,SAAS,WAAY;AAEzB,UAAI,SAAS,SAAS,IAAK;AAC3B,iCAA2B,UAAU,OAAO,SAAS,KAAK,QAAQ,UAAU;AAAA,IAC9E;AAAA,EACF;AAAA,EAEA,MAAM,MAAMA,OAAc,UAAwB,CAAC,GAAkB;AACnE,UAAM,aAAa,iBAAiBA,KAAI;AACxC,QAAI,QAAQ,WAAW;AACrB,YAAM,KAAK,yBAAyB,UAAU;AAC9C;AAAA,IACF;AACA,UAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,OAAO,UAAU,EAAE;AACnE,QAAI,SAAS,WAAY;AACzB,QAAI,SAAS,SAAS,OAAO,QAAQ,cAAe;AACpD,+BAA2B,UAAU,OAAO,YAAY,KAAK,QAAQ,UAAU;AAAA,EACjF;AAAA,EAEA,MAAc,yBAAyB,YAAmC;AACxE,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,qBAAqB,KAAK,SAAS,UAAU;AAAA,IAC/D,SAAS,OAAO;AAEd,UAAI,iBAAiB,kBAAmB;AACxC,YAAM;AAAA,IACR;AACA,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,SAAS,OAAO,MAAM,SAAS,KAAM;AAC/C,YAAM,YAAY,MAAM,KAAK,WAAW,GAAG,IACvC,MAAM,OACN,iBAAiB,GAAG,WAAW,QAAQ,QAAQ,EAAE,CAAC,IAAI,MAAM,IAAI,EAAE;AACtE,UAAI,MAAM,SAAS,aAAa;AAC9B,cAAM,KAAK,yBAAyB,SAAS;AAAA,MAC/C,OAAO;AACL,cAAM,MAAM,MAAM,KAAK,QAAQ,YAAY,QAAQ,SAAS,EAAE;AAC9D,YAAI,CAAC,IAAI,cAAc,IAAI,SAAS,KAAK;AACvC,qCAA2B,KAAK,QAAQ,WAAW,KAAK,QAAQ,UAAU;AAAA,QAC5E;AAAA,MACF;AAAA,IACF;AACA,UAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,OAAO,UAAU,EAAE;AACnE,QAAI,SAAS,WAAY;AACzB,QAAI,SAAS,SAAS,IAAK;AAC3B,+BAA2B,UAAU,OAAO,YAAY,KAAK,QAAQ,UAAU;AAAA,EACjF;AACF;AA+CA,IAAM,uBAAN,MAAM,sBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgCjB,YACN,QACiB,MACA,qBACR,YACQ,WACA,UACjB;AALiB;AACA;AACR;AACQ;AACA;AAEjB,SAAK,SAAS;AACd,SAAK,aAAa,MAAM;AAAA,EAC1B;AAAA,EARmB;AAAA,EACA;AAAA,EACR;AAAA,EACQ;AAAA,EACA;AAAA,EArCF,SAAS,IAAI,kBAAkB;AAAA,EAC/B,YAA2B,CAAC;AAAA,EAC5B,UAA4B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EAES,mBAAmB,CAAC,UAA2B,KAAK,WAAW,KAAK;AAAA,EACpE,oBAAoB,CAAC,UAAiB;AACrD,SAAK,YAAY,sBAAsB,KAAK,MAAM,OAAO,KAAK,UAAU,CAAC;AAAA,EAC3E;AAAA,EACiB,oBAAoB,MAAM;AACzC,SAAK;AAAA,MACH,IAAI,gBAAgB;AAAA,QAClB,MAAM,KAAK;AAAA,QACX,SAAS,GAAG,KAAK,WAAW,YAAY,CAAC;AAAA,QACzC,UAAU,KAAK;AAAA,QACf,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAyBA,IAAI,cAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,8BAAsD;AACxD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,qBAAyC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,kBAAkD;AACpD,WAAO,KAAK,UAAU,mBAAmB,YAAY,KAAK,WAAW;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,QAAQ,SAA2D;AAC9E,UAAM,SAAS,oBAAoB,OAAO;AAC1C,UAAM,UAAU,IAAI;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAEA,QAAI;AACF,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,QAAQ,UAAU,SAAS,aAAa,kBAAkB;AAAA,MAC5D;AAEA,UAAI,QAAQ,UAAU,SAAS,YAAY;AACzC,mCAA2B,QAAQ,QAAQ,UAAU,QAAQ,MAAM,QAAQ,UAAU;AAAA,MACvF;AAEA,YAAM,WAAW,MAAM,QAAQ,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAE1E,UAAI,CAAC,SAAS,YAAY;AACxB,cAAM;AAAA,UACJ;AAAA,UACA,GAAG,QAAQ,WAAW,YAAY,CAAC;AAAA,UACnC;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,UAAI,QAAQ,UAAU,SAAS,YAAY;AACzC,cAAM,sBAAsB,SAAS,QAAQ,QAAQ;AAAA,MACvD,WAAW,QAAQ,UAAU,SAAS,YAAY;AAChD,cAAM,wBAAwB,SAAS,QAAQ,QAAQ;AAAA,MACzD;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM;AACd,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,SAAuB;AAClC,SAAK,OAAO,MAAM,GAAG,OAAO;AAAA,CAAM;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YAAY,SAAuC;AACvD,SAAK,aAAa,OAAO;AACzB,WAAO,KAAK,kBAAkB,EAAE,SAAS,WAAW,mBAAmB,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,UAA6B,EAAE,WAAW,WAAW,GAC/B;AACtB,QAAI,WAAW,MAAM,KAAK,aAAa,OAAO;AAE9C,WAAO,SAAS,aAAa;AAC3B,iBAAW,MAAM,KAAK,aAAa,OAAO;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,UAA6B,EAAE,WAAW,WAAW,GAAyB;AACzF,UAAM,WAAW,KAAK,UAAU,MAAM;AAEtC,QAAI,aAAa,QAAW;AAC1B,aAAO,QAAQ,QAAQ,QAAQ;AAAA,IACjC;AAEA,QAAI,KAAK,gBAAgB,QAAW;AAClC,aAAO,QAAQ,OAAO,KAAK,WAAW;AAAA,IACxC;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI;AACJ,YAAM,qBAAqB,MAAM;AAC/B,YAAI,YAAY,QAAW;AACzB,uBAAa,OAAO;AAAA,QACtB;AAAA,MACF;AACA,YAAM,SAAyB;AAAA,QAC7B,OAAO,OAAO;AACZ,6BAAmB;AACnB,iBAAO,KAAK;AAAA,QACd;AAAA,QACA,QAAQC,WAAU;AAChB,6BAAmB;AACnB,kBAAQA,SAAQ;AAAA,QAClB;AAAA,MACF;AAEA,WAAK,QAAQ,KAAK,MAAM;AAExB,YAAM,YAAY,KAAK;AAEvB,UAAI,cAAc,QAAW;AAC3B,kBAAU,WAAW,MAAM;AACzB,gBAAM,QAAQ,sBAAsB;AAAA,YAClC,GAAG;AAAA,YACH,MAAM,KAAK;AAAA,YACX,YAAY,KAAK;AAAA,YACjB;AAAA,UACF,CAAC;AAED,eAAK,YAAY,KAAK;AACtB,eAAK,MAAM;AAAA,QACb,GAAG,SAAS;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,QAAc;AACZ,QAAI,CAAC,KAAK,OAAO,WAAW;AAC1B,WAAK,OAAO,IAAI;AAChB,WAAK,OAAO,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,UAA6C;AAC9D,UAAM,cAAc,KAAK;AACzB,SAAK,aAAa,WAAW;AAC7B,UAAM,YAAY,WAAW,EAAE,GAAG,SAAS,YAAY,QAAQ,YAAY,CAAC;AAE5E,SAAK,SAAS;AACd,SAAK,aAAa,SAAS;AAE3B,UAAM,iBAAoC;AAAA,MACxC,MAAM,KAAK;AAAA,MACX,qBAAqB,KAAK;AAAA,MAC1B,MAAM;AAAA,MACN,YAAY,KAAK;AAAA,IACnB;AAEA,QAAI,KAAK,cAAc,QAAW;AAChC,qBAAe,YAAY,KAAK;AAAA,IAClC;AAEA,UAAM,qBAAqB,WAAW,gBAAgB,iBAAiB,iBAAiB;AACxF,+BAA2B,WAAW,UAAU,KAAK,MAAM,KAAK,UAAU;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aAAa,QAAsB;AACzC,WAAO,GAAG,QAAQ,KAAK,gBAAgB;AACvC,WAAO,GAAG,SAAS,KAAK,iBAAiB;AACzC,WAAO,GAAG,SAAS,KAAK,iBAAiB;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aAAa,QAAsB;AACzC,WAAO,IAAI,QAAQ,KAAK,gBAAgB;AACxC,WAAO,IAAI,SAAS,KAAK,iBAAiB;AAC1C,WAAO,IAAI,SAAS,KAAK,iBAAiB;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,WAAW,OAA8B;AAC/C,QAAI;AACF,iBAAW,YAAY,KAAK,OAAO,KAAK,KAAK,GAAG;AAC9C,aAAK,gBAAgB,QAAQ;AAAA,MAC/B;AAAA,IACF,SAAS,OAAO;AACd,WAAK;AAAA,QACH,iBAAiB,QAAQ,QAAQ,sBAAsB,KAAK,MAAM,OAAO,KAAK,UAAU;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,UAA6B;AACnD,UAAM,SAAS,KAAK,QAAQ,MAAM;AAElC,QAAI,WAAW,QAAW;AACxB,WAAK,UAAU,KAAK,QAAQ;AAC5B;AAAA,IACF;AAEA,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,YAAY,OAAoB;AACtC,QAAI,KAAK,gBAAgB,QAAW;AAClC;AAAA,IACF;AAEA,SAAK,cAAc;AAEnB,eAAW,UAAU,KAAK,QAAQ,OAAO,CAAC,GAAG;AAC3C,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,EACF;AACF;AAoCA,eAAe,iBACb,SACA,SACAD,OACe;AACf,QAAM,WAAW,MAAM,QAAQ,YAAY,OAAO;AAClD,6BAA2B,UAAU,SAASA,OAAM,QAAQ,UAAU;AACxE;AAEA,eAAe,uBACb,SACA,SACAA,OACA,UAAkC,CAAC,GAClB;AACjB,QAAM,iBAAiB,MAAM,uBAAuB,SAAS,SAASA,OAAM,OAAO;AAEnF,MAAI;AACF,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACRA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,UAAM,gBAAgB,MAAM,QAAQ,kBAAkB;AAAA,MACpD;AAAA,MACA,WAAW;AAAA,MACX,MAAAA;AAAA,IACF,CAAC;AACD,+BAA2B,eAAe,SAASA,OAAM,QAAQ,UAAU;AAC3E,WAAO;AAAA,EACT,SAAS,OAAO;AACd,mBAAe,MAAM;AACrB,UAAM;AAAA,EACR;AACF;AASA,eAAe,qBACb,SACAA,OACwB;AACxB,MAAI;AACF,UAAME,WAAU,MAAM,uBAAuB,SAAS,QAAQF,KAAI,IAAIA,KAAI;AAC1E,WAAO,cAAcE,SAAQ,SAAS,MAAM,GAAGF,KAAI;AAAA,EACrD,SAAS,OAAO;AACd,QAAI,CAAC,6BAA6B,OAAO,MAAM,GAAG;AAChD,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,uBAAuB,SAAS,QAAQA,KAAI,IAAIA,KAAI;AAC1E,SAAO,cAAc,QAAQ,SAAS,MAAM,GAAGA,KAAI;AACrD;AAEA,eAAe,uBACb,SACA,SACAA,OACA,UAAkC,CAAC,GACH;AAChC,QAAM,SAAS,2BAA2B,QAAQ,QAAQ,UAAUA,KAAI;AAExE,MAAI,WAAW,UAAa,SAAS,GAAG;AACtC,UAAM,kBAAkB,SAAS,QAAQA,KAAI;AAAA,EAC/C;AAEA,QAAM,kBAAkB,MAAM,oBAAoB,SAASA,KAAI;AAC/D,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,QAAQ;AAAA,IACRA;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe;AACrB,YAAQ,aAAa,OAAO;AAC5B,UAAM,kBAAkB,MAAM,QAAQ,aAAa;AAAA,MACjD;AAAA,MACA,WAAW;AAAA,MACX,MAAAA;AAAA,IACF,CAAC;AAED,QAAI,CAAC,gBAAgB,aAAa;AAChC,qBAAe,MAAM;AACrB,iCAA2B,iBAAiB,SAASA,OAAM,QAAQ,UAAU;AAC7E,YAAM;AAAA,QACJ;AAAA,QACA,GAAG,QAAQ,WAAW,YAAY,CAAC;AAAA,QACnC;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,mBAAe,MAAM;AACrB,UAAM;AAAA,EACR;AACF;AAEA,eAAe,oBACb,SACAA,OAC0B;AAC1B,QAAM,0BAA0B,MAAM,QAAQ,YAAY,MAAM;AAEhE,MAAI,wBAAwB,YAAY;AACtC,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,CAAC,6BAA6B,uBAAuB,GAAG;AAC1D,+BAA2B,yBAAyB,QAAQA,OAAM,QAAQ,UAAU;AAAA,EACtF;AAEA,QAAM,kBAAkB,MAAM,QAAQ,YAAY,MAAM;AACxD,6BAA2B,iBAAiB,QAAQA,OAAM,QAAQ,UAAU;AAC5E,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAEA,eAAe,wBACb,SACA,SACAA,OACA,SACA,UAAkC,CAAC,GAClB;AACjB,QAAM,iBAAiB,MAAM,uBAAuB,SAAS,SAASA,OAAM,OAAO;AACnF,MAAI,mBAAmB;AACvB,QAAM,iBAAiB;AAAA,IACrB,MAAM,eAAe,SAAS;AAAA,IAC9B,WAAW;AAAA,IACX,MAAAA;AAAA,IACA,YAAY,QAAQ;AAAA,EACtB;AAEA,MAAI;AACF,qBAAiB,SAAS,QAAQ,SAAS;AACzC,cAAQ,eAAe;AACvB,YAAM,SAAS,IAAI,WAAW,KAAK;AACnC,YAAM;AAAA,QACJ,eAAe;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AACA,0BAAoB,OAAO;AAC3B,cAAQ,eAAe,kBAAkB,QAAQ,UAAU;AAAA,IAC7D;AAEA,UAAM,UAAU,eAAe,QAAQ,QAAQ,oBAAoB,cAAc;AACjF,UAAM,gBAAgB,MAAM,QAAQ,kBAAkB;AAAA,MACpD;AAAA,MACA,WAAW;AAAA,MACX,MAAAA;AAAA,IACF,CAAC;AACD,+BAA2B,eAAe,SAASA,OAAM,QAAQ,UAAU;AAC3E,WAAO;AAAA,EACT,SAAS,OAAO;AACd,mBAAe,MAAM;AACrB,UAAM;AAAA,EACR;AACF;AAEA,eAAe,kBACb,SACA,QACAA,OACe;AACf,QAAM,WAAW,MAAM,QAAQ,YAAY,QAAQ,MAAM,EAAE;AAE3D,MAAI,SAAS,cAAc,SAAS,cAAc;AAChD;AAAA,EACF;AAEA,6BAA2B,UAAU,QAAQA,OAAM,QAAQ,UAAU;AACvE;AAWA,SAAS,0BACP,UACA,WACAA,OACA,SACuB;AACvB,QAAM,eAAe,QAAQ;AAC7B,QAAM,SACJ,iBAAiB,SACb,iBAAiB,EAAE,MAAM,SAAS,MAAM,MAAM,SAAS,KAAK,CAAC,IAC7D,WAAW,EAAE,GAAG,aAAa,YAAY,MAAM,SAAS,MAAM,MAAM,SAAS,KAAK,CAAC;AACzF,SAAO,GAAG,SAAS,MAAM,MAAS;AAClC,QAAM,QAAQ,IAAI,QAAc,CAAC,SAAS,WAAW;AACnD,QAAI,UAAU;AACd,QAAI;AACJ,UAAM,aAAa,iBAAiB,SAAY,YAAY;AAE5D,UAAM,UAAU,MAAM;AACpB,aAAO,IAAI,YAAY,aAAa;AACpC,aAAO,IAAI,SAAS,WAAW;AAE/B,UAAI,YAAY,QAAW;AACzB,qBAAa,OAAO;AAAA,MACtB;AAAA,IACF;AACA,UAAM,aAAa,CAAC,UAAiB;AACnC,UAAI,SAAS;AACX;AAAA,MACF;AAEA,gBAAU;AACV,cAAQ;AACR,aAAO,QAAQ;AACf,aAAO,KAAK;AAAA,IACd;AACA,UAAM,gBAAgB,MAAM;AAC1B,UAAI,SAAS;AACX;AAAA,MACF;AAEA,UAAI;AACF,YAAI,iBAAiB,QAAW;AAC9B,qCAA2B,QAAQ,cAAc,SAAS,MAAM,QAAQ,UAAU;AAAA,QACpF;AAEA,kBAAU;AACV,gBAAQ;AACR,gBAAQ;AAAA,MACV,SAAS,OAAO;AACd;AAAA,UACE,iBAAiB,QACb,QACA,sBAAsB,SAAS,MAAM,OAAO,QAAQ,UAAU;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,CAAC,UAAiB;AACpC;AAAA,QACE,iBAAiB,eACb,QACA,sBAAsB,SAAS,MAAM,OAAO,QAAQ,UAAU;AAAA,MACpE;AAAA,IACF;AAEA,WAAO,KAAK,YAAY,aAAa;AACrC,WAAO,KAAK,SAAS,WAAW;AAEhC,QAAI,cAAc,QAAW;AAC3B,gBAAU;AAAA,QACR,MACE;AAAA,UACE,sBAAsB;AAAA,YACpB,MAAM,SAAS;AAAA,YACf,WAAW;AAAA,YACX,MAAAA;AAAA,YACA,YAAY,QAAQ;AAAA,YACpB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AACN,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AACF;AAEA,eAAe,mBACb,gBACA,WACAA,OACA,YACiB;AACjB,QAAM,SAAmB,CAAC;AAC1B,QAAM,mBAAmB,iBAAiB,eAAe,QAAQ,WAAW;AAAA,IAC1E,MAAM,eAAe,SAAS;AAAA,IAC9B,WAAW;AAAA,IACX,MAAAA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI;AACF,qBAAiB,SAAS,eAAe,QAAiC;AACxE,aAAO,KAAKG,QAAO,KAAK,KAAK,CAAC;AAAA,IAChC;AAAA,EACF,UAAE;AACA,qBAAiB;AAAA,EACnB;AAEA,SAAOA,QAAO,OAAO,MAAM;AAC7B;AAEA,gBAAgB,wBACd,SACA,gBACA,SACAH,OACA,OACA,SAC4B;AAC5B,MAAI,eAAe;AACnB,MAAI,YAAY;AAChB,MAAI,mBAA+B,MAAM;AACzC,QAAM,eAAe,MAAM,eAAe,MAAM;AAEhD,UAAQ,QAAQ,iBAAiB,SAAS,cAAc,EAAE,MAAM,KAAK,CAAC;AAEtE,MAAI;AACF,uBAAmB,iBAAiB,eAAe,QAAQ,QAAQ,oBAAoB;AAAA,MACrF,MAAM,eAAe,SAAS;AAAA,MAC9B,WAAW;AAAA,MACX,MAAAA;AAAA,MACA,YAAY,QAAQ;AAAA,IACtB,CAAC;AAED,qBAAiB,SAAS,eAAe,QAAiC;AACxE,cAAQ,eAAe;AACvB,YAAM,SAASG,QAAO,KAAK,KAAK;AAEhC,UAAI,MAAM,WAAW,QAAW;AAC9B,wBAAgB,OAAO;AACvB,cAAM,IAAI,WAAW,MAAM;AAC3B;AAAA,MACF;AAEA,YAAM,YAAY,MAAM,SAAS;AAEjC,UAAI,aAAa,GAAG;AAClB;AAAA,MACF;AAEA,YAAM,SAAS,OAAO,SAAS,GAAG,KAAK,IAAI,WAAW,OAAO,UAAU,CAAC;AACxE,sBAAgB,OAAO;AAEvB,UAAI,OAAO,aAAa,GAAG;AACzB,cAAM,IAAI,WAAW,MAAM;AAAA,MAC7B;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,QAAQ,kBAAkB;AAAA,MACpD;AAAA,MACA,WAAW;AAAA,MACX,MAAAH;AAAA,IACF,CAAC;AACD,+BAA2B,eAAe,SAASA,OAAM,QAAQ,UAAU;AAC3E,gBAAY;AAAA,EACd,UAAE;AACA,qBAAiB;AACjB,YAAQ,QAAQ,oBAAoB,SAAS,YAAY;AAEzD,QAAI,CAAC,WAAW;AACd,qBAAe,MAAM;AAAA,IACvB;AAAA,EACF;AACF;AAEA,SAAS,iBACP,QACA,OACA,WACA,SACe;AACf,MAAI,MAAM,eAAe,GAAG;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAEA,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,mBAAmB,iBAAiB,QAAQ,WAAW,OAAO;AACpE,UAAM,cAAc,CAAC,UAAiB;AACpC,uBAAiB;AACjB,aAAO,IAAI,SAAS,WAAW;AAC/B,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK,SAAS,WAAW;AAChC,WAAO,MAAM,OAAO,CAAC,UAAyB;AAC5C,uBAAiB;AACjB,aAAO,IAAI,SAAS,WAAW;AAE/B,UAAI,SAAS,MAAM;AACjB,eAAO,KAAK;AACZ;AAAA,MACF;AAEA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,UACP,QACA,WACA,SACe;AACf,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,mBAAmB,iBAAiB,QAAQ,WAAW,OAAO;AACpE,UAAM,cAAc,CAAC,UAAiB;AACpC,uBAAiB;AACjB,aAAO,IAAI,SAAS,WAAW;AAC/B,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK,SAAS,WAAW;AAChC,WAAO,IAAI,MAAM;AACf,uBAAiB;AACjB,aAAO,IAAI,SAAS,WAAW;AAC/B,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,iBAAiB,OAAgE;AACxF,MAAI,UAAU,QAAW;AACvB,WAAO,EAAE,QAAQ,EAAE;AAAA,EACrB;AAEA,QAAM,WAA8B;AAAA,IAClC,QAAQ,mBAAmB,MAAM,QAAQ,UAAU,GAAG;AAAA,EACxD;AAEA,MAAI,MAAM,WAAW,QAAW;AAC9B,aAAS,SAAS,mBAAmB,MAAM,QAAQ,UAAU,GAAG;AAAA,EAClE;AAEA,SAAO;AACT;AAEA,SAAS,2BACP,OACA,OACAA,OACoB;AACpB,SAAO,UAAU,SAAY,SAAY,mBAAmB,OAAO,OAAOA,KAAI;AAChF;AAEA,SAAS,mBAAmB,OAAe,OAAeA,OAAsB;AAC9E,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,UAAU,gBAAgB;AAAA,MAC5C,SAAS,gBAAgB,KAAK;AAAA,MAC9B,MAAAA;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAASD,mBAAkB,cAAsE;AAC/F,QAAM,QAAoC,EAAE,UAAU,aAAa,SAAS;AAE5E,MAAI,aAAa,WAAW,OAAW,OAAM,SAAS,aAAa;AACnE,MAAI,aAAa,aAAa,OAAW,OAAM,WAAW,aAAa;AACvE,MAAI,aAAa,qBAAqB,QAAW;AAC/C,UAAM,mBAAmB,aAAa;AAAA,EACxC;AACA,MAAI,aAAa,mBAAmB,OAAW,OAAM,iBAAiB,aAAa;AACnF,MAAI,aAAa,YAAY,OAAW,OAAM,UAAU,EAAE,GAAG,aAAa,QAAQ;AAElF,SAAO;AACT;AAWA,SAAS,qBACP,UACA,aACA,cACA,YACiB;AACjB,QAAM,gBAAgB,sCAAsC,KAAK,SAAS,OAAO;AAEjF,MAAI,kBAAkB,MAAM;AAC1B,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,YAAY,CAAC;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,CAAC,EAAEK,QAAO,QAAQ,OAAO,QAAQ,UAAU,OAAO,IAAI;AAC5D,QAAM,QAAQ,CAACA,QAAO,QAAQ,OAAO,QAAQ,UAAU,OAAO,EAAE,IAAI,CAAC,SAAS,OAAO,IAAI,CAAC;AAE1F,MAAI,MAAM,KAAK,CAAC,SAAS,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,GAAG,GAAG;AAC3E,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,YAAY,CAAC;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AAEtE,SAAO;AAAA,IACL,MAAM,iBAAiB,eAAe,iBAAiB;AAAA,IACvD,MAAM,MAAM,CAAC,IAAK,MAAM,MAAM,CAAC;AAAA,EACjC;AACF;AAUA,SAAS,6BACP,UACA,MACA,YACiB;AACjB,QAAM,gBAAgB,WAAW,KAAK,SAAS,OAAO;AAEtD,MAAI,kBAAkB,MAAM;AAC1B,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,YAAY,CAAC;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,cAAc,CAAC,KAAK;AACzC,QAAM,YAAY,aAAa,CAAC;AAEhC,MAAI,cAAc,QAAW;AAC3B,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,YAAY,CAAC;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,aAAa,MAAM,SAAS;AAC1C,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAE5B,MAAI,CAAC,OAAO,UAAU,IAAI,KAAK,QAAQ,KAAK,OAAO,OAAQ;AACzD,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,YAAY,CAAC;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,KAAK;AACtB;AAQA,SAAS,6BAA6B,UAAgC;AACpE,SACE,SAAS,SAAS,OAClB,SAAS,SAAS,OAClB,SAAS,SAAS,OAClB,SAAS,SAAS,OAClB,SAAS,SAAS;AAEtB;AASA,SAAS,6BAA6B,OAAgB,aAA8B;AAClF,SACE,iBAAiB,iBACjB,MAAM,SAAS,WAAW,WAAW,MAAM,QAC3C,4BAA4B,MAAM,OAAO;AAE7C;AAQA,SAAS,4BAA4B,MAAmC;AACtE,SAAO,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS;AAClE;AAQA,SAAS,oBAAoB,SAAoC;AAC/D,MAAI,QAAQ,UAAU,SAAS,YAAY;AACzC,WAAO,WAAW;AAAA,MAChB,GAAG,QAAQ,SAAS;AAAA,MACpB,MAAM,QAAQ;AAAA,MACd,MAAM,QAAQ;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,SAAO,iBAAiB,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,KAAK,CAAC;AACpE;AASA,eAAe,sBACb,SACA,UACe;AACf,QAAM,eAAe,MAAM,QAAQ,YAAY,UAAU;AAEzD,MAAI,CAAC,aAAa,YAAY;AAC5B,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,QAAQ,aAAa,QAAQ;AACnC,QAAM,wBAAwB,SAAS,QAAQ;AACjD;AASA,eAAe,wBACb,SACA,UACe;AACf,QAAM,iBAAiB,SAAS,UAAU,GAAG;AAC7C,QAAM,iBAAiB,SAAS,SAAS,mBAAmB,YAAY,WAAW,UAAU,GAAG;AAClG;AAQA,SAAS,2BAA2B,SAA0D;AAC5F,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAgC;AAAA,IACpC,oBAAoB,YAAY,sBAAsB;AAAA,EACxD;AACA,QAAM,aACJ,YAAY,eAAe,KAAK,QAAQ,IAAI,MAAM,IAAI,QAAQ,OAAO;AAEvE,MAAI,eAAe,QAAW;AAC5B,YAAQ,aAAa;AAAA,EACvB;AAEA,MAAI,eAAe,QAAW;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,OAAO,OAAW,SAAQ,KAAK,wBAAwB,WAAW,EAAE;AACnF,MAAI,WAAW,SAAS,OAAW,SAAQ,OAAO,wBAAwB,WAAW,IAAI;AACzF,MAAI,WAAW,QAAQ,OAAW,SAAQ,MAAM,wBAAwB,WAAW,GAAG;AACtF,MAAI,WAAW,QAAQ,OAAW,SAAQ,MAAM,wBAAwB,WAAW,GAAG;AACtF,MAAI,WAAW,eAAe;AAC5B,YAAQ,aAAa,eAAe,WAAW,UAAU;AAC3D,MAAI,WAAW,eAAe,OAAW,SAAQ,aAAa,WAAW;AACzE,MAAI,WAAW,eAAe,OAAW,SAAQ,aAAa,WAAW;AACzE,MAAI,WAAW,wBAAwB,QAAW;AAChD,YAAQ,sBAAsB,WAAW;AAAA,EAC3C;AAEA,SAAO;AACT;AAQA,SAAS,4BACP,SAC+B;AAC/B,QAAM,uBAAuB,QAAQ,KAAK;AAE1C,MAAI,yBAAyB,QAAW;AACtC,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM,QAAQ,oBAAoB,IACnD,uBACA,CAAC,oBAAoB;AAEzB,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,qBAAqB;AAAA,MAChC,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,IAAI,6BAA6B;AACvD;AASA,SAAS,8BAA8B,aAA6B;AAClE,QAAM,aAAa,YAAY,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,YAAY;AAEpE,MAAI,CAAC,iBAAiB,KAAK,UAAU,GAAG;AACtC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,sBAAsB,YAAY;AAAA,MAC7C,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAWA,SAAS,2BACP,QACA,UACA,MACA,YACM;AACN,QAAM,uBAAuB,SAAS;AAEtC,MAAI,yBAAyB,QAAW;AACtC;AAAA,EACF;AAEA,MAAI,CAAC,YAAY,MAAM,GAAG;AACxB,UAAM;AAAA,MACJ;AAAA,MACA,IAAI,MAAM,gDAAgD;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,mBAAmB;AAC9C,QAAM,oBAAoB,mCAAmC,WAAW;AAExE,MAAI,qBAAqB,SAAS,iBAAiB,GAAG;AACpD;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA,IAAI,MAAM,oFAAoF;AAAA,IAC9F;AAAA,EACF;AACF;AAQA,SAAS,YAAY,QAAqC;AACxD,SAAO,OAAQ,OAA8B,uBAAuB;AACtE;AAQA,SAAS,mCAAmC,aAAsC;AAChF,SAAO,YAAY,eAAe,QAAQ,MAAM,EAAE,EAAE,YAAY;AAClE;AAQA,SAAS,wBACP,OAC0C;AAC1C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAUD,QAAO,SAAS,IAAI,IAAIA,QAAO,KAAK,IAAI,IAAI,IAAK;AAAA,EAC/E;AAEA,SAAOA,QAAO,SAAS,KAAK,IAAIA,QAAO,KAAK,KAAK,IAAI;AACvD;AAEA,eAAe,uBACb,SACA,UACA,UACA,MACe;AACf,QAAM,eAAe,sBAAsB,UAAU,UAAU;AAC/D,QAAM,eAAe,sBAAsB,UAAU,UAAU;AAC/D,QAAM,eAAe,MAAM,QAAQ,YAAY,QAAQ,YAAY,EAAE;AAErE,MAAI,aAAa,YAAY;AAC3B;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,cAAc;AAC9B,UAAM,0BAA0B,MAAM,QAAQ,cAAc,QAAQ,UAAU;AAAA,EAChF;AAEA,QAAM,mBAAmB,MAAM,QAAQ,YAAY,QAAQ,YAAY,EAAE;AAEzE,MAAI,CAAC,iBAAiB,YAAY;AAChC,UAAM,0BAA0B,MAAM,QAAQ,kBAAkB,QAAQ,UAAU;AAAA,EACpF;AACF;AAEA,SAAS,2BACP,UACA,SACAH,OACA,YACM;AACN,MAAI,SAAS,YAAY;AACvB;AAAA,EACF;AAEA,MAAI,SAAS,SAAS,KAAK;AACzB,UAAM,IAAI,kBAAkB;AAAA,MAC1B;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,SAAS,GAAG,WAAW,YAAY,CAAC,oBAAoBA,KAAI;AAAA,MAC5D,MAAAA;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM;AAAA,IACJ;AAAA,IACA,GAAG,WAAW,YAAY,CAAC,oBAAoB,OAAO;AAAA,IACtD;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qBACP,QACA,SACA,aAA0C,WAC1C,YAAY,cACG;AACf,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,UAAU;AACd,QAAI;AAEJ,UAAM,UAAU,MAAM;AACpB,aAAO,IAAI,WAAW,aAAa;AACnC,aAAO,IAAI,YAAY,aAAa;AACpC,aAAO,IAAI,SAAS,WAAW;AAC/B,cAAQ,QAAQ,oBAAoB,SAAS,WAAW;AAExD,UAAI,YAAY,QAAW;AACzB,qBAAa,OAAO;AAAA,MACtB;AAAA,IACF;AACA,UAAM,aAAa,CAAC,UAAiB;AACnC,UAAI,SAAS;AACX;AAAA,MACF;AAEA,gBAAU;AACV,cAAQ;AACR,aAAO,QAAQ;AACf,aAAO,KAAK;AAAA,IACd;AACA,UAAM,gBAAgB,MAAM;AAC1B,UAAI,SAAS;AACX;AAAA,MACF;AAEA,gBAAU;AACV,cAAQ;AACR,cAAQ;AAAA,IACV;AACA,UAAM,cAAc,CAAC,UACnB,WAAW,sBAAsB,QAAQ,MAAM,OAAO,QAAQ,UAAU,CAAC;AAC3E,UAAM,cAAc,MAClB;AAAA,MACE,IAAI,WAAW;AAAA,QACb,SAAS,EAAE,UAAU;AAAA,QACrB,MAAM,QAAQ;AAAA,QACd,SAAS,GAAG,QAAQ,WAAW,YAAY,CAAC,IAAI,SAAS;AAAA,QACzD,UAAU,QAAQ;AAAA,QAClB,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEF,WAAO,KAAK,YAAY,aAAa;AACrC,WAAO,KAAK,SAAS,WAAW;AAEhC,QAAI,QAAQ,QAAQ,YAAY,MAAM;AACpC,kBAAY;AACZ;AAAA,IACF;AAEA,YAAQ,QAAQ,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAErE,UAAM,YAAY,QAAQ;AAE1B,QAAI,cAAc,QAAW;AAC3B,gBAAU;AAAA,QACR,MACE;AAAA,UACE,sBAAsB;AAAA,YACpB,MAAM,QAAQ;AAAA,YACd;AAAA,YACA,YAAY,QAAQ;AAAA,YACpB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAQA,SAAS,sBAAsB,OAA2C;AACxE,QAAM,UAAmC;AAAA,IACvC,WAAW,MAAM;AAAA,IACjB,WAAW,MAAM;AAAA,EACnB;AAEA,SAAO,IAAI,aAAa;AAAA,IACtB;AAAA,IACA,MAAM,MAAM;AAAA,IACZ,SAAS,GAAG,MAAM,WAAW,YAAY,CAAC,IAAI,MAAM,SAAS,oBAAoB,MAAM,SAAS;AAAA,IAChG,UAAU,MAAM;AAAA,IAChB,WAAW;AAAA,IACX,GAAI,MAAM,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;AAAA,IAChE,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AAAA,EACzD,CAAC;AACH;AAEA,SAAS,iBACP,QACA,WACA,SACY;AACZ,MAAI,cAAc,QAAW;AAC3B,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,gBAAgB,MAAM;AAC1B,WAAO,QAAQ,sBAAsB,EAAE,GAAG,SAAS,UAAU,CAAC,CAAC;AAAA,EACjE;AAEA,SAAO,WAAW,SAAS;AAC3B,SAAO,KAAK,WAAW,aAAa;AAEpC,SAAO,MAAM;AACX,WAAO,IAAI,WAAW,aAAa;AACnC,WAAO,WAAW,CAAC;AAAA,EACrB;AACF;AAEA,SAAS,0BACP,MACA,SACA,UACA,YACqB;AACrB,SAAO,IAAI,oBAAoB;AAAA,IAC7B;AAAA,IACA,SAAS,SAAS;AAAA,IAClB;AAAA,IACA,SAAS,GAAG,WAAW,YAAY,CAAC,iCAAiC,OAAO;AAAA,IAC5E,UAAU;AAAA,IACV,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,sBACP,MACA,OACA,YACiB;AACjB,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,SAAS,GAAG,WAAW,YAAY,CAAC;AAAA,IACpC,UAAU;AAAA,IACV,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,oBACP,SACA,SACA,UACA,YACe;AACf,SAAO,IAAI,cAAc;AAAA,IACvB;AAAA,IACA,SAAS,SAAS;AAAA,IAClB;AAAA,IACA,UAAU;AAAA,IACV,WAAW,SAAS;AAAA,EACtB,CAAC;AACH;AAEA,SAAS,iBAAiBA,OAAsB;AAC9C,QAAM,aAAa,oBAAoBA,KAAI;AAE3C,MAAI,eAAe,OAAO,eAAe,KAAK;AAC5C,WAAO;AAAA,EACT;AAEA,SAAO,WAAW,WAAW,GAAG,IAAI,aAAa,IAAI,UAAU;AACjE;AAEA,SAAS,cAAcA,OAAkC;AACvD,MAAIA,UAAS,KAAK;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,YAAYA,MAAK,YAAY,GAAG;AACtC,SAAO,aAAa,IAAI,MAAMA,MAAK,MAAM,GAAG,SAAS;AACvD;AAEA,SAAS,cAAc,MAAuB;AAC5C,SAAO,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG;AAChD;AAEA,SAAS,eAAe,MAAmB,OAA4B;AACrE,SAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAC3C;AAEA,SAAS,eAAe,OAAgC;AACtD,SAAOG,QAAO,SAAS,KAAK,IAAI,MAAM,SAAS,MAAM,IAAI;AAC3D;;;AK1gEA,SAAS,UAAAE,eAAc;AACvB,SAAS,YAAY,YAAY,uBAAuB;AACxD,OAAO,UAAU;AAcjB,IAAM,EAAE,QAAQ,eAAe,MAAM,IAAI;AA6CzC,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,6BAA4C;AAAA,EAChD,UAAU;AAAA,EACV,gBAAgB,CAAC,YAAY,eAAe,SAAS,sBAAsB;AAAA,EAC3E,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU,CAAC;AAAA,EACX,cAAc;AAAA,EACd,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU,CAAC,cAAc,SAAS,cAAc,SAAS,aAAa;AAAA,EACtE,gBAAgB;AAAA,EAChB,OAAO;AAAA,IACL;AAAA,EACF;AACF;AAgDO,SAAS,0BAA0B,UAA+B,CAAC,GAAoB;AAC5F,8BAA4B,OAAO;AAEnC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ,MAAM,IAAI,aAAa,OAAO;AAAA,EACxC;AACF;AAEA,IAAM,eAAN,MAAoE;AAAA,EAIlE,YAA6B,SAA8B;AAA9B;AAAA,EAA+B;AAAA,EAA/B;AAAA,EAHpB,KAAK;AAAA,EACL,eAAe;AAAA,EAIxB,MAAM,QAAQ,SAA0D;AACtE,UAAM,kBAAkB,MAAM,gCAAgC,OAAO;AACrE,UAAM,WAAW,sBAAsB,gBAAgB,UAAU,UAAU;AAC3E,UAAM,iBAAiB,0BAA0B,eAAe;AAChE,UAAM,SAAS,MAAM,iBAAiB,iBAAiB,KAAK,SAAS,UAAU,cAAc;AAE7F,QAAI;AACF,YAAM,OAAO,MAAM,gBAAgB,QAAQ,eAAe;AAC1D,aAAO,IAAI,oBAAoB,QAAQ,IAAI;AAAA,IAC7C,SAAS,OAAO;AACd,aAAO,IAAI;AACX,YAAM,aAAa,OAAO;AAAA,QACxB,SAAS;AAAA,QACT,MAAM,gBAAgB;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,sBAAN,MAAqE;AAAA,EAMnE,YACmB,QACA,MACjB;AAFiB;AACA;AAEjB,SAAK,OAAO,GAAG,SAAS,IAAI;AAC5B,SAAK,KAAK,IAAI,eAAe,IAAI;AACjC,SAAK,YAAY,IAAI,uBAAuB,IAAI;AAAA,EAClD;AAAA,EANmB;AAAA,EACA;AAAA,EAPV,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EAWT,aAA4B;AAC1B,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,WAAK,OAAO,IAAI;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,MAAsB;AACpB,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,MAAM,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAEA,IAAM,yBAAN,MAAmE;AAAA,EACjE,YAA6B,MAAmB;AAAnB;AAAA,EAAoB;AAAA,EAApB;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,kBAAkB,QAAQ,SAAS,IAAI;AAE1D,QAAI;AACF,YAAM,QAAQ,MAAM,cAAc,KAAK,MAAM,UAAU;AAEvD,UAAI,CAAC,MAAM,OAAO,GAAG;AACnB,cAAM,4BAA4B,YAAY,4BAA4B,UAAU,EAAE;AAAA,MACxF;AAEA,YAAM,QAAQ,qBAAqB,MAAM,MAAM,QAAQ,KAAK;AAC5D,YAAM,SAAqC;AAAA,QACzC,SAAS,qBAAqB,KAAK,MAAM,YAAY,OAAO,OAAO;AAAA,QACnE,YAAY,MAAM;AAAA,MACpB;AAEA,UAAI,MAAM,SAAS,GAAG;AACpB,eAAO,YAAY,MAAM;AAAA,MAC3B;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,EAAE,SAAS,QAAQ,MAAM,WAAW,CAAC;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,UAAM,aAAa,kBAAkB,QAAQ,SAAS,IAAI;AAC1D,UAAM,SAASC,4BAA2B,QAAQ,QAAQ,UAAU,UAAU;AAE9E,QAAI;AACF,YAAM,mBAAmB,MAAM,iBAAiB,KAAK,MAAM,YAAY,SAAS,MAAM;AACtF,YAAM,SAAsC;AAAA,QAC1C;AAAA,QACA,SAAS,WAAW,UAAa,SAAS;AAAA,QAC1C,YAAY,QAAQ,eAAe,UAAU,KAAK;AAAA,QAClD,UAAU,QAAQ,cAAc,YAAY;AAAA,MAC9C;AAEA,UAAI,QAAQ,iBAAiB,QAAW;AACtC,eAAO,eAAeC,mBAAkB,QAAQ,YAAY;AAAA,MAC9D;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,EAAE,SAAS,SAAS,MAAM,WAAW,CAAC;AAAA,IAClE;AAAA,EACF;AACF;AAEA,IAAM,iBAAN,MAAiD;AAAA,EAC/C,YAA6B,MAAmB;AAAnB;AAAA,EAAoB;AAAA,EAApB;AAAA,EAE7B,MAAM,KAAKC,OAAc,UAAuB,CAAC,GAA2B;AAC1E,IAAAC,gBAAe,QAAQ,QAAQD,OAAM,MAAM;AAC3C,UAAM,aAAa,kBAAkBA,KAAI;AAEzC,QAAI;AACF,YAAM,UAAU,MAAM,kBAAkB,KAAK,MAAM,UAAU;AAC7D,aAAO,QACJ,OAAO,CAAC,UAAU,MAAM,aAAa,OAAO,MAAM,aAAa,IAAI,EACnE,IAAI,CAAC,UAAU,sBAAsB,YAAY,KAAK,CAAC,EACvD,KAAKE,eAAc;AAAA,IACxB,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,EAAE,SAAS,WAAW,MAAM,WAAW,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAM,KAAKF,OAAc,UAAuB,CAAC,GAAwB;AACvE,IAAAC,gBAAe,QAAQ,QAAQD,OAAM,MAAM;AAC3C,UAAM,aAAa,kBAAkBA,KAAI;AAEzC,QAAI;AACF,YAAM,QAAQ,MAAM,cAAc,KAAK,MAAM,UAAU;AACvD,aAAO;AAAA,QACL,GAAG,aAAa,YAAY,mBAAmB,UAAU,GAAG,KAAK;AAAA,QACjE,QAAQ;AAAA,MACV;AAAA,IACF,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,EAAE,SAAS,SAAS,MAAM,WAAW,CAAC;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAM,OAAOA,OAAc,UAAyB,CAAC,GAAkB;AACrE,IAAAC,gBAAe,QAAQ,QAAQD,OAAM,QAAQ;AAC7C,UAAM,aAAa,kBAAkBA,KAAI;AACzC,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,UAAU;AAAA,IACxC,SAAS,OAAO;AACd,YAAM,SAAS,aAAa,OAAO,EAAE,SAAS,UAAU,MAAM,WAAW,CAAC;AAC1E,UAAI,QAAQ,iBAAiB,kBAAkB,kBAAmB;AAClE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAc,IAAY,UAAyB,CAAC,GAAkB;AACjF,IAAAC,gBAAe,QAAQ,QAAQ,MAAM,QAAQ;AAC7C,UAAM,WAAW,kBAAkB,IAAI;AACvC,UAAM,SAAS,kBAAkB,EAAE;AACnC,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,UAAU,MAAM;AAAA,IAC9C,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,EAAE,SAAS,UAAU,MAAM,SAAS,CAAC;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,MAAMD,OAAc,UAAwB,CAAC,GAAkB;AACnE,IAAAC,gBAAe,QAAQ,QAAQD,OAAM,OAAO;AAC5C,UAAM,aAAa,kBAAkBA,KAAI;AACzC,QAAI,CAAC,QAAQ,WAAW;AACtB,UAAI;AACF,cAAM,UAAU,KAAK,MAAM,UAAU;AAAA,MACvC,SAAS,OAAO;AACd,cAAM,aAAa,OAAO,EAAE,SAAS,SAAS,MAAM,WAAW,CAAC;AAAA,MAClE;AACA;AAAA,IACF;AACA,UAAM,WAAW,WAAW,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AACjE,QAAI,UAAU;AACd,eAAW,WAAW,UAAU;AAC9B,gBAAU,GAAG,OAAO,IAAI,OAAO;AAC/B,UAAI;AACF,cAAM,UAAU,KAAK,MAAM,OAAO;AAAA,MACpC,SAAS,OAAO;AAEd,YAAI;AACF,gBAAM,QAAQ,MAAM,cAAc,KAAK,MAAM,OAAO;AACpD,cAAI,MAAM,YAAY,EAAG;AAAA,QAC3B,QAAQ;AAAA,QAER;AACA,cAAM,aAAa,OAAO,EAAE,SAAS,SAAS,MAAM,QAAQ,CAAC;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MAAMA,OAAc,UAAwB,CAAC,GAAkB;AACnE,IAAAC,gBAAe,QAAQ,QAAQD,OAAM,OAAO;AAC5C,UAAM,aAAa,kBAAkBA,KAAI;AACzC,QAAI,QAAQ,WAAW;AACrB,YAAM,KAAK,yBAAyB,UAAU;AAC9C;AAAA,IACF;AACA,QAAI;AACF,YAAM,UAAU,KAAK,MAAM,UAAU;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,SAAS,aAAa,OAAO,EAAE,SAAS,SAAS,MAAM,WAAW,CAAC;AACzE,UAAI,QAAQ,iBAAiB,kBAAkB,kBAAmB;AAClE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,yBAAyB,YAAmC;AACxE,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,kBAAkB,KAAK,MAAM,UAAU;AAAA,IACzD,SAAS,OAAO;AACd,YAAM,SAAS,aAAa,OAAO,EAAE,SAAS,WAAW,MAAM,WAAW,CAAC;AAC3E,UAAI,kBAAkB,kBAAmB;AACzC,YAAM;AAAA,IACR;AACA,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,aAAa,OAAO,MAAM,aAAa,KAAM;AACvD,YAAM,YAAY,GAAG,WAAW,QAAQ,QAAQ,EAAE,CAAC,IAAI,MAAM,QAAQ,GAAG,QAAQ,QAAQ,GAAG;AAC3F,YAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,UAAI;AACF,YAAI,OAAO;AACT,gBAAM,KAAK,yBAAyB,SAAS;AAAA,QAC/C,OAAO;AACL,gBAAM,WAAW,KAAK,MAAM,SAAS;AAAA,QACvC;AAAA,MACF,SAAS,OAAO;AACd,cAAM,aAAa,OAAO;AAAA,UACxB,SAAS,QAAQ,UAAU;AAAA,UAC3B,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AACA,QAAI;AACF,YAAM,UAAU,KAAK,MAAM,UAAU;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,aAAa,OAAO,EAAE,SAAS,SAAS,MAAM,WAAW,CAAC;AAAA,IAClE;AAAA,EACF;AACF;AAyCA,eAAe,iBACb,SACA,SACA,UACA,gBACiB;AACjB,QAAM,SAAS,IAAI,cAAc;AACjC,MAAI;AAEJ,MAAI;AACF,aAAS,MAAM,oBAAoB,SAAS,SAAS,UAAU,cAAc;AAAA,EAC/E,SAAS,OAAO;AACd,WAAO,IAAI;AACX,UAAM,uBAAuB,OAAO,QAAQ,IAAI;AAAA,EAClD;AAEA,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,UAAU;AACd,UAAM,OAAO,CAAC,UAAmB;AAC/B,UAAI,SAAS;AACX;AAAA,MACF;AAEA,gBAAU;AACV,cAAQ;AACR,aAAO,IAAI;AACX,aAAO,uBAAuB,OAAO,QAAQ,IAAI,CAAC;AAAA,IACpD;AACA,UAAM,cAAc,MAAM;AACxB;AAAA,QACE,IAAI,WAAW;AAAA,UACb,SAAS,EAAE,WAAW,UAAU;AAAA,UAChC,MAAM,QAAQ;AAAA,UACd,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,cAAc,MAAM;AACxB,gBAAU;AACV,cAAQ;AACR,cAAQ,MAAM;AAAA,IAChB;AACA,UAAM,gBAAgB,MAAM;AAC1B;AAAA,QACE,IAAI,aAAa;AAAA,UACf,SAAS,EAAE,WAAW,UAAU;AAAA,UAChC,MAAM,QAAQ;AAAA,UACd,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,UAAU,MAAM;AACpB,aAAO,IAAI,SAAS,WAAW;AAC/B,aAAO,IAAI,SAAS,IAAI;AACxB,aAAO,IAAI,WAAW,aAAa;AACnC,cAAQ,QAAQ,oBAAoB,SAAS,WAAW;AAAA,IAC1D;AAEA,WAAO,KAAK,SAAS,WAAW;AAChC,WAAO,KAAK,SAAS,IAAI;AACzB,WAAO,KAAK,WAAW,aAAa;AAEpC,QAAI,QAAQ,QAAQ,YAAY,MAAM;AACpC,kBAAY;AACZ;AAAA,IACF;AAEA,YAAQ,QAAQ,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAErE,QAAI;AACF,aAAO,QAAQ,MAAM;AAAA,IACvB,SAAS,OAAO;AACd,WAAK,KAAK;AAAA,IACZ;AAAA,EACF,CAAC;AACH;AAEA,eAAe,oBACb,SACA,SACA,UACA,gBACwB;AACxB,QAAM,SAAwB;AAAA,IAC5B,aAAa,eAAe;AAAA,IAC5B,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACF;AACA,QAAM,YAAY,QAAQ,aAAa,QAAQ;AAE/C,MAAI,cAAc,QAAW;AAC3B,WAAO,eAAe;AACtB,WAAO,UAAU;AAAA,EACnB;AAEA,MAAI,QAAQ,KAAK,eAAe,QAAW;AACzC,WAAO,aAAa,QAAQ,IAAI;AAAA,EAClC;AAEA,QAAM,SAAS,MAAM,iBAAiB,SAAS,QAAQ;AAEvD,MAAI,WAAW,QAAW;AACxB,WAAO,OAAO;AAAA,EAChB;AAEA,+BAA6B,QAAQ,SAAS,OAAO;AAErD,SAAO;AACT;AASA,eAAe,iBACb,SACA,UACgC;AAChC,QAAM,gBAAgB,QAAQ,KAAK;AAEnC,MAAI,kBAAkB,QAAW;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,QAAQ,YAAY,MAAM;AACpC,UAAM,IAAI,WAAW;AAAA,MACnB,SAAS,EAAE,WAAW,UAAU;AAAA,MAChC,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,UAAU;AAAA,IACd,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB,QAAQ,WAAW,SAAY,UAAU,EAAE,GAAG,SAAS,QAAQ,QAAQ,OAAO;AAAA,EAChF;AAEA,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,OAAO,OAAO,SAAS,YAAY;AACtF,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,QAAQ,OAAO,OAAO;AAAA,MACjC,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,6BACP,QACA,SACA,SACM;AACN,QAAM,SAAS,wBAAwB,OAAO;AAE9C,MAAI,WAAW,QAAW;AACxB,QAAI,QAAQ,aAAa,OAAW,QAAO,WAAW,QAAQ;AAC9D,QAAI,QAAQ,iBAAiB,OAAW,QAAO,eAAe,QAAQ;AACtE;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa,UAAa,QAAQ,iBAAiB,QAAW;AACxE,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,UAAU,iBAAiB;AAAA,MACtC,SACE;AAAA,MACF,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,eAAe,CAAC,QAAgB,kBAAkB,QAAQ,GAAG;AACtE;AAEA,SAAS,wBACP,SAC+B;AAC/B,QAAM,aAAa,gBAAgB,QAAQ,KAAK,UAAU;AAC1D,QAAM,OAAO,qBAAqB,QAAQ,KAAK,mBAAmB;AAElE,MAAI,eAAe,UAAa,SAAS,QAAW;AAClD,WAAO;AAAA,EACT;AAEA,QAAM,SAA4B;AAAA,IAChC,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ,QAAQ;AAAA,EACxB;AAEA,MAAI,eAAe,OAAW,QAAO,aAAa;AAClD,MAAI,SAAS,OAAW,QAAO,sBAAsB;AAErD,SAAO;AACT;AAEA,SAAS,kBAAkB,QAA2B,KAAsB;AAC1E,MACE,OAAO,wBAAwB,UAC/B,CAAC,OAAO,oBAAoB,IAAI,YAAY,GAAG,CAAC,GAChD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,eAAe,UAAa,CAAC,kBAAkB,QAAQ,GAAG,GAAG;AACtE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,QAAiE;AACxF,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACvD,QAAM,UAAgC,CAAC;AAEvC,aAAW,SAAS,QAAQ;AAC1B,UAAM,OAAOG,QAAO,SAAS,KAAK,IAAI,MAAM,SAAS,MAAM,IAAI;AAC/D,UAAM,QAAQ,KAAK,MAAM,OAAO;AAEhC,UAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,YAAM,QAAQ,oBAAoB,MAAM,QAAQ,CAAC;AAEjD,UAAI,UAAU,QAAW;AACvB,gBAAQ,KAAK,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAc,YAAoD;AAC7F,QAAM,UAAU,KAAK,KAAK;AAE1B,MAAI,QAAQ,WAAW,KAAK,QAAQ,WAAW,GAAG,GAAG;AACnD,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,QAAQ,MAAM,KAAK;AAClC,QAAM,SAAS,OAAO,CAAC,GAAG,WAAW,GAAG,MAAM,OAAO,IAAI;AACzD,QAAM,QAAQ,OAAO,MAAM;AAC3B,QAAM,UAAU,OAAO,SAAS,CAAC;AACjC,QAAM,UAAU,OAAO,SAAS,CAAC;AAEjC,MAAI,UAAU,UAAa,YAAY,UAAa,YAAY,QAAW;AACzE,UAAM,mCAAmC,YAAY,cAAc;AAAA,EACrE;AAEA,QAAM,MAAM,wBAAwB,GAAG,OAAO,IAAI,OAAO,IAAI,UAAU;AAEvE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,MAAM,MAAM,GAAG,EAAE,OAAO,CAAC,YAAY,QAAQ,SAAS,CAAC;AAAA,EACnE;AACF;AAEA,SAAS,wBAAwB,OAAe,YAA+B;AAC7E,QAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,MAAI,kBAAkB,OAAO;AAC3B,UAAM,mCAAmC,YAAY,OAAO,OAAO;AAAA,EACrE;AAEA,QAAM,eAAmC,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACjF,QAAM,YAAY,aAAa,CAAC;AAEhC,MAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,UAAM,mCAAmC,YAAY,+BAA+B;AAAA,EACtF;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,OAAoC;AACvD,SACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAqC,iBAAiB;AAElE;AAEA,SAAS,kBAAkB,QAA2B,KAAsB;AAC1E,SAAO,OAAO,YAAY,KAAK,CAAC,UAAU,sBAAsB,OAAO,QAAQ,GAAG,CAAC,MAAM;AAC3F;AAEA,SAAS,sBACP,OACA,QACA,KACS;AACT,QAAM,aAAa,0BAA0B,OAAO,MAAM,OAAO,IAAI;AACrE,MAAI,cAAc;AAElB,aAAW,WAAW,MAAM,UAAU;AACpC,UAAM,UAAU,QAAQ,WAAW,GAAG;AACtC,UAAM,cAAc,UAAU,QAAQ,MAAM,CAAC,IAAI;AACjD,UAAM,iBAAiB,WAAW;AAAA,MAAK,CAAC,cACtC,wBAAwB,aAAa,SAAS;AAAA,IAChD;AAEA,QAAI,WAAW,gBAAgB;AAC7B,aAAO;AAAA,IACT;AAEA,QAAI,gBAAgB;AAClB,oBAAc;AAAA,IAChB;AAAA,EACF;AAEA,SAAO,eAAe,MAAM,IAAI,aAAa,EAAE,OAAO,GAAG;AAC3D;AAEA,SAAS,0BAA0B,MAAc,MAAwB;AACvE,QAAM,aAAa,CAAC,MAAM,IAAI,IAAI,KAAK,IAAI,EAAE;AAE7C,SAAO,SAAS,oBAAoB,aAAa,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAC7E;AAEA,SAAS,wBAAwB,SAAiB,WAA4B;AAC5E,MAAI,QAAQ,WAAW,KAAK,GAAG;AAC7B,WAAO,8BAA8B,SAAS,SAAS;AAAA,EACzD;AAEA,SAAO,iCAAiC,OAAO,EAAE,KAAK,SAAS;AACjE;AAEA,SAAS,iCAAiC,SAAyB;AACjE,QAAM,UAAU,QACb,QAAQ,qBAAqB,MAAM,EACnC,QAAQ,OAAO,IAAI,EACnB,QAAQ,OAAO,GAAG;AAErB,SAAO,IAAI,OAAO,IAAI,OAAO,KAAK,GAAG;AACvC;AAEA,SAAS,8BAA8B,SAAiB,WAA4B;AAClF,QAAM,CAAC,EAAE,SAAS,UAAU,QAAQ,IAAI,QAAQ,MAAM,GAAG;AAEzD,MAAI,YAAY,OAAO,aAAa,UAAa,aAAa,QAAW;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,OAAOA,QAAO,KAAK,UAAU,QAAQ;AAC3C,QAAM,WAAWA,QAAO,KAAK,UAAU,QAAQ;AAC/C,QAAM,SAAS,WAAW,QAAQ,IAAI,EAAE,OAAO,SAAS,EAAE,OAAO;AAEjE,SAAO,SAAS,eAAe,OAAO,cAAc,gBAAgB,UAAU,MAAM;AACtF;AAEA,SAAS,qBAAqB,OAAwD;AACpF,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,OAA0B,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI;AAEtE,SAAO,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,oBAAoB,GAAG,CAAC,CAAC;AAC5D;AAEA,SAAS,oBAAoB,OAAuB;AAClD,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,MAAM,QAAQ,QAAQ,MAAM,EAAE;AAEpC,MAAI,IAAI,WAAW,MAAM,eAAe,KAAK,GAAG,GAAG;AACjD,WAAOA,QAAO,KAAK,KAAK,KAAK,EAAE,SAAS,QAAQ,EAAE,QAAQ,QAAQ,EAAE;AAAA,EACtE;AAEA,QAAM,OAAO,QAAQ,WAAW,SAAS,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI;AAE/E,SAAOA,QAAO,KAAKC,WAAU,IAAI,GAAG,QAAQ,EAAE,SAAS,QAAQ,EAAE,QAAQ,QAAQ,EAAE;AACrF;AAEA,SAAS,YAAY,KAAqB;AACxC,SAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,QAAQ,EAAE,QAAQ,QAAQ,EAAE;AAC7E;AAEA,SAASA,WAAU,OAAuB;AACxC,QAAM,YAAY,MAAM,SAAS;AAEjC,SAAO,cAAc,IAAI,QAAQ,GAAG,KAAK,GAAG,IAAI,OAAO,IAAI,SAAS,CAAC;AACvE;AAEA,SAAS,mCACP,YACA,QACoB;AACpB,SAAO,IAAI,mBAAmB;AAAA,IAC5B,SAAS,EAAE,YAAY,UAAU,iBAAiB;AAAA,IAClD,SAAS,yBAAyB,UAAU,IAAI,MAAM;AAAA,IACtD,UAAU;AAAA,IACV,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,0BAA0B,SAA8D;AAC/F,QAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAM,WAAW,8BAA8B,QAAQ,UAAU,UAAU;AAC3E,QAAM,aAAa,QAAQ,KAAK;AAChC,QAAM,aAAa,QAAQ,KAAK;AAChC,QAAM,sBAAsB,QAAQ,KAAK;AACzC,QAAM,WAAW,sBAAsB,QAAQ,UAAU,UAAU;AACnE,QAAM,cAA+B,CAAC;AAEtC,MAAI,eAAe,QAAW;AAC5B,UAAM,SAAwB;AAAA,MAC5B,KAAK;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAEA,QAAI,eAAe,OAAW,QAAO,aAAa;AAElD,gBAAY,KAAK,MAAM;AAAA,EACzB;AAEA,MAAI,aAAa,QAAW;AAC1B,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,QAAW;AACvB,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,wBAAwB,QAAW;AACrC,gBAAY,KAAK;AAAA,MACf,QAAQ,CAAC,MAAM,cAAc,UAAU,SAAS,WAAW;AACzD;AAAA,UACE;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,UAAU,iBAAiB;AAAA,MACtC,SACE;AAAA,MACF,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,YAAY;AACvB;AAEA,SAAS,mCACP,WACA,SACA,QACM;AACN,UAAQ,QAAQ,EACb,KAAK,MAAM,QAAQ,SAAS,CAAC,EAC7B,KAAK,CAAC,YAAY,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,EAC7C,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC;AAC3B;AAEA,SAAS,gBAAgB,QAAgB,SAA0D;AACjG,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAO,KAAK,CAAC,OAAO,SAAS;AAC3B,UAAI,UAAU,QAAW;AACvB;AAAA,UACE,aAAa,OAAO;AAAA,YAClB,SAAS;AAAA,YACT,MAAM,QAAQ;AAAA,UAChB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAEA,cAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,kBAAkB,MAAmBJ,OAA6C;AACzF,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,QAAQA,OAAM,CAAC,OAAO,YAAY;AACrC,UAAI,UAAU,QAAW;AACvB,eAAO,KAAK;AACZ;AAAA,MACF;AAEA,cAAQ,OAAO;AAAA,IACjB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,cAAc,MAAmBA,OAA8B;AACtE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,MAAMA,OAAM,CAAC,OAAO,UAAU;AACjC,UAAI,UAAU,QAAW;AACvB,eAAO,KAAK;AACZ;AAAA,MACF;AAEA,cAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,WAAW,MAAmBA,OAA6B;AAClE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,OAAOA,OAAM,CAAC,UAAU;AAC3B,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC,eAAO,KAAK;AACZ;AAAA,MACF;AACA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,WAAW,MAAmB,MAAc,IAA2B;AAC9E,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,OAAO,MAAM,IAAI,CAAC,UAAU;AAC/B,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC,eAAO,KAAK;AACZ;AAAA,MACF;AACA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,UAAU,MAAmBA,OAA6B;AACjE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,MAAMA,OAAM,CAAC,UAAU;AAC1B,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC,eAAO,KAAK;AACZ;AAAA,MACF;AACA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,UAAU,MAAmBA,OAA6B;AACjE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,SAAK,MAAMA,OAAM,CAAC,UAAU;AAC1B,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC,eAAO,KAAK;AACZ;AAAA,MACF;AACA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,gBAAgB,qBACd,MACAA,OACA,OACA,SAC4B;AAC5B,MAAI,MAAM,UAAU,GAAG;AACrB;AAAA,EACF;AAEA,QAAM,SAAS,KAAK,iBAAiBA,OAAM;AAAA,IACzC,KAAK,MAAM,SAAS,MAAM,SAAS;AAAA,IACnC,OAAO,MAAM;AAAA,EACf,CAAC;AACD,QAAM,eAAe,MAAM,OAAO,QAAQ;AAE1C,UAAQ,QAAQ,iBAAiB,SAAS,cAAc,EAAE,MAAM,KAAK,CAAC;AAEtE,MAAI;AACF,qBAAiB,SAAS,QAAQ;AAChC,cAAQ,eAAe;AACvB,YAAM,IAAI,WAAWG,QAAO,KAAK,KAAK,CAAC;AAAA,IACzC;AAAA,EACF,SAAS,OAAO;AACd,UAAM,aAAa,OAAO,EAAE,SAAS,QAAQ,MAAAH,MAAK,CAAC;AAAA,EACrD,UAAE;AACA,YAAQ,QAAQ,oBAAoB,SAAS,YAAY;AAAA,EAC3D;AACF;AAEA,eAAe,iBACb,MACAA,OACA,SACA,QACiB;AACjB,QAAM,SAAS,sBAAsB,MAAMA,OAAM,MAAM;AACvD,QAAM,eAAe,MAAM,OAAO,QAAQ;AAC1C,MAAI,mBAAmB;AAEvB,UAAQ,QAAQ,iBAAiB,SAAS,cAAc,EAAE,MAAM,KAAK,CAAC;AAEtE,MAAI;AACF,qBAAiB,SAAS,QAAQ,SAAS;AACzC,cAAQ,eAAe;AACvB,YAAM,eAAe,QAAQ,KAAK;AAClC,0BAAoB,MAAM;AAC1B,cAAQ,eAAe,kBAAkB,QAAQ,UAAU;AAAA,IAC7D;AAEA,UAAM,mBAAmB,MAAM;AAC/B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,QAAQ;AACf,UAAM;AAAA,EACR,UAAE;AACA,YAAQ,QAAQ,oBAAoB,SAAS,YAAY;AAAA,EAC3D;AACF;AAEA,SAAS,sBACP,MACAA,OACA,QACa;AACb,MAAI,WAAW,QAAW;AACxB,WAAO,KAAK,kBAAkBA,OAAM,EAAE,OAAO,IAAI,CAAC;AAAA,EACpD;AAEA,SAAO,KAAK,kBAAkBA,OAAM,EAAE,OAAO,MAAM,OAAO,OAAO,CAAC;AACpE;AAEA,SAAS,eAAe,QAAqB,OAAkC;AAC7E,MAAI,MAAM,eAAe,GAAG;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAEA,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,UAAU,MAAM;AACpB,aAAO,IAAI,SAAS,WAAW;AAAA,IACjC;AACA,UAAM,cAAc,CAAC,UAAiB;AACpC,cAAQ;AACR,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK,SAAS,WAAW;AAChC,WAAO,MAAMG,QAAO,KAAK,KAAK,GAAG,CAAC,UAAyB;AACzD,cAAQ;AAER,UAAI,SAAS,MAAM;AACjB,eAAO,KAAK;AACZ;AAAA,MACF;AAEA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,mBAAmB,QAAoC;AAC9D,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,UAAU,MAAM;AACpB,aAAO,IAAI,SAAS,WAAW;AAC/B,aAAO,IAAI,SAAS,WAAW;AAAA,IACjC;AACA,UAAM,cAAc,MAAM;AACxB,cAAQ;AACR,cAAQ;AAAA,IACV;AACA,UAAM,cAAc,CAAC,UAAiB;AACpC,cAAQ;AACR,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK,SAAS,WAAW;AAChC,WAAO,KAAK,SAAS,WAAW;AAChC,WAAO,IAAI;AAAA,EACb,CAAC;AACH;AAEA,SAAS,qBACP,MACA,OACuB;AACvB,MAAI,UAAU,QAAW;AACvB,WAAO,EAAE,QAAQ,MAAM,QAAQ,EAAE;AAAA,EACnC;AAEA,QAAM,kBAAkBE,oBAAmB,MAAM,QAAQ,UAAU,GAAG;AACtE,QAAM,kBACJ,MAAM,WAAW,SACb,OAAO,KAAK,IAAI,iBAAiB,IAAI,IACrCA,oBAAmB,MAAM,QAAQ,UAAU,GAAG;AACpD,QAAM,SAAS,KAAK,IAAI,iBAAiB,IAAI;AAC7C,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,OAAO,MAAM,CAAC;AAEnE,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAEA,SAASP,4BACP,OACA,OACAE,OACoB;AACpB,SAAO,UAAU,SAAY,SAAYK,oBAAmB,OAAO,OAAOL,KAAI;AAChF;AAEA,SAASK,oBAAmB,OAAe,OAAeL,OAAsB;AAC9E,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,UAAU,iBAAiB;AAAA,MAC7C,SAAS,iBAAiB,KAAK;AAAA,MAC/B,MAAAA;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAASD,mBAAkB,cAAsE;AAC/F,QAAM,QAAoC,EAAE,UAAU,aAAa,SAAS;AAE5E,MAAI,aAAa,WAAW,OAAW,OAAM,SAAS,aAAa;AACnE,MAAI,aAAa,aAAa,OAAW,OAAM,WAAW,aAAa;AACvE,MAAI,aAAa,qBAAqB,QAAW;AAC/C,UAAM,mBAAmB,aAAa;AAAA,EACxC;AACA,MAAI,aAAa,mBAAmB,OAAW,OAAM,iBAAiB,aAAa;AACnF,MAAI,aAAa,YAAY,OAAW,OAAM,UAAU,EAAE,GAAG,aAAa,QAAQ;AAElF,SAAO;AACT;AAEA,SAAS,sBAAsB,WAAmB,OAAwC;AACxF,SAAO,aAAa,eAAe,WAAW,MAAM,QAAQ,GAAG,MAAM,UAAU,MAAM,OAAO;AAAA,IAC1F,UAAU,MAAM;AAAA,EAClB,CAAC;AACH;AAEA,SAAS,aACPC,OACA,MACA,OACA,MAA6B,CAAC,GACjB;AACb,QAAM,QAAqB;AAAA,IACzB,OAAO,OAAO,MAAM,GAAG;AAAA,IACvB;AAAA,IACA,OAAO,OAAO,MAAM,GAAG;AAAA,IACvB,MAAAA;AAAA,IACA,aAAa,EAAE,KAAK,eAAe,MAAM,IAAI,EAAE;AAAA,IAC/C,KAAK;AAAA,MACH,OAAO,mBAAmB,KAAK;AAAA,MAC/B,GAAG;AAAA,IACL;AAAA,IACA,MAAM,iBAAiB,KAAK;AAAA,EAC9B;AACA,QAAM,aAAa,kBAAkB,MAAM,KAAK;AAChD,QAAM,aAAa,kBAAkB,MAAM,KAAK;AAEhD,QAAM,OAAO,MAAM;AACnB,QAAM,aAAa;AACnB,QAAM,aAAa;AAEnB,SAAO;AACT;AAEA,SAAS,iBAAiB,OAA+B;AACvD,MAAI,MAAM,OAAO,EAAG,QAAO;AAC3B,MAAI,MAAM,YAAY,EAAG,QAAO;AAChC,MAAI,MAAM,eAAe,EAAG,QAAO;AACnC,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAsC;AAChE,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,KAAK,MAAM;AAAA,IACX,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,IACZ,KAAK,MAAM;AAAA,EACb;AACF;AAEA,SAAS,kBAAkB,OAAqB;AAC9C,SAAO,IAAI,KAAK,QAAQ,GAAI;AAC9B;AAEA,SAAS,eAAe,MAAsB;AAC5C,SAAO,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AACzC;AAEA,SAAS,kBAAkBA,OAAsB;AAC/C,SAAO,oBAAoBA,KAAI;AACjC;AAEA,SAASE,gBAAe,MAAmB,OAA4B;AACrE,SAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAC3C;AAEA,SAAS,sBACP,OACA,OACQ;AACR,QAAM,OAAO,8BAA8B,OAAO,KAAK;AAEvD,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,UAAU,iBAAiB;AAAA,MAC7C,SAAS,2BAA2B,KAAK;AAAA,MACzC,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,8BACP,OACA,OACoB;AACpB,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,OAAOC,QAAO,SAAS,KAAK,IAAI,MAAM,SAAS,MAAM,IAAI;AAE/D,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,UAAU,iBAAiB;AAAA,MAC7C,SAAS,gBAAgB,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,4BAA4B,SAAoC;AACvE,MACE,QAAQ,mBAAmB,WAC1B,CAAC,OAAO,SAAS,QAAQ,cAAc,KAAK,QAAQ,kBAAkB,IACvE;AACA,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,gBAAgB,QAAQ,eAAe;AAAA,MAClD,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;AAEA,SAAS,4BAA4BH,OAAc,SAAoC;AACrF,SAAO,IAAI,kBAAkB;AAAA,IAC3B,SAAS,EAAE,UAAU,iBAAiB;AAAA,IACtC;AAAA,IACA,MAAAA;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAASC,gBACP,QACAD,OACA,WACM;AACN,MAAI,QAAQ,YAAY,MAAM;AAC5B;AAAA,EACF;AAEA,QAAM,IAAI,WAAW;AAAA,IACnB,SAAS,EAAE,UAAU;AAAA,IACrB,SAAS,QAAQ,SAAS;AAAA,IAC1B,MAAAA;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,uBAAuB,OAAgB,MAAiC;AAC/E,MAAI,iBAAiB,mBAAmB;AACtC,WAAO;AAAA,EACT;AAEA,MAAI,0BAA0B,KAAK,GAAG;AACpC,WAAO,IAAI,oBAAoB;AAAA,MAC7B,OAAO;AAAA,MACP;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,gBAAgB;AAAA,IACzB,OAAO;AAAA,IACP,SAAS,EAAE,iBAAiB,gBAAgB,KAAK,EAAE;AAAA,IACnD;AAAA,IACA,SAAS,2BAA2B,gBAAgB,KAAK,CAAC;AAAA,IAC1D,UAAU;AAAA,IACV,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,aAAa,OAAgB,SAA8C;AAClF,MAAI,iBAAiB,mBAAmB;AACtC,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,kBAAkB,KAAK;AACxC,QAAM,cAAc,oBAAoB,OAAO,SAAS,QAAQ;AAEhE,MAAI,aAAa,KAAK,qBAAqB,KAAK,GAAG;AACjD,WAAO,IAAI,kBAAkB;AAAA,MAC3B,GAAG;AAAA,MACH,SAAS,wBAAwB,QAAQ,QAAQ,SAAS;AAAA,MAC1D,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,aAAa,GAAG;AAClB,WAAO,IAAI,sBAAsB;AAAA,MAC/B,GAAG;AAAA,MACH,SAAS,2BAA2B,QAAQ,QAAQ,QAAQ,OAAO;AAAA,MACnE,WAAW;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,cAAc;AAAA,IACvB,GAAG;AAAA,IACH,SAAS,EAAE,iBAAiB,gBAAgB,KAAK,EAAE;AAAA,IACnD,SAAS,QAAQ,QAAQ,OAAO,YAAY,gBAAgB,KAAK,CAAC;AAAA,IAClE,WAAW,aAAa,KAAK,aAAa;AAAA,EAC5C,CAAC;AACH;AAEA,SAAS,oBACP,OACA,SACA,UACe;AACf,QAAM,OAAsB;AAAA,IAC1B,OAAO;AAAA,IACP,SAAS,QAAQ;AAAA,IACjB,UAAU;AAAA,EACZ;AAEA,MAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,MAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,MAAI,aAAa,OAAW,MAAK,WAAW;AAE5C,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAoC;AAC7D,QAAM,OAAOM,UAAS,KAAK,IAAI,MAAM,OAAO;AAE5C,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,0BAA0B,OAAyB;AAC1D,MAAI,CAACA,UAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,QAAS,MAAgC;AAC/C,QAAM,UAAU,gBAAgB,KAAK,EAAE,YAAY;AAEnD,SAAO,UAAU,2BAA2B,QAAQ,SAAS,gBAAgB;AAC/E;AAEA,SAAS,qBAAqB,OAAyB;AACrD,SAAO,0BAA0B,KAAK,gBAAgB,KAAK,CAAC;AAC9D;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAASA,UAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,OAAa;AAAC;;;ACz6CvB,SAAS,UAAAC,eAAc;AAuBhB,SAAS,aACd,SACA,SACK;AACL,QAAM,WAAW,QAAQ,SAAS,WAAW;AAC7C,QAAM,cAAc,QAAQ,SAAS,SAAY,IAAI,QAAQ,IAAI,KAAK;AACtE,QAAMC,QAAO,QAAQ,SAAS,WAAW,IAAI,MAAM,mBAAmB,QAAQ,QAAQ;AACtF,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,QAAQ,KAAK,QAAQ,IAAI,GAAG,WAAW,GAAGA,KAAI,EAAE;AAAA,EACpE,SAAS,OAAO;AACd,UAAM,IAAI,mBAAmB;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,KAAK;AAAA,MAClD,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;AAGO,SAAS,WAAW,SAAc,YAAyB;AAChE,QAAM,cAAc,QAAQ,SAAS,QAAQ,QAAQ,EAAE;AACvD,QAAM,SAAS,eAAe,MAAM,KAAK;AACzC,QAAM,SAAS,IAAI,IAAI,QAAQ,SAAS,CAAC;AACzC,SAAO,WAAW,GAAG,WAAW,GAAG,MAAM;AACzC,SAAO;AACT;AAGO,SAAS,mBAAmB,OAAuB;AACxD,SAAO,MAAM,WAAW,GAAG,IAAI,QAAQ,IAAI,KAAK;AAClD;AAGA,eAAsB,gBACpB,SACA,KACA,MACmB;AACnB,QAAM,UAAU,EAAE,GAAG,QAAQ,SAAS,GAAI,KAAK,WAAW,CAAC,EAAG;AAC9D,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,iBAAiB,KAAK,UAAU;AACtC,MAAI,mBAAmB,MAAM;AAC3B,QAAI,eAAe,QAAS,YAAW,MAAM,eAAe,MAAM;AAAA,QAC7D,gBAAe,iBAAiB,SAAS,MAAM,WAAW,MAAM,eAAe,MAAM,CAAC;AAAA,EAC7F;AAEA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,wBAAwB,CAAC;AAAA,MAC1D,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,IAAI,SAAS,GAAG;AAAA,MACzC,GAAG;AAAA,MACH;AAAA,MACA,QAAQ,WAAW;AAAA,IACrB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,QAAI,WAAW,OAAO,WAAW,gBAAgB,YAAY,MAAM;AACjE,YAAM,IAAI,aAAa;AAAA,QACrB,OAAO;AAAA,QACP,SAAS,EAAE,WAAW,QAAQ,WAAW,KAAK,IAAI,SAAS,EAAE;AAAA,QAC7D,SAAS,mBAAmB,IAAI,SAAS,CAAC,oBAAoB,OAAO,QAAQ,SAAS,CAAC;AAAA,QACvF,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,KAAK,IAAI,SAAS,EAAE;AAAA,MAC/B,SAAS,mBAAmB,IAAI,SAAS,CAAC;AAAA,MAC1C,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAGO,SAAS,uBAAuB,OAAmC;AACxE,QAAM,QAAQ,cAAc,KAAK,KAAK;AACtC,MAAI,UAAU,KAAM,QAAO;AAC3B,QAAM,QAAQ,OAAO,SAAS,MAAM,CAAC,KAAK,IAAI,EAAE;AAChD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAGO,SAAS,gBACd,UACA,aACoB;AACpB,MAAI,SAAS,WAAW,KAAK;AAC3B,UAAM,eAAe,SAAS,QAAQ,IAAI,eAAe;AACzD,QAAI,iBAAiB,MAAM;AACzB,YAAM,QAAQ,uBAAuB,YAAY;AACjD,UAAI,UAAU,OAAW,QAAO;AAAA,IAClC;AAAA,EACF;AACA,QAAM,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB;AAC3D,MAAI,kBAAkB,KAAM,QAAO;AACnC,QAAM,SAAS,OAAO,SAAS,eAAe,EAAE;AAChD,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,EAAG,QAAO;AACnD,SAAO,gBAAgB,UAAa,cAAc,IAAI,SAAS,cAAc;AAC/E;AAGO,SAAS,kBAAkB,QAAgB,QAAoC;AACpF,MAAI,WAAW,OAAW,QAAO,SAAS,OAAO,MAAM,CAAC;AACxD,QAAM,MAAM,SAAS,SAAS;AAC9B,SAAO,SAAS,OAAO,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC;AAC/C;AAGO,SAAS,iBAAiB,UAAoBA,OAAqB;AACxE,QAAM,UAAU,EAAE,MAAAA,OAAM,QAAQ,SAAS,QAAQ,YAAY,SAAS,WAAW;AACjF,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,oBAAoB;AAAA,MAC7B;AAAA,MACA,SAAS,kCAAkCA,KAAI,KAAK,OAAO,SAAS,MAAM,CAAC;AAAA,MAC3E,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,sBAAsB;AAAA,MAC/B;AAAA,MACA,SAAS,6BAA6BA,KAAI,KAAK,OAAO,SAAS,MAAM,CAAC;AAAA,MACtE,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,kBAAkB;AAAA,MAC3B;AAAA,MACA,SAAS,wBAAwBA,KAAI;AAAA,MACrC,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA,SAAS,oBAAoBA,KAAI,uBAAuB,OAAO,SAAS,MAAM,CAAC;AAAA,IAC/E,WAAW,SAAS,UAAU;AAAA,EAChC,CAAC;AACH;AAGA,gBAAuB,yBACrB,MAC2B;AAC3B,QAAM,SAAS,KAAK,UAAU;AAC9B,MAAI;AACF,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,UAAI,UAAU,OAAW,OAAM;AAAA,IACjC;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACF;AAGO,SAASC,gBAAe,OAAwB;AACrD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,iBAAiB,cAAcC,QAAO,SAAS,KAAK,GAAG;AACzD,WAAOA,QAAO,KAAK,KAAmB,EAAE,SAAS,MAAM;AAAA,EACzD;AACA,SAAO,OAAO,KAAK;AACrB;;;ACvJA,IAAM,mBAAmB;AACzB,IAAM,uBAAuB;AAE7B,IAAM,gCAAsD,CAAC,sBAAsB;AAuB5E,SAAS,6BACd,UAAkC,CAAC,GAClB;AACjB,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,iBAAiB,QAAQ,kBAAkB;AAEjD,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,SAAS,OAAO;AAAA,IACjC,UAAU,CAAC,GAAG,6BAA6B;AAAA,IAC3C,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,UAAU;AAAA,IACnC,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,gBAAgB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWA,IAAM,kBAAN,MAAkD;AAAA,EAIhD,YAA6B,WAA2C;AAA3C;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,QAAQC,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAClE,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,iBAAwC;AAAA,MAC5C,YAAY,KAAK,UAAU;AAAA,MAC3B,cAAc,KAAK,UAAU;AAAA,MAC7B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,OAAO,KAAK,UAAU;AAAA,MACtB,IAAI,KAAK,UAAU;AAAA,MACnB;AAAA,IACF;AACA,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,eAAe,cAAc;AAAA,EAC1C;AACF;AAaA,IAAM,iBAAN,MAAgD;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAgC;AAC1C,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,kBAAkB,OAAO;AACvC,SAAK,YAAY,IAAI,0BAA0B,OAAO;AAAA,EACxD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,oBAAN,MAAoD;AAAA,EAClD,YAA6B,SAAgC;AAAhC;AAAA,EAAiC;AAAA,EAAjC;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,UAAU,cAAc,UAAU;AACxC,UAAM,UAAyB,CAAC;AAChC,QAAI;AACJ,OAAG;AACD,YAAM,OACJ,WAAW,SACP,EAAE,oBAAoB,OAAO,MAAM,SAAS,WAAW,MAAM,IAC7D,EAAE,OAAO;AACf,YAAM,WACJ,WAAW,SAAY,yBAAyB;AAClD,YAAM,WAAW,MAAM,WAAW,KAAK,SAAS,UAAU,IAAI;AAC9D,YAAM,SAAU,MAAM,SAAS,KAAK;AACpC,iBAAW,OAAO,OAAO,SAAS;AAChC,cAAM,QAAQ,cAAc,KAAK,UAAU;AAC3C,YAAI,UAAU,OAAW,SAAQ,KAAK,KAAK;AAAA,MAC7C;AACA,eAAS,OAAO,aAAa,OAAO,OAAO,SAAS;AAAA,IACtD,SAAS,WAAW;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAKA,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,UAAU,cAAc,UAAU;AACxC,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,yBAAyB;AAAA,MACvE,iBAAiB;AAAA,MACjB,qCAAqC;AAAA,MACrC,oBAAoB;AAAA,MACpB,MAAM;AAAA,IACR,CAAC;AACD,UAAM,MAAO,MAAM,SAAS,KAAK;AACjC,UAAM,SAAS,UAAU,UAAU;AACnC,UAAM,QAAQ,cAAc,KAAK,MAAM;AACvC,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,kBAAkB;AAAA,QAC1B,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,oCAAoC,UAAU;AAAA,QACvD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,WAAO,EAAE,GAAG,OAAO,QAAQ,KAAK;AAAA,EAClC;AACF;AAEA,IAAM,4BAAN,MAAsE;AAAA,EACpE,YAA6B,SAAgC;AAAhC;AAAA,EAAiC;AAAA,EAAjC;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,SAAS,KAAK,UAAU,EAAE,MAAM,cAAc,UAAU,EAAE,CAAC;AACjE,UAAM,UAAkC;AAAA,MACtC,mBAAmB;AAAA,IACrB;AACA,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AACA,UAAM,MAAM,GAAG,KAAK,QAAQ,cAAc;AAC1C,UAAM,WAAW,MAAM,aAAa,KAAK,SAAS,KAAK,QAAQ;AAAA,MAC7D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,wBAAwB,UAAU,YAAY,MAAM,aAAa,QAAQ,CAAC;AAAA,IAClF;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,wBAAwB,UAAU;AAAA,QAC3C,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,OAAO,oBAAoB,QAAQ,GAAG;AAC5C,QAAI,OAAO,SAAS,YAAY,KAAK,SAAS,EAAG,QAAO,WAAW;AACnE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,QAAI,QAAQ,WAAW,UAAa,QAAQ,SAAS,GAAG;AACtD,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,QAAQ,QAAQ,OAAO;AAAA,QAClC,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,WAAW,MAAM,cAAc,QAAQ,OAAO;AACpD,UAAM,SAAS,KAAK,UAAU;AAAA,MAC5B,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,cAAc,UAAU;AAAA,MAC9B,iBAAiB;AAAA,IACnB,CAAC;AACD,UAAM,MAAM,GAAG,KAAK,QAAQ,cAAc;AAC1C,UAAM,WAAW,MAAM,aAAa,KAAK,SAAS,KAAK,QAAQ;AAAA,MAC7D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM;AAAA,MACN,cAAc;AAAA,QACZ,gBAAgB;AAAA,QAChB,mBAAmB;AAAA,MACrB;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,wBAAwB,UAAU,YAAY,MAAM,aAAa,QAAQ,CAAC;AAAA,IAClF;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,QAAI,OAAO,KAAK,iBAAiB,YAAY,KAAK,aAAa,SAAS,GAAG;AACzE,aAAO,WAAW,KAAK;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AACF;AAQA,eAAe,aACb,SACA,KACA,QACA,eAAoC,CAAC,GAClB;AACnB,QAAM,UAAkC;AAAA,IACtC,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,gBAAgB,CAAC;AAAA,IAClC,eAAe,UAAU,QAAQ,KAAK;AAAA,EACxC;AACA,QAAM,OAAoB,EAAE,SAAS,OAAO;AAC5C,MAAI,aAAa,SAAS,QAAW;AACnC,IAAC,KAA8B,OAAO,aAAa;AAAA,EACrD;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,aAAa,UAAU;AACxC,MAAI,aAAa,MAAM;AACrB,QAAI,SAAS,QAAS,YAAW,MAAM,SAAS,MAAM;AAAA,QACjD,UAAS,iBAAiB,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,CAAC;AAAA,EACjF;AACA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,2BAA2B,CAAC;AAAA,MAC7D,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EACxE,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,IAAI;AAAA,MACf,SAAS,sBAAsB,GAAG;AAAA,MAClC,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAEA,eAAe,WACb,SACA,UACA,MACmB;AACnB,QAAM,MAAM,GAAG,QAAQ,UAAU,GAAG,QAAQ;AAC5C,QAAM,UAAU,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,IAAI,CAAC;AAC7D,QAAM,WAAW,MAAM,aAAa,SAAS,KAAK,QAAQ;AAAA,IACxD,MAAM;AAAA,IACN,cAAc,EAAE,gBAAgB,mBAAmB;AAAA,EACrD,CAAC;AACD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,aAAa,QAAQ;AACxC,UAAM,wBAAwB,UAAU,UAAU,IAAI;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAoB,aAAqB,UAAyB;AACjG,QAAM,UAAU;AAAA,IACd,UAAU,SAAS,MAAM,GAAG,GAAG;AAAA,IAC/B,MAAM;AAAA,IACN,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,EACvB;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,oBAAoB;AAAA,MAC7B;AAAA,MACA,SAAS,qCAAqC,WAAW;AAAA,MACzD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,sBAAsB;AAAA,MAC/B;AAAA,MACA,SAAS,gCAAgC,WAAW;AAAA,MACpD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,OAAO,YAAY,KAAK,QAAQ,GAAG;AACzD,WAAO,IAAI,kBAAkB;AAAA,MAC3B;AAAA,MACA,SAAS,2BAA2B,WAAW;AAAA,MAC/C,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,gBAAgB;AAAA,MACzB;AAAA,MACA,SAAS,8BAA8B,WAAW;AAAA,MAClD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA,SAAS,uBAAuB,WAAW,uBAAuB,OAAO,SAAS,MAAM,CAAC;AAAA,IACzF,WAAW,SAAS,UAAU;AAAA,EAChC,CAAC;AACH;AA+BA,SAAS,cAAc,KAAsB,YAA6C;AACxF,MAAI,IAAI,MAAM,MAAM,UAAW,QAAO;AACtC,QAAM,cAAc,IAAI;AACxB,QAAMA,QAAO,IAAI,gBAAgB,gBAAgB,YAAY,WAAW;AACxE,QAAM,QAAqB;AAAA,IACzB,MAAM,mBAAmBA,KAAI;AAAA,IAC7B,MAAAA;AAAA,IACA;AAAA,IACA,MAAM,IAAI,MAAM,MAAM,WAAW,cAAc;AAAA,EACjD;AACA,MAAI,IAAI,MAAM,MAAM,QAAQ;AAC1B,UAAM,OAAO;AACb,QAAI,OAAO,KAAK,SAAS,SAAU,OAAM,OAAO,KAAK;AACrD,UAAM,WAAW,KAAK,mBAAmB,KAAK;AAC9C,QAAI,OAAO,aAAa,UAAU;AAChC,YAAM,SAAS,IAAI,KAAK,QAAQ;AAChC,UAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,IAC1D;AACA,QAAI,OAAO,KAAK,iBAAiB,SAAU,OAAM,WAAW,KAAK;AAAA,aACxD,OAAO,KAAK,OAAO,SAAU,OAAM,WAAW,KAAK;AAAA,EAC9D,WAAW,OAAO,IAAI,OAAO,UAAU;AACrC,UAAM,WAAW,IAAI;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,cAAc,YAA4B;AACjD,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,SAAO;AACT;AAEA,SAAS,gBAAgB,QAAgB,MAAsB;AAC7D,MAAI,WAAW,MAAM,WAAW,IAAK,QAAO,IAAI,IAAI;AACpD,SAAO,OAAO,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI;AACtE;AAEA,SAAS,UAAU,YAA4B;AAC7C,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,MAAM,WAAW,YAAY,GAAG;AACtC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,WAAW,MAAM,GAAG,GAAG;AAChC;AAEA,eAAe,aAAa,UAAqC;AAC/D,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,oBAAoB,UAA2D;AACtF,QAAM,SAAS,SAAS,QAAQ,IAAI,oBAAoB;AACxD,MAAI,WAAW,QAAQ,WAAW,GAAI,QAAO;AAC7C,MAAI;AACF,WAAO,KAAK,MAAM,MAAM;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,cAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;;;ACxhBA,SAAS,UAAAC,eAAc;AAmCvB,IAAM,kBAAkB;AACxB,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAE3B,IAAM,+BAAqD,CAAC,OAAO,UAAU,QAAQ;AAErF,IAAM,qBACJ;AACF,IAAM,qBAAqB,uBAAuB,kBAAkB;AA4B7D,SAAS,iCACd,UAAsC,CAAC,GACtB;AACjB,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,eAAe,QAAQ,gBAAgB;AAE7C,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,SAAS,OAAO;AAAA,IACjC,UAAU,CAAC,GAAG,4BAA4B;AAAA,IAC1C,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,aAAa,YAAY,UAAU;AAAA,IAC5D,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,oBAAoB;AAAA,MACtB;AAAA,MACA;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAYA,IAAM,sBAAN,MAAsD;AAAA,EAIpD,YAA6B,WAAuC;AAAvC;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,QAAQC,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAClE,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,iBAA4C;AAAA,MAChD,YAAY,KAAK,UAAU;AAAA,MAC3B,cAAc,KAAK,UAAU;AAAA,MAC7B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,OAAO,KAAK,UAAU;AAAA,MACtB,IAAI,KAAK,UAAU;AAAA,MACnB,cAAc,KAAK,UAAU;AAAA,MAC7B;AAAA,MACA,eAAe,KAAK,UAAU;AAAA,IAChC;AACA,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,mBAAmB,cAAc;AAAA,EAC9C;AACF;AAcA,IAAM,qBAAN,MAAoD;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAoC;AAC9C,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,UAAM,WAAW,IAAI,wBAAwB,OAAO;AACpD,SAAK,KAAK,IAAI,sBAAsB,SAAS,QAAQ;AACrD,SAAK,YAAY,IAAI,8BAA8B,SAAS,QAAQ;AAAA,EACtE;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAoBA,IAAM,0BAAN,MAA8B;AAAA,EAG5B,YAA6B,SAAoC;AAApC;AAAA,EAAqC;AAAA,EAArC;AAAA,EAFZ,QAAQ,oBAAI,IAA+B;AAAA;AAAA,EAK5D,MAAM,YAAYC,OAA0C;AAC1D,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,QAAI,eAAe,OAAO,eAAe,IAAI;AAC3C,aAAO;AAAA,QACL,IAAI,KAAK,QAAQ;AAAA,QACjB,UAAU;AAAA,QACV,MAAM;AAAA,MACR;AAAA,IACF;AACA,UAAM,SAAS,KAAK,MAAM,IAAI,UAAU;AACxC,QAAI,WAAW,OAAW,QAAO;AACjC,UAAM,WAAW,WAAW,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AAC7D,QAAI,SAA4B;AAAA,MAC9B,IAAI,KAAK,QAAQ;AAAA,MACjB,UAAU;AAAA,MACV,MAAM;AAAA,IACR;AACA,QAAI,SAAS;AACb,eAAW,WAAW,UAAU;AAC9B,YAAM,QAAQ,MAAM,KAAK,UAAU,OAAO,IAAI,OAAO;AACrD,UAAI,UAAU,QAAW;AACvB,cAAM,IAAI,kBAAkB;AAAA,UAC1B,SAAS,EAAE,MAAM,WAAW;AAAA,UAC5B,SAAS,gCAAgC,UAAU;AAAA,UACnD,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AACA,eAAS,GAAG,MAAM,IAAI,OAAO;AAC7B,WAAK,MAAM,IAAI,QAAQ,KAAK;AAC5B,eAAS;AAAA,IACX;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,gBAAgBA,OAA+B;AACnD,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,QAAI,eAAe,OAAO,eAAe,GAAI,QAAO,KAAK,QAAQ;AACjE,UAAM,MAAM,WAAW,YAAY,GAAG;AACtC,QAAI,OAAO,EAAG,QAAO,KAAK,QAAQ;AAClC,UAAM,aAAa,WAAW,MAAM,GAAG,GAAG;AAC1C,UAAM,SAAS,MAAM,KAAK,YAAY,UAAU;AAChD,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAc,UAAU,UAAkB,MAAsD;AAC9F,UAAM,IAAI,IAAI,aAAa,QAAQ,CAAC,4BAA4B,aAAa,IAAI,CAAC;AAClF,UAAM,WAAW,MAAM;AAAA,MACrB,KAAK;AAAA,MACL;AAAA,MACA,UAAU,YAAY;AAAA,QACpB,QAAQ;AAAA,QACR,UAAU;AAAA,QACV;AAAA,QACA,mBAAmB;AAAA,QACnB,2BAA2B;AAAA,MAC7B,CAAC,CAAC;AAAA,IACJ;AACA,UAAM,SAAU,MAAM,SAAS,KAAK;AACpC,WAAO,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EACjD;AACF;AAEA,IAAM,wBAAN,MAAwD;AAAA,EACtD,YACmB,SACA,UACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EAGnB,MAAM,KAAKA,OAAsC;AAC/C,UAAM,SAAS,MAAM,KAAK,SAAS,YAAYA,KAAI;AACnD,QAAI,OAAO,aAAa,sBAAsB,OAAO,OAAO,KAAK,QAAQ,cAAc;AACrF,YAAM,IAAI,kBAAkB;AAAA,QAC1B,SAAS,EAAE,MAAAA,MAAK;AAAA,QAChB,SAAS,sCAAsCA,KAAI;AAAA,QACnD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,UAAyB,CAAC;AAChC,QAAI;AACJ,OAAG;AACD,YAAM,SAAiC;AAAA,QACrC,QAAQ;AAAA,QACR,2BAA2B;AAAA,QAC3B,UAAU;AAAA,QACV,GAAG,IAAI,aAAa,OAAO,EAAE,CAAC;AAAA,QAC9B,mBAAmB;AAAA,MACrB;AACA,UAAI,cAAc,OAAW,QAAO,WAAW,IAAI;AACnD,YAAM,WAAW,MAAM,SAAS,KAAK,SAAS,OAAO,UAAU,YAAY,MAAM,CAAC,EAAE;AACpF,YAAM,SAAU,MAAM,SAAS,KAAK;AACpC,iBAAW,QAAQ,OAAO,OAAO;AAC/B,gBAAQ,KAAKC,eAAc,MAAM,UAAU,CAAC;AAAA,MAC9C;AACA,kBAAY,OAAO;AAAA,IACrB,SAAS,cAAc;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAKD,OAAmC;AAC5C,UAAM,OAAO,MAAM,KAAK,SAAS,YAAYA,KAAI;AACjD,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,SAASE,WAAU,UAAU;AACnC,UAAM,QAAQD,eAAc,MAAM,MAAM;AACxC,WAAO,EAAE,GAAG,OAAO,QAAQ,KAAK;AAAA,EAClC;AACF;AAEA,IAAM,gCAAN,MAA0E;AAAA,EACxE,YACmB,SACA,UACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EAGnB,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,OAAO,MAAM,KAAK,SAAS,YAAY,UAAU;AACvD,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AACA,UAAM,SAAS,YAAY,EAAE,KAAK,SAAS,mBAAmB,OAAO,CAAC;AACtE,UAAM,WAAW,MAAM;AAAA,MACrB,KAAK;AAAA,MACL;AAAA,MACA,GAAG,KAAK,QAAQ,UAAU,UAAU,mBAAmB,KAAK,EAAE,CAAC,IAAI,MAAM;AAAA,MACzE;AAAA,QACE,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,QACjE,cAAc;AAAA,MAChB;AAAA,IACF;AACA,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,4BAA4B,UAAU,YAAY,MAAME,cAAa,QAAQ,CAAC;AAAA,IACtF;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,6BAA6B,UAAU;AAAA,QAChD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,QAAI,OAAO,KAAK,gBAAgB,YAAY,KAAK,YAAY,SAAS,GAAG;AACvE,aAAO,WAAW,KAAK;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,QAAI,QAAQ,WAAW,UAAa,QAAQ,SAAS,GAAG;AACtD,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,QAAQ,QAAQ,OAAO;AAAA,QAClC,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,WAAW,MAAMC,eAAc,QAAQ,OAAO;AACpD,UAAM,WAAW,MAAM,KAAK,SAAS,gBAAgB,UAAU;AAC/D,UAAM,OAAO,mBAAmB,UAAU;AAC1C,UAAM,WAAW,MAAM,KAAK,aAAa,UAAU,IAAI;AAEvD,UAAM,WAAoC,EAAE,KAAK;AACjD,QAAI,aAAa,OAAW,UAAS,SAAS,IAAI,CAAC,QAAQ;AAE3D,UAAM,WAAW,mBAAmB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC;AAClG,UAAM,YAA0B,CAAC;AACjC,UAAM,MAAM,IAAI,YAAY;AAC5B,cAAU;AAAA,MACR,IAAI;AAAA,QACF,KAAK,QAAQ;AAAA;AAAA;AAAA,EAA4D,KAAK,UAAU,QAAQ,CAAC;AAAA;AAAA,MACnG;AAAA,IACF;AACA,cAAU,KAAK,IAAI,OAAO,KAAK,QAAQ;AAAA;AAAA;AAAA,CAAoD,CAAC;AAC5F,cAAU,KAAK,QAAQ;AACvB,cAAU,KAAK,IAAI,OAAO;AAAA,IAAS,QAAQ;AAAA,CAAQ,CAAC;AACpD,UAAM,OAAO,aAAa,SAAS;AAEnC,UAAM,MACJ,aAAa,SACT,GAAG,KAAK,QAAQ,aAAa,6DAA6D,mBAAmB,kBAAkB,CAAC,KAChI,GAAG,KAAK,QAAQ,aAAa,UAAU,mBAAmB,SAAS,EAAE,CAAC,uDAAuD,mBAAmB,kBAAkB,CAAC;AACzK,UAAM,SAAS,aAAa,SAAY,SAAS;AAEjD,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,QAAQ,KAAK;AAAA,MAC3D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE;AAAA,MACA,cAAc,EAAE,gBAAgB,+BAA+B,QAAQ,GAAG;AAAA,IAC5E,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,4BAA4B,UAAU,YAAY,MAAMD,cAAa,QAAQ,CAAC;AAAA,IACtF;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,QAAI,OAAO,KAAK,gBAAgB,YAAY,KAAK,YAAY,SAAS,GAAG;AACvE,aAAO,WAAW,KAAK;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,aACZ,UACA,MACwC;AACxC,UAAM,IAAI,IAAI,aAAa,QAAQ,CAAC,4BAA4B,aAAa,IAAI,CAAC;AAClF,UAAM,WAAW,MAAM;AAAA,MACrB,KAAK;AAAA,MACL;AAAA,MACA,UAAU,YAAY;AAAA,QACpB,QAAQ;AAAA,QACR,2BAA2B;AAAA,QAC3B,UAAU;AAAA,QACV;AAAA,QACA,mBAAmB;AAAA,MACrB,CAAC,CAAC;AAAA,IACJ;AACA,UAAM,SAAU,MAAM,SAAS,KAAK;AACpC,WAAO,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EACjD;AACF;AAQA,eAAe,WACb,SACA,QACA,KACA,eAAkC,CAAC,GAChB;AACnB,QAAM,UAAkC;AAAA,IACtC,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,gBAAgB,CAAC;AAAA,IAClC,eAAe,UAAU,QAAQ,KAAK;AAAA,EACxC;AACA,QAAM,OAAoB,EAAE,SAAS,OAAO;AAC5C,MAAI,aAAa,SAAS,QAAW;AACnC,IAAC,KAA8B,OAAO,aAAa;AAAA,EACrD;AACA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,aAAa,UAAU;AACxC,MAAI,aAAa,MAAM;AACrB,QAAI,SAAS,QAAS,YAAW,MAAM,SAAS,MAAM;AAAA,QACjD,UAAS,iBAAiB,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,CAAC;AAAA,EACjF;AACA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,gCAAgC,CAAC;AAAA,MAClE,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EACxE,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,IAAI;AAAA,MACf,SAAS,2BAA2B,GAAG;AAAA,MACvC,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAEA,eAAe,SACb,SACA,QACA,SACmB;AACnB,QAAM,MAAM,GAAG,QAAQ,UAAU,GAAG,OAAO;AAC3C,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,GAAG;AACtD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAMA,cAAa,QAAQ;AACxC,UAAM,4BAA4B,UAAU,SAAS,IAAI;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,4BACP,UACA,aACA,UACO;AACP,QAAM,UAAU;AAAA,IACd,UAAU,SAAS,MAAM,GAAG,GAAG;AAAA,IAC/B,MAAM;AAAA,IACN,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,EACvB;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,oBAAoB;AAAA,MAC7B;AAAA,MACA,SAAS,0CAA0C,WAAW;AAAA,MAC9D,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,sBAAsB;AAAA,MAC/B;AAAA,MACA,SAAS,qCAAqC,WAAW;AAAA,MACzD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,kBAAkB;AAAA,MAC3B;AAAA,MACA,SAAS,gCAAgC,WAAW;AAAA,MACpD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,gBAAgB;AAAA,MACzB;AAAA,MACA,SAAS,mCAAmC,WAAW;AAAA,MACvD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA,SAAS,4BAA4B,WAAW,uBAAuB,OAAO,SAAS,MAAM,CAAC;AAAA,IAC9F,WAAW,SAAS,UAAU;AAAA,EAChC,CAAC;AACH;AAEA,SAASF,eAAc,MAAyB,QAA6B;AAC3E,QAAMD,QAAO,cAAc,QAAQ,KAAK,IAAI;AAC5C,QAAM,QAAqB;AAAA,IACzB,MAAM,KAAK;AAAA,IACX,MAAAA;AAAA,IACA,KAAK;AAAA,IACL,MAAM,KAAK,aAAa,qBAAqB,cAAc;AAAA,IAC3D,UAAU,KAAK;AAAA,EACjB;AACA,MAAI,OAAO,KAAK,SAAS,UAAU;AACjC,UAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAI,OAAO,SAAS,KAAK,EAAG,OAAM,OAAO;AAAA,EAC3C;AACA,MAAI,OAAO,KAAK,iBAAiB,UAAU;AACzC,UAAM,SAAS,IAAI,KAAK,KAAK,YAAY;AACzC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,EAC1D;AACA,MAAI,OAAO,KAAK,gBAAgB,UAAU;AACxC,UAAM,SAAS,IAAI,KAAK,KAAK,WAAW;AACxC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,YAAY;AAAA,EACzD;AACA,SAAO;AACT;AAEA,SAAS,cAAc,QAAgB,MAAsB;AAC3D,MAAI,WAAW,MAAM,WAAW,IAAK,QAAO,IAAI,IAAI;AACpD,SAAO,OAAO,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI;AACtE;AAEA,SAASE,WAAU,YAA4B;AAC7C,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,MAAM,WAAW,YAAY,GAAG;AACtC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,WAAW,MAAM,GAAG,GAAG;AAChC;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACzD;AAEA,SAAS,YAAY,QAAwC;AAC3D,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,EAAG,QAAO,IAAI,GAAG,CAAC;AAC5D,SAAO,OAAO,SAAS;AACzB;AAEA,eAAeC,cAAa,UAAqC;AAC/D,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAeC,eAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,SAAO,aAAa,QAAQ,KAAK;AACnC;AAEA,SAAS,aAAa,QAAsB,WAAgC;AAC1E,QAAM,QAAQ,aAAa,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,YAAY,CAAC;AAC1E,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;;;ACjmBA,IAAM,sBAAsB;AAC5B,IAAM,iCAAuD,CAAC,QAAQ,UAAU,cAAc;AAwBvF,SAAS,8BACd,UAAmC,CAAC,GACnB;AACjB,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAM,gBAAgB,QAAQ,gBAAgB,qBAAqB,QAAQ,SAAS,EAAE;AAEtF,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,SAAS,OAAO;AAAA,IACjC,UAAU,CAAC,GAAG,8BAA8B;AAAA,IAC5C,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,aAAa,UAAU;AAAA,IAChD,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,iBAAiB;AAAA,MACnB;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAUA,IAAM,mBAAN,MAAmD;AAAA,EAIjD,YAA6B,WAAoC;AAApC;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,QAAQC,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAClE,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,iBAAyC;AAAA,MAC7C,cAAc,KAAK,UAAU;AAAA,MAC7B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,cAAc,KAAK,UAAU;AAAA,MAC7B,OAAO,KAAK,UAAU;AAAA,MACtB,IAAI,KAAK,UAAU;AAAA,MACnB;AAAA,IACF;AACA,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,gBAAgB,cAAc;AAAA,EAC3C;AACF;AAYA,IAAM,kBAAN,MAAiD;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiC;AAC3C,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,mBAAmB,OAAO;AACxC,SAAK,YAAY,IAAI,2BAA2B,OAAO;AAAA,EACzD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AA8BA,IAAM,qBAAN,MAAqD;AAAA,EACnD,YAA6B,SAAiC;AAAjC;AAAA,EAAkC;AAAA,EAAlC;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,UAAU,GAAG,KAAK,QAAQ,YAAY,GAAG,oBAAoB,UAAU,CAAC;AAC9E,UAAM,UAAyB,CAAC;AAChC,QAAI,UAA8B;AAClC,WAAO,YAAY,QAAW;AAC5B,YAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,OAAO;AAC9D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,yBAAyB,UAAU,YAAY,MAAMC,cAAa,QAAQ,CAAC;AAAA,MACnF;AACA,YAAM,SAAU,MAAM,SAAS,KAAK;AACpC,iBAAW,QAAQ,OAAO,OAAO;AAC/B,gBAAQ,KAAKC,eAAc,MAAM,UAAU,CAAC;AAAA,MAC9C;AACA,gBAAU,OAAO,iBAAiB;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAKF,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,GAAG,YAAY,UAAU,CAAC;AAClE,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,GAAG;AAC1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,yBAAyB,UAAU,YAAY,MAAMC,cAAa,QAAQ,CAAC;AAAA,IACnF;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,SAASE,WAAU,UAAU;AACnC,UAAM,QAAQD,eAAc,MAAM,MAAM;AACxC,WAAO,EAAE,GAAG,OAAO,QAAQ,KAAK;AAAA,EAClC;AACF;AAEA,IAAM,6BAAN,MAAuE;AAAA,EACrE,YAA6B,SAAiC;AAAjC;AAAA,EAAkC;AAAA,EAAlC;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,GAAG,YAAY,UAAU,CAAC;AAClE,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AAIA,UAAM,OAAO,MAAM,KAAK,UAAU,UAAU;AAC5C,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,KAAK;AAAA,MAC1D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,yBAAyB,UAAU,YAAY,MAAMD,cAAa,QAAQ,CAAC;AAAA,IACnF;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,yBAAyB,UAAU;AAAA,QAC5C,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,WAAW,WAAW,KAAK,MAAM,MAAM;AAC7C,QAAI,aAAa,OAAW,QAAO,WAAW;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,QAAI,QAAQ,WAAW,UAAa,QAAQ,SAAS,GAAG;AACtD,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,QAAQ,QAAQ,OAAO;AAAA,QAClC,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,WAAW,MAAMG,eAAc,QAAQ,OAAO;AACpD,UAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,GAAG,YAAY,UAAU,CAAC;AAClE,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,KAAK;AAAA,MAC1D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM;AAAA,MACN,cAAc,EAAE,gBAAgB,2BAA2B;AAAA,IAC7D,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,yBAAyB,UAAU,YAAY,MAAMH,cAAa,QAAQ,CAAC;AAAA,IACnF;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,UAAM,WAAW,WAAW,KAAK,MAAM,MAAM;AAC7C,QAAI,aAAa,OAAW,QAAO,WAAW;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,UAAU,YAAwC;AAC9D,UAAM,MAAM,GAAG,KAAK,QAAQ,YAAY,GAAG,YAAY,UAAU,CAAC;AAClE,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,GAAG;AAC1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,yBAAyB,UAAU,YAAY,MAAMA,cAAa,QAAQ,CAAC;AAAA,IACnF;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AACF;AAQA,eAAe,WACb,SACA,QACA,KACA,eAAkC,CAAC,GAChB;AACnB,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,gBAAgB,CAAC;AAAA,IAClC,eAAe,UAAU,QAAQ,KAAK;AAAA,EACxC;AACA,QAAM,OAAoB,EAAE,SAAS,OAAO;AAC5C,MAAI,aAAa,SAAS,QAAW;AACnC,IAAC,KAA8B,OAAO,aAAa;AAAA,EACrD;AACA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,aAAa,UAAU;AACxC,MAAI,aAAa,MAAM;AACrB,QAAI,SAAS,QAAS,YAAW,MAAM,SAAS,MAAM;AAAA,QACjD,UAAS,iBAAiB,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,CAAC;AAAA,EACjF;AACA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,4BAA4B,CAAC;AAAA,MAC9D,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EACxE,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,IAAI;AAAA,MACf,SAAS,uBAAuB,GAAG;AAAA,MACnC,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAEA,SAAS,yBACP,UACA,aACA,UACO;AACP,QAAM,UAAU;AAAA,IACd,UAAU,SAAS,MAAM,GAAG,GAAG;AAAA,IAC/B,MAAM;AAAA,IACN,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,EACvB;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,oBAAoB;AAAA,MAC7B;AAAA,MACA,SAAS,sCAAsC,WAAW;AAAA,MAC1D,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,sBAAsB;AAAA,MAC/B;AAAA,MACA,SAAS,iCAAiC,WAAW;AAAA,MACrD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,kBAAkB;AAAA,MAC3B;AAAA,MACA,SAAS,4BAA4B,WAAW;AAAA,MAChD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,gBAAgB;AAAA,MACzB;AAAA,MACA,SAAS,+BAA+B,WAAW;AAAA,MACnD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA,SAAS,wBAAwB,WAAW,uBAAuB,OAAO,SAAS,MAAM,CAAC;AAAA,IAC1F,WAAW,SAAS,UAAU;AAAA,EAChC,CAAC;AACH;AAEA,SAASC,eAAc,MAAiB,QAA6B;AACnE,QAAMF,QAAO,SAAS,QAAQ,KAAK,IAAI;AACvC,QAAM,QAAqB;AAAA,IACzB,MAAM,KAAK;AAAA,IACX,MAAAA;AAAA,IACA,KAAK;AAAA,IACL,MAAM,KAAK,WAAW,SAAY,cAAc;AAAA,IAChD,UAAU,KAAK;AAAA,EACjB;AACA,MAAI,OAAO,KAAK,SAAS,SAAU,OAAM,OAAO,KAAK;AACrD,MAAI,OAAO,KAAK,yBAAyB,UAAU;AACjD,UAAM,SAAS,IAAI,KAAK,KAAK,oBAAoB;AACjD,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,EAC1D;AACA,MAAI,OAAO,KAAK,oBAAoB,UAAU;AAC5C,UAAM,SAAS,IAAI,KAAK,KAAK,eAAe;AAC5C,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,YAAY;AAAA,EACzD;AACA,SAAO;AACT;AAEA,SAAS,WAAW,QAAyD;AAC3E,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,OAAO,eAAe,YAAY,OAAO,WAAW,SAAS,GAAG;AACzE,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,OAAO,OAAO,aAAa,YAAY,OAAO,SAAS,SAAS,GAAG;AACrE,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,OAAO,OAAO,iBAAiB,YAAY,OAAO,aAAa,SAAS,GAAG;AAC7E,WAAO,OAAO;AAAA,EAChB;AACA,SAAO;AACT;AAGA,SAAS,YAAY,YAA4B;AAC/C,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,UAAU,WAAW,QAAQ,SAAS,EAAE;AAC9C,SAAO,UAAU,gBAAgB,OAAO,CAAC;AAC3C;AAGA,SAAS,oBAAoB,YAA4B;AACvD,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,UAAU,WAAW,QAAQ,SAAS,EAAE;AAC9C,SAAO,UAAU,gBAAgB,OAAO,CAAC;AAC3C;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,SAAO,MACJ,MAAM,GAAG,EACT,IAAI,CAAC,YAAY,mBAAmB,OAAO,CAAC,EAC5C,KAAK,GAAG;AACb;AAEA,SAAS,SAAS,QAAgB,MAAsB;AACtD,MAAI,WAAW,MAAM,WAAW,IAAK,QAAO,IAAI,IAAI;AACpD,SAAO,OAAO,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI;AACtE;AAEA,SAASG,WAAU,YAA4B;AAC7C,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,MAAM,WAAW,YAAY,GAAG;AACtC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,WAAW,MAAM,GAAG,GAAG;AAChC;AAEA,eAAeF,cAAa,UAAqC;AAC/D,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAeG,eAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;;;ACpeA,IAAM,yBAAyB;AAC/B,IAAM,8BAAoD,CAAC,KAAK;AA2BzD,SAAS,+BAA+B,SAAoD;AACjG,MAAI,OAAO,QAAQ,cAAc,YAAY,QAAQ,cAAc,IAAI;AACrE,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,WAAW,qBAAqB,OAAO;AAC7C,QAAM,aAAa,QAAQ,cAAc;AAEzC,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,SAAS,OAAO;AAAA,IACjC,UAAU,CAAC,GAAG,2BAA2B;AAAA,IACzC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,UAAU;AAAA,IACnC,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,kBAAkB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,IACzE,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAA2C;AACvE,MAAI,OAAO,QAAQ,aAAa,YAAY,QAAQ,aAAa,IAAI;AACnE,WAAO,QAAQ,SAAS,QAAQ,SAAS,EAAE;AAAA,EAC7C;AACA,MAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,YAAY,IAAI;AACjE,WAAO,WAAW,QAAQ,OAAO;AAAA,EACnC;AACA,QAAM,IAAI,mBAAmB;AAAA,IAC3B,SAAS;AAAA,IACT,WAAW;AAAA,EACb,CAAC;AACH;AAaA,IAAM,oBAAN,MAAoD;AAAA,EAIlD,YAA6B,WAAqC;AAArC;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,QAAI;AACJ,QAAI,QAAQ,aAAa,QAAW;AAClC,oBAAcC,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAClE,UAAI,gBAAgB,GAAI,eAAc;AAAA,IACxC;AACA,QAAI,gBAAgB,UAAa,KAAK,UAAU,aAAa,QAAW;AACtE,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SACE;AAAA,QACF,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,iBAA0C;AAAA,MAC9C,YAAY,KAAK,UAAU;AAAA,MAC3B,cAAc,KAAK,UAAU;AAAA,MAC7B,WAAW,KAAK,UAAU;AAAA,MAC1B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,UAAU,KAAK,UAAU;AAAA,MACzB,OAAO,KAAK,UAAU;AAAA,MACtB,IAAI,KAAK,UAAU;AAAA,IACrB;AACA,QAAI,gBAAgB,OAAW,gBAAe,cAAc;AAC5D,QAAI,KAAK,UAAU,aAAa,OAAW,gBAAe,WAAW,KAAK,UAAU;AACpF,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,iBAAiB,cAAc;AAAA,EAC5C;AACF;AAeA,IAAM,mBAAN,MAAkD;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAkC;AAC5C,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,oBAAoB,OAAO;AACzC,SAAK,YAAY,IAAI,4BAA4B,OAAO;AAAA,EAC1D;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,sBAAN,MAAsD;AAAA,EACpD,YAA6B,SAAkC;AAAlC;AAAA,EAAmC;AAAA,EAAnC;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,SAAS,kBAAkB,UAAU;AAC3C,UAAM,UAAyB,CAAC;AAChC,QAAI;AACJ,OAAG;AACD,YAAM,SAAiC;AAAA,QACrC,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AACA,UAAI,WAAW,GAAI,QAAO,QAAQ,IAAI;AACtC,UAAI,WAAW,OAAW,QAAO,QAAQ,IAAI;AAC7C,YAAM,MAAM,kBAAkB,KAAK,SAAS,MAAM;AAClD,YAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,GAAG;AAC1D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,sBAAsB,UAAU,YAAY,MAAMC,cAAa,QAAQ,CAAC;AAAA,MAChF;AACA,YAAM,MAAM,MAAM,SAAS,KAAK;AAChC,YAAM,SAAS,uBAAuB,GAAG;AACzC,iBAAW,QAAQ,OAAO,OAAO;AAC/B,YAAI,KAAK,KAAK,WAAW,MAAM,GAAG;AAChC,gBAAM,QAAQ,YAAY,MAAM,QAAQ,UAAU;AAClD,cAAI,UAAU,OAAW,SAAQ,KAAK,KAAK;AAAA,QAC7C;AAAA,MACF;AACA,iBAAW,OAAO,OAAO,UAAU;AACjC,cAAM,QAAQ,cAAc,KAAK,QAAQ,UAAU;AACnD,YAAI,UAAU,OAAW,SAAQ,KAAK,KAAK;AAAA,MAC7C;AACA,eAAS,OAAO;AAAA,IAClB,SAAS,WAAW,UAAa,WAAW;AAC5C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAKD,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,MAAM,aAAa,KAAK,SAAS,UAAU;AACjD,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,QAAQ,GAAG;AAC3D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,sBAAsB,UAAU,YAAY,MAAMC,cAAa,QAAQ,CAAC;AAAA,IAChF;AACA,UAAM,aAAa,SAAS,QAAQ,IAAI,gBAAgB;AACxD,UAAM,OAAO,eAAe,OAAO,OAAO,UAAU,IAAI;AACxD,UAAM,eAAe,SAAS,QAAQ,IAAI,eAAe;AACzD,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM,KAAK;AAC7C,UAAM,MAAM,SAAS,QAAQ,IAAI,aAAa,KAAK;AACnD,UAAM,OAAmB;AAAA,MACvB,QAAQ;AAAA,MACR,MAAMC,oBAAmB,UAAU;AAAA,MACnC,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,QAAI,OAAO,SAAS,YAAY,OAAO,SAAS,IAAI,EAAG,MAAK,OAAO;AACnE,QAAI,iBAAiB,MAAM;AACzB,YAAM,SAAS,IAAI,KAAK,YAAY;AACpC,UAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,MAAK,aAAa;AAAA,IACzD;AACA,QAAI,SAAS,OAAW,MAAK,WAAW;AAAA,aAC/B,QAAQ,OAAW,MAAK,WAAW;AAC5C,WAAO;AAAA,EACT;AACF;AAEA,IAAM,8BAAN,MAAwE;AAAA,EACtE,YAA6B,SAAkC;AAAlC;AAAA,EAAmC;AAAA,EAAnC;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,MAAM,aAAa,KAAK,SAAS,UAAU;AACjD,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AACA,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,KAAK;AAAA,MAC1D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,sBAAsB,UAAU,YAAY,MAAMD,cAAa,QAAQ,CAAC;AAAA,IAChF;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,2BAA2B,UAAU;AAAA,QAC9C,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,MAAM,SAAS,QAAQ,IAAI,aAAa;AAC9C,QAAI,QAAQ,QAAQ,QAAQ,GAAI,QAAO,WAAW;AAClD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,QAAI,QAAQ,WAAW,UAAa,QAAQ,SAAS,GAAG;AACtD,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,QAAQ,QAAQ,OAAO;AAAA,QAClC,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,WAAW,MAAME,eAAc,QAAQ,OAAO;AACpD,UAAM,MAAM,aAAa,KAAK,SAAS,UAAU;AACjD,UAAM,WAAW,MAAM,WAAW,KAAK,SAAS,OAAO,KAAK;AAAA,MAC1D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM;AAAA,MACN,cAAc;AAAA,QACZ,gBAAgB;AAAA,QAChB,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,sBAAsB,UAAU,YAAY,MAAMF,cAAa,QAAQ,CAAC;AAAA,IAChF;AACA,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,UAAM,MAAM,SAAS,QAAQ,IAAI,aAAa;AAC9C,QAAI,QAAQ,QAAQ,QAAQ,GAAI,QAAO,WAAW;AAClD,WAAO;AAAA,EACT;AACF;AAQA,eAAe,WACb,SACA,QACA,KACA,eAAkC,CAAC,GAChB;AACnB,QAAM,UAAkC;AAAA,IACtC,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,gBAAgB,CAAC;AAAA,IAClC,gBAAgB,QAAQ;AAAA,EAC1B;AACA,MAAI,QAAQ,gBAAgB,QAAW;AACrC,YAAQ,eAAe,IAAI,UAAU,QAAQ,WAAW;AAAA,EAC1D;AACA,QAAM,OAAoB,EAAE,SAAS,OAAO;AAC5C,MAAI,aAAa,SAAS,QAAW;AACnC,IAAC,KAA8B,OAAO,aAAa;AAAA,EACrD;AACA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,aAAa,UAAU;AACxC,MAAI,aAAa,MAAM;AACrB,QAAI,SAAS,QAAS,YAAW,MAAM,SAAS,MAAM;AAAA,QACjD,UAAS,iBAAiB,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,CAAC;AAAA,EACjF;AACA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,8BAA8B,CAAC;AAAA,MAChE,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EACxE,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,IAAI;AAAA,MACf,SAAS,yBAAyB,GAAG;AAAA,MACrC,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAEA,SAAS,kBACP,SACA,QACQ;AACR,QAAM,SAAS,IAAI,gBAAgB,MAAM;AACzC,YAAU,QAAQ,QAAQ,QAAQ;AAClC,SAAO,GAAG,QAAQ,QAAQ,IAAI,mBAAmB,QAAQ,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC;AAC1F;AAEA,SAAS,aAAa,SAAkC,YAA4B;AAClF,QAAM,WAAW,WAAW,QAAQ,SAAS,EAAE;AAC/C,QAAM,UAAU,SACb,MAAM,GAAG,EACT,IAAI,CAAC,YAAY,mBAAmB,OAAO,CAAC,EAC5C,KAAK,GAAG;AACX,QAAM,OAAO,GAAG,QAAQ,QAAQ,IAAI,mBAAmB,QAAQ,SAAS,CAAC,IAAI,OAAO;AACpF,MAAI,QAAQ,aAAa,UAAa,QAAQ,aAAa,IAAI;AAC7D,WAAO,GAAG,IAAI,IAAI,QAAQ,QAAQ;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,UAAU,QAAyB,UAAoC;AAC9E,MAAI,aAAa,UAAa,aAAa,GAAI;AAC/C,QAAM,MAAM,IAAI,gBAAgB,QAAQ;AACxC,aAAW,CAAC,GAAG,CAAC,KAAK,IAAI,QAAQ,EAAG,QAAO,IAAI,GAAG,CAAC;AACrD;AAmBA,SAAS,uBAAuB,KAA+B;AAC7D,QAAM,QAAmC,CAAC;AAC1C,aAAW,SAAS,IAAI,SAAS,2BAA2B,GAAG;AAC7D,UAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,UAAM,OAAO,WAAW,OAAO,MAAM;AACrC,QAAI,SAAS,OAAW;AACxB,UAAM,OAA0C,EAAE,KAAK;AACvD,UAAM,SAAS,WAAW,OAAO,gBAAgB;AACjD,QAAI,WAAW,QAAW;AACxB,YAAM,SAAS,OAAO,MAAM;AAC5B,UAAI,OAAO,SAAS,MAAM,EAAG,MAAK,gBAAgB;AAAA,IACpD;AACA,UAAM,MAAM,WAAW,OAAO,aAAa;AAC3C,QAAI,QAAQ,UAAa,QAAQ,GAAI,MAAK,aAAa;AACvD,UAAM,OAAO,WAAW,OAAO,MAAM;AACrC,QAAI,SAAS,UAAa,SAAS,GAAI,MAAK,OAAO;AACnD,UAAM,OAAO,WAAW,OAAO,eAAe;AAC9C,QAAI,SAAS,UAAa,SAAS,GAAI,MAAK,eAAe;AAC3D,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,QAAM,WAAqB,CAAC;AAC5B,aAAW,SAAS,IAAI,SAAS,uCAAuC,GAAG;AACzE,UAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,UAAM,OAAO,WAAW,OAAO,MAAM;AACrC,QAAI,SAAS,OAAW,UAAS,KAAK,IAAI;AAAA,EAC5C;AACA,QAAM,aAAa,WAAW,KAAK,YAAY;AAC/C,QAAM,SAA2B,EAAE,OAAO,SAAS;AACnD,MAAI,eAAe,UAAa,eAAe,GAAI,QAAO,aAAa;AACvE,SAAO;AACT;AAEA,SAAS,WAAW,OAAe,KAAiC;AAClE,QAAM,KAAK,IAAI,OAAO,IAAI,GAAG,kBAAkB,GAAG,GAAG;AACrD,QAAM,QAAQ,GAAG,KAAK,KAAK;AAC3B,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,cAAc,MAAM,CAAC,KAAK,EAAE;AACrC;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,MACJ,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,GAAG,EACpB,QAAQ,WAAW,GAAG,EACtB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG;AAC1B;AAEA,SAAS,YACP,MACA,QACA,QACyB;AACzB,QAAM,OAAO,KAAK,KAAK,MAAM,OAAO,MAAM;AAC1C,MAAI,SAAS,MAAM,KAAK,SAAS,GAAG,EAAG,QAAO;AAC9C,QAAM,QAAqB;AAAA,IACzB,MAAM;AAAA,IACN,MAAMG,UAAS,QAAQ,IAAI;AAAA,IAC3B,KAAK;AAAA,IACL,MAAM;AAAA,IACN,UAAU,KAAK,QAAQ,KAAK,cAAc,KAAK;AAAA,EACjD;AACA,MAAI,OAAO,KAAK,kBAAkB,SAAU,OAAM,OAAO,KAAK;AAC9D,MAAI,OAAO,KAAK,iBAAiB,UAAU;AACzC,UAAM,SAAS,IAAI,KAAK,KAAK,YAAY;AACzC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,cACP,cACA,QACA,QACyB;AACzB,QAAM,OAAO,aAAa,MAAM,OAAO,MAAM,EAAE,QAAQ,SAAS,EAAE;AAClE,MAAI,SAAS,MAAM,KAAK,SAAS,GAAG,EAAG,QAAO;AAC9C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAMA,UAAS,QAAQ,IAAI;AAAA,IAC3B,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,kBAAkB,YAA4B;AACrD,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,UAAU,WAAW,QAAQ,SAAS,EAAE;AAC9C,SAAO,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACrD;AAEA,SAASA,UAAS,QAAgB,MAAsB;AACtD,MAAI,WAAW,MAAM,WAAW,IAAK,QAAO,IAAI,IAAI;AACpD,SAAO,OAAO,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI;AACtE;AAEA,SAASF,oBAAmB,YAA4B;AACtD,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,UAAU,WAAW,QAAQ,SAAS,EAAE;AAC9C,QAAM,MAAM,QAAQ,YAAY,GAAG;AACnC,SAAO,QAAQ,KAAK,UAAU,QAAQ,MAAM,MAAM,CAAC;AACrD;AAEA,SAAS,sBAAsB,UAAoB,aAAqB,UAAyB;AAC/F,QAAM,UAAU;AAAA,IACd,UAAU,SAAS,MAAM,GAAG,GAAG;AAAA,IAC/B,MAAM;AAAA,IACN,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,EACvB;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,oBAAoB;AAAA,MAC7B;AAAA,MACA,SAAS,wCAAwC,WAAW;AAAA,MAC5D,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,sBAAsB;AAAA,MAC/B;AAAA,MACA,SAAS,mCAAmC,WAAW;AAAA,MACvD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,kBAAkB;AAAA,MAC3B;AAAA,MACA,SAAS,8BAA8B,WAAW;AAAA,MAClD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,gBAAgB;AAAA,MACzB;AAAA,MACA,SAAS,4BAA4B,WAAW;AAAA,MAChD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA,SAAS,0BAA0B,WAAW,uBAAuB,OAAO,SAAS,MAAM,CAAC;AAAA,IAC5F,WAAW,SAAS,UAAU;AAAA,EAChC,CAAC;AACH;AAEA,eAAeD,cAAa,UAAqC;AAC/D,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAeE,eAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;;;ACtkBA,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,4BAAkD,CAAC,OAAO,QAAQ;AAmBjE,SAAS,yBAAyB,SAA8C;AACrF,MAAI,OAAO,QAAQ,WAAW,YAAY,QAAQ,WAAW,IAAI;AAC/D,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,cAAc,QAAQ,cAAc,mBAAmB,QAAQ,SAAS,EAAE;AAChF,QAAM,iBAAiB,QAAQ,iBAAiB,qBAAqB,QAAQ,SAAS,EAAE;AAExF,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,SAAS,OAAO;AAAA,IACjC,UAAU,CAAC,GAAG,yBAAyB;AAAA,IACvC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,aAAa,UAAU;AAAA,IAChD,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,YAAY;AAAA,MACd;AAAA,MACA,QAAQ,QAAQ;AAAA,MAChB;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAYA,IAAM,cAAN,MAA8C;AAAA,EAI5C,YAA6B,WAA+B;AAA/B;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,QAAQE,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAClE,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,iBAAoC;AAAA,MACxC,YAAY,KAAK,UAAU;AAAA,MAC3B,QAAQ,KAAK,UAAU;AAAA,MACvB,cAAc,KAAK,UAAU;AAAA,MAC7B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,OAAO,KAAK,UAAU;AAAA,MACtB,IAAI,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,eAAe,KAAK,UAAU;AAAA,IAChC;AACA,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,WAAW,cAAc;AAAA,EACtC;AACF;AAcA,IAAM,aAAN,MAA4C;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAA4B;AACtC,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,cAAc,OAAO;AACnC,SAAK,YAAY,IAAI,sBAAsB,OAAO;AAAA,EACpD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAmBA,IAAM,gBAAN,MAAgD;AAAA,EAC9C,YAA6B,SAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,SAAS,YAAY,UAAU;AACrC,UAAM,UAAyB,CAAC;AAChC,QAAI;AACJ,OAAG;AACD,YAAM,SAAiC,EAAE,WAAW,IAAI;AACxD,UAAI,WAAW,GAAI,QAAO,QAAQ,IAAI;AACtC,UAAI,cAAc,OAAW,QAAO,WAAW,IAAI;AACnD,YAAM,MAAM,GAAG,KAAK,QAAQ,UAAU,MAAM,mBAAmB,KAAK,QAAQ,MAAM,CAAC,MAAMC,aAAY,MAAM,CAAC;AAC5G,YAAM,WAAW,MAAM,SAAS,KAAK,SAAS,OAAO,GAAG;AACxD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,oBAAoB,UAAU,YAAY,MAAMC,cAAa,QAAQ,CAAC;AAAA,MAC9E;AACA,YAAM,SAAU,MAAM,SAAS,KAAK;AACpC,iBAAW,QAAQ,OAAO,SAAS,CAAC,GAAG;AACrC,cAAM,QAAQ,cAAc,MAAM,QAAQ,UAAU;AACpD,YAAI,UAAU,OAAW,SAAQ,KAAK,KAAK;AAAA,MAC7C;AACA,iBAAW,aAAa,OAAO,YAAY,CAAC,GAAG;AAC7C,cAAM,QAAQC,eAAc,WAAW,QAAQ,UAAU;AACzD,YAAI,UAAU,OAAW,SAAQ,KAAK,KAAK;AAAA,MAC7C;AACA,kBAAY,OAAO;AAAA,IACrB,SAAS,cAAc;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAKH,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,aAAa,gBAAgB,UAAU;AAC7C,UAAM,MAAM,GAAG,KAAK,QAAQ,UAAU,MAAM,mBAAmB,KAAK,QAAQ,MAAM,CAAC,MAAM,mBAAmB,UAAU,CAAC;AACvH,UAAM,WAAW,MAAM,SAAS,KAAK,SAAS,OAAO,GAAG;AACxD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,oBAAoB,UAAU,YAAY,MAAME,cAAa,QAAQ,CAAC;AAAA,IAC9E;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,SAASE,WAAU,UAAU;AACnC,UAAM,QAAQ,cAAc,MAAM,YAAY,MAAM,GAAG,MAAM;AAC7D,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,kBAAkB;AAAA,QAC1B,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,uBAAuB,UAAU;AAAA,QAC1C,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,WAAO,EAAE,GAAG,OAAO,QAAQ,KAAK;AAAA,EAClC;AACF;AAEA,IAAM,wBAAN,MAAkE;AAAA,EAChE,YAA6B,SAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,aAAa,gBAAgB,UAAU;AAC7C,UAAM,MAAM,GAAG,KAAK,QAAQ,UAAU,MAAM,mBAAmB,KAAK,QAAQ,MAAM,CAAC,MAAM,mBAAmB,UAAU,CAAC;AACvH,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AACA,UAAM,WAAW,MAAM,SAAS,KAAK,SAAS,OAAO,KAAK;AAAA,MACxD,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,oBAAoB,UAAU,YAAY,MAAMF,cAAa,QAAQ,CAAC;AAAA,IAC9E;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS,oBAAoB,UAAU;AAAA,QACvC,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,MAAM,SAAS,QAAQ,IAAI,aAAa,KAAK,SAAS,QAAQ,IAAI,aAAa;AACrF,QAAI,QAAQ,QAAQ,QAAQ,GAAI,QAAO,WAAW;AAClD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,QAAI,QAAQ,WAAW,UAAa,QAAQ,SAAS,GAAG;AACtD,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,QAAQ,QAAQ,OAAO;AAAA,QAClC,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,aAAa,gBAAgB,UAAU;AAC7C,UAAM,WAAW,MAAMG,eAAc,QAAQ,OAAO;AACpD,UAAM,MAAM,GAAG,KAAK,QAAQ,aAAa,MAAM,mBAAmB,KAAK,QAAQ,MAAM,CAAC,4BAA4B,mBAAmB,UAAU,CAAC;AAChJ,UAAM,WAAW,MAAM,SAAS,KAAK,SAAS,QAAQ,KAAK;AAAA,MACzD,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM;AAAA,MACN,cAAc,EAAE,gBAAgB,2BAA2B;AAAA,IAC7D,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,oBAAoB,UAAU,YAAY,MAAMH,cAAa,QAAQ,CAAC;AAAA,IAC9E;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,QAAI,OAAO,KAAK,YAAY,YAAY,KAAK,YAAY,GAAI,QAAO,WAAW,KAAK;AACpF,WAAO;AAAA,EACT;AACF;AAQA,eAAe,SACb,SACA,QACA,KACA,eAAgC,CAAC,GACd;AACnB,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,gBAAgB,CAAC;AAAA,IAClC,eAAe,UAAU,QAAQ,KAAK;AAAA,EACxC;AACA,QAAM,OAAoB,EAAE,SAAS,OAAO;AAC5C,MAAI,aAAa,SAAS,QAAW;AACnC,IAAC,KAA8B,OAAO,aAAa;AAAA,EACrD;AACA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,aAAa,UAAU;AACxC,MAAI,aAAa,MAAM;AACrB,QAAI,SAAS,QAAS,YAAW,MAAM,SAAS,MAAM;AAAA,QACjD,UAAS,iBAAiB,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,CAAC;AAAA,EACjF;AACA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,uBAAuB,CAAC;AAAA,MACzD,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EACxE,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,IAAI;AAAA,MACf,SAAS,kBAAkB,GAAG;AAAA,MAC9B,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAEA,SAAS,cAAc,MAAiB,QAAgB,QAAyC;AAC/F,QAAM,OAAO,KAAK,KAAK,WAAW,MAAM,IAAI,KAAK,KAAK,MAAM,OAAO,MAAM,IAAI,KAAK;AAClF,MAAI,SAAS,MAAM,KAAK,SAAS,GAAG,EAAG,QAAO;AAC9C,QAAM,QAAqB;AAAA,IACzB,MAAM;AAAA,IACN,MAAMI,UAAS,QAAQ,IAAI;AAAA,IAC3B,KAAK;AAAA,IACL,MAAM;AAAA,IACN,UAAU,KAAK,QAAQ,KAAK,WAAW,KAAK;AAAA,EAC9C;AACA,MAAI,OAAO,KAAK,SAAS,UAAU;AACjC,UAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAI,OAAO,SAAS,KAAK,EAAG,OAAM,OAAO;AAAA,EAC3C;AACA,MAAI,OAAO,KAAK,YAAY,UAAU;AACpC,UAAM,SAAS,IAAI,KAAK,KAAK,OAAO;AACpC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,EAC1D;AACA,MAAI,OAAO,KAAK,gBAAgB,UAAU;AACxC,UAAM,SAAS,IAAI,KAAK,KAAK,WAAW;AACxC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,YAAY;AAAA,EACzD;AACA,SAAO;AACT;AAEA,SAASH,eACP,cACA,QACA,QACyB;AACzB,QAAM,OAAO,aAAa,MAAM,OAAO,MAAM,EAAE,QAAQ,SAAS,EAAE;AAClE,MAAI,SAAS,MAAM,KAAK,SAAS,GAAG,EAAG,QAAO;AAC9C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAMG,UAAS,QAAQ,IAAI;AAAA,IAC3B,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,YAAY,YAA4B;AAC/C,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,UAAU,WAAW,QAAQ,SAAS,EAAE;AAC9C,SAAO,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACrD;AAEA,SAAS,gBAAgB,YAA4B;AACnD,SAAO,WAAW,QAAQ,SAAS,EAAE;AACvC;AAEA,SAASF,WAAU,YAA4B;AAC7C,MAAI,eAAe,OAAO,eAAe,GAAI,QAAO;AACpD,QAAM,MAAM,WAAW,YAAY,GAAG;AACtC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,WAAW,MAAM,GAAG,GAAG;AAChC;AAEA,SAASE,UAAS,QAAgB,MAAsB;AACtD,MAAI,WAAW,MAAM,WAAW,IAAK,QAAO,IAAI,IAAI;AACpD,SAAO,OAAO,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI;AACtE;AAEA,SAASL,aAAY,QAAwC;AAC3D,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,EAAG,QAAO,IAAI,GAAG,CAAC;AAC5D,SAAO,OAAO,SAAS;AACzB;AAEA,SAAS,oBAAoB,UAAoB,aAAqB,UAAyB;AAC7F,QAAM,UAAU;AAAA,IACd,UAAU,SAAS,MAAM,GAAG,GAAG;AAAA,IAC/B,MAAM;AAAA,IACN,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,EACvB;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,oBAAoB;AAAA,MAC7B;AAAA,MACA,SAAS,iCAAiC,WAAW;AAAA,MACrD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,sBAAsB;AAAA,MAC/B;AAAA,MACA,SAAS,4BAA4B,WAAW;AAAA,MAChD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,kBAAkB;AAAA,MAC3B;AAAA,MACA,SAAS,uBAAuB,WAAW;AAAA,MAC3C,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,IAAI,gBAAgB;AAAA,MACzB;AAAA,MACA,SAAS,0BAA0B,WAAW;AAAA,MAC9C,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,IAAI,gBAAgB;AAAA,IACzB;AAAA,IACA,SAAS,mBAAmB,WAAW,uBAAuB,OAAO,SAAS,MAAM,CAAC;AAAA,IACrF,WAAW,SAAS,UAAU;AAAA,EAChC,CAAC;AACH;AAEA,eAAeC,cAAa,UAAqC;AAC/D,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAeG,eAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;;;ACvgBA,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAO,UAAU;AAgCjB,IAAM,oBAAoB;AAE1B,IAAM,8BAA6C;AAAA,EACjD,UAAU;AAAA,EACV,gBAAgB,CAAC,WAAW;AAAA,EAC5B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU,CAAC;AAAA,EACX,cAAc;AAAA,EACd,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU,CAAC,cAAc,aAAa,cAAc,eAAe,iBAAiB,UAAU;AAAA,EAC9F,gBAAgB;AAAA,EAChB,OAAO,CAAC,8DAA8D;AACxE;AA8BO,SAAS,2BAA2B,UAAgC,CAAC,GAAoB;AAC9F,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ,MAAM,IAAI,cAAc,QAAQ,QAAQ;AAAA,EAClD;AACF;AAEA,IAAM,gBAAN,MAAgD;AAAA,EAI9C,YAA6B,oBAAwC;AAAxC;AAAA,EAAyC;AAAA,EAAzC;AAAA,EAHpB,KAAK;AAAA,EACL,eAAe;AAAA,EAIxB,QAAQ,SAAsD;AAC5D,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,YAAM,WAAW,KAAK,QAAQ,KAAK,sBAAsB,QAAQ,IAAI;AACrE,aAAO,IAAI,qBAAqB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;AAEA,IAAM,uBAAN,MAAsD;AAAA,EAC3C,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EAET,YAAY,UAAkB;AAC5B,SAAK,KAAK,IAAI,gBAAgB,QAAQ;AACtC,SAAK,YAAY,IAAI,wBAAwB,QAAQ;AAAA,EACvD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,0BAAN,MAAoE;AAAA,EAClE,YAA6B,UAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,2BAA2B,QAAQ,SAAS,IAAI;AACnE,UAAM,QAAQ,MAAM,eAAe,KAAK,UAAU,UAAU;AAE5D,QAAI,MAAM,SAAS,QAAQ;AACzB,YAAM,wBAAwB,YAAY,sCAAsC,UAAU,EAAE;AAAA,IAC9F;AAEA,UAAM,QAAQE,kBAAiB,MAAM,QAAQ,GAAG,QAAQ,KAAK;AAC7D,UAAM,SAAqC;AAAA,MACzC,SAAS,sBAAsB,iBAAiB,KAAK,UAAU,UAAU,GAAG,KAAK;AAAA,MACjF,YAAY,MAAM;AAAA,IACpB;AAEA,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,YAAY,MAAM;AAAA,IAC3B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,UAAM,aAAa,2BAA2B,QAAQ,SAAS,IAAI;AACnE,UAAM,YAAY,iBAAiB,KAAK,UAAU,UAAU;AAC5D,UAAM,UAAU,MAAM,uBAAuB,OAAO;AACpD,UAAM,SAASC,4BAA2B,QAAQ,QAAQ,UAAU,UAAU;AAE9E,UAAM,2BAA2B,WAAW,UAAU;AACtD,UAAM,kBAAkB,WAAW,YAAY,SAAS,MAAM;AAE9D,UAAM,OAAO,MAAM,eAAe,KAAK,UAAU,UAAU;AAC3D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,QAAQ;AAAA,MAC1B,SAAS,WAAW,UAAa,SAAS;AAAA,MAC1C,UAAU,QAAQ,cAAc,YAAY;AAAA,IAC9C;AAEA,QAAI,KAAK,SAAS,QAAW;AAC3B,aAAO,aAAa,KAAK;AAAA,IAC3B;AAEA,QAAI,QAAQ,iBAAiB,QAAW;AACtC,aAAO,eAAeC,mBAAkB,QAAQ,YAAY;AAAA,IAC9D;AAEA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,kBAAN,MAAkD;AAAA,EAChD,YAA6B,UAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,2BAA2BA,KAAI;AAClD,UAAM,YAAY,MAAM,KAAK,KAAK,UAAU;AAE5C,QAAI,UAAU,SAAS,aAAa;AAClC,YAAM;AAAA,QACJ;AAAA,QACA,2CAA2C,UAAU;AAAA,MACvD;AAAA,IACF;AAEA,UAAM,YAAY,iBAAiB,KAAK,UAAU,UAAU;AAC5D,UAAM,QAAQ,MAAM,mBAAmB,WAAW,UAAU;AAC5D,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,MAAM,IAAI,CAAC,SAAS,eAAe,KAAK,UAAU,eAAe,YAAY,IAAI,CAAC,CAAC;AAAA,IACrF;AAEA,WAAO,QAAQ,KAAKC,eAAc;AAAA,EACpC;AAAA,EAEA,MAAM,KAAKD,OAAmC;AAC5C,WAAO,eAAe,KAAK,UAAU,2BAA2BA,KAAI,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,OAAO,QAAgB,UAAyB,CAAC,GAAkB;AACvE,UAAM,aAAa,2BAA2B,MAAM;AACpD,UAAM,YAAY,iBAAiB,KAAK,UAAU,UAAU;AAC5D,QAAI;AACF,YAAM,OAAO,SAAS;AAAA,IACxB,SAAS,OAAO;AACd,UAAI,QAAQ,iBAAiB,YAAY,OAAO,QAAQ,EAAG;AAC3D,UAAI,YAAY,OAAO,QAAQ,GAAG;AAChC,cAAM,wBAAwB,YAAY,yBAAyB,UAAU,EAAE;AAAA,MACjF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAc,IAA2B;AACpD,UAAM,aAAa,2BAA2B,IAAI;AAClD,UAAM,WAAW,2BAA2B,EAAE;AAC9C,UAAM,YAAY,iBAAiB,KAAK,UAAU,UAAU;AAC5D,UAAM,UAAU,iBAAiB,KAAK,UAAU,QAAQ;AACxD,QAAI;AACF,YAAM,OAAO,WAAW,OAAO;AAAA,IACjC,SAAS,OAAO;AACd,UAAI,YAAY,OAAO,QAAQ,GAAG;AAChC,cAAM,wBAAwB,YAAY,yBAAyB,UAAU,EAAE;AAAA,MACjF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAAgB,UAAwB,CAAC,GAAkB;AACrE,UAAM,aAAa,2BAA2B,MAAM;AACpD,UAAM,YAAY,iBAAiB,KAAK,UAAU,UAAU;AAC5D,UAAM,MAAM,WAAW,EAAE,WAAW,QAAQ,cAAc,KAAK,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,MAAM,QAAgB,UAAwB,CAAC,GAAkB;AACrE,UAAM,aAAa,2BAA2B,MAAM;AACpD,UAAM,YAAY,iBAAiB,KAAK,UAAU,UAAU;AAC5D,QAAI;AACF,YAAM,GAAG,WAAW,EAAE,WAAW,QAAQ,cAAc,MAAM,OAAO,MAAM,CAAC;AAAA,IAC7E,SAAS,OAAO;AACd,UAAI,YAAY,OAAO,QAAQ,GAAG;AAChC,YAAI,QAAQ,cAAe;AAC3B,cAAM,wBAAwB,YAAY,yBAAyB,UAAU,EAAE;AAAA,MACjF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,YAAY,OAAgB,MAAuB;AAC1D,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAA6B,SAAS;AAE3C;AAOA,SAASH,kBACP,MACA,OACmB;AACnB,MAAI,UAAU,QAAW;AACvB,WAAO,EAAE,QAAQ,MAAM,QAAQ,EAAE;AAAA,EACnC;AAEA,QAAM,kBAAkBK,oBAAmB,MAAM,QAAQ,UAAU,GAAG;AACtE,QAAM,kBACJ,MAAM,WAAW,SACb,OAAO,KAAK,IAAI,iBAAiB,IAAI,IACrCA,oBAAmB,MAAM,QAAQ,UAAU,GAAG;AACpD,QAAM,SAAS,KAAK,IAAI,iBAAiB,IAAI;AAC7C,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,OAAO,MAAM,CAAC;AAEnE,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAEA,gBAAgB,sBACd,WACA,OAC4B;AAC5B,MAAI,MAAM,UAAU,GAAG;AACrB;AAAA,EACF;AAEA,QAAM,SAAS,iBAAiB,WAAW;AAAA,IACzC,KAAK,MAAM,SAAS,MAAM,SAAS;AAAA,IACnC,OAAO,MAAM;AAAA,EACf,CAAC;AAED,mBAAiB,SAAS,QAAQ;AAChC,UAAM,IAAI,WAAW,KAAK;AAAA,EAC5B;AACF;AAEA,eAAe,uBAAuB,SAA4D;AAChG,QAAM,SAAuB,CAAC;AAC9B,MAAI,aAAa;AAEjB,mBAAiB,SAAS,QAAQ,SAAS;AACzC,YAAQ,eAAe;AACvB,UAAM,cAAc,IAAI,WAAW,KAAK;AACxC,WAAO,KAAK,WAAW;AACvB,kBAAc,YAAY;AAC1B,YAAQ,eAAe,YAAY,QAAQ,UAAU;AAAA,EACvD;AAEA,SAAOC,cAAa,QAAQ,UAAU;AACxC;AAEA,SAASA,cAAa,QAAsB,YAAgC;AAC1E,QAAM,UAAU,IAAI,WAAW,UAAU;AACzC,MAAI,SAAS;AAEb,aAAW,SAAS,QAAQ;AAC1B,YAAQ,IAAI,OAAO,MAAM;AACzB,cAAU,MAAM;AAAA,EAClB;AAEA,SAAO;AACT;AAEA,eAAe,2BAA2B,WAAmB,YAAmC;AAC9F,MAAI;AACF,UAAM,MAAM,KAAK,QAAQ,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAC1D,SAAS,OAAO;AACd,UAAM,wBAAwB,OAAO,UAAU;AAAA,EACjD;AACF;AAEA,eAAe,kBACb,WACA,YACA,SACA,QACe;AACf,MAAI;AACF,QAAI,WAAW,QAAW;AACxB,YAAM,UAAU,WAAW,OAAO;AAClC;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,4BAA4B,SAAS;AAE1D,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,GAAG,QAAQ,YAAY,MAAM;AAAA,IAC3D,UAAE;AACA,YAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF,SAAS,OAAO;AACd,UAAM,wBAAwB,OAAO,UAAU;AAAA,EACjD;AACF;AAEA,eAAe,4BAA4B,WAAmB;AAC5D,MAAI;AACF,WAAO,MAAM,KAAK,WAAW,IAAI;AAAA,EACnC,SAAS,OAAO;AACd,QAAI,aAAa,KAAK,MAAM,UAAU;AACpC,aAAO,KAAK,WAAW,IAAI;AAAA,IAC7B;AAEA,UAAM;AAAA,EACR;AACF;AAEA,SAASL,4BACP,OACA,OACA,YACoB;AACpB,SAAO,UAAU,SAAY,SAAYI,oBAAmB,OAAO,OAAO,UAAU;AACtF;AAEA,SAASA,oBAAmB,OAAe,OAAe,YAA4B;AACpF,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,UAAU,kBAAkB;AAAA,MAC9C,SAAS,kBAAkB,KAAK;AAAA,MAChC,MAAM;AAAA,MACN,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAASH,mBAAkB,cAAsE;AAC/F,QAAM,QAAoC,EAAE,UAAU,aAAa,SAAS;AAE5E,MAAI,aAAa,WAAW,OAAW,OAAM,SAAS,aAAa;AACnE,MAAI,aAAa,aAAa,OAAW,OAAM,WAAW,aAAa;AACvE,MAAI,aAAa,qBAAqB,QAAW;AAC/C,UAAM,mBAAmB,aAAa;AAAA,EACxC;AACA,MAAI,aAAa,mBAAmB,OAAW,OAAM,iBAAiB,aAAa;AACnF,MAAI,aAAa,YAAY,OAAW,OAAM,UAAU,EAAE,GAAG,aAAa,QAAQ;AAElF,SAAO;AACT;AAEA,eAAe,mBAAmB,WAAmB,YAAuC;AAC1F,MAAI;AACF,WAAO,MAAM,QAAQ,SAAS;AAAA,EAChC,SAAS,OAAO;AACd,UAAM,wBAAwB,OAAO,UAAU;AAAA,EACjD;AACF;AAEA,eAAe,eAAe,UAAkB,YAAyC;AACvF,QAAM,YAAY,iBAAiB,UAAU,UAAU;AACvD,MAAI;AAEJ,MAAI;AACF,YAAQ,MAAM,MAAM,SAAS;AAAA,EAC/B,SAAS,OAAO;AACd,UAAM,wBAAwB,OAAO,UAAU;AAAA,EACjD;AAEA,QAAM,QAAqB;AAAA,IACzB,YAAY,UAAU,MAAM,KAAK;AAAA,IACjC,WAAW,UAAU,MAAM,SAAS;AAAA,IACpC,YAAY,UAAU,MAAM,KAAK;AAAA,IACjC,MAAM,mBAAmB,UAAU;AAAA,IACnC,MAAM;AAAA,IACN,aAAa,EAAE,KAAK,WAAW,MAAM,IAAI,EAAE;AAAA,IAC3C,MAAM,MAAM;AAAA,IACZ,MAAM,kBAAkB,KAAK;AAAA,IAC7B,UAAU,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG;AAAA,EACrC;AAEA,MAAI,MAAM,SAAS,WAAW;AAC5B,UAAM,gBAAgB,MAAM,kBAAkB,SAAS;AAEvD,QAAI,kBAAkB,QAAW;AAC/B,YAAM,gBAAgB;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ;AAAA,EACV;AACF;AAEA,eAAe,kBAAkB,WAAgD;AAC/E,MAAI;AACF,WAAO,MAAM,SAAS,SAAS;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,2BAA2B,OAAuB;AACzD,QAAM,aAAa,oBAAoB,KAAK;AAE5C,MAAI,eAAe,QAAQ,WAAW,WAAW,KAAK,GAAG;AACvD,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,UAAU,kBAAkB;AAAA,MACvC,SAAS,oDAAoD,UAAU;AAAA,MACvE,MAAM;AAAA,MACN,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,eAAe,OAAO,eAAe,KAAK;AAC5C,WAAO;AAAA,EACT;AAEA,SAAO,WAAW,WAAW,GAAG,IAAI,aAAa,IAAI,UAAU;AACjE;AAEA,SAAS,iBAAiB,UAAkB,YAA4B;AACtE,QAAM,uBAAuB,2BAA2B,UAAU;AAKlE,QAAM,mBAAmB,KAAK,QAAQ,QAAQ;AAC9C,QAAM,oBAAoB,KAAK,QAAQ,qBAAqB,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC;AACrF,MACE,sBAAsB,oBACtB,kBAAkB,WAAW,mBAAmB,KAAK,GAAG,GACxD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,yBAAyB,MAAM,MAAM,qBAAqB,MAAM,CAAC;AACtF,QAAM,eAAe,KAAK,QAAQ,UAAU,aAAa,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC;AAClF,QAAM,iBAAiB,KAAK,SAAS,UAAU,YAAY;AAE3D,MACE,mBAAmB,MAClB,CAAC,eAAe,WAAW,IAAI,KAAK,CAAC,KAAK,WAAW,cAAc,GACpE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,mBAAmB;AAAA,IAC3B,SAAS,EAAE,UAAU,mBAAmB,SAAS;AAAA,IACjD,SAAS,oDAAoD,oBAAoB;AAAA,IACjF,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,kBAAkB,OAA+B;AACxD,MAAI,MAAM,OAAO,EAAG,QAAO;AAC3B,MAAI,MAAM,YAAY,EAAG,QAAO;AAChC,MAAI,MAAM,eAAe,EAAG,QAAO;AACnC,SAAO;AACT;AAEA,SAAS,WAAW,MAAsB;AACxC,UAAQ,OAAO,KAAO,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AACnD;AAEA,SAAS,UAAU,OAAmB;AACpC,SAAO,IAAI,KAAK,MAAM,QAAQ,CAAC;AACjC;AAEA,SAASE,gBAAe,MAAmB,OAA4B;AACrE,SAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAC3C;AAEA,SAAS,wBAAwB,OAAgB,YAA2B;AAC1E,QAAM,OAAO,aAAa,KAAK;AAE/B,MAAI,SAAS,YAAY,SAAS,WAAW;AAC3C,WAAO,wBAAwB,YAAY,kCAAkC,UAAU,EAAE;AAAA,EAC3F;AAEA,MAAI,SAAS,YAAY,SAAS,SAAS;AACzC,WAAO,IAAI,sBAAsB;AAAA,MAC/B,OAAO;AAAA,MACP,SAAS,EAAE,UAAU,kBAAkB;AAAA,MACvC,SAAS,qCAAqC,UAAU;AAAA,MACxD,MAAM;AAAA,MACN,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,mBAAmB;AAAA,IAC5B,OAAO;AAAA,IACP,SAAS,EAAE,MAAM,UAAU,kBAAkB;AAAA,IAC7C,SAAS,+CAA+C,UAAU;AAAA,IAClE,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,wBAAwBD,OAAc,SAAoC;AACjF,SAAO,IAAI,kBAAkB;AAAA,IAC3B,SAAS,EAAE,UAAU,kBAAkB;AAAA,IACvC;AAAA,IACA,MAAAA;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,aAAa,OAAoC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,QAC5D,OAAQ,MAA6B,IAAI,IACzC;AACN;;;ACxkBA,SAAS,UAAAI,eAAc;AAyBvB,IAAM,qBAAqB;AAE3B,IAAM,+BAA8C;AAAA,EAClD,UAAU;AAAA,EACV,gBAAgB,CAAC,WAAW;AAAA,EAC5B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU,CAAC;AAAA,EACX,cAAc;AAAA,EACd,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,gBAAgB;AAAA,EAChB,OAAO,CAAC,6EAA6E;AACvF;AAsBO,SAAS,4BAA4B,UAAiC,CAAC,GAAoB;AAChG,QAAM,QAAQ,kBAAkB,QAAQ,WAAW,CAAC,CAAC;AAErD,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ,MAAM,IAAI,eAAe,KAAK;AAAA,EACxC;AACF;AAEA,IAAM,iBAAN,MAAiD;AAAA,EAI/C,YAA6B,OAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAHpB,KAAK;AAAA,EACL,eAAe;AAAA,EAIxB,UAAoC;AAClC,WAAO,QAAQ,QAAQ,IAAI,sBAAsB,KAAK,KAAK,CAAC;AAAA,EAC9D;AACF;AAEA,IAAM,wBAAN,MAAuD;AAAA,EAC5C,WAAW;AAAA,EACX,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EAET,YAAY,OAA4B;AACtC,SAAK,KAAK,IAAI,iBAAiB,KAAK;AACpC,SAAK,YAAY,IAAI,yBAAyB,KAAK;AAAA,EACrD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAOA,IAAM,mBAAN,MAAmD;AAAA,EACjD,YAA6B,OAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAE7B,KAAKC,OAAsC;AACzC,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,YAAM,iBAAiB,oBAAoBA,KAAI;AAC/C,YAAM,YAAY,KAAK,aAAa,cAAc;AAElD,UAAI,UAAU,SAAS,aAAa;AAClC,cAAMC;AAAA,UACJ;AAAA,UACA,mCAAmC,cAAc;AAAA,QACnD;AAAA,MACF;AAEA,aAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,OAAO,CAAC,EACnC;AAAA,QACC,CAAC,UAAU,MAAM,SAAS,kBAAkBC,eAAc,MAAM,IAAI,MAAM;AAAA,MAC5E,EACC,IAAI,gBAAgB,EACpB,KAAKC,eAAc;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,KAAKH,OAAmC;AACtC,WAAO,QAAQ,QAAQ,EAAE;AAAA,MAAK,MAC5B,gBAAgB,KAAK,aAAa,oBAAoBA,KAAI,CAAC,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,OAAOA,OAAc,UAAyB,CAAC,GAAkB;AAC/D,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,YAAM,aAAa,oBAAoBA,KAAI;AAC3C,YAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,UAAU;AAC/C,UAAI,UAAU,QAAW;AACvB,YAAI,QAAQ,cAAe;AAC3B,cAAMC,yBAAwB,YAAY,0BAA0B,UAAU,EAAE;AAAA,MAClF;AACA,UAAI,MAAM,SAAS,aAAa;AAC9B,cAAMA;AAAA,UACJ;AAAA,UACA,0CAA0C,UAAU;AAAA,QACtD;AAAA,MACF;AACA,WAAK,MAAM,QAAQ,OAAO,UAAU;AACpC,WAAK,MAAM,QAAQ,OAAO,UAAU;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,MAAc,IAA2B;AAC9C,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,YAAM,WAAW,oBAAoB,IAAI;AACzC,YAAM,SAAS,oBAAoB,EAAE;AACrC,YAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,QAAQ;AAC7C,UAAI,UAAU,QAAW;AACvB,cAAMA,yBAAwB,UAAU,0BAA0B,QAAQ,EAAE;AAAA,MAC9E;AACA,8BAAwB,KAAK,MAAM,SAAS,MAAM;AAClD,YAAM,QAAoB,EAAE,GAAG,OAAO,MAAM,QAAQ,MAAM,mBAAmB,MAAM,EAAE;AACrF,WAAK,MAAM,QAAQ,OAAO,QAAQ;AAClC,WAAK,MAAM,QAAQ,IAAI,QAAQ,KAAK;AACpC,YAAM,UAAU,KAAK,MAAM,QAAQ,IAAI,QAAQ;AAC/C,UAAI,YAAY,QAAW;AACzB,aAAK,MAAM,QAAQ,OAAO,QAAQ;AAClC,aAAK,MAAM,QAAQ,IAAI,QAAQ,OAAO;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAMD,OAAc,UAAwB,CAAC,GAAkB;AAC7D,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,YAAM,aAAa,oBAAoBA,KAAI;AAC3C,YAAM,WAAW,KAAK,MAAM,QAAQ,IAAI,UAAU;AAClD,UAAI,aAAa,QAAW;AAC1B,YAAI,SAAS,SAAS,eAAe,QAAQ,UAAW;AACxD,cAAM,0BAA0B,YAAY,+BAA+B,UAAU,EAAE;AAAA,MACzF;AACA,UAAI,QAAQ,WAAW;AACrB,gCAAwB,KAAK,MAAM,SAAS,UAAU;AAAA,MACxD,OAAO;AACL,cAAM,SAASE,eAAc,UAAU;AACvC,YAAI,WAAW,UAAa,CAAC,KAAK,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC3D,gBAAMD,yBAAwB,QAAQ,4BAA4B,MAAM,EAAE;AAAA,QAC5E;AAAA,MACF;AACA,WAAK,MAAM,QAAQ,IAAI,YAAY,qBAAqB,UAAU,CAAC;AAAA,IACrE,CAAC;AAAA,EACH;AAAA,EAEA,MAAMD,OAAc,UAAwB,CAAC,GAAkB;AAC7D,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,YAAM,aAAa,oBAAoBA,KAAI;AAC3C,YAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,UAAU;AAC/C,UAAI,UAAU,QAAW;AACvB,YAAI,QAAQ,cAAe;AAC3B,cAAMC,yBAAwB,YAAY,0BAA0B,UAAU,EAAE;AAAA,MAClF;AACA,UAAI,MAAM,SAAS,aAAa;AAC9B,cAAMA,yBAAwB,YAAY,mCAAmC,UAAU,EAAE;AAAA,MAC3F;AACA,YAAM,WAAW,CAAC,GAAG,KAAK,MAAM,QAAQ,OAAO,CAAC,EAAE;AAAA,QAChD,CAAC,UAAU,MAAM,SAAS,cAAcC,eAAc,MAAM,IAAI,MAAM;AAAA,MACxE;AACA,UAAI,SAAS,SAAS,KAAK,CAAC,QAAQ,WAAW;AAC7C,cAAM,0BAA0B,YAAY,+BAA+B,UAAU,EAAE;AAAA,MACzF;AACA,YAAM,QAAQ,CAAC,GAAG,QAAQ;AAC1B,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,OAAO,MAAM,IAAI;AACvB,YAAI,CAAC,KAAM;AACX,YAAI,KAAK,SAAS,aAAa;AAC7B,qBAAW,SAAS,KAAK,MAAM,QAAQ,OAAO,GAAG;AAC/C,gBAAI,MAAM,SAAS,KAAK,QAAQA,eAAc,MAAM,IAAI,MAAM,KAAK,MAAM;AACvE,oBAAM,KAAK,KAAK;AAAA,YAClB;AAAA,UACF;AAAA,QACF;AACA,aAAK,MAAM,QAAQ,OAAO,KAAK,IAAI;AACnC,aAAK,MAAM,QAAQ,OAAO,KAAK,IAAI;AAAA,MACrC;AACA,WAAK,MAAM,QAAQ,OAAO,UAAU;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEQ,aAAaF,OAA0B;AAC7C,UAAM,QAAQ,KAAK,MAAM,QAAQ,IAAIA,KAAI;AAEzC,QAAI,UAAU,QAAW;AACvB,YAAMC,yBAAwBD,OAAM,0BAA0BA,KAAI,EAAE;AAAA,IACtE;AAEA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,2BAAN,MAAqE;AAAA,EACnE,YAA6B,OAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAE7B,KAAK,SAA2E;AAC9E,WAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,cAAQ,eAAe;AACvB,YAAMA,QAAO,oBAAoB,QAAQ,SAAS,IAAI;AACtD,YAAM,QAAQ,iBAAiB,KAAK,OAAOA,KAAI;AAC/C,YAAM,UAAU,KAAK,MAAM,QAAQ,IAAIA,KAAI,KAAK,IAAI,WAAW,MAAM,QAAQ,CAAC;AAC9E,YAAM,QAAQ,iBAAiB,QAAQ,YAAY,QAAQ,KAAK;AAChE,YAAM,QAAQ,QAAQ,MAAM,MAAM,QAAQ,MAAM,SAAS,MAAM,MAAM;AACrE,YAAM,SAAqC;AAAA,QACzC,SAAS,0BAA0B,KAAK;AAAA,QACxC,YAAY,MAAM;AAAA,MACpB;AAEA,UAAI,MAAM,SAAS,GAAG;AACpB,eAAO,YAAY,MAAM;AAAA,MAC3B;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,UAAMA,QAAO,oBAAoB,QAAQ,SAAS,IAAI;AACtD,UAAM,WAAW,KAAK,MAAM,QAAQ,IAAIA,KAAI;AAE5C,QAAI,UAAU,SAAS,aAAa;AAClC,YAAM,0BAA0BA,OAAM,+BAA+BA,KAAI,EAAE;AAAA,IAC7E;AAEA,UAAM,iBAAiB,MAAMI,wBAAuB,OAAO;AAC3D,UAAM,SAASC,4BAA2B,QAAQ,QAAQ,QAAQ;AAClE,UAAM,kBAAkB,KAAK,MAAM,QAAQ,IAAIL,KAAI,KAAK,IAAI,WAAW,CAAC;AACxE,UAAM,UACJ,WAAW,SACP,iBACA,qBAAqB,iBAAiB,gBAAgB,MAAM;AAElE,4BAAwB,KAAK,MAAM,SAASA,KAAI;AAChD,SAAK,MAAM,QAAQ,IAAIA,OAAM,uBAAuBA,OAAM,QAAQ,UAAU,CAAC;AAC7E,SAAK,MAAM,QAAQ,IAAIA,OAAM,OAAO;AAEpC,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,eAAe;AAAA,MACjC,SAAS,WAAW,UAAa,SAAS;AAAA,MAC1C,YAAY,QAAQ;AAAA,MACpB,UAAU,QAAQ,cAAc,YAAY;AAAA,IAC9C;AAEA,QAAI,QAAQ,iBAAiB,QAAW;AACtC,aAAO,eAAeM,mBAAkB,QAAQ,YAAY;AAAA,IAC9D;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,SAA6D;AACtF,QAAM,QAA6B;AAAA,IACjC,SAAS,oBAAI,IAAI;AAAA,IACjB,SAAS,oBAAI,IAAI,CAAC,CAAC,KAAK,qBAAqB,GAAG,CAAC,CAAC,CAAC;AAAA,EACrD;AAEA,aAAW,SAAS,SAAS;AAC3B,UAAM,QAAQ,kBAAkB,KAAK;AACrC,UAAM,UAAU,oBAAoB,OAAO,KAAK;AAEhD,QAAI,MAAM,SAAS,OAAO,MAAM,SAAS,aAAa;AACpD,YAAM,0BAA0B,MAAM,MAAM,0CAA0C;AAAA,IACxF;AAEA,4BAAwB,MAAM,SAAS,MAAM,IAAI;AACjD,UAAM,QAAQ,IAAI,MAAM,MAAM,KAAK;AAEnC,QAAI,YAAY,QAAW;AACzB,YAAM,QAAQ,IAAI,MAAM,MAAM,OAAO;AAAA,IACvC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAwC;AACjE,QAAMN,QAAO,oBAAoB,MAAM,IAAI;AAC3C,QAAM,QAAqB;AAAA,IACzB,MAAM,MAAM,QAAQ,mBAAmBA,KAAI;AAAA,IAC3C,MAAAA;AAAA,IACA,MAAM,MAAM;AAAA,EACd;AAEA,0BAAwB,OAAO,KAAK;AAEpC,QAAM,UAAU,uBAAuB,MAAM,OAAO;AAEpD,MAAI,YAAY,QAAW;AACzB,UAAM,OAAO,QAAQ;AAAA,EACvB;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ;AAAA,EACV;AACF;AAEA,SAAS,oBACP,OACA,OACwB;AACxB,QAAM,UAAU,uBAAuB,MAAM,OAAO;AAEpD,MAAI,YAAY,QAAW;AACzB,QAAI,MAAM,SAAS,QAAQ;AACzB,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,2CAA2C,MAAM,IAAI;AAAA,MACvD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,WAAO,IAAI,WAAW,MAAM,QAAQ,CAAC;AAAA,EACvC;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,SAAkE;AAChG,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,YAAY,WAAWO,QAAO,KAAK,OAAO,IAAI,IAAI,WAAW,OAAO;AACpF;AAEA,SAAS,uBAAuBP,OAAc,MAA0B;AACtE,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,YAAY,oBAAI,KAAK;AAAA,IACrB,MAAM,mBAAmBA,KAAI;AAAA,IAC7B,MAAAA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,qBAAqBA,OAA0B;AACtD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,MAAM,mBAAmBA,KAAI;AAAA,IAC7B,MAAAA;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,wBAAwB,OAAgCA,OAAoB;AACnF,aAAW,cAAc,iBAAiBA,KAAI,GAAG;AAC/C,UAAM,SAAS,MAAM,IAAI,UAAU;AAEnC,QAAI,WAAW,UAAa,OAAO,SAAS,aAAa;AACvD,YAAM;AAAA,QACJ;AAAA,QACA,6CAA6C,UAAU;AAAA,MACzD;AAAA,IACF;AAEA,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,YAAY,qBAAqB,UAAU,CAAC;AAAA,IACxD;AAAA,EACF;AACF;AAEA,SAAS,oBAAoBA,OAAsB;AACjD,QAAM,aAAa,oBAAoBA,KAAI;AAE3C,MAAI,eAAe,OAAO,eAAe,KAAK;AAC5C,WAAO;AAAA,EACT;AAEA,SAAO,WAAW,WAAW,GAAG,IAAI,aAAa,IAAI,UAAU;AACjE;AAEA,SAAS,iBAAiBA,OAAwB;AAChD,QAAM,YAAsB,CAAC;AAC7B,MAAI,aAAaE,eAAcF,KAAI;AAEnC,SAAO,eAAe,UAAa,eAAe,KAAK;AACrD,cAAU,QAAQ,UAAU;AAC5B,iBAAaE,eAAc,UAAU;AAAA,EACvC;AAEA,SAAO;AACT;AAEA,SAASA,eAAcF,OAAkC;AACvD,MAAIA,UAAS,KAAK;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,YAAYA,MAAK,YAAY,GAAG;AACtC,SAAO,aAAa,IAAI,MAAMA,MAAK,MAAM,GAAG,SAAS;AACvD;AAEA,SAAS,iBAAiB,OAA4BA,OAA0B;AAC9E,QAAM,QAAQ,MAAM,QAAQ,IAAIA,KAAI;AAEpC,MAAI,UAAU,QAAW;AACvB,UAAMC,yBAAwBD,OAAM,0BAA0BA,KAAI,EAAE;AAAA,EACtE;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,UAAMC,yBAAwBD,OAAM,8BAA8BA,KAAI,EAAE;AAAA,EAC1E;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,MACA,OACoC;AACpC,MAAI,UAAU,QAAW;AACvB,WAAO,EAAE,QAAQ,MAAM,QAAQ,EAAE;AAAA,EACnC;AAEA,QAAM,kBAAkBQ,oBAAmB,MAAM,QAAQ,QAAQ;AACjE,QAAM,kBACJ,MAAM,WAAW,SACb,OAAO,KAAK,IAAI,iBAAiB,IAAI,IACrCA,oBAAmB,MAAM,QAAQ,QAAQ;AAC/C,QAAM,SAAS,KAAK,IAAI,iBAAiB,IAAI;AAC7C,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,OAAO,MAAM,CAAC;AAEnE,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAEA,eAAeJ,wBAAuB,SAA4D;AAChG,QAAM,SAAuB,CAAC;AAC9B,MAAI,aAAa;AAEjB,mBAAiB,SAAS,QAAQ,SAAS;AACzC,YAAQ,eAAe;AACvB,UAAM,cAAc,IAAI,WAAW,KAAK;AACxC,WAAO,KAAK,WAAW;AACvB,kBAAc,YAAY;AAC1B,YAAQ,eAAe,YAAY,QAAQ,UAAU;AAAA,EACvD;AAEA,SAAOK,cAAa,QAAQ,UAAU;AACxC;AAEA,SAASA,cAAa,QAAsB,YAAgC;AAC1E,QAAM,UAAU,IAAI,WAAW,UAAU;AACzC,MAAI,SAAS;AAEb,aAAW,SAAS,QAAQ;AAC1B,YAAQ,IAAI,OAAO,MAAM;AACzB,cAAU,MAAM;AAAA,EAClB;AAEA,SAAO;AACT;AAEA,SAAS,qBACP,iBACA,gBACA,QACY;AACZ,QAAM,UAAU,IAAI;AAAA,IAClB,KAAK,IAAI,gBAAgB,YAAY,SAAS,eAAe,UAAU;AAAA,EACzE;AACA,UAAQ,IAAI,eAAe;AAC3B,UAAQ,IAAI,gBAAgB,MAAM;AAClC,SAAO;AACT;AAEA,gBAAgB,0BAA0B,SAAiD;AACzF,QAAM,QAAQ,QAAQ;AACtB,QAAM,IAAI,WAAW,OAAO;AAC9B;AAEA,SAASJ,4BAA2B,OAA2B,OAAmC;AAChG,SAAO,UAAU,SAAY,SAAYG,oBAAmB,OAAO,KAAK;AAC1E;AAEA,SAASA,oBAAmB,OAAe,OAAuB;AAChE,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,UAAM,0BAA0B,KAAK,mBAAmB,KAAK,gCAAgC;AAAA,EAC/F;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAASF,mBAAkB,cAAsE;AAC/F,QAAM,QAAoC,EAAE,UAAU,aAAa,SAAS;AAE5E,MAAI,aAAa,WAAW,OAAW,OAAM,SAAS,aAAa;AACnE,MAAI,aAAa,aAAa,OAAW,OAAM,WAAW,aAAa;AACvE,MAAI,aAAa,qBAAqB,QAAW;AAC/C,UAAM,mBAAmB,aAAa;AAAA,EACxC;AACA,MAAI,aAAa,mBAAmB,OAAW,OAAM,iBAAiB,aAAa;AACnF,MAAI,aAAa,YAAY,OAAW,OAAM,UAAU,EAAE,GAAG,aAAa,QAAQ;AAElF,SAAO;AACT;AAEA,SAAS,iBAAiB,OAAiC;AACzD,QAAM,QAAqB;AAAA,IACzB,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,EACd;AAEA,0BAAwB,OAAO,KAAK;AACpC,SAAO;AACT;AAEA,SAAS,gBAAgB,OAA+B;AACtD,SAAO;AAAA,IACL,GAAG,iBAAiB,KAAK;AAAA,IACzB,QAAQ;AAAA,EACV;AACF;AAEA,SAAS,wBAAwB,QAAqB,QAAoC;AACxF,MAAI,OAAO,SAAS,OAAW,QAAO,OAAO,OAAO;AACpD,MAAI,OAAO,eAAe,OAAW,QAAO,aAAaI,WAAU,OAAO,UAAU;AACpF,MAAI,OAAO,cAAc,OAAW,QAAO,YAAYA,WAAU,OAAO,SAAS;AACjF,MAAI,OAAO,eAAe,OAAW,QAAO,aAAaA,WAAU,OAAO,UAAU;AACpF,MAAI,OAAO,gBAAgB,OAAW,QAAO,cAAc,iBAAiB,OAAO,WAAW;AAC9F,MAAI,OAAO,UAAU,OAAW,QAAO,QAAQ,OAAO;AACtD,MAAI,OAAO,UAAU,OAAW,QAAO,QAAQ,OAAO;AACtD,MAAI,OAAO,kBAAkB,OAAW,QAAO,gBAAgB,OAAO;AACtE,MAAI,OAAO,aAAa,OAAW,QAAO,WAAW,OAAO;AAC5D,MAAI,OAAO,QAAQ,OAAW,QAAO,MAAM,OAAO;AACpD;AAEA,SAASA,WAAU,OAAmB;AACpC,SAAO,IAAI,KAAK,MAAM,QAAQ,CAAC;AACjC;AAEA,SAAS,iBAAiB,aAAmD;AAC3E,SAAO,EAAE,GAAG,YAAY;AAC1B;AAEA,SAASP,gBAAe,MAAmB,OAA4B;AACrE,SAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAC3C;AAEA,SAASF,yBAAwBD,OAAc,SAAoC;AACjF,SAAO,IAAI,kBAAkB;AAAA,IAC3B,SAAS,EAAE,UAAU,mBAAmB;AAAA,IACxC;AAAA,IACA,MAAAA;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACH;AAEA,SAAS,0BAA0BA,OAAc,SAAqC;AACpF,SAAO,IAAI,mBAAmB;AAAA,IAC5B,SAAS,EAAE,UAAU,mBAAmB;AAAA,IACxC;AAAA,IACA,MAAAA;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACH;;;AC5mBA,SAAS,UAAAW,eAAc;AAmDvB,IAAM,6BAAmD,CAAC,MAAM;AAQzD,SAAS,0BAA0B,UAA+B,CAAC,GAAoB;AAC5F,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,SAAS,QAAQ,UAAU,OAAO;AACxC,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAE9C,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,aAAa,YAAY,OAAO;AAAA,IACjD,UAAU,CAAC,GAAG,0BAA0B;AAAA,IACxC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,YAAY,UAAU;AAAA,IAC/C,OAAO,CAAC,wDAAwD;AAAA,IAChE,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,aAAa;AAAA,MACf;AAAA,MACA;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWA,IAAM,eAAN,MAA+C;AAAA,EAI7C,YAA6B,WAAwC;AAAxC;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,UAAM,UAAU,EAAE,GAAG,KAAK,UAAU,eAAe;AACnD,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,WAAW,MAAM,cAAc,QAAQ,QAAQ;AACrD,YAAM,WAAW,QAAQ,aAAa,SAAY,MAAM,cAAc,QAAQ,QAAQ,IAAI;AAC1F,YAAM,eAAeC,gBAAe,QAAQ;AAC5C,YAAM,eAAeA,gBAAe,QAAQ;AAC5C,cAAQ,eAAe,IACrB,SAASC,QAAO,KAAK,GAAG,YAAY,IAAI,YAAY,EAAE,EAAE,SAAS,QAAQ,CAAC;AAAA,IAC9E;AAEA,UAAM,UAAU,oBAAoB,SAAS,KAAK,SAAS;AAC3D,UAAM,iBAAqC;AAAA,MACzC;AAAA,MACA,cAAc,KAAK,UAAU;AAAA,MAC7B,OAAO,KAAK,UAAU;AAAA,MACtB;AAAA,MACA,IAAI,KAAK,UAAU;AAAA,IACrB;AACA,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,UAAM,UAAU,IAAI,oBAAoB,cAAc;AACtD,WAAO;AAAA,EACT;AACF;AAOA,IAAM,sBAAN,MAAqD;AAAA,EAMnD,YAA6B,SAA6B;AAA7B;AAC3B,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,eAAe,OAAO;AACpC,SAAK,YAAY,IAAI,uBAAuB,OAAO;AAAA,EACrD;AAAA,EAL6B;AAAA,EALpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAST,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,iBAAN,MAAiD;AAAA,EAC/C,YAA6B,SAA6B;AAA7B;AAAA,EAA8B;AAAA,EAA9B;AAAA,EAE7B,OAA+B;AAC7B,WAAO,QAAQ;AAAA,MACb,IAAI,wBAAwB;AAAA,QAC1B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,KAAKC,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,MAAM,WAAW,KAAK,QAAQ,SAAS,UAAU;AACvD,UAAM,WAAW,MAAM,gBAAgB,KAAK,SAAS,KAAK;AAAA,MACxD,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AACA,WAAO,eAAe,UAAU,UAAU;AAAA,EAC5C;AACF;AAEA,IAAM,yBAAN,MAAmE;AAAA,EACjE,YAA6B,SAA6B;AAA7B;AAAA,EAA8B;AAAA,EAA9B;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,MAAM,WAAW,KAAK,QAAQ,SAAS,UAAU;AACvD,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AAEA,UAAM,cAAkE;AAAA,MACtE;AAAA,MACA,QAAQ;AAAA,IACV;AACA,QAAI,QAAQ,WAAW,OAAW,aAAY,SAAS,QAAQ;AAC/D,UAAM,WAAW,MAAM,gBAAgB,KAAK,SAAS,KAAK,WAAW;AAErE,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AAEA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,iCAAiC,IAAI,SAAS,CAAC;AAAA,QACxD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,QAAO,WAAW;AAErC,WAAO;AAAA,EACT;AAAA,EAEA,QAA8C;AAC5C,WAAO,QAAQ;AAAA,MACb,IAAI,wBAAwB;AAAA,QAC1B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,oBACP,SACA,WACK;AACL,SAAO,aAAa,SAAS,EAAE,UAAU,UAAU,UAAU,QAAQ,UAAU,OAAO,CAAC;AACzF;AAEA,SAAS,eAAe,UAAoB,gBAAoC;AAC9E,QAAM,OAAmB;AAAA,IACvB,QAAQ;AAAA,IACR,MAAM,mBAAmB,cAAc;AAAA,IACvC,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACA,QAAM,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB;AAC3D,MAAI,kBAAkB,MAAM;AAC1B,UAAM,OAAO,OAAO,SAAS,eAAe,EAAE;AAC9C,QAAI,OAAO,SAAS,IAAI,KAAK,QAAQ,EAAG,MAAK,OAAO;AAAA,EACtD;AACA,QAAM,eAAe,SAAS,QAAQ,IAAI,eAAe;AACzD,MAAI,iBAAiB,MAAM;AACzB,UAAM,SAAS,IAAI,KAAK,YAAY;AACpC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,MAAK,aAAa;AAAA,EACzD;AACA,QAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,MAAI,SAAS,KAAM,MAAK,WAAW;AACnC,SAAO;AACT;;;ACzRA,SAAS,UAAAC,gBAAc;AAoDvB,IAAM,+BAAqD,CAAC,MAAM;AAQ3D,SAAS,4BAA4B,UAAiC,CAAC,GAAoB;AAChG,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAE9C,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,aAAa,YAAY,OAAO;AAAA,IACjD,UAAU,CAAC,GAAG,4BAA4B;AAAA,IAC1C,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,YAAY,UAAU;AAAA,IAC/C,OAAO,CAAC,sFAAsF;AAAA,IAC9F,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,eAAe;AAAA,MACjB;AAAA,MACA;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWA,IAAM,iBAAN,MAAiD;AAAA,EAI/C,YAA6B,WAA0C;AAA1C;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,UAAM,UAAU,EAAE,GAAG,KAAK,UAAU,eAAe;AACnD,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,WAAW,MAAM,cAAc,QAAQ,QAAQ;AACrD,YAAM,WAAW,QAAQ,aAAa,SAAY,MAAM,cAAc,QAAQ,QAAQ,IAAI;AAC1F,YAAM,eAAeC,gBAAe,QAAQ;AAC5C,YAAM,eAAeA,gBAAe,QAAQ;AAC5C,cAAQ,eAAe,IAAI,SAASC,SAAO,KAAK,GAAG,YAAY,IAAI,YAAY,EAAE,EAAE;AAAA,QACjF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,UAAU,aAAa,SAAS;AAAA,MACpC,UAAU,KAAK,UAAU;AAAA,MACzB,QAAQ,KAAK,UAAU;AAAA,IACzB,CAAC;AACD,UAAM,iBAAuC;AAAA,MAC3C;AAAA,MACA,cAAc,KAAK,UAAU;AAAA,MAC7B,OAAO,KAAK,UAAU;AAAA,MACtB;AAAA,MACA,IAAI,KAAK,UAAU;AAAA,IACrB;AACA,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,cAAc,cAAc;AAAA,EACzC;AACF;AAOA,IAAM,gBAAN,MAA+C;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAA+B;AACzC,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,iBAAiB,OAAO;AACtC,SAAK,YAAY,IAAI,yBAAyB,OAAO;AAAA,EACvD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,mBAAN,MAAmD;AAAA,EACjD,YAA6B,SAA+B;AAA/B;AAAA,EAAgC;AAAA,EAAhC;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,MAAM,WAAW,KAAK,QAAQ,SAAS,UAAU;AACvD,UAAM,WAAW,MAAM,gBAAgB,KAAK,SAAS,KAAK;AAAA,MACxD,SAAS,EAAE,OAAO,KAAK,gBAAgB,kBAAkB;AAAA,MACzD,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AACA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,UAAU,uBAAuB,MAAM,KAAK,QAAQ,OAAO;AACjE,WAAO,QACJ,OAAO,CAAC,UAAU,MAAM,SAAS,cAAc,MAAM,SAAS,GAAG,UAAU,GAAG,EAC9E,IAAI,CAAC,UAAU,eAAe,OAAO,UAAU,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,KAAKA,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,MAAM,WAAW,KAAK,QAAQ,SAAS,UAAU;AACvD,UAAM,WAAW,MAAM,gBAAgB,KAAK,SAAS,KAAK;AAAA,MACxD,SAAS,EAAE,OAAO,KAAK,gBAAgB,kBAAkB;AAAA,MACzD,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AACA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,UAAU,uBAAuB,MAAM,KAAK,QAAQ,OAAO;AACjE,UAAM,SACJ,QAAQ,KAAK,CAACC,WAAUA,OAAM,SAAS,cAAcA,OAAM,SAAS,GAAG,UAAU,GAAG,KACpF,QAAQ,CAAC;AACX,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,cAAc;AAAA,QACtB,SAAS,EAAE,MAAM,WAAW;AAAA,QAC5B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,QAAQ,eAAe,QAAQ,SAAS,UAAU,CAAC;AACzD,UAAM,OAAmB;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,MAAM;AAAA,MACZ,MAAM;AAAA,MACN,MAAM,MAAM;AAAA,IACd;AACA,QAAI,MAAM,SAAS,OAAW,MAAK,OAAO,MAAM;AAChD,QAAI,MAAM,eAAe,OAAW,MAAK,aAAa,MAAM;AAC5D,QAAI,MAAM,aAAa,OAAW,MAAK,WAAW,MAAM;AACxD,WAAO;AAAA,EACT;AACF;AAEA,IAAM,2BAAN,MAAqE;AAAA,EACnE,YAA6B,SAA+B;AAA/B;AAAA,EAAgC;AAAA,EAAhC;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,MAAM,WAAW,KAAK,QAAQ,SAAS,UAAU;AACvD,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AAEA,UAAM,OAA2D;AAAA,MAC/D;AAAA,MACA,QAAQ;AAAA,IACV;AACA,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,UAAM,WAAW,MAAM,gBAAgB,KAAK,SAAS,KAAK,IAAI;AAE9D,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,mCAAmC,IAAI,SAAS,CAAC;AAAA,QAC1D,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,QAAO,WAAW;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,QAAI,QAAQ,WAAW,UAAa,QAAQ,SAAS,GAAG;AACtD,YAAM,IAAI,wBAAwB;AAAA,QAChC,SAAS,EAAE,QAAQ,QAAQ,OAAO;AAAA,QAClC,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,MAAM,WAAW,KAAK,QAAQ,SAAS,UAAU;AAEvD,UAAM,WAAW,MAAMC,eAAc,QAAQ,OAAO;AACpD,UAAM,UAAkC;AAAA,MACtC,kBAAkB,OAAO,SAAS,UAAU;AAAA,MAC5C,gBAAgB;AAAA,IAClB;AAEA,UAAM,OAA2D;AAAA,MAC/D,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,IACV;AACA,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,UAAM,WAAW,MAAM,gBAAgB,KAAK,SAAS,KAAK,IAAI;AAC9D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AACA,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,QAAO,WAAW;AACrC,WAAO;AAAA,EACT;AACF;AAEA,eAAeA,eAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAUA,SAAS,uBAAuB,KAAa,SAA+B;AAC1E,QAAM,UAA2B,CAAC;AAClC,QAAM,gBACJ;AACF,MAAI;AACJ,UAAQ,QAAQ,cAAc,KAAK,GAAG,OAAO,MAAM;AACjD,UAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,UAAM,OAAOC,YAAW,OAAO,MAAM;AACrC,QAAI,SAAS,OAAW;AACxB,UAAMH,QAAO,WAAW,MAAM,OAAO;AACrC,UAAM,YAAYG,YAAW,OAAO,MAAM,KAAK;AAC/C,UAAM,eAAe,oCAAoC,KAAK,SAAS;AACvE,UAAM,WAAWA,YAAW,WAAW,kBAAkB;AACzD,UAAM,eAAeA,YAAW,WAAW,iBAAiB;AAC5D,UAAM,OAAOA,YAAW,WAAW,SAAS;AAC5C,UAAM,QAAuB;AAAA,MAC3B,MAAAH;AAAA,MACA,MAAM,eAAe,cAAc;AAAA,IACrC;AACA,QAAI,aAAa,QAAW;AAC1B,YAAM,OAAO,OAAO,SAAS,SAAS,KAAK,GAAG,EAAE;AAChD,UAAI,OAAO,SAAS,IAAI,KAAK,QAAQ,EAAG,OAAM,OAAO;AAAA,IACvD;AACA,QAAI,iBAAiB,QAAW;AAC9B,YAAM,SAAS,IAAI,KAAK,aAAa,KAAK,CAAC;AAC3C,UAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,IAC1D;AACA,QAAI,SAAS,OAAW,OAAM,WAAW,KAAK,KAAK;AACnD,YAAQ,KAAK,KAAK;AAAA,EACpB;AACA,SAAO;AACT;AAEA,SAASG,YAAW,KAAa,WAAuC;AACtE,QAAM,UAAU,IAAI;AAAA,IAClB,uBAAuB,SAAS,oDAAoD,SAAS;AAAA,IAC7F;AAAA,EACF;AACA,QAAM,QAAQ,QAAQ,KAAK,GAAG;AAC9B,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,MAAM,CAAC,KAAK;AACrB;AAEA,SAAS,WAAW,SAAiB,SAAsB;AACzD,QAAM,UAAU,mBAAmB,QAAQ,KAAK,CAAC;AACjD,MAAI,WAAW;AACf,MAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,QAAI;AACF,iBAAW,IAAI,IAAI,OAAO,EAAE;AAAA,IAC9B,QAAQ;AACN,iBAAW;AAAA,IACb;AAAA,EACF;AACA,QAAM,eAAe,QAAQ,SAAS,QAAQ,QAAQ,EAAE;AACxD,MAAI,aAAa,SAAS,KAAK,SAAS,WAAW,YAAY,GAAG;AAChE,eAAW,SAAS,MAAM,aAAa,MAAM;AAAA,EAC/C;AACA,MAAI,CAAC,SAAS,WAAW,GAAG,EAAG,YAAW,IAAI,QAAQ;AACtD,MAAI,SAAS,SAAS,KAAK,SAAS,SAAS,GAAG,EAAG,YAAW,SAAS,MAAM,GAAG,EAAE;AAClF,SAAO;AACT;AAEA,SAAS,eAAe,OAAsB,YAAiC;AAC7E,QAAM,UAAU,MAAM,KAAK,SAAS,GAAG,IAAI,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AAC3E,QAAM,OAAO,mBAAmB,YAAY,KAAK,MAAM,OAAO;AAC9D,QAAM,SAAsB;AAAA,IAC1B,MAAM,SAAS,KAAK,UAAU;AAAA,IAC9B,MAAM,YAAY,KAAK,MAAM;AAAA,IAC7B,MAAM,MAAM;AAAA,EACd;AACA,MAAI,MAAM,SAAS,OAAW,QAAO,OAAO,MAAM;AAClD,MAAI,MAAM,eAAe,OAAW,QAAO,aAAa,MAAM;AAC9D,MAAI,MAAM,aAAa,OAAW,QAAO,WAAW,MAAM;AAC1D,OAAK;AACL,SAAO;AACT;AAEA,SAAS,SAASH,OAAsB;AACtC,MAAIA,UAAS,OAAOA,UAAS,GAAI,QAAO;AACxC,QAAM,MAAMA,MAAK,YAAY,GAAG;AAChC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAOA,MAAK,MAAM,GAAG,GAAG;AAC1B;;;ACraA,SAAS,cAAAI,aAAY,cAAAC,mBAAkB;AA6BhC,SAAS,UAAU,OAAqE;AAC7F,QAAM,MAAM,MAAM,OAAO,oBAAI,KAAK;AAClC,QAAM,UAAU,cAAc,GAAG;AACjC,QAAM,YAAY,QAAQ,MAAM,GAAG,CAAC;AACpC,QAAM,cACJ,MAAM,SAAS,SAAY,UAAU,MAAM,IAAI,IAAI,UAAU,IAAI,WAAW,CAAC;AAE/E,QAAM,QAAQ,MAAM,IAAI,MAAM,IAAI;AAClC,QAAM,QAAQ,YAAY,IAAI;AAC9B,QAAM,QAAQ,sBAAsB,IAAI;AACxC,MAAI,MAAM,iBAAiB,QAAW;AACpC,UAAM,QAAQ,sBAAsB,IAAI,MAAM;AAAA,EAChD;AAEA,QAAM,eAAe,iBAAiB,MAAM,IAAI,QAAQ;AACxD,QAAM,iBAAiB,kBAAkB,MAAM,IAAI,YAAY;AAC/D,QAAM,eAAwC,OAAO,QAAQ,MAAM,OAAO,EACvE,IAAsB,CAAC,CAAC,MAAM,KAAK,MAAM;AAAA,IACxC,KAAK,YAAY;AAAA,IACjB,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AAAA,EAClC,CAAC,EACA,KAAK,CAAC,QAAQ,WAAY,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,IAAI,CAAE;AACxF,QAAM,mBAAmB,aAAa,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC;AAAA,CAAI,EAAE,KAAK,EAAE;AAC5E,QAAM,gBAAgB,aAAa,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG;AAE3D,QAAM,mBAAmB;AAAA,IACvB,MAAM,OAAO,YAAY;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,QAAM,kBAAkB,GAAG,SAAS,IAAI,MAAM,MAAM,IAAI,MAAM,OAAO;AACrE,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,OAAO,KAAK,kBAAkB,MAAM,CAAC;AAAA,EACjD,EAAE,KAAK,IAAI;AAEX,QAAM,QAAQ,KAAK,OAAO,MAAM,eAAe,IAAI,SAAS;AAC5D,QAAM,UAAU,KAAK,OAAO,MAAM,MAAM;AACxC,QAAM,WAAW,KAAK,SAAS,MAAM,OAAO;AAC5C,QAAM,WAAW,KAAK,UAAU,cAAc;AAC9C,QAAM,YAAY,QAAQ,UAAU,YAAY;AAEhD,QAAM,gBAAgB,+BAA+B,MAAM,WAAW,IAAI,eAAe,mBAAmB,aAAa,eAAe,SAAS;AACjJ,QAAM,QAAQ,eAAe,IAAI;AACjC,SAAO,EAAE,eAAe,cAAc;AACxC;AAKA,SAAS,cAAc,KAAmB;AACxC,QAAM,MAAM,IAAI,YAAY;AAC5B,SAAO,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,GAAG,IAAI,MAAM,IAAI,EAAE,CAAC,GAAG,IAAI,MAAM,IAAI,EAAE,CAAC;AAC7H;AAEA,SAAS,iBAAiB,UAA0B;AAClD,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,SAAO,SACJ,MAAM,GAAG,EACT,IAAI,CAAC,YAAY,cAAc,mBAAmB,OAAO,CAAC,CAAC,EAC3D,KAAK,GAAG;AACb;AAEA,SAAS,kBAAkB,QAAiC;AAC1D,QAAM,UAAmC,CAAC;AAC1C,SAAO,QAAQ,CAAC,OAAO,QAAQ;AAC7B,YAAQ,KAAK,CAAC,KAAK,KAAK,CAAC;AAAA,EAC3B,CAAC;AACD,UAAQ;AAAA,IAAK,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAC7B,OAAO,KAAM,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,IAAK,KAAK,KAAK,KAAK;AAAA,EAChE;AACA,SAAO,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,cAAc,GAAG,CAAC,IAAI,cAAc,KAAK,CAAC,EAAE,EAAE,KAAK,GAAG;AAChG;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,mBAAmB,KAAK,EAAE;AAAA,IAC/B;AAAA,IACA,CAAC,SAAS,IAAI,KAAK,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,YAAY,CAAC;AAAA,EAC7D;AACF;AAEA,SAAS,UAAU,MAA0B;AAC3C,SAAOC,YAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AACvD;AAEA,SAAS,KAAK,KAAsB,MAAsB;AACxD,SAAOC,YAAW,UAAU,GAAG,EAAE,OAAO,MAAM,MAAM,EAAE,OAAO;AAC/D;AAEA,SAAS,QAAQ,KAAa,MAAsB;AAClD,SAAOA,YAAW,UAAU,GAAG,EAAE,OAAO,MAAM,MAAM,EAAE,OAAO,KAAK;AACpE;;;ACCA,IAAM,8BAA8B,IAAI,OAAO;AAC/C,IAAM,8BAA8B,IAAI,OAAO;AAE/C,IAAM,2BAAiD,CAAC,MAAM;AAqCvD,SAAS,wBAAwB,UAA6B,CAAC,GAAoB;AACxF,QAAM,KAAiB,QAAQ,MAAM;AACrC,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAM,WAAW,QAAQ,YAAY,cAAc,MAAM;AAEzD,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI;AACJ,MAAI;AACF,kBAAc,IAAI,IAAI,QAAQ;AAAA,EAChC,SAAS,OAAO;AACd,UAAM,IAAI,mBAAmB;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS,EAAE,SAAS;AAAA,MACpB,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,mBAAmB,QAAQ,WAAW,WAAW;AACvD,QAAM,YAAsC;AAAA,IAC1C,SAAS;AAAA,IACT,eAAe,QAAQ,WAAW,iBAAiB;AAAA,IACnD,gBAAgB,QAAQ,WAAW,kBAAkB;AAAA,IACrD,GAAI,QAAQ,WAAW,gBAAgB,SACnC,EAAE,aAAa,QAAQ,UAAU,YAAY,IAC7C,CAAC;AAAA,EACP;AAEA,QAAM,eAA8B;AAAA,IAClC,cAAc;AAAA,IACd,gBAAgB,CAAC,YAAY,OAAO;AAAA,IACpC,UAAU,CAAC,GAAG,wBAAwB;AAAA,IACtC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU,CAAC,cAAc,YAAY,UAAU;AAAA,IAC/C,OAAO,mBACH;AAAA,MACE,yCAAyC,OAAO,UAAU,aAAa,CAAC,gBAAgB,OAAO,UAAU,cAAc,CAAC;AAAA,IAC1H,IACA;AAAA,MACE;AAAA,IACF;AAAA,IACJ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MACN,IAAI,WAAW;AAAA,MACb;AAAA,MACA,gBAAgB,EAAE,GAAI,QAAQ,kBAAkB,CAAC,EAAG;AAAA,MACpD;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,GAAI,QAAQ,iBAAiB,SAAY,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;AAAA,IACrF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAuBA,IAAM,aAAN,MAA6C;AAAA,EAI3C,YAA6B,WAAsC;AAAtC;AAC3B,SAAK,KAAK,UAAU;AACpB,SAAK,eAAe,UAAU;AAAA,EAChC;AAAA,EAH6B;AAAA,EAHpB;AAAA,EACA;AAAA,EAOT,MAAM,QAAQ,SAAsD;AAClE,QAAI,QAAQ,aAAa,UAAa,QAAQ,aAAa,QAAW;AACpE,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,cAAcC,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AACxE,UAAM,kBAAkBA,gBAAe,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAC5E,UAAM,eACJ,KAAK,UAAU,iBAAiB,SAC5BA,gBAAe,MAAM,cAAc,KAAK,UAAU,YAAY,CAAC,IAC/D;AAEN,UAAM,SACJ,QAAQ,SAAS,UAAa,QAAQ,SAAS,KAAK,QAAQ,OAAO,KAAK,UAAU;AACpF,QAAI,WAAW,UAAa,WAAW,IAAI;AACzC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SACE;AAAA,QACF,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,iBAAmC;AAAA,MACvC;AAAA,MACA;AAAA,MACA,cAAc,KAAK,UAAU;AAAA,MAC7B,gBAAgB,KAAK,UAAU;AAAA,MAC/B,aAAa,KAAK,UAAU;AAAA,MAC5B,OAAO,KAAK,UAAU;AAAA,MACtB,IAAI,KAAK,UAAU;AAAA,MACnB,WAAW,KAAK,UAAU;AAAA,MAC1B,WAAW,KAAK,UAAU;AAAA,MAC1B,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,SAAS,KAAK,UAAU;AAAA,IAC1B;AACA,QAAI,iBAAiB,OAAW,gBAAe,eAAe;AAC9D,QAAI,QAAQ,cAAc,OAAW,gBAAe,YAAY,QAAQ;AACxE,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AACF;AAmBA,IAAM,YAAN,MAA2C;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAA2B;AACrC,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,KAAK,IAAI,aAAa,OAAO;AAClC,SAAK,YAAY,IAAI,qBAAqB,OAAO;AAAA,EACnD;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,eAAN,MAA+C;AAAA,EAC7C,YAA6B,SAA2B;AAA3B;AAAA,EAA4B;AAAA,EAA5B;AAAA,EAE7B,MAAM,KAAKC,OAAsC;AAC/C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,SAAS,eAAe,MAAM,KAAK,GAAG,WAAW,MAAM,CAAC,CAAC;AAC/D,UAAM,MAAM,eAAe,KAAK,OAAO;AACvC,QAAI,aAAa,IAAI,aAAa,GAAG;AACrC,QAAI,aAAa,IAAI,aAAa,GAAG;AACrC,QAAI,OAAO,SAAS,EAAG,KAAI,aAAa,IAAI,UAAU,MAAM;AAE5D,UAAM,WAAW,MAAM,QAAQ,KAAK,SAAS,OAAO,GAAG;AACvD,QAAI,CAAC,SAAS,GAAI,OAAM,iBAAiB,UAAU,UAAU;AAC7D,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,mBAAmB,MAAM,MAAM;AAAA,EACxC;AAAA,EAEA,MAAM,KAAKA,OAAmC;AAC5C,UAAM,aAAa,oBAAoBA,KAAI;AAC3C,UAAM,MAAM,eAAe,KAAK,SAAS,UAAU;AACnD,UAAM,WAAW,MAAM,QAAQ,KAAK,SAAS,QAAQ,GAAG;AACxD,QAAI,CAAC,SAAS,GAAI,OAAM,iBAAiB,UAAU,UAAU;AAC7D,UAAM,OAAmB;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,mBAAmB,UAAU;AAAA,MACnC,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,UAAM,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB;AAC3D,QAAI,kBAAkB,MAAM;AAC1B,YAAM,OAAO,OAAO,SAAS,eAAe,EAAE;AAC9C,UAAI,OAAO,SAAS,IAAI,KAAK,QAAQ,EAAG,MAAK,OAAO;AAAA,IACtD;AACA,UAAM,eAAe,SAAS,QAAQ,IAAI,eAAe;AACzD,QAAI,iBAAiB,MAAM;AACzB,YAAM,SAAS,IAAI,KAAK,YAAY;AACpC,UAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,MAAK,aAAa;AAAA,IACzD;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,MAAK,WAAW;AACnC,WAAO;AAAA,EACT;AACF;AAEA,IAAM,uBAAN,MAAiE;AAAA,EAC/D,YAA6B,SAA2B;AAA3B;AAAA,EAA4B;AAAA,EAA5B;AAAA,EAE7B,MAAM,KAAK,SAA2E;AACpF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,MAAM,eAAe,KAAK,SAAS,UAAU;AACnD,UAAM,UAAkC,CAAC;AACzC,QAAI,QAAQ,UAAU,QAAW;AAC/B,cAAQ,OAAO,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACjF;AACA,UAAM,WAAW,MAAM,QAAQ,KAAK,SAAS,OAAO,KAAK;AAAA,MACvD,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,iBAAiB,UAAU,UAAU;AAAA,IAC7C;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS,+BAA+B,IAAI,SAAS,CAAC;AAAA,QACtD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,UAAM,SAAqC;AAAA,MACzC,SAAS,yBAAyB,IAAI;AAAA,IACxC;AACA,UAAM,aAAa,gBAAgB,UAAU,QAAQ,OAAO,MAAM;AAClE,QAAI,eAAe,OAAW,QAAO,aAAa;AAClD,QAAI,QAAQ,OAAO,WAAW,UAAa,QAAQ,MAAM,SAAS,GAAG;AACnE,aAAO,YAAY,QAAQ,MAAM;AAAA,IACnC;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,QAAO,WAAW;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAA6E;AACvF,YAAQ,eAAe;AACvB,UAAM,aAAa,oBAAoB,QAAQ,SAAS,IAAI;AAC5D,UAAM,YAAY,KAAK,QAAQ;AAC/B,UAAM,SAAS,QAAQ,UAAU;AACjC,QAAI,SAAS,GAAG;AACd,UAAI,CAAC,UAAU,WAAW,UAAU,gBAAgB,QAAW;AAC7D,cAAM,IAAI,wBAAwB;AAAA,UAChC,SAAS,EAAE,OAAO;AAAA,UAClB,SACE;AAAA,UACF,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AACA,aAAO,KAAK,eAAe,SAAS,YAAY,MAAM;AAAA,IACxD;AACA,QAAI,UAAU,SAAS;AACrB,aAAO,KAAK,eAAe,SAAS,YAAY,CAAC;AAAA,IACnD;AACA,WAAO,KAAK,gBAAgB,SAAS,UAAU;AAAA,EACjD;AAAA,EAEA,MAAc,gBACZ,SACA,YACsC;AACtC,UAAM,MAAM,eAAe,KAAK,SAAS,UAAU;AACnD,UAAM,WAAW,MAAMC,eAAc,QAAQ,OAAO;AACpD,UAAM,WAAW,MAAM,QAAQ,KAAK,SAAS,OAAO,KAAK;AAAA,MACvD,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM;AAAA,MACN,cAAc,EAAE,gBAAgB,2BAA2B;AAAA,IAC7D,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,OAAM,iBAAiB,UAAU,UAAU;AAC7D,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,QAAO,WAAW;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eACZ,SACA,YACA,iBACsC;AACtC,UAAM,YAAY,KAAK,QAAQ;AAC/B,UAAM,WAAW,UAAU;AAC3B,UAAM,YAAY,eAAe,KAAK,SAAS,UAAU;AACzD,UAAM,cAAc,UAAU;AAC9B,UAAM,YAAkC;AAAA,MACtC,QAAQ,KAAK,QAAQ;AAAA,MACrB,OAAO,QAAQ,IAAI;AAAA,MACnB,MAAM;AAAA,IACR;AAGA,QAAI;AACJ,QAAI,gBAAgB,QAAW;AAC7B,iBAAY,MAAM,YAAY,KAAK,SAAS,KAAM;AAAA,IACpD;AACA,QAAI,kBAAkB,GAAG;AACvB,UAAI,aAAa,QAAW;AAC1B,cAAM,IAAI,wBAAwB;AAAA,UAChC,SAAS,EAAE,QAAQ,gBAAgB;AAAA,UACnC,SAAS;AAAA,UACT,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AACA,YAAM,cAAc,SAAS,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,WAAW;AAC1E,UAAI,gBAAgB,iBAAiB;AACnC,cAAM,IAAI,wBAAwB;AAAA,UAChC,SAAS,EAAE,kBAAkB,aAAa,gBAAgB;AAAA,UAC1D,SAAS;AAAA,UACT,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,WAAW,QAAQ,QAAQ,OAAO,aAAa,EAAE;AAKvD,UAAM,gBAA8B,CAAC;AACrC,QAAI,cAAc;AAClB,QAAI,aAAa,QAAW;AAC1B,aAAO,eAAe,UAAU,gBAAgB;AAC9C,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,KAAK,SAAS,KAAM;AACxB,cAAM,QAAQ,KAAK;AACnB,YAAI,MAAM,eAAe,EAAG;AAC5B,sBAAc,KAAK,KAAK;AACxB,uBAAe,MAAM;AAAA,MACvB;AACA,UAAI,eAAe,UAAU,gBAAgB;AAC3C,cAAM,WAAW,OAAO,eAAe,WAAW;AAClD,eAAO,KAAK,qBAAqB,SAAS,YAAY,QAAQ;AAAA,MAChE;AAAA,IACF;AAGA,QAAI;AACJ,QAAI,aAAa,QAAW;AAC1B,iBAAW,SAAS;AAAA,IACtB,OAAO;AACL,YAAM,cAAc,IAAI,IAAI,UAAU,SAAS,CAAC;AAChD,kBAAY,aAAa,IAAI,WAAW,EAAE;AAC1C,YAAM,mBAAmB,MAAM,QAAQ,KAAK,SAAS,QAAQ,aAAa;AAAA,QACxE,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,QACjE,cAAc,EAAE,gBAAgB,2BAA2B;AAAA,MAC7D,CAAC;AACD,UAAI,CAAC,iBAAiB,GAAI,OAAM,iBAAiB,kBAAkB,UAAU;AAC7E,YAAM,eAAe,MAAM,iBAAiB,KAAK;AACjD,YAAM,YAAY,UAAU,cAAc,UAAU;AACpD,UAAI,cAAc,UAAa,cAAc,IAAI;AAC/C,cAAM,IAAI,gBAAgB;AAAA,UACxB,SAAS;AAAA,UACT,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AACA,iBAAW;AACX,UAAI,gBAAgB,QAAW;AAC7B,cAAM,YAAY,KAAK,WAAW,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;AAAA,MAC3D;AAAA,IACF;AAEA,UAAM,QAA2B,aAAa,SAAY,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;AACjF,UAAM,eAAe,MAAM,SAAS,IAAK,MAAM,MAAM,SAAS,CAAC,GAAG,WAAW,IAAK;AAClF,QAAI,mBAAmB;AACvB,QAAI,aAAa,MAAM,SAAS;AAChC,QAAI,SAAuB,CAAC;AAC5B,QAAI,aAAa;AACjB,QAAI,aAAa,QAAW;AAC1B,YAAM,WAAW,OAAO,eAAe,WAAW;AAClD,eAAS,CAAC,QAAQ;AAClB,mBAAa,SAAS;AAAA,IACxB;AAEA,UAAM,YAAY,OAAO,UAAkC;AACzD,aAAO,cAAc,YAAa,SAAS,aAAa,GAAI;AAC1D,cAAM,OAAO,QAAQ,aAAa;AAClC,cAAM,YAAY,iBAAiB,QAAQ,IAAI;AAC/C,iBAAS,UAAU;AACnB,sBAAc,UAAU,MAAM;AAC9B,cAAM,UAAU,IAAI,IAAI,UAAU,SAAS,CAAC;AAC5C,gBAAQ,aAAa,IAAI,cAAc,OAAO,UAAU,CAAC;AACzD,gBAAQ,aAAa,IAAI,YAAY,QAAQ;AAC7C,cAAM,eAAe,MAAM,QAAQ,KAAK,SAAS,OAAO,SAAS;AAAA,UAC/D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,UACjE,MAAM,UAAU;AAAA,QAClB,CAAC;AACD,YAAI,CAAC,aAAa,IAAI;AACpB,gBAAM,iBAAiB,cAAc,UAAU;AAAA,QACjD;AACA,cAAM,WAAW,aAAa,QAAQ,IAAI,MAAM;AAChD,YAAI,aAAa,MAAM;AACrB,gBAAM,IAAI,gBAAgB;AAAA,YACxB,SAAS,2CAA2C,OAAO,UAAU,CAAC;AAAA,YACtE,WAAW;AAAA,UACb,CAAC;AAAA,QACH;AACA,4BAAoB,UAAU,MAAM;AACpC,cAAM,KAAK,EAAE,SAAS,kBAAkB,MAAM,UAAU,WAAW,CAAC;AACpE,YAAI,gBAAgB,QAAW;AAC7B,gBAAM,YAAY,KAAK,WAAW,EAAE,OAAO,CAAC,GAAG,KAAK,GAAG,SAAS,CAAC;AAAA,QACnE;AACA,gBAAQ,eAAe,kBAAkB,MAAS;AAClD,sBAAc;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,KAAK;AACrB,aAAO,MAAM;AACX,gBAAQ,eAAe;AACvB,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,KAAK,SAAS,KAAM;AACxB,YAAI,KAAK,MAAM,eAAe,EAAG;AACjC,eAAO,KAAK,KAAK,KAAK;AACtB,sBAAc,KAAK,MAAM;AACzB,cAAM,UAAU,KAAK;AAAA,MACvB;AACA,YAAM,UAAU,IAAI;AAAA,IACtB,SAAS,OAAO;AAId,UAAI,gBAAgB,QAAW;AAC7B,cAAM,eAAe,KAAK,SAAS,WAAW,QAAQ,EAAE,MAAM,MAAM,MAAS;AAAA,MAC/E;AACA,YAAM;AAAA,IACR;AAEA,QAAI,MAAM,WAAW,GAAG;AACtB,UAAI,gBAAgB,OAAW,OAAM,YAAY,MAAM,SAAS;AAChE,YAAM,eAAe,KAAK,SAAS,WAAW,QAAQ,EAAE,MAAM,MAAM,MAAS;AAC7E,YAAM,IAAI,gBAAgB;AAAA,QACxB,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,IAAI,IAAI,UAAU,SAAS,CAAC;AAChD,gBAAY,aAAa,IAAI,YAAY,QAAQ;AACjD,UAAM,UAAU,2BAA2B,KAAK;AAChD,UAAM,mBAAmB,MAAM,QAAQ,KAAK,SAAS,QAAQ,aAAa;AAAA,MACxE,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM,IAAI,YAAY,EAAE,OAAO,OAAO;AAAA,MACtC,cAAc,EAAE,gBAAgB,kBAAkB;AAAA,IACpD,CAAC;AACD,QAAI,CAAC,iBAAiB,IAAI;AACxB,UAAI,gBAAgB,QAAW;AAC7B,cAAM,eAAe,KAAK,SAAS,WAAW,QAAQ,EAAE,MAAM,MAAM,MAAS;AAAA,MAC/E;AACA,YAAM,iBAAiB,kBAAkB,UAAU;AAAA,IACrD;AACA,QAAI,gBAAgB,OAAW,OAAM,YAAY,MAAM,SAAS;AAChE,UAAM,eAAe,MAAM,iBAAiB,KAAK;AACjD,UAAM,YAAY,UAAU,cAAc,MAAM;AAChD,UAAM,SAAsC;AAAA,MAC1C;AAAA,MACA,YAAY;AAAA,IACd;AACA,QAAI,cAAc,OAAW,QAAO,WAAW;AAC/C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,qBACZ,SACA,YACA,UACsC;AACtC,UAAM,MAAM,eAAe,KAAK,SAAS,UAAU;AACnD,UAAM,WAAW,MAAM,QAAQ,KAAK,SAAS,OAAO,KAAK;AAAA,MACvD,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,MAAM;AAAA,MACN,cAAc,EAAE,gBAAgB,2BAA2B;AAAA,IAC7D,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,OAAM,iBAAiB,UAAU,UAAU;AAC7D,YAAQ,eAAe,SAAS,YAAY,SAAS,UAAU;AAC/D,UAAM,SAAsC;AAAA,MAC1C,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,IACvB;AACA,UAAM,OAAO,SAAS,QAAQ,IAAI,MAAM;AACxC,QAAI,SAAS,KAAM,QAAO,WAAW;AACrC,WAAO;AAAA,EACT;AACF;AAQA,eAAe,QACb,SACA,QACA,KACA,eAA+B,CAAC,GACb;AACnB,QAAM,UAAkC;AAAA,IACtC,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,gBAAgB,CAAC;AAAA,EACpC;AACA,MAAI,aAAa,SAAS,QAAW;AACnC,YAAQ,gBAAgB,IAAI,OAAO,aAAa,KAAK,UAAU;AAAA,EACjE;AACA,YAAU;AAAA,IACR,aAAa,QAAQ;AAAA,IACrB;AAAA,IACA;AAAA,IACA,QAAQ,QAAQ;AAAA,IAChB,iBAAiB,QAAQ;AAAA,IACzB,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA,GAAI,aAAa,SAAS,SAAY,EAAE,MAAM,aAAa,KAAK,IAAI,CAAC;AAAA,IACrE,GAAI,QAAQ,iBAAiB,SAAY,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;AAAA,EACrF,CAAC;AAED,QAAM,OAAoB,EAAE,SAAS,OAAO;AAC5C,MAAI,aAAa,SAAS,OAAW,CAAC,KAA8B,OAAO,aAAa;AACxF,MAAI,aAAa,WAAW,OAAW,MAAK,SAAS,aAAa;AAElE,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,iBAAiB,KAAK,UAAU;AACtC,MAAI,mBAAmB,MAAM;AAC3B,QAAI,eAAe,QAAS,YAAW,MAAM,eAAe,MAAM;AAAA,QAC7D,gBAAe,iBAAiB,SAAS,MAAM,WAAW,MAAM,eAAe,MAAM,CAAC;AAAA,EAC7F;AACA,MAAI;AACJ,MAAI,QAAQ,cAAc,UAAa,QAAQ,YAAY,GAAG;AAC5D,YAAQ;AAAA,MACN,MAAM,WAAW,MAAM,IAAI,MAAM,sBAAsB,CAAC;AAAA,MACxD,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM,QAAQ,MAAM,IAAI,SAAS,GAAG,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EACnF,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB;AAAA,MACxB,OAAO;AAAA,MACP,SAAS,EAAE,KAAK,IAAI,SAAS,EAAE;AAAA,MAC/B,SAAS,iBAAiB,IAAI,SAAS,CAAC;AAAA,MACxC,WAAW;AAAA,IACb,CAAC;AAAA,EACH,UAAE;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C;AACF;AAEA,SAAS,eAAe,SAAgC;AACtD,QAAM,MAAM,IAAI,IAAI,QAAQ,YAAY,SAAS,CAAC;AAClD,MAAI,QAAQ,WAAW;AACrB,QAAI,WAAW,IAAI,QAAQ,MAAM;AAAA,EACnC,OAAO;AACL,QAAI,OAAO,GAAG,QAAQ,MAAM,IAAI,QAAQ,YAAY,IAAI;AACxD,QAAI,WAAW;AAAA,EACjB;AACA,SAAO;AACT;AAEA,SAAS,eAAe,SAA2B,gBAA6B;AAC9E,QAAM,MAAM,mBAAmB,MAAM,KAAK,eAAe,MAAM,CAAC;AAChE,QAAM,MAAM,eAAe,OAAO;AAClC,MAAI,QAAQ,WAAW;AACrB,QAAI,WAAW,IAAI,QAAQ,MAAM,IAAI,GAAG;AAAA,EAC1C,OAAO;AACL,QAAI,WAAW,IAAI,GAAG;AAAA,EACxB;AACA,SAAO;AACT;AAEA,eAAeA,eAAc,QAAwD;AACnF,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,KAAK;AACjB,aAAS,MAAM;AAAA,EACjB;AACA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,OAAO,QAAsB,WAA+B;AACnE,QAAM,MAAM,IAAI,WAAW,SAAS;AACpC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,iBACP,SACA,MACgD;AAChD,QAAM,MAAM,IAAI,WAAW,IAAI;AAC/B,MAAI,SAAS;AACb,MAAI,IAAI;AACR,SAAO,SAAS,QAAQ,IAAI,QAAQ,QAAQ;AAC1C,UAAM,QAAQ,QAAQ,CAAC;AACvB,QAAI,UAAU,QAAW;AACvB,WAAK;AACL;AAAA,IACF;AACA,UAAM,YAAY,OAAO;AACzB,QAAI,MAAM,cAAc,WAAW;AACjC,UAAI,IAAI,OAAO,MAAM;AACrB,gBAAU,MAAM;AAChB,WAAK;AAAA,IACP,OAAO;AACL,UAAI,IAAI,MAAM,SAAS,GAAG,SAAS,GAAG,MAAM;AAC5C,YAAM,WAAW,MAAM,SAAS,SAAS;AACzC,YAAM,OAAO,QAAQ,MAAM,IAAI,CAAC;AAChC,WAAK,QAAQ,QAAQ;AACrB,aAAO,EAAE,OAAO,KAAK,WAAW,KAAK;AAAA,IACvC;AAAA,EACF;AACA,SAAO,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,GAAG,WAAW,QAAQ,MAAM,CAAC,EAAE;AACvE;AAEA,eAAe,eACb,SACA,WACA,UACe;AACf,QAAM,MAAM,IAAI,IAAI,UAAU,SAAS,CAAC;AACxC,MAAI,aAAa,IAAI,YAAY,QAAQ;AACzC,QAAM,QAAQ,SAAS,UAAU,GAAG;AACtC;AAEA,SAAS,2BACP,OACQ;AACR,QAAM,WAAW,MACd;AAAA,IACC,CAAC,SACC,qBAAqB,OAAO,KAAK,UAAU,CAAC,sBAAsB,UAAU,KAAK,IAAI,CAAC;AAAA,EAC1F,EACC,KAAK,EAAE;AACV,SAAO,kEAAkE,QAAQ;AACnF;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAC3B;AAEA,SAAS,mBAAmB,KAAa,QAA+B;AACtE,QAAM,UAAyB,CAAC;AAChC,QAAM,eAAe;AACrB,MAAI;AACJ,UAAQ,QAAQ,aAAa,KAAK,GAAG,OAAO,MAAM;AAChD,UAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,UAAM,MAAM,UAAU,OAAO,KAAK;AAClC,QAAI,QAAQ,UAAa,QAAQ,OAAQ;AACzC,UAAM,OAAO,UAAU,OAAO,MAAM;AACpC,UAAM,eAAe,UAAU,OAAO,cAAc;AACpD,UAAM,OAAO,UAAU,OAAO,MAAM;AACpC,UAAM,WAAW,IAAI,WAAW,MAAM,IAAI,IAAI,MAAM,OAAO,MAAM,IAAI;AACrE,QAAI,aAAa,GAAI;AACrB,UAAMD,QAAO,IAAI,GAAG;AACpB,UAAM,QAAqB;AAAA,MACzB,MAAM,mBAAmBA,KAAI;AAAA,MAC7B,MAAAA;AAAA,MACA,MAAM;AAAA,IACR;AACA,QAAI,SAAS,QAAW;AACtB,YAAM,QAAQ,OAAO,SAAS,MAAM,EAAE;AACtC,UAAI,OAAO,SAAS,KAAK,KAAK,SAAS,EAAG,OAAM,OAAO;AAAA,IACzD;AACA,QAAI,iBAAiB,QAAW;AAC9B,YAAM,SAAS,IAAI,KAAK,YAAY;AACpC,UAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,OAAM,aAAa;AAAA,IAC1D;AACA,QAAI,SAAS,OAAW,OAAM,WAAW;AACzC,YAAQ,KAAK,KAAK;AAAA,EACpB;AAEA,QAAM,cAAc;AACpB,UAAQ,QAAQ,YAAY,KAAK,GAAG,OAAO,MAAM;AAC/C,UAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,UAAM,YAAY,UAAU,OAAO,QAAQ;AAC3C,QAAI,cAAc,OAAW;AAC7B,UAAM,UAAU,UAAU,SAAS,GAAG,IAAI,UAAU,MAAM,GAAG,EAAE,IAAI;AACnE,UAAMA,QAAO,IAAI,OAAO;AACxB,YAAQ,KAAK;AAAA,MACX,MAAM,mBAAmBA,KAAI;AAAA,MAC7B,MAAAA;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,UAAU,KAAa,KAAiC;AAC/D,QAAM,UAAU,IAAI,OAAO,IAAI,GAAG,iCAAiC,GAAG,MAAM,GAAG;AAC/E,QAAM,QAAQ,QAAQ,KAAK,GAAG;AAC9B,MAAI,UAAU,KAAM,QAAO;AAC3B,UAAQ,MAAM,CAAC,KAAK,IAAI,KAAK;AAC/B;;;ACp3BA,IAAM,YAA0B,MAAM,QAAQ,OAAO,IAAI,MAAM,gCAAgC,CAAC;AAUzF,SAAS,6BAA6D;AAC3E,SAAO;AAAA,IACL;AAAA,MACE,cAAc,2BAA2B,EAAE;AAAA,MAC3C,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,4BAA4B,EAAE;AAAA,MAC5C,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,yBAAyB,EAAE;AAAA,MACzC,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,0BAA0B,EAAE;AAAA,MAC1C,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,0BAA0B,EAAE;AAAA,MAC1C,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,0BAA0B,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MAC9D,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,4BAA4B,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MAChE,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,wBAAwB,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MAC5D,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,wBAAwB;AAAA,QACpC,OAAO;AAAA,QACP,WAAW,EAAE,SAAS,KAAK;AAAA,MAC7B,CAAC,EAAE;AAAA,MACH,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,6BAA6B,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MACjE,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,iCAAiC,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MACrE,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,8BAA8B,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MAClE,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,+BAA+B;AAAA,QAC3C,WAAW;AAAA,QACX,UAAU;AAAA,QACV,OAAO;AAAA,QACP,UAAU;AAAA,MACZ,CAAC,EAAE;AAAA,MACH,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,cAAc,yBAAyB;AAAA,QACrC,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC,EAAE;AAAA,MACH,IAAI;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAOO,SAAS,+BACd,SAAsD,2BAA2B,GACzE;AACR,QAAM,SACJ;AACF,QAAM,UAAU;AAChB,QAAM,OAAO,OAAO,IAAI,CAAC,UAAU;AACjC,UAAM,IAAI,MAAM;AAChB,UAAM,QAAQ,CAAC,UAA4B,QAAQ,WAAM;AACzD,UAAM,WAAW,GAAG,MAAM,EAAE,cAAc,CAAC,MAAM,MAAM,EAAE,cAAc,CAAC;AACxE,UAAM,YAAY,EAAE,SAAS,WAAW,IAAI,WAAM,EAAE,SAAS,KAAK,IAAI;AACtE,UAAM,OAAO,EAAE,eAAe,WAAW,IAAI,WAAM,EAAE,eAAe,KAAK,IAAI;AAC7E,WAAO,KAAK,MAAM,KAAK,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM,MAAM,EAAE,UAAU,CAAC,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,MAAM,EAAE,cAAc,CAAC,MAAM,MAAM,EAAE,YAAY,CAAC,MAAM,QAAQ,MAAM,SAAS,MAAM,IAAI;AAAA,EACjN,CAAC;AACD,SAAO,CAAC,QAAQ,SAAS,GAAG,IAAI,EAAE,KAAK,IAAI;AAC7C;;;ACzFO,SAAS,6BACd,SACA,UAAyC,CAAC,GAC1B;AAChB,MAAI,OAAO,YAAY,YAAY;AACjC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,MAAM,QAAQ,QAAQ,MAAM,KAAK,IAAI;AAC3C,MAAI,SAAS,GAAG;AACd,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI;AACJ,MAAI;AAEJ,QAAM,QAAQ,YAAkC;AAC9C,UAAM,SAAS,MAAM,QAAQ;AAC7B,QAAI,OAAO,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,IAAI;AACvE,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,QAAI;AACJ,QAAI,OAAO,cAAc,QAAW;AAClC,YAAM,KAAK,OAAO,UAAU,QAAQ;AACpC,UAAI,OAAO,SAAS,EAAE,EAAG,eAAc;AAAA,IACzC,WAAW,OAAO,OAAO,qBAAqB,UAAU;AACtD,UAAI,CAAC,OAAO,SAAS,OAAO,gBAAgB,KAAK,OAAO,oBAAoB,GAAG;AAC7E,cAAM,IAAI,mBAAmB;AAAA,UAC3B,SAAS;AAAA,UACT,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AACA,oBAAc,IAAI,IAAI,OAAO,mBAAmB;AAAA,IAClD;AACA,UAAM,SAAsB,EAAE,aAAa,OAAO,aAAa,YAAY;AAC3E,YAAQ;AACR,WAAO;AAAA,EACT;AAEA,SAAO,YAAY;AACjB,UAAM,UAAU;AAChB,QAAI,YAAY,UAAa,QAAQ,SAAS,QAAQ,GAAG,GAAG;AAC1D,aAAO,QAAQ;AAAA,IACjB;AACA,QAAI,YAAY,QAAW;AACzB,gBAAU,MAAM,EAAE,QAAQ,MAAM;AAC9B,kBAAU;AAAA,MACZ,CAAC;AAAA,IACH;AACA,UAAM,YAAY,MAAM;AACxB,WAAO,UAAU;AAAA,EACnB;AACF;AAEA,SAAS,QAAQ,OAAoB,QAAgB,KAA4B;AAC/E,MAAI,MAAM,gBAAgB,OAAW,QAAO;AAC5C,SAAO,MAAM,cAAc,SAAS,IAAI;AAC1C;;;ACnIA,SAAS,UAAAE,gBAAc;AACvB,SAAS,cAAAC,mBAAkB;AAgCpB,SAASC,iBAAgB,MAAiC;AAC/D,QAAM,UAA6B,CAAC;AACpC,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,YAAY,MAAM,QAAQ,WAAW,GAAG,EAAG;AAC/C,UAAM,QAAQC,qBAAoB,IAAI;AACtC,QAAI,UAAU,OAAW,SAAQ,KAAK,KAAK;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAASA,qBAAoB,MAA2C;AACtE,QAAM,SAAS,KAAK,KAAK,EAAE,MAAM,KAAK;AACtC,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,MAAI,QAAQ;AACZ,MAAI;AACJ,QAAMC,SAAQ,OAAO,KAAK;AAC1B,MAAIA,WAAU,qBAAqBA,WAAU,YAAY;AACvD,aAASA,WAAU,oBAAoB,mBAAmB;AAC1D,aAAS;AAAA,EACX;AACA,QAAM,YAAY,OAAO,KAAK;AAC9B,QAAM,UAAU,OAAO,QAAQ,CAAC;AAChC,QAAM,YAAY,OAAO,QAAQ,CAAC;AAClC,MAAI,cAAc,UAAa,YAAY,UAAa,cAAc,OAAW,QAAO;AACxF,QAAM,gBAAgB,OAAO,MAAM,QAAQ,CAAC;AAC5C,QAAM,UAAU,cAAc,SAAS,IAAI,cAAc,KAAK,GAAG,IAAI;AAErE,MAAI,eAAkC,CAAC;AACvC,MAAI;AACJ,MAAI;AACJ,MAAI,UAAU,WAAW,KAAK,GAAG;AAC/B,UAAM,QAAQ,UAAU,MAAM,GAAG;AACjC,QAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,iBAAa,MAAM,CAAC;AACpB,iBAAa,MAAM,CAAC;AAAA,EACtB,OAAO;AACL,mBAAe,UAAU,MAAM,GAAG,EAAE,OAAO,CAAC,UAAU,UAAU,EAAE;AAAA,EACpE;AAEA,QAAM,QAAyB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,EACP;AACA,MAAI,WAAW,OAAW,OAAM,SAAS;AACzC,MAAI,YAAY,OAAW,OAAM,UAAU;AAC3C,MAAI,eAAe,OAAW,OAAM,aAAa;AACjD,MAAI,eAAe,OAAW,OAAM,aAAa;AACjD,SAAO;AACT;AAGA,IAAM,mBAAmB;AAWlB,SAAS,qBACd,OACA,MACA,OAAe,kBACN;AACT,MAAI,MAAM,eAAe,UAAa,MAAM,eAAe,QAAW;AACpE,WAAO,mBAAmB,MAAM,YAAY,MAAM,YAAY,MAAM,IAAI;AAAA,EAC1E;AACA,MAAI,UAAU;AACd,aAAW,WAAW,MAAM,cAAc;AACxC,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,YAAM,UAAU,QAAQ,MAAM,CAAC;AAC/B,UAAI,oBAAoB,SAAS,MAAM,IAAI,EAAG,QAAO;AACrD;AAAA,IACF;AACA,QAAI,oBAAoB,SAAS,MAAM,IAAI,EAAG,WAAU;AAAA,EAC1D;AACA,SAAO;AACT;AAUO,SAAS,gBACd,SACA,MACA,OAAe,kBACI;AACnB,SAAO,QAAQ,OAAO,CAAC,UAAU,qBAAqB,OAAO,MAAM,IAAI,CAAC;AAC1E;AAEA,SAAS,oBAAoB,SAAiB,MAAc,MAAuB;AACjF,QAAM,YAAY,QAAQ,MAAM,kBAAkB;AAClD,MAAI,WAAW;AACb,UAAM,CAAC,EAAE,aAAa,QAAQ,IAAI;AAClC,QAAI,gBAAgB,UAAa,aAAa,OAAW,QAAO;AAChE,UAAM,eAAe,OAAO,SAAS,UAAU,EAAE;AACjD,QAAI,OAAO,MAAM,YAAY,KAAK,iBAAiB,KAAM,QAAO;AAChE,WAAO,UAAU,aAAa,IAAI;AAAA,EACpC;AACA,SAAO,SAAS,oBAAoB,UAAU,SAAS,IAAI;AAC7D;AAEA,SAAS,UAAU,SAAiB,OAAwB;AAC1D,QAAM,QAAQ,IAAI;AAAA,IAChB,IAAI,QACD,QAAQ,kBAAkB,MAAM,EAChC,QAAQ,OAAO,IAAI,EACnB,QAAQ,OAAO,GAAG,CAAC;AAAA,IACtB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,mBAAmB,MAAc,MAAc,MAAc,MAAuB;AAC3F,QAAM,aAAaJ,SAAO,KAAK,MAAM,QAAQ;AAC7C,MAAI,WAAW,WAAW,EAAG,QAAO;AACpC,QAAM,aAAa,SAAS,mBAAmB,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC1F,aAAW,aAAa,YAAY;AAClC,UAAM,WAAWC,YAAW,QAAQ,UAAU,EAAE,OAAO,SAAS,EAAE,OAAO,QAAQ;AACjF,QAAI,aAAa,KAAM,QAAO;AAAA,EAChC;AACA,SAAO;AACT;;;AChJO,SAAS,mBAAmB,MAAoC;AACrE,QAAM,UAAgC,CAAC;AACvC,MAAI;AACJ,MAAI,WAAW;AACf,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,aAAW,WAAW,OAAO;AAC3B,UAAM,OAAO,QAAQ,QAAQ,QAAQ,EAAE,EAAE,KAAK;AAC9C,QAAI,SAAS,GAAI;AACjB,UAAM,QAAQ,KAAK,MAAM,wCAAwC;AACjE,QAAI,CAAC,MAAO;AACZ,UAAM,CAAC,EAAE,YAAY,QAAQ,IAAI;AACjC,QAAI,eAAe,UAAa,aAAa,OAAW;AACxD,UAAM,UAAU,WAAW,YAAY;AACvC,UAAM,QAAQ,SAAS,KAAK;AAC5B,QAAI,YAAY,QAAQ;AACtB,UAAI,YAAY,OAAW,SAAQ,KAAK,OAAO;AAC/C,gBAAU,EAAE,SAAS,CAAC,GAAG,UAAU,eAAe,KAAK,EAAE;AACzD,iBAAW;AACX;AAAA,IACF;AACA,QAAI,YAAY,SAAS;AACvB,UAAI,YAAY,OAAW,SAAQ,KAAK,OAAO;AAC/C,gBAAU;AACV,iBAAW;AACX;AAAA,IACF;AACA,QAAI,YAAY,YAAY,OAAW;AACvC,UAAM,SAAS,eAAe,KAAK;AACnC,UAAM,WAAW,QAAQ,QAAQ,OAAO;AACxC,QAAI,aAAa,QAAW;AAC1B,cAAQ,QAAQ,OAAO,IAAI,CAAC,GAAG,MAAM;AAAA,IACvC,OAAO;AACL,eAAS,KAAK,GAAG,MAAM;AAAA,IACzB;AAAA,EACF;AACA,MAAI,YAAY,OAAW,SAAQ,KAAK,OAAO;AAC/C,SAAO;AACT;AAEA,SAAS,eAAe,OAAyB;AAC/C,MAAI,UAAU,GAAI,QAAO,CAAC;AAC1B,QAAM,SAAmB,CAAC;AAC1B,QAAM,QAAQ;AACd,MAAI;AACJ,UAAQ,QAAQ,MAAM,KAAK,KAAK,OAAO,MAAM;AAC3C,WAAO,KAAK,MAAM,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE;AAAA,EACxC;AACA,SAAO;AACT;AAsBO,SAAS,mBACd,SACA,OACqB;AACrB,QAAM,SAAmC,CAAC;AAC1C,QAAM,UAAgC,CAAC;AACvC,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,kBAAkB,OAAO,KAAK,EAAG;AACtC,YAAQ,KAAK,KAAK;AAClB,eAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,MAAM,OAAO,GAAG;AACzD,UAAI,OAAO,GAAG,MAAM,OAAW,QAAO,GAAG,IAAI,CAAC,GAAG,MAAM;AAAA,IACzD;AAAA,EACF;AACA,SAAO,EAAE,OAAO,SAAS,SAAS,OAAO;AAC3C;AAEA,SAAS,kBAAkB,OAA2B,OAAwB;AAC5E,MAAI,UAAU;AACd,aAAW,WAAW,MAAM,UAAU;AACpC,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,UAAII,WAAU,QAAQ,MAAM,CAAC,GAAG,KAAK,EAAG,QAAO;AAC/C;AAAA,IACF;AACA,QAAIA,WAAU,SAAS,KAAK,EAAG,WAAU;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,SAASA,WAAU,SAAiB,OAAwB;AAC1D,QAAM,QAAQ,IAAI;AAAA,IAChB,IAAI,QACD,QAAQ,kBAAkB,MAAM,EAChC,QAAQ,OAAO,IAAI,EACnB,QAAQ,OAAO,GAAG,CAAC;AAAA,IACtB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,KAAK;AACzB;AA+BO,SAAS,oBACd,SAC2B;AAC3B,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,UACJ,QAAQ,YAAY,QAAQ,SAAS,SAAY,mBAAmB,QAAQ,IAAI,IAAI;AACtF,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,WAAW,mBAAmB,SAAS,KAAK;AAClD,QAAM,aAAa,SAAS;AAE5B,QAAM,OAAO,MAAM,YAAY,UAAU,KAAK;AAC9C,QAAM,WAAW,MAAM,YAAY,MAAM;AACzC,QAAM,OAAO,aAAa,SAAY,QAAQ,QAAQ,IAAI;AAC1D,QAAM,OAAO,MAAM,YAAY,MAAM;AACrC,QAAM,gBAAgB,WAAW,cAAc,KAAK,CAAC;AACrD,QAAM,kBAAkB,WAAW,oBAAoB,KAAK,CAAC;AAC7D,QAAM,qBAAqB,MAAM,YAAY,gBAAgB;AAC7D,QAAM,YAAY,MAAM,YAAY,WAAW;AAC/C,QAAM,MAAM,WAAW,eAAe,KAAK,CAAC;AAC5C,QAAM,UAAU,WAAW,SAAS,KAAK,CAAC;AAC1C,QAAM,OAAO,WAAW,MAAM,KAAK,CAAC;AACpC,QAAM,gBAAgB,WAAW,mBAAmB,KAAK,CAAC;AAE1D,QAAM,UAA6B,EAAE,MAAM,UAAU,OAAO;AAC5D,MAAI,SAAS,OAAW,SAAQ,OAAO;AACvC,MAAI,SAAS,OAAW,SAAQ,WAAW,EAAE,OAAO,KAAK;AACzD,MAAI,uBAAuB,QAAW;AACpC,UAAM,UAAU,QAAQ,kBAAkB;AAC1C,QAAI,YAAY,OAAW,SAAQ,YAAY,UAAU;AAAA,EAC3D;AAEA,QAAM,MAA6C,CAAC;AACpD,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,WAAW,cAAc,CAAC;AAChC,QAAI,aAAa,OAAW,KAAI,aAAa,EAAE,MAAM,WAAW,QAAQ,EAAE;AAAA,EAC5E;AACA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,QAAI,aAAa,gBAAgB,IAAI,CAACC,WAAU,EAAE,MAAM,WAAWA,KAAI,EAAE,EAAE;AAAA,EAC7E;AACA,QAAM,aAAuC,CAAC;AAC9C,MAAI,IAAI,SAAS,EAAG,YAAW,KAAK,IAAI,iBAAiB,GAAG;AAC5D,MAAI,QAAQ,SAAS,EAAG,YAAW,QAAQ,IAAI,iBAAiB,OAAO;AACvE,MAAI,KAAK,SAAS,EAAG,YAAW,MAAM,IAAI,iBAAiB,IAAI;AAC/D,MAAI,cAAc,SAAS,EAAG,YAAW,eAAe,IAAI,iBAAiB,aAAa;AAC1F,MAAI,OAAO,KAAK,UAAU,EAAE,SAAS,GAAG;AACtC,QAAI,aAAa;AAAA,EACnB;AACA,MAAI,OAAO,KAAK,GAAG,EAAE,SAAS,EAAG,SAAQ,MAAM;AAE/C,QAAM,SAAoC;AAAA,IACxC,eAAe,cAAc,IAAI,UAAU;AAAA,IAC3C;AAAA,IACA;AAAA,EACF;AACA,MAAI,cAAc,OAAW,QAAO,YAAY;AAChD,SAAO;AACT;AAEA,SAAS,MACP,SACA,KACoB;AACpB,QAAM,SAAS,QAAQ,GAAG;AAC1B,SAAO,WAAW,UAAa,OAAO,SAAS,IAAI,OAAO,CAAC,IAAI;AACjE;AAEA,SAAS,QAAQ,MAAkC;AACjD,QAAM,QAAQ,OAAO,SAAS,MAAM,EAAE;AACtC,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAEA,SAAS,WAAWA,OAAsB;AACxC,MAAI,CAACA,MAAK,WAAW,GAAG,EAAG,QAAOA;AAClC,QAAM,OAAO,QAAQ,IAAI,MAAM,KAAK,QAAQ,IAAI,aAAa;AAC7D,MAAI,SAAS,OAAW,QAAOA;AAC/B,MAAIA,UAAS,IAAK,QAAO;AACzB,MAAIA,MAAK,WAAW,IAAI,KAAKA,MAAK,WAAW,KAAK,EAAG,QAAO,GAAG,IAAI,GAAGA,MAAK,MAAM,CAAC,CAAC;AACnF,SAAOA;AACT;AAEA,SAAS,iBAAiB,QAAqC;AAC7D,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,QAAQ;AAC1B,eAAW,QAAQ,MAAM,MAAM,GAAG,GAAG;AACnC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,YAAY,GAAI,KAAI,KAAK,OAAO;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;;;AC5PA,SAAS,UAAAC,gBAAc;AAiChB,SAAS,qBAAqB,KAAyC;AAC5E,QAAM,SAAS,YAAY,GAAG;AAC9B,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,QAAyB,CAAC;AAChC,QAAM,UAA4E,CAAC;AACnF,QAAM,cAAwB,CAAC;AAC/B,QAAM,oBAA+B,CAAC;AACtC,MAAI,WAAW;AACf,MAAI,eAAuC,CAAC;AAC5C,MAAI;AACJ,MAAI;AACJ,MAAI,oBAAoB;AAExB,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,QAAQ;AACzB,UAAI,MAAM,SAAS,UAAU;AAC3B,oBAAY,KAAK,EAAE;AACnB,0BAAkB,KAAK,IAAI;AAC3B;AAAA,MACF;AACA,UAAI,MAAM,SAAS,UAAU;AAC3B,mBAAW;AACX,uBAAe,CAAC;AAChB,iCAAyB;AACzB;AAAA,MACF;AACA,kBAAY,MAAM;AAClB,UAAI,MAAM,SAAS,UAAU,UAAU;AACrC,iCAAyB,MAAM,WAAW,UAAU;AAAA,MACtD;AACA,UAAI,MAAM,SAAS,UAAU,CAAC,YAAY,kBAAkB,SAAS,GAAG;AACtE,4BAAoB;AAAA,MACtB;AACA;AAAA,IACF;AACA,QAAI,MAAM,SAAS,QAAQ;AACzB,UAAI,mBAAmB;AACrB,cAAM,MAAM,YAAY,SAAS;AACjC,YAAI,OAAO,EAAG,aAAY,GAAG,IAAI,MAAM,KAAK,KAAK;AACjD,4BAAoB;AACpB;AAAA,MACF;AACA,UAAI,YAAY,cAAc,QAAW;AACvC,qBAAa,SAAS,KAAK,aAAa,SAAS,KAAK,MAAM,MAAM;AAAA,MACpE;AACA;AAAA,IACF;AACA,QAAI,MAAM,SAAS,SAAS;AAC1B,UAAI,MAAM,SAAS,UAAU;AAC3B,oBAAY,IAAI;AAChB,0BAAkB,IAAI;AACtB;AAAA,MACF;AACA,UAAI,MAAM,SAAS,UAAU;AAC3B,cAAM,SAAS,YAAY,OAAO,CAAC,YAAY,YAAY,EAAE;AAC7D,cAAM,SAAS,oBAAoB,cAAc,sBAAsB;AACvE,YAAI,OAAO,SAAS,QAAQ;AAC1B,gBAAM,KAAK,EAAE,GAAG,OAAO,MAAM,OAAO,CAAC;AAAA,QACvC,OAAO;AACL,kBAAQ,KAAK;AAAA,YACX;AAAA,YACA,MAAM,OAAO;AAAA,YACb,GAAI,OAAO,aAAa,SAAY,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;AAAA,UACvE,CAAC;AAAA,QACH;AACA,mBAAW;AACX,uBAAe,CAAC;AAChB,iCAAyB;AACzB,oBAAY;AACZ;AAAA,MACF;AACA,UAAI,cAAc,MAAM,KAAM,aAAY;AAAA,IAC5C;AAAA,EACF;AACA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAaA,SAAS,oBACP,QACA,kBACyB;AACzB,QAAM,QAAQ,OAAO,MAAM,KAAK,OAAO,MAAM,KAAK,YAAY,KAAK;AACnE,QAAM,QAAQ,OAAO,MAAM,KAAK,IAAI,KAAK;AACzC,MAAI,SAAS,GAAI,QAAO,EAAE,MAAM,WAAW,KAAK;AAChD,QAAM,eAAe,OAAO,UAAU;AACtC,QAAM,WAAW,iBAAiB,SAAY,OAAO,SAAS,aAAa,KAAK,GAAG,EAAE,IAAI;AACzF,QAAM,SAAS,qBAAqB,QAAQ;AAC5C,MAAI,WAAW,QAAW;AACxB,WAAO,OAAO,SAAS,QAAQ,IAC3B,EAAE,MAAM,WAAW,MAAM,SAAS,IAClC,EAAE,MAAM,WAAW,KAAK;AAAA,EAC9B;AACA,QAAM,UAA6B,EAAE,MAAM,UAAU,OAAO,SAAS;AACrE,MAAI,OAAO,WAAW,OAAW,SAAQ,SAAS,OAAO;AACzD,QAAM,WAAW,OAAO,MAAM;AAC9B,MAAI,aAAa,QAAW;AAC1B,UAAM,OAAO,OAAO,SAAS,SAAS,KAAK,GAAG,EAAE;AAChD,QAAI,OAAO,SAAS,IAAI,EAAG,SAAQ,OAAO;AAAA,EAC5C;AACA,QAAM,OAAO,OAAO,MAAM,GAAG,KAAK;AAClC,MAAI,SAAS,UAAa,SAAS,GAAI,SAAQ,WAAW,EAAE,OAAO,KAAK;AAExE,MAAI;AACJ,QAAM,UAAU,OAAO,MAAM;AAC7B,MAAI,YAAY,UAAa,YAAY,IAAI;AAC3C,QAAI,qBAAqB,UAAU;AACjC,iBAAWC,SAAO,KAAK,SAAS,QAAQ,EAAE,SAAS,MAAM;AAAA,IAC3D,OAAO;AACL,iBAAW;AAAA,IACb;AACA,QAAI,aAAa,UAAa,aAAa,GAAI,SAAQ,WAAW,EAAE,OAAO,SAAS;AAAA,EACtF;AAEA,QAAM,OAAsC,EAAE,MAAM,QAAQ;AAC5D,MAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,QAAM,YAAY,OAAO,WAAW;AACpC,MAAI,cAAc,QAAW;AAC3B,UAAM,YAAY,OAAO,SAAS,UAAU,KAAK,GAAG,EAAE;AACtD,QAAI,OAAO,SAAS,SAAS,EAAG,MAAK,YAAY;AAAA,EACnD;AACA,SAAO,EAAE,MAAM,QAAQ,KAAK;AAC9B;AAEA,SAAS,qBACP,MACwF;AACxF,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B,KAAK;AACH,aAAO,EAAE,UAAU,OAAO;AAAA,IAC5B,KAAK;AACH,aAAO,EAAE,UAAU,QAAQ,QAAQ,KAAK;AAAA,IAC1C,KAAK;AACH,aAAO,EAAE,UAAU,QAAQ,QAAQ,KAAK;AAAA,IAC1C,KAAK;AACH,aAAO,EAAE,UAAU,OAAO,QAAQ,MAAM;AAAA,IAC1C;AACE,aAAO;AAAA,EACX;AACF;AAkBA,SAAS,YAAY,KAAyB;AAC5C,QAAM,SAAqB,CAAC;AAC5B,MAAI,QAAQ;AACZ,QAAM,SAAS,IAAI;AACnB,SAAO,QAAQ,QAAQ;AACrB,UAAM,KAAK,IAAI,QAAQ,KAAK,KAAK;AACjC,QAAI,OAAO,IAAI;AACb,YAAM,OAAO,IAAI,MAAM,KAAK;AAC5B,UAAI,KAAK,KAAK,MAAM,GAAI,QAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,eAAe,IAAI,EAAE,CAAC;AAChF;AAAA,IACF;AACA,QAAI,KAAK,OAAO;AACd,YAAM,OAAO,IAAI,MAAM,OAAO,EAAE;AAChC,UAAI,KAAK,KAAK,MAAM,GAAI,QAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,eAAe,IAAI,EAAE,CAAC;AAAA,IAClF;AACA,QAAI,IAAI,WAAW,QAAQ,EAAE,GAAG;AAC9B,YAAM,MAAM,IAAI,QAAQ,OAAO,KAAK,CAAC;AACrC,cAAQ,QAAQ,KAAK,SAAS,MAAM;AACpC;AAAA,IACF;AACA,QAAI,IAAI,WAAW,aAAa,EAAE,GAAG;AACnC,YAAM,MAAM,IAAI,QAAQ,OAAO,KAAK,CAAC;AACrC,YAAM,WAAW,QAAQ,KAAK,SAAS;AACvC,aAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,IAAI,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;AAC/D,cAAQ,QAAQ,KAAK,SAAS,MAAM;AACpC;AAAA,IACF;AACA,QAAI,IAAI,KAAK,CAAC,MAAM,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK;AAC9C,YAAMC,MAAK,IAAI,QAAQ,KAAK,KAAK,CAAC;AAClC,cAAQA,QAAO,KAAK,SAASA,MAAK;AAClC;AAAA,IACF;AACA,UAAM,KAAK,IAAI,QAAQ,KAAK,KAAK,CAAC;AAClC,QAAI,OAAO,GAAI;AACf,UAAM,UAAU,IAAI,MAAM,KAAK,GAAG,EAAE;AACpC,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,aAAO,KAAK,EAAE,MAAM,SAAS,MAAM,QAAQ,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,IAC9D,OAAO;AACL,YAAM,cAAc,QAAQ,SAAS,GAAG;AACxC,YAAM,OAAO,cAAc,QAAQ,MAAM,GAAG,EAAE,IAAI;AAClD,YAAM,EAAE,MAAM,WAAW,IAAI,aAAa,KAAK,KAAK,CAAC;AACrD,aAAO,KAAK,EAAE,YAAY,MAAM,QAAQ,MAAM,YAAY,CAAC;AAC3D,UAAI,YAAa,QAAO,KAAK,EAAE,MAAM,SAAS,KAAK,CAAC;AAAA,IACtD;AACA,YAAQ,KAAK;AAAA,EACf;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAoE;AACxF,QAAM,QAAQ,KAAK,MAAM,+BAA+B;AACxD,MAAI,CAAC,MAAO,QAAO,EAAE,YAAY,CAAC,GAAG,MAAM,KAAK;AAChD,QAAM,OAAO,MAAM,CAAC,KAAK;AACzB,QAAM,OAAO,MAAM,CAAC,KAAK;AACzB,QAAM,aAAqC,CAAC;AAC5C,QAAM,YAAY;AAClB,MAAI;AACJ,UAAQ,YAAY,UAAU,KAAK,IAAI,OAAO,MAAM;AAClD,UAAM,MAAM,UAAU,CAAC;AACvB,UAAM,QAAQ,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK;AAC9C,QAAI,QAAQ,OAAW,YAAW,GAAG,IAAI,eAAe,KAAK;AAAA,EAC/D;AACA,SAAO,EAAE,YAAY,KAAK;AAC5B;AAEA,SAAS,eAAe,MAAsB;AAC5C,SAAO,KACJ,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,GAAG,EACpB,QAAQ,WAAW,GAAG,EACtB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG;AAC1B;;;ACzPO,SAAS,qBAAqB,KAAyC;AAC5E,QAAM,WAAW,SAAS,GAAG;AAC7B,QAAM,kBAAkB,SAAS,OAAO,CAAC,YAAY,QAAQ,KAAK,WAAW,YAAY,CAAC;AAC1F,MAAI,gBAAgB,WAAW,GAAG;AAChC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,WAA4B,CAAC;AACnC,QAAM,UAA8E,CAAC;AACrF,aAAW,WAAW,iBAAiB;AACrC,UAAM,cAAc,kBAAkB,QAAQ,KAAK,MAAM,aAAa,MAAM,CAAC;AAC7E,UAAM,WAAW,YAAY,MAAM,GAAG,EAAE,OAAO,CAAC,YAAY,YAAY,EAAE;AAC1E,UAAM,OAAO,SAAS,SAAS,SAAS,CAAC,KAAK;AAC9C,UAAM,SAAS,SAAS,MAAM,GAAG,EAAE;AACnC,UAAM,QAAQ,oBAAoB,MAAM,QAAQ,MAAM;AACtD,QAAI,MAAM,SAAS,WAAW;AAC5B,eAAS,KAAK,EAAE,GAAG,MAAM,SAAS,OAAO,CAAC;AAAA,IAC5C,OAAO;AACL,cAAQ,KAAK;AAAA,QACX;AAAA,QACA;AAAA,QACA,GAAI,MAAM,eAAe,SAAY,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,MAC3E,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,EAAE,UAAU,QAAQ;AAC7B;AAWA,SAAS,oBACP,MACA,QAC+B;AAC/B,QAAM,OAAO,OAAO,UAAU,GAAG,KAAK;AACtC,MAAI,SAAS,UAAa,SAAS,GAAI,QAAO,EAAE,MAAM,UAAU;AAChE,QAAM,iBAAiB,OAAO,YAAY;AAC1C,QAAM,aAAa,mBAAmB,SAAY,OAAO,SAAS,gBAAgB,EAAE,IAAI;AACxF,QAAM,WAAW,OAAO,MAAM;AAC9B,QAAM,OAAO,aAAa,SAAY,OAAO,SAAS,UAAU,EAAE,IAAI;AACtE,QAAM,SAAS,kBAAkB,YAAY,IAAI;AACjD,MAAI,WAAW,QAAW;AACxB,WAAO,OAAO,SAAS,UAAU,IAAI,EAAE,YAAY,MAAM,UAAU,IAAI,EAAE,MAAM,UAAU;AAAA,EAC3F;AAEA,QAAM,UAA6B,EAAE,MAAM,UAAU,OAAO,SAAS;AACrE,MAAI,OAAO,WAAW,OAAW,SAAQ,SAAS,OAAO;AACzD,QAAM,WAAW,OAAO,YAAY;AACpC,MAAI,aAAa,QAAW;AAC1B,UAAM,OAAO,OAAO,SAAS,UAAU,EAAE;AACzC,QAAI,OAAO,SAAS,IAAI,EAAG,SAAQ,OAAO;AAAA,EAC5C;AACA,QAAM,OAAO,OAAO,UAAU,GAAG,KAAK;AACtC,MAAI,SAAS,UAAa,SAAS,GAAI,SAAQ,WAAW,EAAE,OAAO,KAAK;AAExE,MAAI,OAAO,aAAa,QAAQ;AAC9B,UAAM,MAA6C,CAAC;AACpD,UAAM,UAAU,OAAO,eAAe,GAAG,KAAK;AAC9C,QAAI,YAAY,UAAa,YAAY,GAAI,KAAI,aAAa,EAAE,MAAM,QAAQ;AAC9E,QAAI,OAAO,KAAK,GAAG,EAAE,SAAS,EAAG,SAAQ,MAAM;AAAA,EACjD;AAEA,QAAM,UAAyC,EAAE,MAAM,QAAQ;AAC/D,MAAI,OAAO,SAAS,UAAU,EAAG,SAAQ,aAAa;AACtD,MAAI,OAAO,SAAS,IAAI,KAAK,SAAS,EAAG,SAAQ,OAAO;AACxD,SAAO,EAAE,MAAM,WAAW,QAAQ;AACpC;AAEA,SAAS,kBACP,YACA,MACwF;AACxF,UAAQ,YAAY;AAAA,IAClB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,EAAE,UAAU,OAAO;AAAA,IAC5B,KAAK;AACH,aAAO,SAAS,IAAI,EAAE,UAAU,MAAM,IAAI,EAAE,UAAU,QAAQ,QAAQ,SAAS,EAAE;AAAA,IACnF;AACE,aAAO;AAAA,EACX;AACF;AAOA,SAAS,SAAS,MAA4B;AAC5C,QAAM,WAAyB,CAAC;AAChC,MAAI;AACJ,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,aAAW,WAAW,OAAO;AAC3B,UAAM,OAAO,QAAQ,QAAQ,eAAe,EAAE,EAAE,KAAK;AACrD,QAAI,SAAS,GAAI;AACjB,UAAM,eAAe,KAAK,MAAM,YAAY;AAC5C,QAAI,gBAAgB,aAAa,CAAC,MAAM,QAAW;AACjD,gBAAU,EAAE,MAAM,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE;AAC9C,eAAS,KAAK,OAAO;AACrB;AAAA,IACF;AACA,QAAI,YAAY,OAAW;AAC3B,UAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,QAAI,OAAO,GAAI;AACf,UAAM,MAAM,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK;AACnC,UAAM,QAAQ,KAAK,MAAM,KAAK,CAAC,EAAE,KAAK;AACtC,QAAI,QAAQ,GAAI,SAAQ,OAAO,GAAG,IAAI;AAAA,EACxC;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAsB;AAE/C,MAAI;AACF,WAAO,mBAAmB,IAAI;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC5HO,SAAS,kBAAkB,OAA8C;AAC9E,QAAM,UAAmC;AAAA,IACvC,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,UAAU,MAAM,YAAY;AAAA,IAC5B,WAAW;AAAA,EACb;AAEA,MAAI,MAAM,YAAY,OAAW,SAAQ,UAAU,MAAM;AACzD,MAAI,MAAM,SAAS,OAAW,SAAQ,OAAO,MAAM;AACnD,MAAI,MAAM,UAAU,OAAW,SAAQ,QAAQ,MAAM;AAErD,MAAI,MAAM,YAAY,KAAK;AACzB,WAAO,IAAI,oBAAoB,OAAO;AAAA,EACxC;AAEA,MAAI,MAAM,YAAY,KAAK;AACzB,WAAO,IAAI,gBAAgB;AAAA,MACzB,GAAG;AAAA,MACH,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,MAAM,YAAY,KAAK;AACzB,WAAO,UAAU,OAAO;AAAA,EAC1B;AAEA,MAAI,CAAC,KAAK,KAAK,GAAG,EAAE,SAAS,MAAM,OAAO,GAAG;AAC3C,WAAO,IAAI,cAAc;AAAA,MACvB,GAAG;AAAA,MACH,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,MAAM,WAAW,OAAO,MAAM,UAAU,KAAK;AAC/C,WAAO,IAAI,gBAAgB;AAAA,MACzB,GAAG;AAAA,MACH,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,cAAc,OAAO;AAClC;AAQA,SAAS,UAAU,SAAqD;AACtE,QAAM,eAAe,QAAQ,QAAQ,YAAY;AAEjD,MAAI,aAAa,SAAS,SAAS,KAAK,aAAa,SAAS,QAAQ,GAAG;AACvE,WAAO,IAAI,uBAAuB,OAAO;AAAA,EAC3C;AAEA,MACE,aAAa,SAAS,WAAW,KACjC,aAAa,SAAS,SAAS,KAC/B,aAAa,SAAS,aAAa,GACnC;AACA,WAAO,IAAI,kBAAkB,OAAO;AAAA,EACtC;AAEA,SAAO,IAAI,sBAAsB,OAAO;AAC1C;;;AChCO,SAAS,mBAAmB,OAAwC;AACzE,QAAM,OAAqB;AAAA,IACzB,WAAW,MAAM,MAAM,KAAK,oBAAI,KAAK;AAAA,IACrC,QAAQ,MAAM,UAAU;AAAA,IACxB,IAAI,MAAM;AAAA,IACV,OAAO,MAAM,MAAM,IAAI,aAAa;AAAA,IACpC,UAAU,CAAC,GAAI,MAAM,YAAY,CAAC,CAAE;AAAA,EACtC;AAEA,MAAI,MAAM,aAAa,QAAW;AAChC,SAAK,WAAW,EAAE,GAAG,MAAM,SAAS;AAAA,EACtC;AAEA,SAAO;AACT;AAGO,SAAS,sBAAsB,MAAyC;AAC7E,QAAM,UAAkC,CAAC;AACzC,MAAI,mBAAmB;AACvB,MAAI,kBAAkB;AACtB,MAAI,eAAe;AACnB,MAAI,qBAAqB;AAEzB,aAAW,QAAQ,KAAK,OAAO;AAC7B,YAAQ,KAAK,MAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,KAAK;AACrD,wBAAoB,KAAK,gBAAgB,OAAO,IAAI;AACpD,oBAAgB,KAAK,WAAW,SAAS,IAAI;AAC7C,uBAAmB,KAAK,WAAW,SAAS,IAAI;AAChD,0BAAsB,KAAK,iBAAiB;AAAA,EAC9C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,KAAK,MAAM;AAAA,EACzB;AACF;AAGO,SAAS,2BAA2B,MAAmC;AAC5E,SAAO,KAAK,MAAM,QAAQ,CAAC,SAAS;AAClC,QAAI,KAAK,WAAW,QAAQ;AAC1B,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,MAAmB;AAAA,MACvB,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,EAAE;AAAA,MACzB,WAAW,KAAK;AAAA,IAClB;AAEA,QAAI,KAAK,WAAW,OAAW,KAAI,SAASC,eAAc,KAAK,MAAM;AACrE,QAAI,KAAK,gBAAgB,OAAW,KAAI,cAAcA,eAAc,KAAK,WAAW;AACpF,QAAI,KAAK,kBAAkB,OAAW,KAAI,aAAa,KAAK;AAC5D,QAAI,KAAK,aAAa,OAAW,KAAI,WAAW,EAAE,GAAG,KAAK,SAAS;AAEnE,WAAO,CAAC,GAAG;AAAA,EACb,CAAC;AACH;AAEA,SAAS,cAAc,MAA0C;AAC/D,QAAM,QAA0B;AAAA,IAC9B,QAAQ,KAAK;AAAA,IACb,IAAI,KAAK;AAAA,EACX;AAEA,MAAI,KAAK,WAAW,OAAW,OAAM,SAASA,eAAc,KAAK,MAAM;AACvE,MAAI,KAAK,gBAAgB,OAAW,OAAM,cAAcA,eAAc,KAAK,WAAW;AACtF,MAAI,KAAK,kBAAkB,OAAW,OAAM,gBAAgB,KAAK;AACjE,MAAI,KAAK,gBAAgB,OAAW,OAAM,cAAc,KAAK;AAC7D,MAAI,KAAK,WAAW,OAAW,OAAM,SAAS,KAAK;AACnD,MAAI,KAAK,aAAa,OAAW,OAAM,WAAW,EAAE,GAAG,KAAK,SAAS;AAErE,SAAO;AACT;AAEA,SAASA,eAAc,UAA8C;AACnE,QAAM,QAA0B,EAAE,MAAM,SAAS,KAAK;AAEtD,MAAI,SAAS,aAAa,QAAW;AACnC,UAAM,WAAW,SAAS;AAAA,EAC5B;AAEA,SAAO;AACT;;;AC9DO,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EACA,QAAqC,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,UAAgC,CAAC,GAAG;AAC9C,SAAK,SAAS,QAAQ,UAAU,IAAI,eAAe;AACnD,SAAK,cAAc,qBAAqB,QAAQ,WAAW;AAC3D,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,QAAQ,QAAQ;AACrB,SAAK,UAAU,QAAQ;AACvB,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,aAAa,QAAQ;AAC1B,SAAK,YAAY,QAAQ;AACzB,SAAK,UAAU,QAAQ;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,KAAkB,UAAgD;AACpE,QAAI,KAAK,MAAM,KAAK,CAACC,UAASA,MAAK,OAAO,IAAI,EAAE,GAAG;AACjD,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS,EAAE,OAAO,IAAI,GAAG;AAAA,QACzB,SAAS,wCAAwC,IAAI,EAAE;AAAA,QACvD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,OAAkC;AAAA,MACtC,YAAY,IAAI,gBAAgB;AAAA,MAChC,IAAI,IAAI;AAAA,MACR,KAAK,iBAAiB,GAAG;AAAA,MACzB,QAAQ;AAAA,IACV;AAEA,QAAI,aAAa,QAAW;AAC1B,WAAK,WAAW;AAAA,IAClB;AAEA,SAAK,MAAM,KAAK,IAAI;AACpB,WAAO,aAAa,IAAI;AAAA,EAC1B;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,SAAe;AACb,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,eAAe,aAA2B;AACxC,SAAK,cAAc,qBAAqB,WAAW;AAAA,EACrD;AAAA;AAAA,EAGA,OAAO,OAAwB;AAC7B,UAAM,OAAO,KAAK,MAAM,KAAK,CAAC,cAAc,UAAU,OAAO,KAAK;AAElE,QACE,SAAS,UACT,KAAK,WAAW,eAChB,KAAK,WAAW,YAChB,KAAK,WAAW,YAChB;AACA,aAAO;AAAA,IACT;AAEA,SAAK,WAAW,MAAM;AAEtB,QAAI,KAAK,WAAW,UAAU;AAC5B,WAAK,SAAS;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,OAA8C;AAChD,UAAM,OAAO,KAAK,MAAM,KAAK,CAAC,cAAc,UAAU,OAAO,KAAK;AAClE,WAAO,SAAS,SAAY,SAAY,aAAa,IAAI;AAAA,EAC3D;AAAA;AAAA,EAGA,OAA4B;AAC1B,WAAO,KAAK,MAAM,IAAI,YAAY;AAAA,EACpC;AAAA;AAAA,EAGA,MAAM,IAAI,UAAmC,CAAC,GAAkC;AAC9E,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,aAAa,KAAK,uBAAuB,CAAC,CAAC;AACzF,UAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,MAAM,KAAK,UAAU,OAAO,CAAC;AAEjF,UAAM,QAAQ,IAAI,OAAO;AACzB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA,EAGA,YAAkC;AAChC,UAAM,cAAc,KAAK,MAAM,IAAI,YAAY;AAE/C,WAAO;AAAA,MACL,UAAU,YAAY,OAAO,CAAC,SAAS,KAAK,WAAW,UAAU,EAAE;AAAA,MACnE,WAAW,YAAY,OAAO,CAAC,SAAS,KAAK,WAAW,WAAW,EAAE;AAAA,MACrE,QAAQ,YAAY,OAAO,CAAC,SAAS,KAAK,WAAW,QAAQ,EAAE;AAAA,MAC/D,UAAU,YAAY,OAAO,CAAC,SAAS,KAAK,WAAW,QAAQ;AAAA,MAC/D,QAAQ,YAAY,OAAO,CAAC,SAAS,KAAK,WAAW,QAAQ,EAAE;AAAA,MAC/D,UAAU,YACP;AAAA,QACC,CAAC,SACC,KAAK,YAAY;AAAA,MACrB,EACC,IAAI,CAAC,SAAS,KAAK,OAAO;AAAA,MAC7B,SAAS,YAAY,OAAO,CAAC,SAAS,KAAK,WAAW,SAAS,EAAE;AAAA,MACjE,OAAO,YAAY;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAc,UAAU,SAAiD;AACvE,eAAS;AACP,YAAM,OAAO,KAAK,eAAe;AAEjC,UAAI,SAAS,QAAW;AACtB;AAAA,MACF;AAEA,YAAM,KAAK,QAAQ,MAAM,OAAO;AAAA,IAClC;AAAA,EACF;AAAA,EAEQ,iBAAwD;AAC9D,QAAI,KAAK,QAAQ;AACf,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,KAAK,MAAM,KAAK,CAAC,cAAc,UAAU,WAAW,QAAQ;AAEzE,QAAI,SAAS,QAAW;AACtB,WAAK,SAAS,KAAK,WAAW,OAAO,UAAU,aAAa;AAAA,IAC9D;AAEA,WAAO,MAAM,WAAW,YAAY,OAAO;AAAA,EAC7C;AAAA,EAEA,MAAc,QACZ,MACA,SACe;AACf,UAAM,gBAAgB,qBAAqB,QAAQ,QAAQ,KAAK,UAAU;AAE1E,QAAI;AACF,YAAM,iBAA+C;AAAA,QACnD,QAAQ,KAAK,WAAW;AAAA,MAC1B;AACA,YAAM,aAAa,QAAQ,cAAc,KAAK;AAC9C,YAAM,QAAQ,QAAQ,SAAS,KAAK;AACpC,YAAM,UAAU,QAAQ,WAAW,KAAK;AACxC,YAAM,iBAAiB,QAAQ,kBAAkB,KAAK;AAEtD,UAAI,eAAe,QAAW;AAC5B,uBAAe,aAAa;AAAA,MAC9B;AAEA,UAAI,UAAU,QAAW;AACvB,uBAAe,QAAQ;AAAA,MACzB;AAEA,UAAI,YAAY,QAAW;AACzB,uBAAe,UAAU;AAAA,MAC3B;AAEA,UAAI,mBAAmB,QAAW;AAChC,uBAAe,iBAAiB;AAAA,MAClC;AAEA,YAAM,UAAU,MAAM,KAAK,OAAO;AAAA,QAChC,KAAK;AAAA,QACL,KAAK,gBAAgB,IAAI;AAAA,QACzB;AAAA,MACF;AAEA,WAAK,UAAU;AACf,WAAK,SAAS;AACd,WAAK,YAAY,OAAO;AAAA,IAC1B,SAAS,OAAO;AACd,WAAK,QAAQ;AACb,WAAK,SAAS,KAAK,WAAW,OAAO,UAAU,aAAa;AAE5D,UAAI,KAAK,WAAW,UAAU;AAC5B,aAAK,UAAU,aAAa,IAAI,GAAG,KAAK;AAAA,MAC1C;AAAA,IACF,UAAE;AACA,oBAAc,QAAQ;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,gBAAgB,MAAmD;AACzE,UAAM,WAAW,KAAK,YAAY,KAAK,mBAAmB,KAAK,kBAAkB,KAAK,GAAG;AAEzF,QAAI,aAAa,QAAW;AAC1B,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS,EAAE,OAAO,KAAK,IAAI,GAAG;AAAA,QAC9B,SAAS,uCAAuC,KAAK,IAAI,EAAE;AAAA,QAC3D,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,yBAAiC;AACvC,WAAO,KAAK,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,YAAY,CAAC,KAAK,WAAW,OAAO,OAAO,EAC3F;AAAA,EACL;AACF;AAEA,SAAS,qBAAqB,OAAmC;AAC/D,MAAI,UAAU,UAAa,CAAC,OAAO,SAAS,KAAK,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC;AAEA,SAAS,qBACP,QACA,QACqB;AACrB,MAAI,WAAW,QAAW;AACxB,WAAO,EAAE,SAAS,MAAM,OAAU;AAAA,EACpC;AAEA,QAAM,QAAQ,MAAY,OAAO,MAAM;AAEvC,MAAI,OAAO,SAAS;AAClB,UAAM;AACN,WAAO,EAAE,SAAS,MAAM,OAAU;AAAA,EACpC;AAEA,SAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;AAEtD,SAAO;AAAA,IACL,SAAS,MAAM,OAAO,oBAAoB,SAAS,KAAK;AAAA,EAC1D;AACF;AAEA,SAAS,aAAa,MAAoD;AACxE,QAAM,WAA8B;AAAA,IAClC,IAAI,KAAK;AAAA,IACT,KAAK,iBAAiB,KAAK,GAAG;AAAA,IAC9B,QAAQ,KAAK;AAAA,EACf;AAEA,MAAI,KAAK,YAAY,OAAW,UAAS,UAAU,KAAK;AACxD,MAAI,KAAK,UAAU,OAAW,UAAS,QAAQ,KAAK;AAEpD,SAAO;AACT;AAEA,SAAS,iBAAiB,KAA+B;AACvD,QAAM,QAAqB;AAAA,IACzB,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,EACjB;AAEA,MAAI,IAAI,WAAW,OAAW,OAAM,SAAS,EAAE,GAAG,IAAI,OAAO;AAC7D,MAAI,IAAI,gBAAgB,OAAW,OAAM,cAAc,EAAE,GAAG,IAAI,YAAY;AAC5E,MAAI,IAAI,eAAe,OAAW,OAAM,aAAa,IAAI;AACzD,MAAI,IAAI,YAAY,OAAW,OAAM,UAAU,IAAI;AACnD,MAAI,IAAI,aAAa,OAAW,OAAM,WAAW,EAAE,GAAG,IAAI,SAAS;AAEnE,SAAO;AACT;;;ACrTO,SAAS,iBAAiB,OAAuB;AACtD,QAAM,aAAa,oBAAoB,KAAK;AAC5C,MAAI,eAAe,IAAK,QAAO;AAC/B,QAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,QAAM,IAAI;AACV,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO,IAAI,MAAM,KAAK,GAAG,CAAC;AAC5B;AAQO,SAAS,uBAAuB,OAAmC;AACxE,QAAM,aAAa,oBAAoB,KAAK;AAC5C,QAAM,SAA6B,CAAC,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC;AAC5D,MAAI,eAAe,IAAK,QAAO;AAE/B,QAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO;AACxB,cAAU,IAAI,IAAI;AAClB,WAAO,KAAK,EAAE,MAAM,MAAM,MAAM,OAAO,CAAC;AAAA,EAC1C;AACA,SAAO;AACT;AAWO,SAAS,kBACd,SACA,MAA0B,QAC1B,QAA8B,OACf;AACf,QAAM,YAAY,UAAU,QAAQ,IAAI;AACxC,SAAO,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,MAAM,UAAU;AACxC,QAAI,QAAQ,QAAQ;AAClB,YAAM,YAAY,KAAK,SAAS;AAChC,YAAM,aAAa,MAAM,SAAS;AAClC,UAAI,cAAc,WAAY,QAAO,YAAY,KAAK;AAAA,IACxD;AAEA,UAAM,WAAW,oBAAoB,MAAM,OAAO,GAAG;AACrD,QAAI,aAAa,EAAG,QAAO,WAAW;AACtC,WAAO,aAAa,MAAM,KAAK;AAAA,EACjC,CAAC;AACH;AASO,SAAS,oBACd,SACA,UAAkE,CAAC,GACpD;AACf,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,SAAS,QAAQ;AACvB,SAAO,QAAQ,OAAO,CAAC,UAAU;AAC/B,QAAI,CAAC,cAAc,MAAM,KAAK,WAAW,GAAG,EAAG,QAAO;AACtD,QAAI,WAAW,UAAa,CAAC,OAAO,KAAK,EAAG,QAAO;AACnD,WAAO;AAAA,EACT,CAAC;AACH;AAYO,SAAS,oBAAoB,SAAoD;AACtF,QAAM,EAAE,GAAG,IAAI;AACf,MAAI,cAAc,oBAAoB,QAAQ,eAAe,GAAG;AAChE,MAAI,gBAA+B,CAAC;AACpC,MAAI,UAA8B,QAAQ,WAAW;AACrD,MAAI,YAAkC,QAAQ,aAAa;AAC3D,MAAI,aAAa,QAAQ,cAAc;AACvC,QAAM,SAAS,QAAQ;AAEvB,iBAAe,cAA8C;AAC3D,UAAM,MAAM,MAAM,GAAG,KAAK,WAAW;AACrC,UAAM,YAAY,eAAe,GAAG;AACpC,oBAAgB;AAChB,WAAO,SAAS;AAAA,EAClB;AAEA,WAAS,eAAe,KAA4C;AAClE,UAAM,gBAAuE,EAAE,WAAW;AAC1F,QAAI,WAAW,OAAW,eAAc,SAAS;AACjD,UAAM,WAAW,oBAAoB,KAAK,aAAa;AACvD,WAAO,kBAAkB,UAAU,SAAS,SAAS;AAAA,EACvD;AAEA,WAAS,WAAkC;AACzC,WAAO;AAAA,MACL,aAAa,uBAAuB,WAAW;AAAA,MAC/C,SAAS,CAAC,GAAG,aAAa;AAAA,MAC1B,MAAM;AAAA,IACR;AAAA,EACF;AAEA,iBAAe,SAAS,QAAgD;AACtE,kBAAc,cAAc,aAAa,MAAM;AAC/C,WAAO,YAAY;AAAA,EACrB;AAEA,iBAAeC,MAAK,OAAoD;AACtE,QAAI,MAAM,SAAS,aAAa;AAC9B,YAAM,IAAI,UAAU,oCAAoC,MAAM,IAAI,YAAY,MAAM,IAAI,GAAG;AAAA,IAC7F;AACA,WAAO,SAAS,MAAM,IAAI;AAAA,EAC5B;AAEA,SAAO;AAAA,IACL,aAAa,MAAM,uBAAuB,WAAW;AAAA,IACrD,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA;AAAA,IACA,MAAAA;AAAA,IACA,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,SAAS;AAAA,IACT,cAAc,OAAgB;AAC5B,mBAAa;AAAA,IACf;AAAA,IACA,QAAQ,KAAyB,QAA8B,WAAW;AACxE,gBAAU;AACV,kBAAY;AAAA,IACd;AAAA,IACA,IAAI,MAAM,SAAS,iBAAiB,WAAW,CAAC;AAAA,EAClD;AACF;AAEA,SAAS,cAAc,aAAqB,QAAwB;AAClE,MAAI,OAAO,WAAW,GAAG,EAAG,QAAO,oBAAoB,MAAM;AAC7D,MAAI,WAAW,MAAM,WAAW,IAAK,QAAO;AAC5C,MAAI,WAAW,KAAM,QAAO,iBAAiB,WAAW;AACxD,QAAM,OAAO,gBAAgB,MAAM,KAAK;AACxC,SAAO,oBAAoB,GAAG,IAAI,IAAI,MAAM,EAAE;AAChD;AAEA,SAAS,oBACP,MACA,OACA,KACQ;AACR,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,cAAQ,KAAK,QAAQ,MAAM,MAAM,QAAQ;AAAA,IAC3C,KAAK,cAAc;AACjB,YAAM,WAAW,KAAK,YAAY,QAAQ,KAAK;AAC/C,YAAM,YAAY,MAAM,YAAY,QAAQ,KAAK;AACjD,aAAO,WAAW;AAAA,IACpB;AAAA,IACA,KAAK;AACH,aAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAAA,IAC3C,KAAK;AAAA,IACL;AACE,aAAO,aAAa,MAAM,KAAK;AAAA,EACnC;AACF;AAEA,SAAS,aAAa,MAAmB,OAA4B;AACnE,SAAO,KAAK,KAAK,cAAc,MAAM,MAAM,QAAW,EAAE,SAAS,MAAM,aAAa,OAAO,CAAC;AAC9F;;;ACxLO,SAAS,eAAe,SAA8C;AAC3E,QAAM,YAA2B,QAAQ,aAAa;AACtD,QAAM,eAAiC,QAAQ,gBAAgB;AAC/D,QAAM,iBAAqC,QAAQ,kBAAkB;AACrE,QAAM,0BAA0B,QAAQ,2BAA2B;AACnE,QAAM,aAAa,oBAAoB,QAAQ,OAAO,QAAQ;AAC9D,QAAM,kBAAkB,oBAAoB,QAAQ,YAAY,QAAQ;AACxE,QAAM,WAAqB,CAAC;AAC5B,QAAM,QAA4B,CAAC;AAEnC,aAAW,SAAS,QAAQ,KAAK,SAAS;AACxC,UAAM,UAA4B;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,OAAO,aAAa,OAAW,SAAQ,iBAAiB,QAAQ,OAAO;AACnF,QAAI,QAAQ,YAAY,aAAa,QAAW;AAC9C,cAAQ,sBAAsB,QAAQ,YAAY;AAAA,IACpD;AACA,UAAM,OAAO,UAAU,OAAO;AAE9B,QAAI,SAAS,OAAW,OAAM,KAAK,IAAI;AAAA,EACzC;AAEA,QAAM,YAAsD;AAAA,IAC1D,IAAI,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAQ,WAAW,OAAW,WAAU,SAAS,QAAQ;AAC7D,MAAI,QAAQ,QAAQ,OAAW,WAAU,MAAM,QAAQ;AACvD,MAAI,QAAQ,aAAa,OAAW,WAAU,WAAW,QAAQ;AAEjE,SAAO,mBAAmB,SAAS;AACrC;AAeA,SAAS,UAAU,SAAyD;AAC1E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,cAAc,iBAAiB,KAAK;AAE1C,MAAI,eAAe,CAAC,QAAQ,yBAAyB;AACnD,WAAO;AAAA,EACT;AAEA,UAAQ,MAAM,QAAQ;AAAA,IACpB,KAAK;AACH,aAAO,UAAU,OAAO;AAAA,IAC1B,KAAK;AACH,aAAO,YAAY,OAAO;AAAA,IAC5B,KAAK;AACH,aAAO,aAAa,OAAO;AAAA,IAC7B,KAAK;AACH,aAAO,cAAc,OAAO;AAAA,IAC9B;AAEE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,UAAU,SAA6C;AAC9D,MAAI,QAAQ,cAAc,yBAAyB;AACjD,WAAO,eAAe,SAAS,UAAU,eAAe,iBAAiB,QAAQ,KAAK,CAAC;AAAA,EACzF;AAGA,MAAI,QAAQ,iBAAiB,SAAS;AACpC,WAAO,eAAe,SAAS,8CAA8C;AAAA,EAC/E;AAEA,SAAO,iBAAiB,SAAS,QAAQ;AAC3C;AAEA,SAAS,YAAY,SAA6C;AAChE,MAAI,QAAQ,cAAc,yBAAyB;AACjD,WAAO,eAAe,SAAS,eAAe,UAAU,iBAAiB,QAAQ,KAAK,CAAC;AAAA,EACzF;AAGA,MAAI,QAAQ,iBAAiB,SAAS;AACpC,WAAO,eAAe,SAAS,mDAAmD;AAAA,EACpF;AAEA,MAAI,QAAQ,iBAAiB,gBAAgB;AAC3C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,iBAAiB,SAAS,aAAa;AAChD;AAEA,SAAS,aAAa,SAA6C;AACjE,UAAQ,QAAQ,gBAAgB;AAAA,IAC9B,KAAK;AACH,aAAO,eAAe,SAAS,UAAU,eAAe,iBAAiB,QAAQ,KAAK,GAAG;AAAA,QACvF,aAAa;AAAA,MACf,CAAC;AAAA,IACH,KAAK;AACH,aAAO,eAAe,SAAS,eAAe,UAAU,iBAAiB,QAAQ,KAAK,GAAG;AAAA,QACvF,aAAa;AAAA,MACf,CAAC;AAAA,IACH,KAAK;AACH,aAAO,eAAe,SAAS,qBAAqB,QAAQ,MAAM,QAAQ,KAAK,GAAG,CAAC,EAAE;AAAA,IACvF,KAAK;AACH,YAAM,IAAI,mBAAmB;AAAA,QAC3B,SAAS;AAAA,UACP,MAAM,QAAQ,MAAM;AAAA,UACpB,SAAS,QAAQ,MAAM;AAAA,QACzB;AAAA,QACA,SAAS,yBAAyB,QAAQ,MAAM,IAAI,kBAAkB,QAAQ,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,QACtG,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACE,aAAO,eAAe,SAAS,kBAAkB;AAAA,EACrD;AACF;AAEA,SAAS,cAAc,SAA6C;AAClE,SAAO,eAAe,SAAS,uBAAuB;AACxD;AAEA,SAAS,eACP,SACA,UACA,QACA,eACA,YAAuC,CAAC,GACtB;AAClB,QAAM,OAAyB;AAAA,IAC7B,QAAQ;AAAA,IACR,IAAI,WAAW,QAAQ,OAAO,QAAQ,QAAQ,OAAO,MAAM,EAAE;AAAA,IAC7D,QAAQ,gBAAgB,QAAQ,OAAO,QAAQ,QAAQ,OAAO,MAAM,EAAE;AAAA,EACxE;AAEA,OAAK,SAAS,YAAY,SAAS,QAAQ;AAC3C,OAAK,cAAc,YAAY,SAAS,MAAM;AAC9C,MAAI,kBAAkB,OAAW,MAAK,gBAAgB;AACtD,MAAI,UAAU,gBAAgB,KAAM,MAAK,cAAc;AACvD,MAAI,UAAU,aAAa,OAAW,MAAK,WAAW,EAAE,GAAG,UAAU,SAAS;AAE9E,SAAO;AACT;AAEA,SAAS,iBACP,SACA,MACkB;AAClB,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,YAAY,SAAS,IAAI;AAAA,IACtC,aAAa;AAAA,IACb,IAAI,WAAW,QAAQ,OAAO,UAAU,IAAI,EAAE;AAAA,IAC9C,QAAQ,UAAU,IAAI;AAAA,EACxB;AACF;AAEA,SAAS,eAAe,SAA2B,QAAkC;AACnF,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,IAAI,WAAW,QAAQ,OAAO,MAAM;AAAA,IACpC;AAAA,IACA,QAAQ,YAAY,SAAS,QAAQ;AAAA,IACrC,aAAa,YAAY,SAAS,aAAa;AAAA,EACjD;AACF;AAEA,SAAS,YACP,SACA,MACyC;AACzC,QAAM,OAAO,SAAS,WAAW,QAAQ,aAAa,QAAQ;AAC9D,QAAM,WAAW,SAAS,WAAW,QAAQ,iBAAiB,QAAQ;AACtE,QAAM,WAAoD;AAAA,IACxD,MAAM,oBAAoB,MAAM,QAAQ,MAAM,IAAI;AAAA,EACpD;AACA,MAAI,aAAa,OAAW,UAAS,WAAW;AAChD,SAAO;AACT;AAEA,SAAS,oBAAoB,UAAkB,cAA8B;AAC3E,MAAI,aAAa,IAAK,QAAO;AAC7B,MAAI,iBAAiB,IAAK,QAAO;AACjC,SAAO,eAAe,UAAU,YAAY;AAC9C;AAEA,SAAS,WAAW,OAA4B,QAAwB;AACtE,SAAO,GAAG,MAAM,IAAI,IAAI,MAAM;AAChC;AAEA,SAAS,gBAAgB,OAA4B,QAAwB;AAC3E,MAAI,MAAM,QAAQ,WAAW,EAAG,QAAO;AACvC,SAAO,GAAG,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,CAAC;AAC9C;AAEA,SAAS,iBAAiB,OAAgD;AACxE,SAAO,MAAM,QAAQ,QAAQ,MAAM,aAAa;AAClD;AAEA,SAAS,iBAAiB,OAAqC;AAC7D,SAAO,MAAM,QAAQ,SAAS,eAAe,MAAM,aAAa,SAAS;AAC3E;;;ACtLA,IAAM,6BAA6B;AACnC,IAAM,iBAAiB;AAShB,SAAS,uBAAuB,SAA0D;AAC/F,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,SAAS,GAAG;AACd,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO;AAAA,MAClB,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,oBAAoB,QAAQ,YAAY,QAAQ;AACjE,MAAI,aAAa,KAAK;AACpB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,WAAiC,QAAQ,YAAY;AAC3D,QAAM,MAAM,QAAQ,MAAM,KAAK,oBAAI,KAAK;AACxC,QAAM,YAAY,QAAQ,aAAa,iBAAiB,GAAG;AAC3D,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,QAAQ,qBAAqB;AAAA,EAC/B;AACA,QAAM,cAAc,eAAe,cAAc,SAAS;AAC1D,QAAM,aACJ,aAAa,WAAW,eAAe,cAAc,GAAG,SAAS,WAAW,IAAI;AAClF,QAAM,WAAW,QAAQ,YAAY,YAAY,QAAQ,OAAO;AAChE,QAAM,WAAqB,CAAC;AAE5B,QAAM,aAAa,eAAe;AAAA,IAChC,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,aAAa;AAAA,MACX,GAAI,QAAQ,YAAY,aAAa,SACjC,EAAE,UAAU,QAAQ,YAAY,SAAS,IACzC,CAAC;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,WAAW;AAAA,IACX,QAAQ,QAAQ,UAAU;AAAA,IAC1B,IAAI,GAAG,QAAQ,EAAE;AAAA,IACjB,yBAAyB;AAAA,IACzB,GAAI,QAAQ,QAAQ,SAAY,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IACxD,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,QAAM,WAAW,mBAAmB;AAAA,IAClC;AAAA,IACA;AAAA,IACA,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,gBAAgB;AAAA,IAC5B,kBAAkB,QAAQ,oBAAoB,CAAC;AAAA,IAC/C,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,OAAyB;AAAA,IAC7B;AAAA,IACA,WAAW;AAAA,IACX,IAAI,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,MAAI,eAAe,OAAW,MAAK,aAAa;AAChD,MAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,EAAE,GAAG,QAAQ,SAAS;AAC1E,SAAO;AACT;AAWA,SAAS,mBAAmB,SAA2D;AACrF,MAAI,QAAQ,aAAa,WAAW;AAClC,UAAM,OAAiC;AAAA,MACrC,aAAa;AAAA,MACb,UAAU,QAAQ;AAAA,MAClB,IAAI,GAAG,QAAQ,MAAM;AAAA,MACrB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,IAClB;AACA,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,WAAO,CAAC,IAAI;AAAA,EACd;AAEA,QAAM,QAAoC,CAAC;AAC3C,MAAI,QAAQ,eAAe,QAAW;AACpC,UAAM,SAAmC;AAAA,MACvC,aAAa;AAAA,MACb,UAAU,QAAQ;AAAA,MAClB,IAAI,GAAG,QAAQ,MAAM;AAAA,MACrB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,IAClB;AACA,QAAI,QAAQ,aAAa,OAAW,QAAO,WAAW,QAAQ;AAC9D,UAAM,KAAK,MAAM;AAAA,EACnB;AAEA,QAAM,UAAoC;AAAA,IACxC,aAAa;AAAA,IACb,UAAU,QAAQ;AAAA,IAClB,IAAI,GAAG,QAAQ,MAAM;AAAA,IACrB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ,QAAQ;AAAA,EAClB;AACA,MAAI,QAAQ,aAAa,OAAW,SAAQ,WAAW,QAAQ;AAC/D,QAAM,KAAK,OAAO;AAClB,SAAO;AACT;AAWA,SAAS,gBAAgB,SAAqD;AAC5E,MAAI,QAAQ,iBAAiB,WAAW,EAAG,QAAO,CAAC;AAEnD,QAAM,iBAAiB,oBAAoB,QAAQ,YAAY;AAC/D,QAAM,iBAAiB,eAAe,gBAAgB,QAAQ,SAAS;AACvE,QAAM,aAAa,CAAC,GAAG,IAAI,IAAI,QAAQ,iBAAiB,IAAI,CAACC,UAAS,oBAAoBA,KAAI,CAAC,CAAC,CAAC,EAC9F,OAAO,CAACA,UAASA,UAAS,cAAc,EACxC,KAAK;AAER,QAAM,mBAAmB,KAAK,IAAI,GAAG,QAAQ,SAAS,CAAC;AACvD,MAAI,WAAW,UAAU,iBAAkB,QAAO,CAAC;AAEnD,QAAM,UAAU,WAAW,MAAM,GAAG,WAAW,SAAS,gBAAgB;AACxE,SAAO,QAAQ,IAAI,CAACA,OAAM,UAAU;AAClC,UAAM,OAA8B;AAAA,MAClC,IAAI,GAAG,QAAQ,MAAM,UAAU,KAAK;AAAA,MACpC,MAAAA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,iBAAiB,KAAmB;AAE3C,SAAO,IAAI,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC/C;;;AC1PA,gBAAuB,eACrB,IACA,UACA,UAAiC,CAAC,GACD;AACjC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,qBAAqB,QAAQ,sBAAsB;AACzD,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,OAAO,oBAAoB,QAAQ;AACzC,QAAM,aAAoC;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAQ,aAAa,OAAW,YAAW,WAAW,QAAQ;AAClE,MAAI,QAAQ,WAAW,OAAW,YAAW,SAAS,QAAQ;AAC9D,MAAI,QAAQ,WAAW,OAAW,YAAW,SAAS,QAAQ;AAE9D,SAAO,cAAc,IAAI,MAAM,GAAG,UAAU;AAC9C;AAYA,gBAAgB,cACd,IACAC,OACA,OACA,SACiC;AACjC,EAAAC,gBAAe,QAAQ,MAAM;AAC7B,QAAM,UAAU,MAAM,GAAG,KAAKD,KAAI;AAClC,QAAM,SAAS,CAAC,GAAG,OAAO,EAAE,KAAKE,eAAc;AAE/C,aAAW,SAAS,QAAQ;AAC1B,QAAI,QAAQ,WAAW,UAAa,CAAC,QAAQ,OAAO,KAAK,EAAG;AAE5D,QAAI,iBAAiB,OAAO,QAAQ,oBAAoB,QAAQ,YAAY,GAAG;AAC7E,YAAM,EAAE,OAAO,OAAO,YAAYF,MAAK;AAAA,IACzC;AAEA,QACE,QAAQ,aACR,eAAe,OAAO,QAAQ,cAAc,MAC3C,QAAQ,aAAa,UAAa,QAAQ,QAAQ,WACnD;AACA,aAAO,cAAc,IAAI,kBAAkB,OAAOA,KAAI,GAAG,QAAQ,GAAG,OAAO;AAAA,IAC7E;AAAA,EACF;AACF;AAEA,SAAS,iBACP,OACA,oBACA,cACS;AACT,MAAI,MAAM,SAAS,YAAa,QAAO;AACvC,MAAI,MAAM,SAAS,OAAQ,QAAO;AAClC,SAAO;AACT;AAEA,SAAS,eAAe,OAAoB,gBAAkC;AAC5E,MAAI,MAAM,SAAS,YAAa,QAAO;AACvC,SAAO,kBAAkB,MAAM,SAAS;AAC1C;AAEA,SAAS,kBAAkB,OAAoB,YAA4B;AACzE,MAAI,MAAM,SAAS,MAAM,MAAM,SAAS,MAAM,MAAM;AAClD,WAAO,oBAAoB,MAAM,IAAI;AAAA,EACvC;AAEA,SAAO,eAAe,YAAY,MAAM,IAAI;AAC9C;AAEA,SAASE,gBAAe,MAAmB,OAA4B;AACrE,MAAI,KAAK,OAAO,MAAM,KAAM,QAAO;AACnC,MAAI,KAAK,OAAO,MAAM,KAAM,QAAO;AACnC,SAAO;AACT;AAEA,SAASD,gBAAe,QAAuC;AAC7D,MAAI,QAAQ,YAAY,MAAM;AAC5B,UAAM,IAAI,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF;;;ACvDA,eAAsB,gBACpB,QACA,YACA,aACA,iBACA,UAAkC,CAAC,GACV;AACzB,QAAM,mBAAmB,QAAQ,oBAAoB;AACrD,QAAM,aAAa,oBAAoB,UAAU;AACjD,QAAM,kBAAkB,oBAAoB,eAAe;AAC3D,QAAM,aAAa,kBAAkB,SAAS,QAAQ,YAAY;AAClE,QAAM,kBAAkB,kBAAkB,SAAS,QAAQ,iBAAiB;AAE5E,QAAM,CAAC,eAAe,kBAAkB,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC5D,eAAe,QAAQ,YAAY,UAAU;AAAA,IAC7C,eAAe,aAAa,iBAAiB,eAAe;AAAA,EAC9D,CAAC;AAED,QAAM,UAAU,aAAa,eAAe,kBAAkB;AAC9D,QAAM,UAAiC,CAAC;AACxC,QAAM,UAAiC;AAAA,IACrC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAEA,aAAW,EAAE,MAAAE,OAAM,QAAQ,aAAa,aAAa,iBAAiB,KAAK,SAAS;AAClF,YAAQ,SAAS;AACjB,UAAM,UAAkC,CAAC;AACzC,QAAI;AAEJ,QAAI,gBAAgB,UAAa,qBAAqB,QAAW;AAC/D,eAAS;AACT,cAAQ,SAAS;AAAA,IACnB,WAAW,gBAAgB,UAAa,qBAAqB,QAAW;AACtE,eAAS;AACT,cAAQ,WAAW;AAAA,IACrB,WAAW,gBAAgB,UAAa,qBAAqB,QAAW;AACtE,YAAM,kBAAkBC,gBAAe,aAAa,kBAAkB,OAAO;AAE7E,UAAI,gBAAgB,WAAW,GAAG;AAChC,iBAAS;AACT,gBAAQ,aAAa;AAAA,MACvB,OAAO;AACL,iBAAS;AACT,gBAAQ,KAAK,GAAG,eAAe;AAC/B,gBAAQ,YAAY;AAAA,MACtB;AAAA,IACF,OAAO;AAEL;AAAA,IACF;AAEA,QAAI,WAAW,eAAe,CAAC,iBAAkB;AAEjD,UAAM,SAA8B,EAAE,MAAAD,OAAM,SAAS,OAAO;AAC5D,QAAI,gBAAgB,OAAW,QAAO,SAAS;AAC/C,QAAI,qBAAqB,OAAW,QAAO,cAAc;AACzD,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,UAAQ,KAAK,CAAC,MAAM,UAAW,KAAK,OAAO,MAAM,OAAO,KAAK,KAAK,OAAO,MAAM,OAAO,IAAI,CAAE;AAE5F,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAEA,SAAS,kBACP,SACA,QACuB;AACvB,QAAM,OAAO,QAAQ,QAAQ,CAAC;AAC9B,QAAM,SAAgC,CAAC;AAEvC,MAAI,KAAK,cAAc,OAAW,QAAO,YAAY,KAAK;AAC1D,MAAI,KAAK,aAAa,OAAW,QAAO,WAAW,KAAK;AACxD,MAAI,KAAK,uBAAuB,OAAW,QAAO,qBAAqB,KAAK;AAC5E,MAAI,KAAK,iBAAiB,OAAW,QAAO,eAAe,KAAK;AAChE,MAAI,KAAK,mBAAmB,OAAW,QAAO,iBAAiB,KAAK;AACpE,QAAM,iBAAiB,UAAU,KAAK;AACtC,MAAI,mBAAmB,OAAW,QAAO,SAAS;AAClD,MAAI,QAAQ,WAAW,OAAW,QAAO,SAAS,QAAQ;AAE1D,SAAO;AACT;AAOA,eAAe,eACb,IACA,UACA,aACmC;AACnC,QAAM,MAAM,oBAAI,IAAyB;AAEzC,mBAAiB,UAAU,eAAe,IAAI,UAAU,WAAW,GAAG;AACpE,UAAM,YAAY,iBAAiB,OAAO,OAAO,QAAQ;AACzD,QAAI,cAAc,OAAW,KAAI,IAAI,UAAU,cAAc,UAAU,KAAK;AAAA,EAC9E;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAAoB,UAA8C;AAC1F,QAAM,OAAO,oBAAoB,QAAQ;AACzC,QAAMA,QAAO,oBAAoB,MAAM,IAAI;AAE3C,MAAIA,UAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,IAAK,QAAO,EAAE,OAAO,cAAcA,MAAK;AACrD,MAAIA,MAAK,WAAW,GAAG,IAAI,GAAG,GAAG;AAC/B,WAAO,EAAE,OAAO,cAAcA,MAAK,MAAM,KAAK,MAAM,EAAE;AAAA,EACxD;AAEA,SAAO;AACT;AAQA,SAAS,aACP,eACA,oBACe;AACf,QAAM,QAAQ,oBAAI,IAAY,CAAC,GAAG,cAAc,KAAK,GAAG,GAAG,mBAAmB,KAAK,CAAC,CAAC;AACrF,QAAM,UAAyB,CAAC;AAEhC,aAAWA,SAAQ,OAAO;AACxB,UAAM,OAAoB,EAAE,MAAAA,MAAK;AACjC,UAAM,SAAS,cAAc,IAAIA,KAAI;AACrC,UAAM,cAAc,mBAAmB,IAAIA,KAAI;AAE/C,QAAI,WAAW,OAAW,MAAK,SAAS;AACxC,QAAI,gBAAgB,OAAW,MAAK,cAAc;AAClD,YAAQ,KAAK,IAAI;AAAA,EACnB;AAEA,SAAO;AACT;AAEA,SAASC,gBACP,QACA,aACA,SACwB;AACxB,QAAM,UAAkC,CAAC;AACzC,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,oBAAoB,QAAQ,qBAAqB;AACvD,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,YAAY,QAAQ,yBAAyB;AAEnD,MAAI,OAAO,SAAS,YAAY,MAAM;AACpC,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,MAAI,eAAe,eAAe,QAAQ,WAAW,KAAK,OAAO,SAAS,YAAY,MAAM;AAC1F,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,MAAI,qBAAqB,sBAAsB,QAAQ,aAAa,SAAS,GAAG;AAC9E,YAAQ,KAAK,YAAY;AAAA,EAC3B;AAEA,MACE,mBACA,OAAO,aAAa,UACpB,YAAY,aAAa,UACzB,OAAO,aAAa,YAAY,UAChC;AACA,YAAQ,KAAK,UAAU;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,QAAqB,aAAmC;AAC9E,MAAI,OAAO,SAAS,UAAU,YAAY,SAAS,OAAQ,QAAO;AAClE,SAAO,OAAO,SAAS,UAAa,YAAY,SAAS;AAC3D;AAEA,SAAS,sBACP,QACA,aACA,aACS;AACT,MAAI,OAAO,eAAe,UAAa,YAAY,eAAe,OAAW,QAAO;AACpF,QAAM,QAAQ,KAAK,IAAI,OAAO,WAAW,QAAQ,IAAI,YAAY,WAAW,QAAQ,CAAC;AACrF,SAAO,QAAQ;AACjB;;;ACrQO,IAAM,iCAAiC;AAuE9C,eAAsB,qBACpB,IACA,UACA,UAAuC,CAAC,GACf;AACzB,QAAM,OAAO,oBAAoB,QAAQ;AACzC,QAAM,cAAqC,EAAE,GAAI,QAAQ,QAAQ,CAAC,EAAG;AACrE,QAAM,iBAAiB,QAAQ,UAAU,QAAQ,MAAM;AACvD,MAAI,mBAAmB,OAAW,aAAY,SAAS;AACvD,MAAI,QAAQ,WAAW,OAAW,aAAY,SAAS,QAAQ;AAE/D,QAAM,UAAiC,CAAC;AAExC,mBAAiB,UAAU,eAAe,IAAI,MAAM,WAAW,GAAG;AAChE,UAAM,eAAe,iBAAiB,OAAO,MAAM,MAAM,IAAI;AAC7D,QAAI,iBAAiB,OAAW;AAChC,YAAQ,KAAK,gBAAgB,OAAO,OAAO,YAAY,CAAC;AAAA,EAC1D;AAEA,UAAQ,KAAK,CAAC,MAAM,UAAW,KAAK,OAAO,MAAM,OAAO,KAAK,KAAK,OAAO,MAAM,OAAO,IAAI,CAAE;AAE5F,QAAM,eAAe,QAAQ,MAAM,KAAK,oBAAI,KAAK,GAAG,YAAY;AAChE,QAAM,WAA2B;AAAA,IAC/B;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAQ,aAAa,OAAW,UAAS,WAAW,QAAQ;AAChE,SAAO;AACT;AASO,SAAS,wBAAwB,UAA0B,SAAiB,GAAW;AAC5F,SAAO,KAAK,UAAU,UAAU,QAAW,MAAM;AACnD;AASO,SAAS,oBAAoB,MAA8B;AAChE,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,SAAS,OAAO;AACd,UAAM,IAAI,mBAAmB;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,QAAQ,OAAO,WAAW,UAAU;AACjD,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,YAAY;AAClB,MAAI,UAAU,kBAAkB,gCAAgC;AAC9D,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,QACP,UAAU;AAAA,QACV,UAAU,UAAU;AAAA,MACtB;AAAA,MACA,SAAS,8CAA8C,OAAO,UAAU,aAAa,CAAC;AAAA,MACtF,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,UAAU,SAAS,YAAY,UAAU,KAAK,WAAW,GAAG;AACrE,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,UAAU,gBAAgB,UAAU;AAC7C,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,MAAM,QAAQ,UAAU,OAAO,GAAG;AACrC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,UAAU,QAAQ,IAAI,CAAC,OAAO,UAAU,uBAAuB,OAAO,KAAK,CAAC;AAC5F,QAAM,WAA2B;AAAA,IAC/B;AAAA,IACA,eAAe;AAAA,IACf,aAAa,UAAU;AAAA,IACvB,MAAM,oBAAoB,UAAU,IAAI;AAAA,EAC1C;AACA,MAAI,OAAO,UAAU,aAAa,SAAU,UAAS,WAAW,UAAU;AAC1E,SAAO;AACT;AAcO,SAAS,uBACd,QACA,aACA,UAAyC,CAAC,GAC1B;AAChB,QAAM,mBAAmB,QAAQ,oBAAoB;AACrD,QAAM,YAAY,aAAa,MAAM;AACrC,QAAM,iBAAiB,aAAa,WAAW;AAC/C,QAAM,QAAQ,oBAAI,IAAY,CAAC,GAAG,UAAU,KAAK,GAAG,GAAG,eAAe,KAAK,CAAC,CAAC;AAE7E,QAAM,UAAiC,CAAC;AACxC,QAAM,UAAiC;AAAA,IACrC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAEA,aAAWC,SAAQ,OAAO;AACxB,YAAQ,SAAS;AACjB,UAAM,cAAc,UAAU,IAAIA,KAAI;AACtC,UAAM,mBAAmB,eAAe,IAAIA,KAAI;AAChD,UAAM,UAAkC,CAAC;AACzC,QAAI;AAEJ,QAAI,gBAAgB,UAAa,qBAAqB,QAAW;AAC/D,eAAS;AACT,cAAQ,SAAS;AAAA,IACnB,WAAW,gBAAgB,UAAa,qBAAqB,QAAW;AACtE,eAAS;AACT,cAAQ,WAAW;AAAA,IACrB,WAAW,gBAAgB,UAAa,qBAAqB,QAAW;AACtE,YAAM,WAAW,uBAAuB,aAAa,kBAAkB,OAAO;AAC9E,UAAI,SAAS,WAAW,GAAG;AACzB,iBAAS;AACT,gBAAQ,aAAa;AAAA,MACvB,OAAO;AACL,iBAAS;AACT,gBAAQ,KAAK,GAAG,QAAQ;AACxB,gBAAQ,YAAY;AAAA,MACtB;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAEA,QAAI,WAAW,eAAe,CAAC,iBAAkB;AAEjD,UAAM,SAA8B,EAAE,MAAAA,OAAM,SAAS,OAAO;AAC5D,QAAI,gBAAgB,QAAW;AAC7B,aAAO,SAAS,sBAAsB,aAAa,OAAO,IAAI;AAAA,IAChE;AACA,QAAI,qBAAqB,QAAW;AAClC,aAAO,cAAc,sBAAsB,kBAAkB,YAAY,IAAI;AAAA,IAC/E;AACA,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,UAAQ,KAAK,CAAC,MAAM,UAAW,KAAK,OAAO,MAAM,OAAO,KAAK,KAAK,OAAO,MAAM,OAAO,IAAI,CAAE;AAC5F,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAEA,SAAS,iBAAiB,WAAmB,MAAkC;AAC7E,QAAMA,QAAO,oBAAoB,SAAS;AAC1C,MAAIA,UAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,IAAK,QAAOA;AACzB,MAAIA,MAAK,WAAW,GAAG,IAAI,GAAG,EAAG,QAAOA,MAAK,MAAM,KAAK,MAAM;AAC9D,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAoB,cAA2C;AACtF,QAAM,gBAAqC;AAAA,IACzC,MAAM;AAAA,IACN,MAAM,MAAM;AAAA,EACd;AACA,MAAI,MAAM,SAAS,OAAW,eAAc,OAAO,MAAM;AACzD,MAAI,MAAM,eAAe,OAAW,eAAc,aAAa,MAAM,WAAW,YAAY;AAC5F,MAAI,MAAM,aAAa,OAAW,eAAc,WAAW,MAAM;AACjE,MAAI,MAAM,kBAAkB,OAAW,eAAc,gBAAgB,MAAM;AAC3E,SAAO;AACT;AAEA,SAAS,uBAAuB,OAAgB,OAAoC;AAClF,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,MAAM;AAAA,MACjB,SAAS,kCAAkC,KAAK;AAAA,MAChD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,YAAY;AAClB,MAAI,OAAO,UAAU,SAAS,YAAY,UAAU,KAAK,WAAW,GAAG;AACrE,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,MAAM;AAAA,MACjB,SAAS,kCAAkC,KAAK;AAAA,MAChD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,MAAI,CAAC,kBAAkB,UAAU,IAAI,GAAG;AACtC,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,EAAE,OAAO,UAAU,UAAU,KAAK;AAAA,MAC3C,SAAS,kCAAkC,KAAK;AAAA,MAChD,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,QAA6B;AAAA,IACjC,MAAM,UAAU;AAAA,IAChB,MAAM,UAAU;AAAA,EAClB;AACA,MAAI,OAAO,UAAU,SAAS,SAAU,OAAM,OAAO,UAAU;AAC/D,MAAI,OAAO,UAAU,eAAe,SAAU,OAAM,aAAa,UAAU;AAC3E,MAAI,OAAO,UAAU,aAAa,SAAU,OAAM,WAAW,UAAU;AACvE,MAAI,OAAO,UAAU,kBAAkB,SAAU,OAAM,gBAAgB,UAAU;AACjF,SAAO;AACT;AAEA,SAAS,kBAAkB,OAA0C;AACnE,SAAO,UAAU,UAAU,UAAU,eAAe,UAAU,aAAa,UAAU;AACvF;AAEA,SAAS,aAAa,UAA4D;AAChF,QAAM,MAAM,oBAAI,IAAiC;AACjD,aAAW,SAAS,SAAS,QAAS,KAAI,IAAI,MAAM,MAAM,KAAK;AAC/D,SAAO;AACT;AAEA,SAAS,sBAAsB,OAA4B,MAA2B;AACpF,QAAMC,gBAAe,SAAS,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,MAAM,IAAI;AACrE,QAAM,SAAsB;AAAA,IAC1B,MAAM,WAAW,MAAM,IAAI;AAAA,IAC3B,MAAMA;AAAA,IACN,MAAM,MAAM;AAAA,EACd;AACA,MAAI,MAAM,SAAS,OAAW,QAAO,OAAO,MAAM;AAClD,MAAI,MAAM,eAAe,QAAW;AAClC,UAAM,SAAS,IAAI,KAAK,MAAM,UAAU;AACxC,QAAI,CAAC,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,QAAO,aAAa;AAAA,EAC3D;AACA,MAAI,MAAM,aAAa,OAAW,QAAO,WAAW,MAAM;AAC1D,MAAI,MAAM,kBAAkB,OAAW,QAAO,gBAAgB,MAAM;AACpE,SAAO;AACT;AAEA,SAAS,WAAWD,OAAsB;AACxC,QAAM,WAAWA,MAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,SAAO,SAAS,WAAW,IAAI,MAAO,SAAS,SAAS,SAAS,CAAC,KAAK;AACzE;AAEA,SAAS,uBACP,QACA,aACA,SACwB;AACxB,QAAM,UAAkC,CAAC;AACzC,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,oBAAoB,QAAQ,qBAAqB;AACvD,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,YAAY,QAAQ,yBAAyB;AAEnD,MAAI,OAAO,SAAS,YAAY,KAAM,SAAQ,KAAK,MAAM;AAEzD,MACE,eACA,OAAO,SAAS,UAChB,YAAY,SAAS,UACrB,OAAO,SAAS,UAChB,YAAY,SAAS,UACrB,OAAO,SAAS,YAAY,MAC5B;AACA,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,MAAI,qBAAqBE,uBAAsB,QAAQ,aAAa,SAAS,GAAG;AAC9E,YAAQ,KAAK,YAAY;AAAA,EAC3B;AAEA,MACE,mBACA,OAAO,aAAa,UACpB,YAAY,aAAa,UACzB,OAAO,aAAa,YAAY,UAChC;AACA,YAAQ,KAAK,UAAU;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,SAASA,uBACP,QACA,aACA,aACS;AACT,MAAI,OAAO,eAAe,UAAa,YAAY,eAAe,OAAW,QAAO;AACpF,QAAM,aAAa,KAAK,MAAM,OAAO,UAAU;AAC/C,QAAM,kBAAkB,KAAK,MAAM,YAAY,UAAU;AACzD,MAAI,OAAO,MAAM,UAAU,KAAK,OAAO,MAAM,eAAe,EAAG,QAAO;AACtE,SAAO,KAAK,IAAI,aAAa,eAAe,IAAI;AAClD;","names":["Buffer","Buffer","path","waitMs","totalBytes","calculateBytesPerSecond","normalized","Buffer","Buffer","Buffer","isAbsolute","cloneVerification","path","response","payload","Buffer","first","Buffer","normalizeOptionalByteCount","cloneVerification","path","throwIfAborted","compareEntries","Buffer","padBase64","normalizeByteCount","isRecord","Buffer","path","secretToString","Buffer","secretToString","path","Buffer","secretToString","path","toRemoteEntry","parentDir","safeReadText","collectChunks","secretToString","path","safeReadText","toRemoteEntry","parentDir","collectChunks","secretToString","path","safeReadText","basenameRemotePath","collectChunks","joinPath","secretToString","path","buildSearch","safeReadText","prefixToEntry","parentDir","collectChunks","joinPath","resolveReadRange","normalizeOptionalByteCount","cloneVerification","path","compareEntries","normalizeByteCount","concatChunks","Buffer","path","createPathNotFoundError","getParentPath","compareEntries","collectTransferContent","normalizeOptionalByteCount","cloneVerification","Buffer","normalizeByteCount","concatChunks","cloneDate","Buffer","secretToString","Buffer","path","Buffer","secretToString","Buffer","path","entry","collectChunks","extractTag","createHash","createHmac","createHash","createHmac","secretToString","path","collectChunks","Buffer","createHmac","parseKnownHosts","parseKnownHostsLine","first","globMatch","path","Buffer","Buffer","gt","cloneEndpoint","item","open","path","path","throwIfAborted","compareEntries","path","compareEntries","path","absolutePath","isModifiedAtDifferent"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ZeroTransfer.ts","../../../src/errors/ZeroTransferError.ts","../../../src/logging/Logger.ts","../../../src/profiles/ProfileValidator.ts","../../../src/core/ProviderId.ts","../../../src/core/ProviderRegistry.ts","../../../src/core/TransferClient.ts","../../../src/core/createTransferClient.ts","../../../src/client/operations.ts","../../../src/transfers/BandwidthThrottle.ts","../../../src/transfers/createProviderTransferExecutor.ts","../../../src/services/TransferService.ts","../../../src/transfers/TransferEngine.ts","../../../src/mft/runRoute.ts","../../../src/logging/redaction.ts","../../../src/profiles/SecretSource.ts","../../../src/profiles/ProfileRedactor.ts","../../../src/diagnostics/index.ts","../../../src/providers/local/LocalProvider.ts","../../../src/utils/path.ts","../../../src/providers/memory/MemoryProvider.ts","../../../src/profiles/resolveConnectionProfileSecrets.ts","../../../src/profiles/OAuthTokenSource.ts","../../../src/profiles/importers/KnownHostsParser.ts","../../../src/profiles/importers/OpenSshConfigImporter.ts","../../../src/profiles/importers/FileZillaImporter.ts","../../../src/profiles/importers/WinScpImporter.ts","../../../src/errors/errorFactory.ts","../../../src/transfers/TransferPlan.ts","../../../src/transfers/TransferQueue.ts","../../../src/sync/createRemoteBrowser.ts","../../../src/sync/createSyncPlan.ts","../../../src/sync/createAtomicDeployPlan.ts","../../../src/sync/walkRemoteTree.ts","../../../src/sync/diffRemoteTrees.ts","../../../src/sync/manifest.ts","../../../src/providers/cloud/GoogleDriveProvider.ts","../../../src/providers/web/httpInternals.ts"],"sourcesContent":["/**\n * Client facade for the ZeroTransfer SDK foundation.\n *\n * This module intentionally keeps the top-level API small while protocol-specific\n * behavior is delegated to injected adapters. The facade owns lifecycle state,\n * event emission, logging coordination, and common capability discovery.\n *\n * @module client/ZeroTransfer\n */\nimport { EventEmitter } from \"node:events\";\nimport { createTransferClient } from \"../core/createTransferClient\";\nimport { isClassicProviderId } from \"../core/ProviderId\";\nimport { UnsupportedFeatureError } from \"../errors/ZeroTransferError\";\nimport { emitLog, noopLogger, type ZeroTransferLogger } from \"../logging/Logger\";\nimport type { RemoteFileAdapter } from \"../protocols/RemoteFileAdapter\";\nimport type {\n ConnectionProfile,\n ListOptions,\n RemoteEntry,\n RemoteProtocol,\n RemoteStat,\n StatOptions,\n} from \"../types/public\";\n\n/**\n * Construction options for a {@link ZeroTransfer} instance.\n *\n * @remarks\n * The adapter option is primarily used by protocol implementations and tests. Until\n * the built-in FTP, FTPS, and SFTP adapters are implemented, callers can inject a\n * compatible adapter to exercise the facade contract.\n */\nexport interface ZeroTransferOptions {\n /** Protocol used when the connection profile does not provide one. */\n protocol?: RemoteProtocol;\n /** Structured logger used for lifecycle and operation records. */\n logger?: ZeroTransferLogger;\n /** Protocol adapter that performs concrete remote file operations. */\n adapter?: RemoteFileAdapter;\n}\n\n/**\n * Lightweight capability snapshot for the current client instance.\n */\nexport interface ZeroTransferCapabilities {\n /** The protocol selected for this client facade. */\n protocol: RemoteProtocol;\n /** Whether a concrete protocol adapter has been supplied. */\n adapterReady: boolean;\n}\n\n/**\n * SDK entry point for FTP, FTPS, and SFTP workflows.\n *\n * @remarks\n * ZeroTransfer extends Node.js EventEmitter so applications can observe lifecycle\n * events while still using promise-based APIs for operations. The facade is\n * deliberately protocol-neutral; concrete behavior lives behind\n * {@link RemoteFileAdapter}.\n *\n */\nexport class ZeroTransfer extends EventEmitter {\n /** Creates a provider-neutral transfer client with the built-in provider registry. */\n static readonly createTransferClient = createTransferClient;\n\n /** Protocol selected for this client instance. */\n readonly protocol: RemoteProtocol;\n\n private readonly logger: ZeroTransferLogger;\n private readonly adapter: RemoteFileAdapter | undefined;\n private connected = false;\n\n /**\n * Creates a client facade without opening a network connection.\n *\n * @param options - Optional facade configuration, logger, and protocol adapter.\n */\n constructor(options: ZeroTransferOptions = {}) {\n super();\n this.protocol = options.protocol ?? \"ftp\";\n this.logger = options.logger ?? noopLogger;\n this.adapter = options.adapter;\n }\n\n /**\n * Creates a new client facade using the provided options.\n *\n * @param options - Optional facade configuration, logger, and adapter.\n * @returns A disconnected {@link ZeroTransfer} instance.\n */\n static create(options: ZeroTransferOptions = {}): ZeroTransfer {\n return new ZeroTransfer(options);\n }\n\n /**\n * Creates a client and connects it in one step.\n *\n * @param profile - Remote host, authentication, and protocol connection settings.\n * @param options - Optional facade settings that can be overridden by the profile.\n * @returns A connected {@link ZeroTransfer} instance.\n * @throws {@link UnsupportedFeatureError} When no adapter is available for the protocol.\n */\n static async connect(\n profile: ConnectionProfile,\n options: ZeroTransferOptions = {},\n ): Promise<ZeroTransfer> {\n const clientOptions: ZeroTransferOptions = { ...options };\n\n if (profile.logger !== undefined) {\n clientOptions.logger = profile.logger;\n }\n\n if (profile.protocol !== undefined) {\n clientOptions.protocol = profile.protocol;\n } else if (isClassicProviderId(profile.provider)) {\n clientOptions.protocol = profile.provider;\n }\n\n const client = new ZeroTransfer(clientOptions);\n await client.connect(profile);\n return client;\n }\n\n /**\n * Opens a remote connection through the configured protocol adapter.\n *\n * @param profile - Remote host, authentication, timeout, logger, and protocol settings.\n * @returns A promise that resolves after the adapter reports a successful connection.\n * @throws {@link UnsupportedFeatureError} When the client does not have an adapter.\n */\n async connect(profile: ConnectionProfile): Promise<void> {\n const adapter = this.requireAdapter();\n const protocol =\n profile.protocol ??\n (isClassicProviderId(profile.provider) ? profile.provider : this.protocol);\n emitLog(this.logger, \"info\", {\n component: \"client\",\n host: profile.host,\n message: \"Connecting\",\n protocol,\n });\n await adapter.connect({\n ...profile,\n protocol,\n });\n this.connected = true;\n this.emit(\"connect\", {\n host: profile.host,\n protocol,\n });\n }\n\n /**\n * Closes the active remote connection if one exists.\n *\n * @returns A promise that resolves after the adapter disconnects or immediately when idle.\n */\n async disconnect(): Promise<void> {\n if (this.adapter !== undefined && this.connected) {\n await this.adapter.disconnect();\n }\n\n this.connected = false;\n this.emit(\"disconnect\");\n }\n\n /**\n * Checks whether the facade currently considers the adapter connected.\n *\n * @returns `true` after a successful connection and before disconnection.\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Describes protocol and adapter readiness for feature discovery.\n *\n * @returns A capability snapshot for diagnostics and UI state.\n */\n getCapabilities(): ZeroTransferCapabilities {\n return {\n adapterReady: this.adapter !== undefined,\n protocol: this.protocol,\n };\n }\n\n /**\n * Lists remote entries for a path using the configured adapter.\n *\n * @param path - Remote directory path to inspect.\n * @param options - Optional listing controls such as recursion and abort signal.\n * @returns Normalized remote entries for the requested directory.\n * @throws {@link UnsupportedFeatureError} When the client does not have an adapter.\n */\n async list(path: string, options?: ListOptions): Promise<RemoteEntry[]> {\n return this.requireAdapter().list(path, options);\n }\n\n /**\n * Reads metadata for a remote path using the configured adapter.\n *\n * @param path - Remote file, directory, or symbolic-link path to inspect.\n * @param options - Optional stat controls such as abort signal.\n * @returns Normalized metadata for an existing remote entry.\n * @throws {@link UnsupportedFeatureError} When the client does not have an adapter.\n */\n async stat(path: string, options?: StatOptions): Promise<RemoteStat> {\n return this.requireAdapter().stat(path, options);\n }\n\n /**\n * Returns the configured adapter or raises the alpha unsupported-feature error.\n *\n * @returns A concrete remote file adapter ready to execute operations.\n * @throws {@link UnsupportedFeatureError} When no adapter has been provided.\n */\n private requireAdapter(): RemoteFileAdapter {\n if (this.adapter === undefined) {\n throw new UnsupportedFeatureError({\n message: `The ${this.protocol.toUpperCase()} adapter is not implemented in this alpha foundation yet`,\n protocol: this.protocol,\n retryable: false,\n });\n }\n\n return this.adapter;\n }\n}\n","/**\n * Structured ZeroTransfer error hierarchy.\n *\n * The classes in this module preserve protocol details, retryability, command/path\n * context, and machine-readable codes so application code does not need to parse\n * human error messages.\n *\n * @module errors/ZeroTransferError\n */\nimport type { RemoteProtocol } from \"../types/public\";\n\n/**\n * Complete set of fields required to create a ZeroTransfer error.\n */\nexport interface ZeroTransferErrorDetails {\n /** Stable machine-readable error code. */\n code: string;\n /** Human-readable error message safe to show in logs or diagnostics. */\n message: string;\n /** Original error or exception that caused this error. */\n cause?: unknown;\n /** Protocol active when the error occurred. */\n protocol?: RemoteProtocol;\n /** Remote host associated with the failing operation. */\n host?: string;\n /** Protocol command associated with the failure, if any. */\n command?: string;\n /** FTP response code associated with the failure. */\n ftpCode?: number;\n /** SFTP status code associated with the failure. */\n sftpCode?: number;\n /** Remote path associated with the failure. */\n path?: string;\n /** Whether retry policy may safely retry this failure. */\n retryable: boolean;\n /** Additional structured details for diagnostics. */\n details?: Record<string, unknown>;\n}\n\n/**\n * Error construction input for subclasses that provide default codes.\n */\nexport type SpecializedErrorDetails = Omit<ZeroTransferErrorDetails, \"code\"> & {\n /** Optional override for the subclass default code. */\n code?: string;\n};\n\n/**\n * Base class for all typed ZeroTransfer errors.\n */\nexport class ZeroTransferError extends Error {\n /** Stable machine-readable error code. */\n readonly code: string;\n /** Protocol active when the error occurred. */\n readonly protocol?: RemoteProtocol;\n /** Remote host associated with the failing operation. */\n readonly host?: string;\n /** Protocol command associated with the failure, if any. */\n readonly command?: string;\n /** FTP response code associated with the failure. */\n readonly ftpCode?: number;\n /** SFTP status code associated with the failure. */\n readonly sftpCode?: number;\n /** Remote path associated with the failure. */\n readonly path?: string;\n /** Whether retry policy may safely retry this failure. */\n readonly retryable: boolean;\n /** Additional structured details for diagnostics. */\n readonly details?: Record<string, unknown>;\n\n /**\n * Creates a structured SDK error.\n *\n * @param details - Code, message, retryability, and optional protocol context.\n */\n constructor(details: ZeroTransferErrorDetails) {\n super(details.message, details.cause === undefined ? undefined : { cause: details.cause });\n this.name = new.target.name;\n this.code = details.code;\n this.retryable = details.retryable;\n\n if (details.protocol !== undefined) this.protocol = details.protocol;\n if (details.host !== undefined) this.host = details.host;\n if (details.command !== undefined) this.command = details.command;\n if (details.ftpCode !== undefined) this.ftpCode = details.ftpCode;\n if (details.sftpCode !== undefined) this.sftpCode = details.sftpCode;\n if (details.path !== undefined) this.path = details.path;\n if (details.details !== undefined) this.details = details.details;\n }\n\n /**\n * Serializes the error into a plain object suitable for logs or API responses.\n *\n * @returns A JSON-safe object containing public structured error fields.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n protocol: this.protocol,\n host: this.host,\n command: this.command,\n ftpCode: this.ftpCode,\n sftpCode: this.sftpCode,\n path: this.path,\n retryable: this.retryable,\n details: this.details,\n };\n }\n}\n\n/**\n * Applies a subclass default code while preserving caller overrides.\n *\n * @param details - Subclass error details with optional code override.\n * @param code - Default code for the specific subclass.\n * @returns Complete base error details.\n */\nfunction withDefaultCode(details: SpecializedErrorDetails, code: string): ZeroTransferErrorDetails {\n return {\n ...details,\n code: details.code ?? code,\n };\n}\n\n/** Error raised when a remote connection cannot be opened or is lost unexpectedly. */\nexport class ConnectionError extends ZeroTransferError {\n /**\n * Creates a connection failure.\n *\n * @param details - Error context with optional host, protocol, and retryability details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_CONNECTION_ERROR\"));\n }\n}\n\n/** Error raised when authentication credentials are rejected. */\nexport class AuthenticationError extends ZeroTransferError {\n /**\n * Creates an authentication failure.\n *\n * @param details - Error context with optional host, protocol, and command details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_AUTHENTICATION_ERROR\"));\n }\n}\n\n/** Error raised when authenticated credentials are not authorized for an operation. */\nexport class AuthorizationError extends ZeroTransferError {\n /**\n * Creates an authorization failure.\n *\n * @param details - Error context with optional path and protocol details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_AUTHORIZATION_ERROR\"));\n }\n}\n\n/** Error raised when a requested remote path does not exist. */\nexport class PathNotFoundError extends ZeroTransferError {\n /**\n * Creates a missing-path failure.\n *\n * @param details - Error context with optional path and protocol details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PATH_NOT_FOUND\"));\n }\n}\n\n/** Error raised when a create or rename operation targets an existing path. */\nexport class PathAlreadyExistsError extends ZeroTransferError {\n /**\n * Creates an already-exists failure.\n *\n * @param details - Error context with optional path and command details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PATH_ALREADY_EXISTS\"));\n }\n}\n\n/** Error raised when the remote server denies access to a path or command. */\nexport class PermissionDeniedError extends ZeroTransferError {\n /**\n * Creates a permission failure.\n *\n * @param details - Error context with optional path, command, and protocol details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PERMISSION_DENIED\"));\n }\n}\n\n/** Error raised when an operation exceeds its configured timeout. */\nexport class TimeoutError extends ZeroTransferError {\n /**\n * Creates a timeout failure.\n *\n * @param details - Error context with optional duration and retryability details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_TIMEOUT\"));\n }\n}\n\n/** Error raised when an operation is cancelled by an AbortSignal or caller action. */\nexport class AbortError extends ZeroTransferError {\n /**\n * Creates an aborted-operation failure.\n *\n * @param details - Error context with optional operation and path details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_ABORTED\"));\n }\n}\n\n/** Error raised when a server response violates protocol expectations. */\nexport class ProtocolError extends ZeroTransferError {\n /**\n * Creates a protocol failure.\n *\n * @param details - Error context with optional response code and command details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PROTOCOL_ERROR\"));\n }\n}\n\n/** Error raised when protocol text or metadata cannot be parsed safely. */\nexport class ParseError extends ZeroTransferError {\n /**\n * Creates a parser failure.\n *\n * @param details - Error context with malformed input details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_PARSE_ERROR\"));\n }\n}\n\n/** Error raised when an upload, download, or stream transfer fails. */\nexport class TransferError extends ZeroTransferError {\n /**\n * Creates a transfer failure.\n *\n * @param details - Error context with optional path, bytes, and retryability details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_TRANSFER_ERROR\"));\n }\n}\n\n/** Error raised when post-transfer verification fails. */\nexport class VerificationError extends ZeroTransferError {\n /**\n * Creates a verification failure.\n *\n * @param details - Error context with checksum, size, or timestamp mismatch details.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_VERIFICATION_ERROR\"));\n }\n}\n\n/** Error raised when a requested protocol feature is not implemented or unavailable. */\nexport class UnsupportedFeatureError extends ZeroTransferError {\n /**\n * Creates an unsupported-feature failure.\n *\n * @param details - Error context describing the missing feature or adapter.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_UNSUPPORTED_FEATURE\"));\n }\n}\n\n/** Error raised when user-provided options or paths are invalid before network I/O. */\nexport class ConfigurationError extends ZeroTransferError {\n /**\n * Creates a configuration failure.\n *\n * @param details - Error context describing the invalid option or argument.\n */\n constructor(details: SpecializedErrorDetails) {\n super(withDefaultCode(details, \"ZERO_TRANSFER_CONFIGURATION_ERROR\"));\n }\n}\n","/**\n * Structured logging contracts and helpers for ZeroTransfer.\n *\n * The logger shape is intentionally compatible with popular structured loggers while\n * staying small enough for applications to implement directly.\n *\n * @module logging/Logger\n */\n/** Supported ZeroTransfer log levels. */\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/**\n * Complete structured log record emitted by ZeroTransfer helpers.\n */\nexport interface LogRecord {\n /** Severity level for the record. */\n level: LogLevel;\n /** Human-readable summary message. */\n message: string;\n /** SDK component that produced the record. */\n component?: string;\n /** Active protocol for the record. */\n protocol?: string;\n /** Remote host associated with the record. */\n host?: string;\n /** Correlation id for a connection lifecycle. */\n connectionId?: string;\n /** Correlation id for a protocol command. */\n commandId?: string;\n /** Correlation id for a transfer lifecycle. */\n transferId?: string;\n /** Remote or local path associated with the record. */\n path?: string;\n /** Operation duration in milliseconds. */\n durationMs?: number;\n /** Byte count associated with the operation. */\n bytes?: number;\n /** Additional structured fields supplied by adapters or services. */\n [key: string]: unknown;\n}\n\n/**\n * Log record input accepted by {@link emitLog}; the helper adds the level.\n */\nexport interface LogRecordInput extends Omit<LogRecord, \"level\"> {\n /** Human-readable summary message. */\n message: string;\n}\n\n/**\n * Logger method signature used for each severity level.\n *\n * @param record - Structured log record.\n * @param message - Convenience message argument for console-like loggers.\n */\nexport type LoggerMethod = (record: LogRecord, message?: string) => void;\n\n/**\n * Partial structured logger accepted by ZeroTransfer.\n */\nexport interface ZeroTransferLogger {\n /** Receives highly detailed diagnostic records. */\n trace?: LoggerMethod;\n /** Receives development/debugging records. */\n debug?: LoggerMethod;\n /** Receives normal lifecycle records. */\n info?: LoggerMethod;\n /** Receives recoverable issue records. */\n warn?: LoggerMethod;\n /** Receives failed operation records. */\n error?: LoggerMethod;\n}\n\n/**\n * Logger implementation that intentionally drops every record.\n */\nexport const noopLogger: Required<ZeroTransferLogger> = {\n trace() {},\n debug() {},\n info() {},\n warn() {},\n error() {},\n};\n\n/**\n * Emits a structured log record if the logger implements the requested level.\n *\n * @param logger - Logger that may contain a method for the requested level.\n * @param level - Severity level to emit.\n * @param record - Log record fields without the level property.\n * @returns Nothing; missing logger methods are ignored.\n */\nexport function emitLog(logger: ZeroTransferLogger, level: LogLevel, record: LogRecordInput): void {\n const method = logger[level];\n\n if (method === undefined) {\n return;\n }\n\n const logRecord: LogRecord = {\n ...record,\n level,\n };\n\n method(logRecord, logRecord.message);\n}\n","/**\n * Connection profile validation helpers.\n *\n * @module profiles/ProfileValidator\n */\nimport { Buffer } from \"node:buffer\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { ConnectionProfile, SshProfile, TlsProfile } from \"../types/public\";\nimport { resolveProviderId } from \"../core/ProviderId\";\n\n/** TLS protocol versions accepted by Node's `SecureVersion` option. */\nconst TLS_VERSIONS = new Set([\"TLSv1\", \"TLSv1.1\", \"TLSv1.2\", \"TLSv1.3\"]);\n/** Hex characters in a SHA-256 certificate fingerprint after separators are removed. */\nconst SHA256_FINGERPRINT_HEX_LENGTH = 64;\n/** Raw SHA-256 digest byte length. */\nconst SHA256_DIGEST_BYTE_LENGTH = 32;\n\n/**\n * Validates provider-neutral connection profile fields before provider lookup.\n *\n * @param profile - Profile to validate.\n * @returns The original profile when valid.\n * @throws {@link ConfigurationError} When required provider, host, or numeric fields are invalid.\n */\nexport function validateConnectionProfile(profile: ConnectionProfile): ConnectionProfile {\n if (resolveProviderId(profile) === undefined) {\n throw new ConfigurationError({\n message: \"Connection profiles must include a provider or protocol\",\n retryable: false,\n });\n }\n\n if (profile.host.trim().length === 0) {\n throw new ConfigurationError({\n message: \"Connection profiles must include a non-empty host\",\n retryable: false,\n });\n }\n\n if (profile.port !== undefined && !isValidPort(profile.port)) {\n throw new ConfigurationError({\n details: { port: profile.port },\n message: \"Connection profile port must be an integer between 1 and 65535\",\n retryable: false,\n });\n }\n\n if (profile.timeoutMs !== undefined && !isPositiveFiniteNumber(profile.timeoutMs)) {\n throw new ConfigurationError({\n details: { timeoutMs: profile.timeoutMs },\n message: \"Connection profile timeoutMs must be a positive finite number\",\n retryable: false,\n });\n }\n\n if (profile.tls !== undefined) {\n validateTlsProfile(profile.tls);\n }\n\n if (profile.ssh !== undefined) {\n validateSshProfile(profile.ssh);\n }\n\n return profile;\n}\n\n/**\n * Validates SSH profile policy fields that can be checked without resolving secrets.\n *\n * @param profile - SSH profile to validate.\n * @throws {@link ConfigurationError} When host-key pin values are invalid.\n */\nfunction validateSshProfile(profile: SshProfile): void {\n validatePinnedHostKeySha256(profile.pinnedHostKeySha256);\n\n if (profile.algorithms !== undefined) {\n validateSshAlgorithms(profile.algorithms);\n }\n\n if (profile.agent !== undefined) {\n validateSshAgentSource(profile.agent);\n }\n\n if (\n profile.keyboardInteractive !== undefined &&\n typeof profile.keyboardInteractive !== \"function\"\n ) {\n throw new ConfigurationError({\n details: { keyboardInteractive: typeof profile.keyboardInteractive },\n message: \"Connection profile ssh.keyboardInteractive must be a function when provided\",\n retryable: false,\n });\n }\n\n if (profile.socketFactory !== undefined && typeof profile.socketFactory !== \"function\") {\n throw new ConfigurationError({\n details: { socketFactory: typeof profile.socketFactory },\n message: \"Connection profile ssh.socketFactory must be a function when provided\",\n retryable: false,\n });\n }\n}\n\n/**\n * Validates SSH algorithm override shape without duplicating ssh2's literal unions.\n *\n * @param value - Algorithm override object from an SSH profile.\n * @throws {@link ConfigurationError} When overrides are not object-shaped or contain empty lists.\n */\nfunction validateSshAlgorithms(value: SshProfile[\"algorithms\"]): void {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw createSshAlgorithmsError(value);\n }\n\n const algorithms = value as Record<string, unknown>;\n\n for (const [name, list] of Object.entries(algorithms)) {\n if (list === undefined) {\n continue;\n }\n\n if (Array.isArray(list)) {\n if (!isNonEmptyStringArray(list)) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n\n continue;\n }\n\n if (typeof list !== \"object\" || list === null || Array.isArray(list)) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n\n const operationLists = list as Record<string, unknown>;\n\n for (const [operation, operationList] of Object.entries(operationLists)) {\n if (![\"append\", \"prepend\", \"remove\"].includes(operation)) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n\n if (\n typeof operationList !== \"string\" &&\n (!Array.isArray(operationList) || !isNonEmptyStringArray(operationList))\n ) {\n throw createSshAlgorithmsError({ [name]: list });\n }\n }\n }\n}\n\nfunction isNonEmptyStringArray(value: unknown[]): value is string[] {\n return value.length > 0 && value.every((item) => typeof item === \"string\" && item.length > 0);\n}\n\n/**\n * Validates SSH agent source values.\n *\n * @param value - Agent socket path or agent implementation.\n * @throws {@link ConfigurationError} When the value is neither a non-empty path nor an agent object.\n */\nfunction validateSshAgentSource(value: SshProfile[\"agent\"]): void {\n if (typeof value === \"string\") {\n if (value.trim().length > 0) {\n return;\n }\n } else if (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { getIdentities?: unknown }).getIdentities === \"function\" &&\n typeof (value as { sign?: unknown }).sign === \"function\"\n ) {\n return;\n }\n\n throw new ConfigurationError({\n details: { agent: typeof value },\n message: \"Connection profile ssh.agent must be a non-empty socket path or agent object\",\n retryable: false,\n });\n}\n\n/**\n * Validates TLS profile policy fields that can be checked without resolving secrets.\n *\n * @param profile - TLS profile to validate.\n * @throws {@link ConfigurationError} When server name, boolean, or TLS-version fields are invalid.\n */\nfunction validateTlsProfile(profile: TlsProfile): void {\n if (profile.servername !== undefined && profile.servername.trim().length === 0) {\n throw new ConfigurationError({\n message: \"Connection profile tls.servername must be non-empty when provided\",\n retryable: false,\n });\n }\n\n if (profile.rejectUnauthorized !== undefined && typeof profile.rejectUnauthorized !== \"boolean\") {\n throw new ConfigurationError({\n details: { rejectUnauthorized: profile.rejectUnauthorized },\n message: \"Connection profile tls.rejectUnauthorized must be a boolean\",\n retryable: false,\n });\n }\n\n validateTlsVersion(profile.minVersion, \"minVersion\");\n validateTlsVersion(profile.maxVersion, \"maxVersion\");\n validatePinnedFingerprint256(profile.pinnedFingerprint256);\n}\n\n/**\n * Validates SHA-256 certificate fingerprint pinning values.\n *\n * @param value - Single fingerprint or allowed fingerprint set from the TLS profile.\n * @throws {@link ConfigurationError} When a fingerprint is empty or not SHA-256 hex.\n */\nfunction validatePinnedFingerprint256(value: TlsProfile[\"pinnedFingerprint256\"]): void {\n if (value === undefined) {\n return;\n }\n\n const fingerprints = Array.isArray(value) ? value : [value];\n\n if (fingerprints.length === 0) {\n throw createPinnedFingerprintError(value);\n }\n\n for (const fingerprint of fingerprints) {\n if (typeof fingerprint !== \"string\" || !isSha256Fingerprint(fingerprint)) {\n throw createPinnedFingerprintError(value);\n }\n }\n}\n\n/**\n * Validates SHA-256 SSH host-key pinning values.\n *\n * @param value - Single fingerprint or allowed fingerprint set from the SSH profile.\n * @throws {@link ConfigurationError} When a fingerprint is empty or not a SHA-256 digest.\n */\nfunction validatePinnedHostKeySha256(value: SshProfile[\"pinnedHostKeySha256\"]): void {\n if (value === undefined) {\n return;\n }\n\n const fingerprints = Array.isArray(value) ? value : [value];\n\n if (fingerprints.length === 0) {\n throw createPinnedHostKeyError(value);\n }\n\n for (const fingerprint of fingerprints) {\n if (typeof fingerprint !== \"string\" || !isSshHostKeySha256Fingerprint(fingerprint)) {\n throw createPinnedHostKeyError(value);\n }\n }\n}\n\n/**\n * Checks whether a string is a supported SHA-256 certificate fingerprint.\n *\n * @param value - Candidate fingerprint string.\n * @returns `true` when the value is 64 hex characters after optional colons are removed.\n */\nfunction isSha256Fingerprint(value: string): boolean {\n const normalized = value.trim().replace(/:/g, \"\");\n return normalized.length === SHA256_FINGERPRINT_HEX_LENGTH && /^[a-f0-9]+$/i.test(normalized);\n}\n\n/**\n * Checks whether a string is a supported SSH SHA-256 host-key fingerprint.\n *\n * @param value - Candidate fingerprint string.\n * @returns `true` when the value is OpenSSH SHA256 base64, bare base64, or SHA-256 hex.\n */\nfunction isSshHostKeySha256Fingerprint(value: string): boolean {\n const trimmed = value.trim();\n\n if (isSha256Fingerprint(trimmed)) {\n return true;\n }\n\n const bare = trimmed.startsWith(\"SHA256:\") ? trimmed.slice(\"SHA256:\".length) : trimmed;\n const padded = padBase64(bare);\n\n if (!/^[a-z0-9+/]+={0,2}$/i.test(padded)) {\n return false;\n }\n\n try {\n return Buffer.from(padded, \"base64\").byteLength === SHA256_DIGEST_BYTE_LENGTH;\n } catch {\n return false;\n }\n}\n\nfunction padBase64(value: string): string {\n const remainder = value.length % 4;\n\n return remainder === 0 ? value : `${value}${\"=\".repeat(4 - remainder)}`;\n}\n\n/**\n * Creates a consistent validation error for invalid certificate pin values.\n *\n * @param value - Invalid profile value included in diagnostics.\n * @returns Configuration error describing the supported fingerprint format.\n */\nfunction createPinnedFingerprintError(value: unknown): ConfigurationError {\n return new ConfigurationError({\n details: { pinnedFingerprint256: value },\n message:\n \"Connection profile tls.pinnedFingerprint256 must be a SHA-256 hex fingerprint or non-empty array of fingerprints\",\n retryable: false,\n });\n}\n\n/**\n * Creates a consistent validation error for invalid SSH host-key pin values.\n *\n * @param value - Invalid profile value included in diagnostics.\n * @returns Configuration error describing the supported fingerprint formats.\n */\nfunction createPinnedHostKeyError(value: unknown): ConfigurationError {\n return new ConfigurationError({\n details: { pinnedHostKeySha256: value },\n message:\n \"Connection profile ssh.pinnedHostKeySha256 must be an OpenSSH SHA256, base64, or hex fingerprint or non-empty array of fingerprints\",\n retryable: false,\n });\n}\n\n/**\n * Creates a consistent validation error for invalid SSH algorithm overrides.\n *\n * @param value - Invalid profile value included in diagnostics.\n * @returns Configuration error describing the expected ssh2-compatible shape.\n */\nfunction createSshAlgorithmsError(value: unknown): ConfigurationError {\n return new ConfigurationError({\n details: { algorithms: value },\n message: \"Connection profile ssh.algorithms must use SSH-compatible non-empty algorithm lists\",\n retryable: false,\n });\n}\n\n/**\n * Validates a configured TLS protocol version string.\n *\n * @param value - TLS version value from the profile, if provided.\n * @param field - Profile field name used in diagnostics.\n * @throws {@link ConfigurationError} When the value is not one of Node's supported TLS versions.\n */\nfunction validateTlsVersion(value: TlsProfile[\"minVersion\"], field: string): void {\n if (value === undefined) {\n return;\n }\n\n if (!TLS_VERSIONS.has(value)) {\n throw new ConfigurationError({\n details: { [field]: value },\n message: `Connection profile tls.${field} must be a supported TLS version`,\n retryable: false,\n });\n }\n}\n\nfunction isValidPort(value: number): boolean {\n return Number.isInteger(value) && value >= 1 && value <= 65_535;\n}\n\nfunction isPositiveFiniteNumber(value: number): boolean {\n return Number.isFinite(value) && value > 0;\n}\n","/**\n * Provider identifiers used by the provider-neutral ZeroTransfer core.\n *\n * @module core/ProviderId\n */\n\n/** Classic remote-transfer providers kept compatible with the original protocol field. */\nexport const CLASSIC_PROVIDER_IDS = [\"ftp\", \"ftps\", \"sftp\"] as const;\n\n/** Provider ids that map directly to the original protocol-focused alpha facade. */\nexport type ClassicProviderId = (typeof CLASSIC_PROVIDER_IDS)[number];\n\n/** Provider ids reserved for first-party ZeroTransfer adapters. */\nexport type BuiltInProviderId =\n | ClassicProviderId\n | \"memory\"\n | \"local\"\n | \"http\"\n | \"https\"\n | \"webdav\"\n | \"s3\"\n | \"azure-blob\"\n | \"gcs\"\n | \"dropbox\"\n | \"google-drive\"\n | \"one-drive\";\n\n/** Provider identifier accepted by registries, profiles, and provider factories. */\nexport type ProviderId = BuiltInProviderId | (string & {});\n\n/** Minimal shape used to resolve a provider from new and compatibility profile fields. */\nexport interface ProviderSelection {\n /** Provider id for provider-neutral ZeroTransfer profiles. */\n provider?: ProviderId;\n /** Compatibility protocol field accepted while the provider-neutral API rolls out. */\n protocol?: ClassicProviderId;\n}\n\n/**\n * Checks whether a provider id belongs to the classic FTP/FTPS/SFTP family.\n *\n * @param providerId - Provider id to inspect.\n * @returns `true` when the id is one of the classic protocol providers.\n */\nexport function isClassicProviderId(\n providerId: ProviderId | undefined,\n): providerId is ClassicProviderId {\n return (\n typeof providerId === \"string\" && CLASSIC_PROVIDER_IDS.includes(providerId as ClassicProviderId)\n );\n}\n\n/**\n * Resolves the provider id from a profile, preferring the new `provider` field.\n *\n * @param selection - Profile-like object containing provider and/or protocol fields.\n * @returns The selected provider id, or `undefined` when neither field is present.\n */\nexport function resolveProviderId(selection: ProviderSelection): ProviderId | undefined {\n return selection.provider ?? selection.protocol;\n}\n","/**\n * Provider registry for the provider-neutral ZeroTransfer core.\n *\n * @module core/ProviderRegistry\n */\nimport { ConfigurationError, UnsupportedFeatureError } from \"../errors/ZeroTransferError\";\nimport type { ProviderFactory } from \"../providers/ProviderFactory\";\nimport type { CapabilitySet } from \"./CapabilitySet\";\nimport type { ProviderId } from \"./ProviderId\";\n\n/** Mutable registry of provider factories available to a transfer client. */\nexport class ProviderRegistry {\n private readonly factories = new Map<ProviderId, ProviderFactory>();\n\n /**\n * Creates a registry and optionally seeds it with provider factories.\n *\n * @param providers - Provider factories to register immediately.\n */\n constructor(providers: Iterable<ProviderFactory> = []) {\n for (const provider of providers) {\n this.register(provider);\n }\n }\n\n /**\n * Registers a provider factory.\n *\n * @param provider - Provider factory to add.\n * @returns This registry for fluent setup.\n * @throws {@link ConfigurationError} When a provider id is registered twice.\n */\n register(provider: ProviderFactory): this {\n if (this.factories.has(provider.id)) {\n throw new ConfigurationError({\n details: { provider: provider.id },\n message: `Provider \"${provider.id}\" is already registered`,\n retryable: false,\n });\n }\n\n this.factories.set(provider.id, provider);\n return this;\n }\n\n /**\n * Removes a provider factory from the registry.\n *\n * @param providerId - Provider id to remove.\n * @returns `true` when a provider was removed.\n */\n unregister(providerId: ProviderId): boolean {\n return this.factories.delete(providerId);\n }\n\n /**\n * Checks whether a provider id is registered.\n *\n * @param providerId - Provider id to inspect.\n * @returns `true` when a provider factory exists.\n */\n has(providerId: ProviderId): boolean {\n return this.factories.has(providerId);\n }\n\n /**\n * Gets a provider factory when registered.\n *\n * @param providerId - Provider id to retrieve.\n * @returns The provider factory, or `undefined` when missing.\n */\n get(providerId: ProviderId): ProviderFactory | undefined {\n return this.factories.get(providerId);\n }\n\n /**\n * Gets a registered provider factory or throws a typed SDK error.\n *\n * @param providerId - Provider id to retrieve.\n * @returns The registered provider factory.\n * @throws {@link UnsupportedFeatureError} When no provider has been registered.\n */\n require(providerId: ProviderId): ProviderFactory {\n const provider = this.get(providerId);\n\n if (provider === undefined) {\n throw new UnsupportedFeatureError({\n details: { provider: providerId },\n message: `Provider \"${providerId}\" is not registered`,\n retryable: false,\n });\n }\n\n return provider;\n }\n\n /**\n * Gets a provider capability snapshot when registered.\n *\n * @param providerId - Provider id to inspect.\n * @returns Capability snapshot, or `undefined` when missing.\n */\n getCapabilities(providerId: ProviderId): CapabilitySet | undefined {\n return this.get(providerId)?.capabilities;\n }\n\n /**\n * Gets a provider capability snapshot or throws a typed SDK error.\n *\n * @param providerId - Provider id to inspect.\n * @returns Capability snapshot for the registered provider.\n * @throws {@link UnsupportedFeatureError} When no provider has been registered.\n */\n requireCapabilities(providerId: ProviderId): CapabilitySet {\n return this.require(providerId).capabilities;\n }\n\n /**\n * Lists registered provider factories in insertion order.\n *\n * @returns Registered provider factories.\n */\n list(): ProviderFactory[] {\n return [...this.factories.values()];\n }\n\n /**\n * Lists registered provider capabilities in insertion order.\n *\n * @returns Capability snapshots for every registered provider.\n */\n listCapabilities(): CapabilitySet[] {\n return this.list().map((provider) => provider.capabilities);\n }\n}\n","/**\n * Provider-neutral transfer client foundation.\n *\n * @module core/TransferClient\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport {\n emitLog,\n noopLogger,\n type LogRecordInput,\n type ZeroTransferLogger,\n} from \"../logging/Logger\";\nimport { validateConnectionProfile } from \"../profiles/ProfileValidator\";\nimport type { ProviderFactory } from \"../providers/ProviderFactory\";\nimport type { ConnectionProfile } from \"../types/public\";\nimport type { CapabilitySet } from \"./CapabilitySet\";\nimport type { ProviderId } from \"./ProviderId\";\nimport { isClassicProviderId, resolveProviderId } from \"./ProviderId\";\nimport { ProviderRegistry } from \"./ProviderRegistry\";\nimport type { TransferSession } from \"./TransferSession\";\n\n/** Options used to create a provider-neutral transfer client. */\nexport interface TransferClientOptions {\n /** Existing registry to reuse. When omitted, a fresh empty registry is created. */\n registry?: ProviderRegistry;\n /** Provider factories to register with the client registry. */\n providers?: ProviderFactory[];\n /** Structured logger used for client lifecycle records. */\n logger?: ZeroTransferLogger;\n}\n\n/** Small provider-neutral client that owns provider lookup and connection setup. */\nexport class TransferClient {\n /** Provider registry used by this client. */\n readonly registry: ProviderRegistry;\n\n private readonly logger: ZeroTransferLogger;\n\n /**\n * Creates a transfer client without opening any provider connections.\n *\n * @param options - Optional registry, provider factories, and logger.\n */\n constructor(options: TransferClientOptions = {}) {\n this.registry = options.registry ?? new ProviderRegistry();\n this.logger = options.logger ?? noopLogger;\n\n for (const provider of options.providers ?? []) {\n this.registry.register(provider);\n }\n }\n\n /**\n * Registers a provider factory with this client's registry.\n *\n * @param provider - Provider factory to register.\n * @returns This client for fluent setup.\n */\n registerProvider(provider: ProviderFactory): this {\n this.registry.register(provider);\n return this;\n }\n\n /**\n * Checks whether this client can create sessions for a provider id.\n *\n * @param providerId - Provider id to inspect.\n * @returns `true` when a provider factory is registered.\n */\n hasProvider(providerId: ProviderId): boolean {\n return this.registry.has(providerId);\n }\n\n /** Lists all registered provider capability snapshots. */\n getCapabilities(): CapabilitySet[];\n /** Gets a specific provider capability snapshot. */\n getCapabilities(providerId: ProviderId): CapabilitySet;\n getCapabilities(providerId?: ProviderId): CapabilitySet | CapabilitySet[] {\n if (providerId === undefined) {\n return this.registry.listCapabilities();\n }\n\n return this.registry.requireCapabilities(providerId);\n }\n\n /**\n * Opens a provider session using `profile.provider`, with `profile.protocol` as compatibility fallback.\n *\n * @param profile - Connection profile containing a provider or legacy protocol field.\n * @returns A connected provider session.\n * @throws {@link ConfigurationError} When neither provider nor protocol is present.\n */\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n const validProfile = validateConnectionProfile(profile);\n const providerId = resolveProviderId(validProfile);\n\n if (providerId === undefined) {\n throw new ConfigurationError({\n message: \"Connection profiles must include a provider or protocol\",\n retryable: false,\n });\n }\n\n const providerFactory = this.registry.require(providerId);\n const provider = providerFactory.create();\n const normalizedProfile: ConnectionProfile = {\n ...validProfile,\n provider: providerId,\n };\n\n if (normalizedProfile.protocol === undefined && isClassicProviderId(providerId)) {\n normalizedProfile.protocol = providerId;\n }\n\n emitLog(this.logger, \"info\", createConnectLogRecord(normalizedProfile, providerId));\n\n return provider.connect(normalizedProfile);\n }\n}\n\nfunction createConnectLogRecord(\n profile: ConnectionProfile,\n providerId: ProviderId,\n): LogRecordInput {\n const record: LogRecordInput = {\n component: \"core\",\n host: profile.host,\n message: \"Connecting through provider\",\n provider: providerId,\n };\n\n if (isClassicProviderId(providerId)) {\n record.protocol = providerId;\n }\n\n return record;\n}\n","/**\n * Factory for provider-neutral ZeroTransfer clients.\n *\n * @module core/createTransferClient\n */\nimport { TransferClient, type TransferClientOptions } from \"./TransferClient\";\n\n/**\n * Creates a provider-neutral transfer client.\n *\n * The returned client owns a registry of provider factories and produces\n * `TransferSession` instances on demand via {@link TransferClient.connect}.\n * Registering only the providers you actually use keeps bundle size small\n * (each factory pulls in its own SDK dependencies).\n *\n * @param options - Optional registry, provider factories, and logger.\n * @returns A disconnected {@link TransferClient} instance.\n *\n * @example Multi-provider client\n * ```ts\n * import {\n * createS3ProviderFactory,\n * createSftpProviderFactory,\n * createTransferClient,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({\n * providers: [createSftpProviderFactory(), createS3ProviderFactory()],\n * });\n *\n * const session = await client.connect({\n * host: \"sftp.example.com\",\n * provider: \"sftp\",\n * username: \"deploy\",\n * ssh: { privateKey: { path: \"./keys/id_ed25519\" } },\n * });\n * try {\n * const list = await session.fs.list(\"/uploads\");\n * console.log(list);\n * } finally {\n * await session.disconnect();\n * }\n * ```\n *\n * @example Friendly one-shot helpers\n * ```ts\n * import { uploadFile } from \"@zero-transfer/sdk\";\n *\n * await uploadFile({\n * client,\n * destination: { path: \"/uploads/report.csv\", profile },\n * localPath: \"./out/report.csv\",\n * });\n * ```\n */\nexport function createTransferClient(options: TransferClientOptions = {}): TransferClient {\n return new TransferClient(options);\n}\n","/**\n * Friendly one-call helpers built on top of {@link runRoute}.\n *\n * These helpers give applications a quick surface for the common single-file flows\n * (`uploadFile`, `downloadFile`, `copyBetween`) without forcing them to assemble\n * {@link MftRoute} objects directly. Each helper composes a one-shot route and\n * delegates execution to the existing route runner so retry, abort, progress,\n * timeout, and bandwidth controls behave identically to scheduled runs.\n *\n * @module client/operations\n */\nimport { isAbsolute, resolve as resolvePath } from \"node:path\";\nimport type { TransferClient } from \"../core/TransferClient\";\nimport type { MftRoute } from \"../mft/MftRoute\";\nimport { runRoute, type RunRouteOptions } from \"../mft/runRoute\";\nimport type { TransferReceipt } from \"../transfers/TransferJob\";\nimport type { ConnectionProfile } from \"../types/public\";\n\n/** Endpoint shape accepted by the friendly helpers. */\nexport interface RemoteFileEndpoint {\n /** Provider profile used to open the session. */\n profile: ConnectionProfile;\n /** Provider, remote, or local path the helper operates on. */\n path: string;\n}\n\n/** Shared options consumed by {@link uploadFile}, {@link downloadFile}, and {@link copyBetween}. */\nexport type FriendlyTransferOptions = Omit<RunRouteOptions, \"client\" | \"route\"> & {\n /** Stable route id assigned to the synthetic route. Defaults to `\"upload:...\"`, `\"download:...\"`, or `\"copy:...\"`. */\n routeId?: string;\n /** Optional human-readable route name forwarded to telemetry. */\n routeName?: string;\n};\n\n/** Connection profile for the local filesystem provider. */\nconst LOCAL_PROFILE: ConnectionProfile = { host: \"local\", provider: \"local\" };\n\n/** Options for {@link uploadFile}. */\nexport interface UploadFileOptions extends FriendlyTransferOptions {\n /** Transfer client used to resolve both endpoint providers. */\n client: TransferClient;\n /** Local source path. Relative paths are resolved against `process.cwd()`. */\n localPath: string;\n /** Remote destination endpoint. */\n destination: RemoteFileEndpoint;\n}\n\n/**\n * Uploads a single local file to a remote endpoint.\n *\n * The remote provider is resolved from `destination.profile.provider`, so any\n * provider factory you registered with {@link createTransferClient} can be used\n * as the destination.\n *\n * @param options - Friendly upload options.\n * @returns Receipt produced by the underlying transfer engine.\n *\n * @example Upload to SFTP with public-key auth\n * ```ts\n * import {\n * createSftpProviderFactory,\n * createTransferClient,\n * uploadFile,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createSftpProviderFactory()] });\n *\n * await uploadFile({\n * client,\n * destination: {\n * path: \"/uploads/report.csv\",\n * profile: {\n * host: \"sftp.example.com\",\n * provider: \"sftp\",\n * username: \"deploy\",\n * ssh: { privateKey: { path: \"./keys/id_ed25519\" } },\n * },\n * },\n * localPath: \"./out/report.csv\",\n * });\n * ```\n */\nexport function uploadFile(options: UploadFileOptions): Promise<TransferReceipt> {\n const { client, destination, localPath, routeId, routeName, ...rest } = options;\n const route = buildRoute({\n destination: { path: destination.path, profile: destination.profile },\n id: routeId ?? `upload:${defaultRouteSuffix(localPath, destination.path)}`,\n name: routeName,\n operation: \"upload\",\n source: { path: absolutePath(localPath), profile: LOCAL_PROFILE },\n });\n return runRoute({ client, route, ...rest });\n}\n\n/** Options for {@link downloadFile}. */\nexport interface DownloadFileOptions extends FriendlyTransferOptions {\n /** Transfer client used to resolve both endpoint providers. */\n client: TransferClient;\n /** Remote source endpoint. */\n source: RemoteFileEndpoint;\n /** Local destination path. Relative paths are resolved against `process.cwd()`. */\n localPath: string;\n}\n\n/**\n * Downloads a single remote file to a local path.\n *\n * The remote provider is resolved from `source.profile.provider`. The local\n * destination path is created (including parent directories) on demand.\n *\n * @param options - Friendly download options.\n * @returns Receipt produced by the underlying transfer engine.\n *\n * @example Download from S3\n * ```ts\n * import {\n * createS3ProviderFactory,\n * createTransferClient,\n * downloadFile,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({ providers: [createS3ProviderFactory()] });\n *\n * await downloadFile({\n * client,\n * localPath: \"./tmp/snapshot.tar.gz\",\n * source: {\n * path: \"snapshots/2026-04-28/snapshot.tar.gz\",\n * profile: {\n * host: \"snapshots\", // S3 bucket\n * provider: \"s3\",\n * s3: { region: \"us-east-1\" },\n * },\n * },\n * });\n * ```\n */\nexport function downloadFile(options: DownloadFileOptions): Promise<TransferReceipt> {\n const { client, localPath, routeId, routeName, source, ...rest } = options;\n const route = buildRoute({\n destination: { path: absolutePath(localPath), profile: LOCAL_PROFILE },\n id: routeId ?? `download:${defaultRouteSuffix(source.path, localPath)}`,\n name: routeName,\n operation: \"download\",\n source: { path: source.path, profile: source.profile },\n });\n return runRoute({ client, route, ...rest });\n}\n\n/** Options for {@link copyBetween}. */\nexport interface CopyBetweenOptions extends FriendlyTransferOptions {\n /** Transfer client used to resolve both endpoint providers. */\n client: TransferClient;\n /** Source remote endpoint. */\n source: RemoteFileEndpoint;\n /** Destination remote endpoint. */\n destination: RemoteFileEndpoint;\n}\n\n/**\n * Copies a file between two remote endpoints in a single call.\n *\n * Both source and destination providers must be registered with the\n * {@link TransferClient}. Streams are piped end-to-end without staging the file\n * on the local disk.\n *\n * @param options - Friendly copy options.\n * @returns Receipt produced by the underlying transfer engine.\n *\n * @example Copy from SFTP to S3\n * ```ts\n * import {\n * copyBetween,\n * createS3ProviderFactory,\n * createSftpProviderFactory,\n * createTransferClient,\n * } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({\n * providers: [createSftpProviderFactory(), createS3ProviderFactory()],\n * });\n *\n * await copyBetween({\n * client,\n * source: {\n * path: \"/exports/daily.csv\",\n * profile: { host: \"sftp.example.com\", provider: \"sftp\", username: \"etl\" },\n * },\n * destination: {\n * path: \"warehouse/daily.csv\",\n * profile: { host: \"warehouse\", provider: \"s3\", s3: { region: \"us-east-1\" } },\n * },\n * });\n * ```\n */\nexport function copyBetween(options: CopyBetweenOptions): Promise<TransferReceipt> {\n const { client, destination, routeId, routeName, source, ...rest } = options;\n const route = buildRoute({\n destination: { path: destination.path, profile: destination.profile },\n id: routeId ?? `copy:${defaultRouteSuffix(source.path, destination.path)}`,\n name: routeName,\n operation: \"copy\",\n source: { path: source.path, profile: source.profile },\n });\n return runRoute({ client, route, ...rest });\n}\n\ninterface BuildRouteInput {\n id: string;\n name?: string | undefined;\n operation: NonNullable<MftRoute[\"operation\"]>;\n source: MftRoute[\"source\"];\n destination: MftRoute[\"destination\"];\n}\n\nfunction buildRoute(input: BuildRouteInput): MftRoute {\n const route: MftRoute = {\n destination: input.destination,\n id: input.id,\n operation: input.operation,\n source: input.source,\n };\n if (input.name !== undefined) route.name = input.name;\n return route;\n}\n\nfunction absolutePath(localPath: string): string {\n return isAbsolute(localPath) ? localPath : resolvePath(localPath);\n}\n\nfunction defaultRouteSuffix(source: string, destination: string): string {\n return `${source}->${destination}`;\n}\n","/**\n * Token-bucket bandwidth throttle for transfer streams.\n *\n * @module transfers/BandwidthThrottle\n */\nimport { AbortError, ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferBandwidthLimit } from \"./TransferJob\";\n\n/** Sleep helper signature used by {@link createBandwidthThrottle}. */\nexport type BandwidthSleep = (delayMs: number, signal?: AbortSignal) => Promise<void>;\n\n/** Construction overrides for deterministic tests. */\nexport interface BandwidthThrottleOptions {\n /** Monotonic clock returning milliseconds since an arbitrary epoch. Defaults to `Date.now`. */\n now?: () => number;\n /** Sleep implementation honoring an optional abort signal. Defaults to a `setTimeout` helper. */\n sleep?: BandwidthSleep;\n}\n\n/** Token-bucket throttle used to pace transfer chunks. */\nexport interface BandwidthThrottle {\n /** Maximum sustained transfer rate in bytes per second. */\n readonly bytesPerSecond: number;\n /** Burst capacity in bytes available before throttling kicks in. */\n readonly burstBytes: number;\n /**\n * Consumes `bytes` from the bucket, awaiting refill when not enough tokens are available.\n *\n * @param bytes - Non-negative byte count being released by the throttle.\n * @param signal - Optional abort signal that interrupts pending waits.\n * @throws {@link AbortError} When the signal is aborted while waiting.\n */\n consume(bytes: number, signal?: AbortSignal): Promise<void>;\n}\n\n/**\n * Creates a token-bucket throttle that paces an asynchronous data pipeline to\n * a sustained {@link TransferBandwidthLimit}.\n *\n * Returns `undefined` when no limit is supplied so callers can omit throttling\n * without conditional branches at the call site.\n *\n * @param limit - Optional throughput limit. Returns `undefined` when omitted.\n * @param options - Optional clock/sleep overrides for deterministic tests.\n * @returns Throttle implementation when a limit is supplied, otherwise `undefined`.\n * @throws {@link ConfigurationError} When the supplied limit shape is invalid.\n */\nexport function createBandwidthThrottle(\n limit: TransferBandwidthLimit | undefined,\n options: BandwidthThrottleOptions = {},\n): BandwidthThrottle | undefined {\n if (limit === undefined) return undefined;\n\n const bytesPerSecond = normalizeRate(limit.bytesPerSecond);\n const burstBytes = normalizeBurst(limit.burstBytes, bytesPerSecond);\n const now = options.now ?? Date.now;\n const sleep = options.sleep ?? defaultSleep;\n\n let tokens = burstBytes;\n let lastRefillAt = now();\n\n function refill(): void {\n const current = now();\n const elapsedMs = Math.max(0, current - lastRefillAt);\n\n if (elapsedMs > 0) {\n tokens = Math.min(burstBytes, tokens + (elapsedMs / 1000) * bytesPerSecond);\n lastRefillAt = current;\n }\n }\n\n async function consume(bytes: number, signal?: AbortSignal): Promise<void> {\n if (!Number.isFinite(bytes) || bytes < 0) {\n throw new ConfigurationError({\n details: { bytes },\n message: \"Bandwidth throttle byte count must be a non-negative number\",\n retryable: false,\n });\n }\n\n if (bytes === 0) return;\n\n let remaining = bytes;\n\n while (remaining > 0) {\n throwIfAborted(signal);\n refill();\n\n if (tokens >= remaining) {\n tokens -= remaining;\n return;\n }\n\n if (tokens >= burstBytes) {\n // Bucket is full but the request still exceeds the burst. Drain the\n // full bucket and wait for the remainder at the sustained rate.\n const drained = tokens;\n tokens = 0;\n remaining -= drained;\n const waitMs = Math.ceil((Math.min(remaining, burstBytes) / bytesPerSecond) * 1000);\n await sleep(waitMs, signal);\n continue;\n }\n\n const deficit = Math.min(remaining, burstBytes) - tokens;\n const waitMs = Math.max(1, Math.ceil((deficit / bytesPerSecond) * 1000));\n await sleep(waitMs, signal);\n }\n }\n\n return { burstBytes, bytesPerSecond, consume };\n}\n\n/**\n * Wraps an async iterable of byte chunks so each chunk is released only after\n * the throttle has admitted its byte count.\n *\n * When `throttle` is `undefined`, the source iterable is returned unchanged.\n *\n * @param source - Async iterable that produces byte chunks.\n * @param throttle - Optional throttle that paces chunk emission.\n * @param signal - Optional abort signal interrupting pending waits.\n * @returns Async generator emitting the original chunks at the throttled rate.\n */\nexport function throttleByteIterable(\n source: AsyncIterable<Uint8Array>,\n throttle: BandwidthThrottle | undefined,\n signal?: AbortSignal,\n): AsyncIterable<Uint8Array> {\n if (throttle === undefined) return source;\n\n return {\n [Symbol.asyncIterator]: async function* () {\n for await (const chunk of source) {\n throwIfAborted(signal);\n if (chunk.byteLength > 0) {\n await throttle.consume(chunk.byteLength, signal);\n }\n yield chunk;\n }\n },\n };\n}\n\nfunction normalizeRate(value: number): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw new ConfigurationError({\n details: { bytesPerSecond: value },\n message: \"Bandwidth limit bytesPerSecond must be a positive number\",\n retryable: false,\n });\n }\n\n return value;\n}\n\nfunction normalizeBurst(value: number | undefined, bytesPerSecond: number): number {\n if (value === undefined) return bytesPerSecond;\n\n if (!Number.isFinite(value) || value <= 0) {\n throw new ConfigurationError({\n details: { burstBytes: value },\n message: \"Bandwidth limit burstBytes must be a positive number when provided\",\n retryable: false,\n });\n }\n\n return value;\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw new AbortError({\n message: \"Bandwidth throttle wait aborted\",\n retryable: false,\n });\n }\n}\n\nfunction defaultSleep(delayMs: number, signal?: AbortSignal): Promise<void> {\n if (delayMs <= 0) return Promise.resolve();\n\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, delayMs);\n\n const onAbort = () => {\n cleanup();\n reject(\n new AbortError({\n message: \"Bandwidth throttle wait aborted\",\n retryable: false,\n }),\n );\n };\n\n function cleanup(): void {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onAbort);\n }\n\n if (signal !== undefined) {\n if (signal.aborted) {\n onAbort();\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n","/**\n * Transfer executor bridge for provider-backed read/write sessions.\n *\n * @module transfers/createProviderTransferExecutor\n */\nimport type { TransferSession } from \"../core/TransferSession\";\nimport { ConfigurationError, UnsupportedFeatureError } from \"../errors/ZeroTransferError\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../providers/ProviderTransferOperations\";\nimport {\n createBandwidthThrottle,\n throttleByteIterable,\n type BandwidthThrottleOptions,\n} from \"./BandwidthThrottle\";\nimport type { TransferExecutionContext, TransferExecutor } from \"./TransferEngine\";\nimport type {\n TransferEndpoint,\n TransferExecutionResult,\n TransferJob,\n TransferOperation,\n TransferVerificationResult,\n} from \"./TransferJob\";\n\n/** Endpoint role used while resolving provider sessions for a transfer job. */\nexport type ProviderTransferEndpointRole = \"source\" | \"destination\";\n\n/** Input passed to provider transfer session resolvers. */\nexport interface ProviderTransferSessionResolverInput {\n /** Endpoint being resolved. */\n endpoint: TransferEndpoint;\n /** Whether the endpoint is the source or destination side of the transfer. */\n role: ProviderTransferEndpointRole;\n /** Job currently being executed. */\n job: TransferJob;\n}\n\n/** Resolves the connected provider session that owns an endpoint. */\nexport type ProviderTransferSessionResolver = (\n input: ProviderTransferSessionResolverInput,\n) => TransferSession | undefined;\n\n/** Options for {@link createProviderTransferExecutor}. */\nexport interface ProviderTransferExecutorOptions {\n /** Resolves connected provider sessions for source and destination endpoints. */\n resolveSession: ProviderTransferSessionResolver;\n /** Optional clock/sleep overrides for the bandwidth throttle. */\n throttle?: BandwidthThrottleOptions;\n}\n\n/**\n * Creates a {@link TransferExecutor} that reads from a source provider and writes to a destination provider.\n *\n * The returned executor supports single-object `upload`, `download`, and `copy` jobs. Provider sessions must\n * expose `session.transfers.read()` and `session.transfers.write()`; concrete providers remain responsible for\n * the actual streaming implementation.\n *\n * @param options - Session resolver used for source and destination endpoints.\n * @returns Transfer executor suitable for {@link TransferEngine.execute} or {@link TransferQueue}.\n */\nexport function createProviderTransferExecutor(\n options: ProviderTransferExecutorOptions,\n): TransferExecutor {\n return async (context) => {\n const { job } = context;\n\n if (!isReadWriteOperation(job.operation)) {\n throw new UnsupportedFeatureError({\n details: { jobId: job.id, operation: job.operation },\n message: `Provider read/write executor does not support transfer operation: ${job.operation}`,\n retryable: false,\n });\n }\n\n const source = requireEndpoint(job, \"source\");\n const destination = requireEndpoint(job, \"destination\");\n const sourceSession = options.resolveSession({ endpoint: source, job, role: \"source\" });\n const destinationSession = options.resolveSession({\n endpoint: destination,\n job,\n role: \"destination\",\n });\n const sourceTransfers = requireTransferOperations(sourceSession, source, \"source\", job);\n const destinationTransfers = requireTransferOperations(\n destinationSession,\n destination,\n \"destination\",\n job,\n );\n\n context.throwIfAborted();\n const readResult = await sourceTransfers.read(createReadRequest(context, source));\n context.throwIfAborted();\n const throttledReadResult = applyBandwidthThrottle(readResult, context, options.throttle);\n const writeResult = await destinationTransfers.write(\n createWriteRequest(context, destination, throttledReadResult),\n );\n\n return mergeProviderTransferResult(readResult, writeResult, job);\n };\n}\n\nfunction applyBandwidthThrottle(\n readResult: ProviderTransferReadResult,\n context: TransferExecutionContext,\n options: BandwidthThrottleOptions | undefined,\n): ProviderTransferReadResult {\n const throttle = createBandwidthThrottle(context.bandwidthLimit, options);\n\n if (throttle === undefined) return readResult;\n\n return {\n ...readResult,\n content: throttleByteIterable(readResult.content, throttle, context.signal),\n };\n}\n\nfunction isReadWriteOperation(operation: TransferOperation): boolean {\n return operation === \"copy\" || operation === \"download\" || operation === \"upload\";\n}\n\nfunction requireEndpoint(job: TransferJob, role: ProviderTransferEndpointRole): TransferEndpoint {\n const endpoint = role === \"source\" ? job.source : job.destination;\n\n if (endpoint === undefined) {\n throw new ConfigurationError({\n details: { jobId: job.id, operation: job.operation, role },\n message: `Transfer job requires a ${role} endpoint: ${job.id}`,\n retryable: false,\n });\n }\n\n return endpoint;\n}\n\nfunction requireTransferOperations(\n session: TransferSession | undefined,\n endpoint: TransferEndpoint,\n role: ProviderTransferEndpointRole,\n job: TransferJob,\n): ProviderTransferOperations {\n if (session === undefined) {\n throw new UnsupportedFeatureError({\n details: { endpoint: cloneEndpoint(endpoint), jobId: job.id, operation: job.operation, role },\n message: `No provider session resolved for ${role} endpoint: ${endpoint.path}`,\n retryable: false,\n });\n }\n\n if (session.transfers === undefined) {\n throw new UnsupportedFeatureError({\n details: {\n endpoint: cloneEndpoint(endpoint),\n jobId: job.id,\n operation: job.operation,\n provider: session.provider,\n role,\n },\n message: `Provider session does not expose transfer operations: ${session.provider}`,\n retryable: false,\n });\n }\n\n return session.transfers;\n}\n\nfunction createReadRequest(\n context: TransferExecutionContext,\n endpoint: TransferEndpoint,\n): ProviderTransferReadRequest {\n const request: ProviderTransferReadRequest = {\n attempt: context.attempt,\n endpoint: cloneEndpoint(endpoint),\n job: context.job,\n reportProgress: (bytesTransferred, totalBytes) =>\n context.reportProgress(bytesTransferred, totalBytes),\n throwIfAborted: () => context.throwIfAborted(),\n };\n\n if (context.signal !== undefined) request.signal = context.signal;\n if (context.bandwidthLimit !== undefined) {\n request.bandwidthLimit = { ...context.bandwidthLimit };\n }\n\n return request;\n}\n\nfunction createWriteRequest(\n context: TransferExecutionContext,\n endpoint: TransferEndpoint,\n readResult: ProviderTransferReadResult,\n): ProviderTransferWriteRequest {\n const request: ProviderTransferWriteRequest = {\n attempt: context.attempt,\n content: readResult.content,\n endpoint: cloneEndpoint(endpoint),\n job: context.job,\n reportProgress: (bytesTransferred, totalBytes) =>\n context.reportProgress(bytesTransferred, totalBytes),\n throwIfAborted: () => context.throwIfAborted(),\n };\n const totalBytes = readResult.totalBytes ?? context.job.totalBytes;\n\n if (context.signal !== undefined) request.signal = context.signal;\n if (context.bandwidthLimit !== undefined) {\n request.bandwidthLimit = { ...context.bandwidthLimit };\n }\n if (totalBytes !== undefined) request.totalBytes = totalBytes;\n if (context.job.resumed === true) request.offset = readResult.bytesRead ?? 0;\n if (readResult.verification !== undefined) {\n request.verification = cloneVerification(readResult.verification);\n }\n\n return request;\n}\n\nfunction mergeProviderTransferResult(\n readResult: ProviderTransferReadResult,\n writeResult: ProviderTransferWriteResult,\n job: TransferJob,\n): TransferExecutionResult {\n const result: TransferExecutionResult = {\n bytesTransferred: writeResult.bytesTransferred,\n };\n const totalBytes = writeResult.totalBytes ?? readResult.totalBytes ?? job.totalBytes;\n const warnings = [...(readResult.warnings ?? []), ...(writeResult.warnings ?? [])];\n\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (writeResult.resumed !== undefined) result.resumed = writeResult.resumed;\n if (writeResult.verified !== undefined) result.verified = writeResult.verified;\n if (writeResult.checksum !== undefined) result.checksum = writeResult.checksum;\n else if (readResult.checksum !== undefined) result.checksum = readResult.checksum;\n if (writeResult.verification !== undefined) {\n result.verification = cloneVerification(writeResult.verification);\n } else if (readResult.verification !== undefined) {\n result.verification = cloneVerification(readResult.verification);\n }\n if (warnings.length > 0) result.warnings = warnings;\n\n return result;\n}\n\nfunction cloneEndpoint(endpoint: TransferEndpoint): TransferEndpoint {\n const clone: TransferEndpoint = { path: endpoint.path };\n\n if (endpoint.provider !== undefined) clone.provider = endpoint.provider;\n\n return clone;\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n","/**\n * Transfer result and progress calculation helpers.\n *\n * These helpers are pure functions so future FTP, FTPS, and SFTP adapters can share\n * timing, throughput, and progress calculations without coupling to transport code.\n *\n * @module services/TransferService\n */\nimport type { TransferProgressEvent, TransferResult } from \"../types/public\";\n\n/**\n * Input used to create a final transfer result.\n */\nexport interface TransferResultInput {\n /** Local or remote source path when known. */\n sourcePath?: string;\n /** Local or remote destination path for the transfer. */\n destinationPath: string;\n /** Total bytes transferred. */\n bytesTransferred: number;\n /** Time the transfer began. */\n startedAt: Date;\n /** Time the transfer completed. */\n completedAt: Date;\n /** Whether the transfer resumed from an earlier partial state. */\n resumed?: boolean;\n /** Whether post-transfer verification succeeded. */\n verified?: boolean;\n /** Optional checksum value produced or verified by the transfer. */\n checksum?: string;\n}\n\n/**\n * Input used to create a transfer progress event.\n */\nexport interface ProgressEventInput {\n /** Stable transfer identifier for correlation. */\n transferId: string;\n /** Bytes transferred so far. */\n bytesTransferred: number;\n /** Time the transfer began. */\n startedAt: Date;\n /** Time to use for the progress calculation; defaults to current time. */\n now?: Date;\n /** Total expected bytes when known. */\n totalBytes?: number;\n}\n\n/**\n * Creates a final transfer result with duration and average throughput.\n *\n * @param input - Transfer paths, byte count, timestamps, and optional verification metadata.\n * @returns A normalized transfer result.\n */\nexport function createTransferResult(input: TransferResultInput): TransferResult {\n const durationMs = Math.max(0, input.completedAt.getTime() - input.startedAt.getTime());\n const result: TransferResult = {\n destinationPath: input.destinationPath,\n bytesTransferred: input.bytesTransferred,\n startedAt: input.startedAt,\n completedAt: input.completedAt,\n durationMs,\n averageBytesPerSecond: calculateBytesPerSecond(input.bytesTransferred, durationMs),\n resumed: input.resumed ?? false,\n verified: input.verified ?? false,\n };\n\n if (input.sourcePath !== undefined) result.sourcePath = input.sourcePath;\n if (input.checksum !== undefined) result.checksum = input.checksum;\n\n return result;\n}\n\n/**\n * Creates a progress event with elapsed time, rate, and optional percentage.\n *\n * @param input - Transfer id, byte count, start time, optional current time, and total bytes.\n * @returns A normalized transfer progress event.\n */\nexport function createProgressEvent(input: ProgressEventInput): TransferProgressEvent {\n const now = input.now ?? new Date();\n const elapsedMs = Math.max(0, now.getTime() - input.startedAt.getTime());\n const event: TransferProgressEvent = {\n transferId: input.transferId,\n bytesTransferred: input.bytesTransferred,\n startedAt: input.startedAt,\n elapsedMs,\n bytesPerSecond: calculateBytesPerSecond(input.bytesTransferred, elapsedMs),\n };\n\n if (input.totalBytes !== undefined) {\n event.totalBytes = input.totalBytes;\n event.percent = input.totalBytes > 0 ? (input.bytesTransferred / input.totalBytes) * 100 : 0;\n }\n\n return event;\n}\n\n/**\n * Calculates average throughput for a byte count and duration.\n *\n * @param bytes - Number of bytes transferred.\n * @param durationMs - Transfer duration in milliseconds.\n * @returns Average bytes per second, falling back to bytes for zero-duration samples.\n */\nfunction calculateBytesPerSecond(bytes: number, durationMs: number): number {\n if (durationMs <= 0) {\n return bytes;\n }\n\n return bytes / (durationMs / 1000);\n}\n","/**\n * Abort-aware transfer engine foundation.\n *\n * @module transfers/TransferEngine\n */\nimport {\n AbortError,\n TimeoutError,\n TransferError,\n ZeroTransferError,\n} from \"../errors/ZeroTransferError\";\nimport { createProgressEvent } from \"../services/TransferService\";\nimport type { TransferProgressEvent } from \"../types/public\";\nimport type {\n TransferAttempt,\n TransferAttemptError,\n TransferBandwidthLimit,\n TransferExecutionResult,\n TransferJob,\n TransferReceipt,\n TransferTimeoutPolicy,\n TransferVerificationResult,\n} from \"./TransferJob\";\n\n/** Context passed to a concrete transfer operation. */\nexport interface TransferExecutionContext {\n /** Job being executed. */\n job: TransferJob;\n /** One-based attempt number. */\n attempt: number;\n /** Abort signal active for this execution when supplied. */\n signal?: AbortSignal;\n /** Optional throughput limit shape for concrete executors to honor. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Throws an SDK abort error when the active signal has been cancelled. */\n throwIfAborted(): void;\n /** Emits a normalized progress event through engine options. */\n reportProgress(bytesTransferred: number, totalBytes?: number): TransferProgressEvent;\n}\n\n/** Concrete transfer operation implementation used by the engine. */\nexport type TransferExecutor = (\n context: TransferExecutionContext,\n) => Promise<TransferExecutionResult> | TransferExecutionResult;\n\n/** Input used by retry policy hooks. */\nexport interface TransferRetryDecisionInput {\n /** Error thrown by the failed attempt. */\n error: unknown;\n /** One-based attempt number that failed. */\n attempt: number;\n /** Job being executed. */\n job: TransferJob;\n}\n\n/** Retry policy for transfer execution. */\nexport interface TransferRetryPolicy {\n /** Maximum total attempts, including the first attempt. Defaults to `1`. */\n maxAttempts?: number;\n /** Decides whether a failed attempt should be retried. Defaults to SDK retryability metadata. */\n shouldRetry?(input: TransferRetryDecisionInput): boolean;\n /** Observes retry decisions before the next attempt starts. */\n onRetry?(input: TransferRetryDecisionInput): void;\n}\n\n/** Options used by {@link TransferEngine.execute}. */\nexport interface TransferEngineExecuteOptions {\n /** Abort signal used to cancel the job. */\n signal?: AbortSignal;\n /** Retry policy used for failed attempts. */\n retry?: TransferRetryPolicy;\n /** Progress observer for normalized transfer progress events. */\n onProgress?(event: TransferProgressEvent): void;\n /** Timeout policy enforced by the engine. */\n timeout?: TransferTimeoutPolicy;\n /** Optional throughput limit shape passed through to concrete executors. */\n bandwidthLimit?: TransferBandwidthLimit;\n}\n\n/** Construction options for deterministic tests and host integration. */\nexport interface TransferEngineOptions {\n /** Clock used for receipts and progress events. Defaults to `new Date()`. */\n now?: () => Date;\n}\n\n/** Executes transfer jobs and produces audit-friendly receipts. */\nexport class TransferEngine {\n private readonly now: () => Date;\n\n /**\n * Creates a transfer engine.\n *\n * @param options - Optional clock override for deterministic tests.\n */\n constructor(options: TransferEngineOptions = {}) {\n this.now = options.now ?? (() => new Date());\n }\n\n /**\n * Executes a transfer job through a caller-supplied operation.\n *\n * @param job - Job metadata used for correlation and receipts.\n * @param executor - Concrete transfer operation implementation.\n * @param options - Optional abort, retry, and progress hooks.\n * @returns Receipt for the completed transfer.\n * @throws {@link AbortError} When execution is cancelled.\n * @throws {@link TransferError} When all attempts fail.\n */\n async execute(\n job: TransferJob,\n executor: TransferExecutor,\n options: TransferEngineExecuteOptions = {},\n ): Promise<TransferReceipt> {\n const maxAttempts = normalizeMaxAttempts(options.retry?.maxAttempts);\n const attempts: TransferAttempt[] = [];\n const startedAt = this.now();\n const abortScope = createAbortScope(options.signal, options.timeout, job);\n let latestBytesTransferred = 0;\n\n try {\n for (let attemptNumber = 1; attemptNumber <= maxAttempts; attemptNumber += 1) {\n this.throwIfAborted(abortScope.signal, job);\n\n const attemptStartedAt = this.now();\n const context = this.createExecutionContext(\n job,\n attemptNumber,\n attemptStartedAt,\n options,\n abortScope.signal,\n (bytesTransferred) => {\n latestBytesTransferred = bytesTransferred;\n },\n );\n\n try {\n const result = await runExecutor(executor, context, abortScope.signal, job);\n context.throwIfAborted();\n latestBytesTransferred = result.bytesTransferred;\n\n const completedAt = this.now();\n attempts.push(\n createAttempt(attemptNumber, attemptStartedAt, completedAt, result.bytesTransferred),\n );\n\n return createReceipt(job, result, attempts, startedAt, completedAt);\n } catch (error) {\n const completedAt = this.now();\n const attempt = createAttempt(\n attemptNumber,\n attemptStartedAt,\n completedAt,\n latestBytesTransferred,\n summarizeError(error),\n );\n attempts.push(attempt);\n\n if (error instanceof AbortError || error instanceof TimeoutError) {\n throw error;\n }\n\n const retryInput: TransferRetryDecisionInput = { attempt: attemptNumber, error, job };\n const shouldRetry =\n attemptNumber < maxAttempts &&\n (options.retry?.shouldRetry?.(retryInput) ?? isRetryable(error));\n\n if (shouldRetry) {\n options.retry?.onRetry?.(retryInput);\n continue;\n }\n\n throw createTransferFailure(job, error, attempts);\n }\n }\n\n throw createTransferFailure(job, undefined, attempts);\n } finally {\n abortScope.dispose();\n }\n }\n\n private createExecutionContext(\n job: TransferJob,\n attempt: number,\n startedAt: Date,\n options: TransferEngineExecuteOptions,\n signal: AbortSignal | undefined,\n updateBytesTransferred: (bytesTransferred: number) => void,\n ): TransferExecutionContext {\n const context: TransferExecutionContext = {\n attempt,\n job,\n reportProgress: (bytesTransferred, totalBytes) => {\n this.throwIfAborted(signal, job);\n updateBytesTransferred(bytesTransferred);\n const progressInput = {\n bytesTransferred,\n now: this.now(),\n startedAt,\n transferId: job.id,\n };\n const resolvedTotalBytes = totalBytes ?? job.totalBytes;\n const event = createProgressEvent(\n resolvedTotalBytes === undefined\n ? progressInput\n : { ...progressInput, totalBytes: resolvedTotalBytes },\n );\n options.onProgress?.(event);\n return event;\n },\n throwIfAborted: () => this.throwIfAborted(signal, job),\n };\n\n if (signal !== undefined) {\n context.signal = signal;\n }\n\n if (options.bandwidthLimit !== undefined) {\n context.bandwidthLimit = { ...options.bandwidthLimit };\n }\n\n return context;\n }\n\n private throwIfAborted(signal: AbortSignal | undefined, job: TransferJob): void {\n if (signal?.aborted === true) {\n if (signal.reason instanceof ZeroTransferError) {\n throw signal.reason;\n }\n\n throw new AbortError({\n details: { jobId: job.id, operation: job.operation },\n message: `Transfer job aborted: ${job.id}`,\n retryable: false,\n });\n }\n }\n}\n\ninterface AbortScope {\n signal?: AbortSignal;\n dispose(): void;\n}\n\nfunction createAbortScope(\n parentSignal: AbortSignal | undefined,\n timeout: TransferTimeoutPolicy | undefined,\n job: TransferJob,\n): AbortScope {\n const timeoutMs = normalizeTimeoutMs(timeout?.timeoutMs);\n\n if (parentSignal === undefined && timeoutMs === undefined) {\n return { dispose: () => undefined };\n }\n\n const controller = new AbortController();\n const abortFromParent = (): void => controller.abort(parentSignal?.reason);\n const timeoutHandle =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n controller.abort(\n new TimeoutError({\n details: { jobId: job.id, operation: job.operation, timeoutMs },\n message: `Transfer job timed out after ${timeoutMs}ms: ${job.id}`,\n retryable: timeout?.retryable ?? true,\n }),\n );\n }, timeoutMs);\n\n if (parentSignal?.aborted === true) {\n abortFromParent();\n } else {\n parentSignal?.addEventListener(\"abort\", abortFromParent, { once: true });\n }\n\n return {\n dispose: () => {\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle);\n }\n parentSignal?.removeEventListener(\"abort\", abortFromParent);\n },\n signal: controller.signal,\n };\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number | undefined {\n if (value === undefined || !Number.isFinite(value) || value <= 0) {\n return undefined;\n }\n\n return Math.floor(value);\n}\n\nasync function runExecutor(\n executor: TransferExecutor,\n context: TransferExecutionContext,\n signal: AbortSignal | undefined,\n job: TransferJob,\n): Promise<TransferExecutionResult> {\n if (signal === undefined) {\n return executor(context);\n }\n\n return Promise.race([executor(context), rejectWhenAborted(signal, job)]);\n}\n\nfunction rejectWhenAborted(\n signal: AbortSignal,\n job: TransferJob,\n): Promise<TransferExecutionResult> {\n return new Promise((_, reject) => {\n const rejectAbort = (): void => {\n if (signal.reason instanceof ZeroTransferError) {\n reject(signal.reason);\n return;\n }\n\n reject(\n new AbortError({\n details: { jobId: job.id, operation: job.operation },\n message: `Transfer job aborted: ${job.id}`,\n retryable: false,\n }),\n );\n };\n\n if (signal.aborted) {\n rejectAbort();\n return;\n }\n\n signal.addEventListener(\"abort\", rejectAbort, { once: true });\n });\n}\n\nfunction normalizeMaxAttempts(value: number | undefined): number {\n if (value === undefined) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction createAttempt(\n attempt: number,\n startedAt: Date,\n completedAt: Date,\n bytesTransferred: number,\n error?: TransferAttemptError,\n): TransferAttempt {\n const result: TransferAttempt = {\n attempt,\n bytesTransferred,\n completedAt,\n durationMs: Math.max(0, completedAt.getTime() - startedAt.getTime()),\n startedAt,\n };\n\n if (error !== undefined) {\n result.error = error;\n }\n\n return result;\n}\n\nfunction createReceipt(\n job: TransferJob,\n result: TransferExecutionResult,\n attempts: TransferAttempt[],\n startedAt: Date,\n completedAt: Date,\n): TransferReceipt {\n const durationMs = Math.max(0, completedAt.getTime() - startedAt.getTime());\n const verification = normalizeVerificationResult(result);\n const receipt: TransferReceipt = {\n attempts,\n averageBytesPerSecond: calculateBytesPerSecond(result.bytesTransferred, durationMs),\n bytesTransferred: result.bytesTransferred,\n completedAt,\n durationMs,\n jobId: job.id,\n operation: job.operation,\n resumed: result.resumed ?? job.resumed ?? false,\n startedAt,\n transferId: job.id,\n verified: verification?.verified ?? result.verified ?? false,\n warnings: [...(result.warnings ?? [])],\n };\n\n if (job.source !== undefined) receipt.source = { ...job.source };\n if (job.destination !== undefined) receipt.destination = { ...job.destination };\n if (result.totalBytes !== undefined) receipt.totalBytes = result.totalBytes;\n else if (job.totalBytes !== undefined) receipt.totalBytes = job.totalBytes;\n if (result.checksum !== undefined) receipt.checksum = result.checksum;\n else if (verification?.checksum !== undefined) receipt.checksum = verification.checksum;\n if (verification !== undefined) receipt.verification = verification;\n if (job.metadata !== undefined) receipt.metadata = { ...job.metadata };\n\n return receipt;\n}\n\nfunction normalizeVerificationResult(\n result: TransferExecutionResult,\n): TransferVerificationResult | undefined {\n const verification = result.verification;\n\n if (verification !== undefined) {\n const normalized: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) normalized.method = verification.method;\n if (verification.checksum !== undefined) normalized.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n normalized.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined)\n normalized.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) normalized.details = { ...verification.details };\n\n return normalized;\n }\n\n if (result.verified === undefined && result.checksum === undefined) {\n return undefined;\n }\n\n const normalized: TransferVerificationResult = { verified: result.verified ?? false };\n\n if (result.checksum !== undefined) {\n normalized.checksum = result.checksum;\n }\n\n return normalized;\n}\n\nfunction createTransferFailure(\n job: TransferJob,\n error: unknown,\n attempts: TransferAttempt[],\n): TransferError {\n return new TransferError({\n cause: error,\n details: {\n attempts,\n jobId: job.id,\n operation: job.operation,\n },\n message: `Transfer job failed: ${job.id}`,\n retryable: isRetryable(error),\n });\n}\n\nfunction summarizeError(error: unknown): TransferAttemptError {\n if (error instanceof ZeroTransferError) {\n return {\n code: error.code,\n message: error.message,\n name: error.name,\n retryable: error.retryable,\n };\n }\n\n if (error instanceof Error) {\n return {\n message: error.message,\n name: error.name,\n };\n }\n\n return {\n message: String(error),\n name: \"Error\",\n };\n}\n\nfunction isRetryable(error: unknown): boolean {\n return error instanceof ZeroTransferError && error.retryable;\n}\n\nfunction calculateBytesPerSecond(bytes: number, durationMs: number): number {\n if (durationMs <= 0) {\n return bytes;\n }\n\n return bytes / (durationMs / 1000);\n}\n","/**\n * Route executor that dispatches a single transfer through {@link TransferEngine}.\n *\n * `runRoute` opens both endpoints through the supplied {@link TransferClient},\n * builds a {@link TransferJob} with route correlation metadata, and runs the\n * provider read/write executor under retry, abort, progress, timeout, and\n * bandwidth-limit hooks. Sessions are released in `finally` blocks even when\n * the transfer fails, throws, or is aborted.\n *\n * @module mft/runRoute\n */\nimport type { TransferClient } from \"../core/TransferClient\";\nimport type { TransferSession } from \"../core/TransferSession\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferProgressEvent } from \"../types/public\";\nimport { createProviderTransferExecutor } from \"../transfers/createProviderTransferExecutor\";\nimport { TransferEngine } from \"../transfers/TransferEngine\";\nimport type {\n TransferEngineExecuteOptions,\n TransferRetryPolicy,\n} from \"../transfers/TransferEngine\";\nimport type {\n TransferBandwidthLimit,\n TransferEndpoint,\n TransferJob,\n TransferReceipt,\n TransferTimeoutPolicy,\n} from \"../transfers/TransferJob\";\nimport type { MftRoute } from \"./MftRoute\";\n\n/** Options accepted by {@link runRoute}. */\nexport interface RunRouteOptions {\n /** Transfer client whose registry can resolve both endpoint providers. */\n client: TransferClient;\n /** Route to execute. */\n route: MftRoute;\n /** Optional transfer engine override. A fresh engine is created when omitted. */\n engine?: TransferEngine;\n /** Optional explicit job id. Defaults to a deterministic route-derived id. */\n jobId?: string;\n /** Optional clock used to derive the default job id. Defaults to `Date.now`. */\n now?: () => Date;\n /** Abort signal used to cancel the route execution. */\n signal?: AbortSignal;\n /** Retry policy forwarded to the engine. */\n retry?: TransferRetryPolicy;\n /** Progress observer forwarded to the engine. */\n onProgress?: (event: TransferProgressEvent) => void;\n /** Timeout policy forwarded to the engine. */\n timeout?: TransferTimeoutPolicy;\n /** Optional bandwidth limit forwarded to the engine. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Caller-defined metadata merged into the resulting transfer job. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Executes an MFT route as a single transfer through the supplied client.\n *\n * @param options - Client, route, and optional engine/abort/retry hooks.\n * @returns Receipt produced by the underlying transfer engine.\n * @throws {@link ConfigurationError} When the route is disabled.\n */\nexport async function runRoute(options: RunRouteOptions): Promise<TransferReceipt> {\n const { client, route } = options;\n\n if (route.enabled === false) {\n throw new ConfigurationError({\n details: { routeId: route.id },\n message: `MFT route \"${route.id}\" is disabled`,\n retryable: false,\n });\n }\n\n const sourceSession = await client.connect(route.source.profile);\n\n let destinationSession: TransferSession | undefined;\n try {\n destinationSession = await client.connect(route.destination.profile);\n const engine = options.engine ?? new TransferEngine();\n const job = createRouteJob(route, sourceSession, destinationSession, options);\n const sessions = new Map<string, TransferSession>([\n [\"source\", sourceSession],\n [\"destination\", destinationSession],\n ]);\n const executor = createProviderTransferExecutor({\n resolveSession: ({ role }) => sessions.get(role),\n });\n\n return await engine.execute(job, executor, buildExecuteOptions(options));\n } finally {\n if (destinationSession !== undefined) {\n await destinationSession.disconnect();\n }\n await sourceSession.disconnect();\n }\n}\n\nfunction createRouteJob(\n route: MftRoute,\n sourceSession: TransferSession,\n destinationSession: TransferSession,\n options: RunRouteOptions,\n): TransferJob {\n const operation = route.operation ?? \"copy\";\n const source: TransferEndpoint = {\n path: route.source.path,\n provider: sourceSession.provider,\n };\n const destination: TransferEndpoint = {\n path: route.destination.path,\n provider: destinationSession.provider,\n };\n\n const baseMetadata: Record<string, unknown> = { routeId: route.id };\n if (route.name !== undefined) baseMetadata[\"routeName\"] = route.name;\n if (route.metadata !== undefined) Object.assign(baseMetadata, route.metadata);\n if (options.metadata !== undefined) Object.assign(baseMetadata, options.metadata);\n\n const job: TransferJob = {\n destination,\n id: options.jobId ?? defaultJobId(route, options.now),\n operation,\n source,\n };\n\n if (Object.keys(baseMetadata).length > 0) {\n job.metadata = baseMetadata;\n }\n\n return job;\n}\n\nfunction defaultJobId(route: MftRoute, now: (() => Date) | undefined): string {\n const timestamp = (now?.() ?? new Date()).getTime();\n return `route:${route.id}:${timestamp.toString(36)}`;\n}\n\nfunction buildExecuteOptions(options: RunRouteOptions): TransferEngineExecuteOptions {\n const execute: TransferEngineExecuteOptions = {};\n if (options.signal !== undefined) execute.signal = options.signal;\n if (options.retry !== undefined) execute.retry = options.retry;\n if (options.onProgress !== undefined) execute.onProgress = options.onProgress;\n if (options.timeout !== undefined) execute.timeout = options.timeout;\n if (options.bandwidthLimit !== undefined) execute.bandwidthLimit = options.bandwidthLimit;\n return execute;\n}\n","/**\n * Secret redaction helpers for logs, events, and diagnostics.\n *\n * These functions focus on preserving useful operational context while removing\n * credentials and command payloads that should not appear in logs.\n *\n * @module logging/redaction\n */\n/** Placeholder used when sensitive content has been removed. */\nexport const REDACTED = \"[REDACTED]\";\n\nconst SENSITIVE_KEY_PATTERN = /(?:password|passphrase|privatekey|token|secret|username|user)$/i;\nconst SECRET_COMMAND_PATTERN = /^(PASS|USER|ACCT)\\s+(.+)$/i;\n\n/**\n * Checks whether an object key is likely to contain sensitive data.\n *\n * @param key - Object key to inspect.\n * @returns `true` when the key name should be redacted.\n */\nexport function isSensitiveKey(key: string): boolean {\n return SENSITIVE_KEY_PATTERN.test(key.replace(/[_-]/g, \"\"));\n}\n\n/**\n * Redacts sensitive FTP command payloads while preserving the command name.\n *\n * @param command - Raw command text such as `PASS secret` or `USER deploy`.\n * @returns Command text with secret arguments replaced by {@link REDACTED}.\n */\nexport function redactCommand(command: string): string {\n return command.replace(SECRET_COMMAND_PATTERN, (_fullMatch, commandName: string) => {\n return `${commandName.toUpperCase()} ${REDACTED}`;\n });\n}\n\n/**\n * Recursively redacts strings, arrays, and plain object values.\n *\n * @param value - Arbitrary value to sanitize for diagnostics.\n * @returns A redacted copy for arrays and objects, or the original primitive value.\n */\nexport function redactValue(value: unknown): unknown {\n if (typeof value === \"string\") {\n return redactCommand(value);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => redactValue(item));\n }\n\n if (value !== null && typeof value === \"object\") {\n return redactObject(value as Record<string, unknown>);\n }\n\n return value;\n}\n\n/**\n * Redacts sensitive keys and nested values in a plain object.\n *\n * @param input - Object containing diagnostic fields.\n * @returns A shallow object copy with sensitive fields and nested secrets redacted.\n */\nexport function redactObject(input: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(input).map(([key, value]) => {\n if (isSensitiveKey(key)) {\n return [key, REDACTED];\n }\n\n return [key, redactValue(value)];\n }),\n );\n}\n","/**\n * Secret source contracts and resolution helpers for connection profiles.\n *\n * @module profiles/SecretSource\n */\nimport { Buffer } from \"node:buffer\";\nimport { readFile } from \"node:fs/promises\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport { REDACTED } from \"../logging/redaction\";\n\n/** Resolved secret value accepted by profile credential fields. */\nexport type SecretValue = string | Buffer;\n\n/** Callback source used by applications to integrate vaults or credential brokers. */\nexport type SecretProvider = () => SecretValue | Promise<SecretValue>;\n\n/** Inline secret descriptor. Prefer env, path, or callback sources for real applications. */\nexport interface ValueSecretSource {\n /** Inline secret value. */\n value: SecretValue;\n}\n\n/** Environment variable descriptor for text secrets. */\nexport interface EnvSecretSource {\n /** Environment variable containing the secret. */\n env: string;\n}\n\n/** Environment variable descriptor for base64-encoded binary secrets. */\nexport interface Base64EnvSecretSource {\n /** Environment variable containing a base64-encoded secret. */\n base64Env: string;\n}\n\n/** File-backed secret descriptor. */\nexport interface FileSecretSource {\n /** Path to the file containing the secret. */\n path: string;\n /** Text encoding to use, or `buffer` to return raw bytes. Defaults to `utf8`. */\n encoding?: BufferEncoding | \"buffer\";\n}\n\n/** Secret source accepted by profile credential fields. */\nexport type SecretSource =\n | SecretValue\n | SecretProvider\n | ValueSecretSource\n | EnvSecretSource\n | Base64EnvSecretSource\n | FileSecretSource;\n\n/** Injectable dependencies used by tests or host applications during secret resolution. */\nexport interface ResolveSecretOptions {\n /** Environment source. Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n /** File reader. Defaults to `fs.promises.readFile`. */\n readFile?: (path: string) => Promise<Buffer> | Buffer;\n}\n\n/**\n * Resolves a secret source into a string or Buffer without logging the value.\n *\n * @param source - Secret source to resolve.\n * @param options - Optional env and file-reader overrides.\n * @returns Resolved secret value.\n * @throws {@link ConfigurationError} When a descriptor is invalid or unavailable.\n */\nexport async function resolveSecret(\n source: SecretSource,\n options: ResolveSecretOptions = {},\n): Promise<SecretValue> {\n if (isSecretValue(source)) {\n return cloneSecretValue(source);\n }\n\n if (typeof source === \"function\") {\n return cloneSecretValue(await source());\n }\n\n if (isValueSecretSource(source)) {\n return cloneSecretValue(source.value);\n }\n\n if (isEnvSecretSource(source)) {\n const value = (options.env ?? process.env)[source.env];\n\n if (value === undefined) {\n throw createSecretConfigurationError(\n \"Secret environment variable is not set\",\n \"env\",\n source.env,\n );\n }\n\n return value;\n }\n\n if (isBase64EnvSecretSource(source)) {\n const value = (options.env ?? process.env)[source.base64Env];\n\n if (value === undefined) {\n throw createSecretConfigurationError(\n \"Secret environment variable is not set\",\n \"base64Env\",\n source.base64Env,\n );\n }\n\n return Buffer.from(value, \"base64\");\n }\n\n if (isFileSecretSource(source)) {\n const fileReader = options.readFile ?? readFile;\n const value = await fileReader(source.path);\n\n if (source.encoding === \"buffer\") {\n return Buffer.from(value);\n }\n\n return value.toString(source.encoding ?? \"utf8\");\n }\n\n throw createSecretConfigurationError(\"Unsupported secret source\", \"source\", \"unknown\");\n}\n\n/**\n * Redacts a secret source or resolved secret for safe diagnostics.\n *\n * @param source - Secret source or resolved value to sanitize.\n * @returns Redacted placeholder or descriptor shape.\n */\nexport function redactSecretSource(source: SecretSource | SecretValue): unknown {\n if (isSecretValue(source) || typeof source === \"function\") {\n return REDACTED;\n }\n\n if (isValueSecretSource(source)) return { value: REDACTED };\n if (isEnvSecretSource(source)) return { env: REDACTED };\n if (isBase64EnvSecretSource(source)) return { base64Env: REDACTED };\n if (isFileSecretSource(source)) return { encoding: source.encoding, path: REDACTED };\n\n return REDACTED;\n}\n\nfunction isSecretValue(value: unknown): value is SecretValue {\n return typeof value === \"string\" || Buffer.isBuffer(value);\n}\n\nfunction isValueSecretSource(value: unknown): value is ValueSecretSource {\n return isRecord(value) && \"value\" in value && isSecretValue(value.value);\n}\n\nfunction isEnvSecretSource(value: unknown): value is EnvSecretSource {\n return isRecord(value) && typeof value.env === \"string\";\n}\n\nfunction isBase64EnvSecretSource(value: unknown): value is Base64EnvSecretSource {\n return isRecord(value) && typeof value.base64Env === \"string\";\n}\n\nfunction isFileSecretSource(value: unknown): value is FileSecretSource {\n return isRecord(value) && typeof value.path === \"string\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction cloneSecretValue(value: SecretValue): SecretValue {\n return Buffer.isBuffer(value) ? Buffer.from(value) : value;\n}\n\nfunction createSecretConfigurationError(\n message: string,\n sourceType: string,\n sourceName: string,\n): ConfigurationError {\n return new ConfigurationError({\n details: { sourceName, sourceType },\n message,\n retryable: false,\n });\n}\n","/**\n * Connection profile redaction helpers.\n *\n * @module profiles/ProfileRedactor\n */\nimport type { ConnectionProfile, SshProfile, TlsProfile, TlsSecretSource } from \"../types/public\";\nimport { REDACTED, redactObject } from \"../logging/redaction\";\nimport { redactSecretSource } from \"./SecretSource\";\n\n/**\n * Produces a diagnostics-safe profile copy with credentials and runtime hooks redacted.\n *\n * @param profile - Connection profile to sanitize.\n * @returns Plain object safe to include in logs, traces, or validation reports.\n */\nexport function redactConnectionProfile(profile: ConnectionProfile): Record<string, unknown> {\n const { logger, password, signal, ssh, tls, username, ...rest } = profile;\n const redacted = redactObject(rest);\n\n if (username !== undefined) redacted.username = redactSecretSource(username);\n if (password !== undefined) redacted.password = redactSecretSource(password);\n if (ssh !== undefined) redacted.ssh = redactSshProfile(ssh);\n if (tls !== undefined) redacted.tls = redactTlsProfile(tls);\n if (signal !== undefined) redacted.signal = \"[AbortSignal]\";\n if (logger !== undefined) redacted.logger = REDACTED;\n\n return redacted;\n}\n\n/**\n * Redacts SSH private-key profile fields while preserving non-sensitive policy settings.\n *\n * @param profile - SSH profile to sanitize.\n * @returns Plain object safe to include in diagnostics.\n */\nfunction redactSshProfile(profile: SshProfile): Record<string, unknown> {\n const { agent, keyboardInteractive, knownHosts, passphrase, privateKey, socketFactory, ...rest } =\n profile;\n const redacted = redactObject(rest);\n\n if (agent !== undefined) redacted.agent = REDACTED;\n if (privateKey !== undefined) redacted.privateKey = redactSecretSource(privateKey);\n if (passphrase !== undefined) redacted.passphrase = redactSecretSource(passphrase);\n if (knownHosts !== undefined) redacted.knownHosts = redactSshKnownHostsSource(knownHosts);\n if (keyboardInteractive !== undefined) redacted.keyboardInteractive = REDACTED;\n if (socketFactory !== undefined) redacted.socketFactory = REDACTED;\n\n return redacted;\n}\n\n/**\n * Redacts an SSH known_hosts source, preserving array shape for diagnostics.\n *\n * @param source - Single known_hosts source or ordered source array.\n * @returns Redacted source descriptor.\n */\nfunction redactSshKnownHostsSource(source: NonNullable<SshProfile[\"knownHosts\"]>): unknown {\n if (Array.isArray(source)) {\n return source.map((item) => redactSecretSource(item));\n }\n\n return redactSecretSource(source);\n}\n\n/**\n * Redacts certificate-bearing TLS profile fields while preserving non-sensitive policy settings.\n *\n * @param profile - TLS profile to sanitize.\n * @returns Plain object safe to include in diagnostics.\n */\nfunction redactTlsProfile(profile: TlsProfile): Record<string, unknown> {\n const { ca, cert, checkServerIdentity, key, passphrase, pfx, ...rest } = profile;\n const redacted = redactObject(rest);\n\n if (ca !== undefined) redacted.ca = redactTlsSecretSource(ca);\n if (cert !== undefined) redacted.cert = redactSecretSource(cert);\n if (key !== undefined) redacted.key = redactSecretSource(key);\n if (passphrase !== undefined) redacted.passphrase = redactSecretSource(passphrase);\n if (pfx !== undefined) redacted.pfx = redactSecretSource(pfx);\n if (checkServerIdentity !== undefined) redacted.checkServerIdentity = REDACTED;\n\n return redacted;\n}\n\n/**\n * Redacts a TLS material source, preserving array shape for CA bundle diagnostics.\n *\n * @param source - Single secret source or ordered source array.\n * @returns Redacted source descriptor.\n */\nfunction redactTlsSecretSource(source: TlsSecretSource): unknown {\n if (Array.isArray(source)) {\n return source.map((item) => redactSecretSource(item));\n }\n\n return redactSecretSource(source);\n}\n","/**\n * Diagnostics helpers for inspecting a {@link TransferClient} and probing connection profiles.\n *\n * These helpers are intentionally side-effect-light: they exercise an existing client without\n * mutating registry state and never log secret material. Use them to render setup screens,\n * collect bug-report payloads, or verify a profile after an importer run.\n *\n * @module diagnostics\n */\nimport type { TransferClient } from \"../core/TransferClient\";\nimport type { CapabilitySet } from \"../core/CapabilitySet\";\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { redactConnectionProfile } from \"../profiles/ProfileRedactor\";\nimport type { ConnectionProfile, RemoteEntry } from \"../types/public\";\n\n/** Snapshot of the providers registered with a client. */\nexport interface ClientDiagnostics {\n /** Providers currently registered, keyed by id. */\n providers: ReadonlyArray<{ id: ProviderId; capabilities: CapabilitySet }>;\n}\n\n/**\n * Returns a redaction-safe snapshot of the providers registered with a client.\n *\n * @param client - Transfer client to inspect.\n * @returns Provider id and capability snapshot tuples.\n */\nexport function summarizeClientDiagnostics(client: TransferClient): ClientDiagnostics {\n const capabilities = client.getCapabilities();\n return {\n providers: capabilities.map((entry) => ({ capabilities: entry, id: entry.provider })),\n };\n}\n\n/** Per-step duration measurements collected by {@link runConnectionDiagnostics}. */\nexport interface ConnectionDiagnosticTimings {\n /** Total time spent inside `client.connect`. */\n connectMs?: number;\n /** Time spent inside the optional `fs.list` probe. */\n listMs?: number;\n /** Time spent inside the optional `session.disconnect`. */\n disconnectMs?: number;\n}\n\n/** Result returned by {@link runConnectionDiagnostics}. */\nexport interface ConnectionDiagnosticsResult {\n /** Resolved provider id used to open the session. */\n provider?: ProviderId;\n /** Profile host (after redaction). */\n host: string;\n /** Capability snapshot reported by the connected session. */\n capabilities?: CapabilitySet;\n /** Redacted connection profile mirroring {@link redactConnectionProfile}. */\n redactedProfile: Record<string, unknown>;\n /** Per-step duration measurements. */\n timings: ConnectionDiagnosticTimings;\n /** Sample of entries returned by the optional `fs.list` probe. */\n sample?: readonly RemoteEntry[];\n /** Whether all probes ran without throwing. */\n ok: boolean;\n /** Captured error summary when the diagnostics could not complete. */\n error?: { message: string; name?: string; code?: string };\n}\n\n/** Options accepted by {@link runConnectionDiagnostics}. */\nexport interface RunConnectionDiagnosticsOptions {\n /** Transfer client used to open the session. */\n client: TransferClient;\n /** Connection profile to probe. */\n profile: ConnectionProfile;\n /** Path passed to the optional `fs.list` probe. Defaults to `\"/\"`. */\n listPath?: string;\n /** When `false`, skips the `fs.list` probe. Defaults to `true`. */\n probeList?: boolean;\n /** Maximum number of entries retained in the result sample. Defaults to `5`. */\n sampleSize?: number;\n /** Optional clock injected for deterministic test timings. Defaults to `performance.now`. */\n now?: () => number;\n}\n\n/**\n * Connects to a profile, captures capability and listing samples, and returns a redaction-safe report.\n *\n * @param options - Diagnostic probe options.\n * @returns Diagnostic report including timings and any captured error.\n */\nexport async function runConnectionDiagnostics(\n options: RunConnectionDiagnosticsOptions,\n): Promise<ConnectionDiagnosticsResult> {\n const now = options.now ?? (() => performance.now());\n const probeList = options.probeList !== false;\n const listPath = options.listPath ?? \"/\";\n const sampleSize = Math.max(0, options.sampleSize ?? 5);\n const redactedProfile = redactConnectionProfile(options.profile);\n\n const result: ConnectionDiagnosticsResult = {\n host: options.profile.host,\n ok: false,\n redactedProfile,\n timings: {},\n };\n\n const connectStart = now();\n try {\n const session = await options.client.connect(options.profile);\n result.timings.connectMs = now() - connectStart;\n result.provider = session.provider;\n result.capabilities = session.capabilities;\n try {\n if (probeList) {\n const listStart = now();\n const entries = await session.fs.list(listPath);\n result.timings.listMs = now() - listStart;\n result.sample = entries.slice(0, sampleSize);\n }\n result.ok = true;\n } finally {\n const disconnectStart = now();\n await session.disconnect();\n result.timings.disconnectMs = now() - disconnectStart;\n }\n } catch (error) {\n result.error = summarizeDiagnosticError(error);\n }\n return result;\n}\n\nfunction summarizeDiagnosticError(error: unknown): {\n message: string;\n name?: string;\n code?: string;\n} {\n if (error instanceof Error) {\n const summary: { message: string; name?: string; code?: string } = { message: error.message };\n if (error.name !== \"Error\") summary.name = error.name;\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\") summary.code = code;\n return summary;\n }\n return { message: String(error) };\n}\n","/**\n * Local file-system provider for deterministic provider contract coverage.\n *\n * @module providers/local/LocalProvider\n */\nimport { createReadStream } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n open,\n readdir,\n readlink,\n rename,\n rm,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { Buffer } from \"node:buffer\";\nimport type { Stats } from \"node:fs\";\nimport type { CapabilitySet } from \"../../core/CapabilitySet\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n ConfigurationError,\n PathNotFoundError,\n PermissionDeniedError,\n} from \"../../errors/ZeroTransferError\";\nimport type { TransferVerificationResult } from \"../../transfers/TransferJob\";\nimport type {\n ConnectionProfile,\n MkdirOptions,\n RemoteEntry,\n RemoteEntryType,\n RemoteStat,\n RemoveOptions,\n RmdirOptions,\n} from \"../../types/public\";\nimport { basenameRemotePath, joinRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\n\nconst LOCAL_PROVIDER_ID = \"local\";\n\nconst LOCAL_PROVIDER_CAPABILITIES: CapabilitySet = {\n provider: LOCAL_PROVIDER_ID,\n authentication: [\"anonymous\"],\n list: true,\n stat: true,\n readStream: true,\n writeStream: true,\n serverSideCopy: false,\n serverSideMove: false,\n resumeDownload: true,\n resumeUpload: true,\n checksum: [],\n atomicRename: false,\n chmod: false,\n chown: false,\n symlink: true,\n metadata: [\"accessedAt\", \"createdAt\", \"modifiedAt\", \"permissions\", \"symlinkTarget\", \"uniqueId\"],\n maxConcurrency: 16,\n notes: [\"Local filesystem provider for tests and local-only workflows\"],\n};\n\n/** Options used to create a local file-system provider factory. */\nexport interface LocalProviderOptions {\n /** Root directory exposed as `/`. When omitted, `profile.host` is treated as the root path. */\n rootPath?: string;\n}\n\n/**\n * Creates a provider factory backed by the local filesystem.\n *\n * Useful for copying files between two remote endpoints via a local staging\n * area, or as the destination for `downloadFile`. The friendly `uploadFile`\n * helper registers a local provider implicitly.\n *\n * @param options - Optional local root path exposed through provider sessions.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n *\n * @example Use a fixed root directory\n * ```ts\n * import { createLocalProviderFactory, createTransferClient } from \"@zero-transfer/sdk\";\n *\n * const client = createTransferClient({\n * providers: [createLocalProviderFactory({ rootPath: \"/var/lib/zt-staging\" })],\n * });\n *\n * const session = await client.connect({ host: \"staging\", provider: \"local\" });\n * const list = await session.fs.list(\"/\");\n * ```\n */\nexport function createLocalProviderFactory(options: LocalProviderOptions = {}): ProviderFactory {\n return {\n id: LOCAL_PROVIDER_ID,\n capabilities: LOCAL_PROVIDER_CAPABILITIES,\n create: () => new LocalProvider(options.rootPath),\n };\n}\n\nclass LocalProvider implements TransferProvider {\n readonly id = LOCAL_PROVIDER_ID;\n readonly capabilities = LOCAL_PROVIDER_CAPABILITIES;\n\n constructor(private readonly configuredRootPath: string | undefined) {}\n\n connect(profile: ConnectionProfile): Promise<TransferSession> {\n return Promise.resolve().then(() => {\n const rootPath = path.resolve(this.configuredRootPath ?? profile.host);\n return new LocalTransferSession(rootPath);\n });\n }\n}\n\nclass LocalTransferSession implements TransferSession {\n readonly provider = LOCAL_PROVIDER_ID;\n readonly capabilities = LOCAL_PROVIDER_CAPABILITIES;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(rootPath: string) {\n this.fs = new LocalFileSystem(rootPath);\n this.transfers = new LocalTransferOperations(rootPath);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\nclass LocalTransferOperations implements ProviderTransferOperations {\n constructor(private readonly rootPath: string) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const remotePath = normalizeLocalProviderPath(request.endpoint.path);\n const entry = await readLocalEntry(this.rootPath, remotePath);\n\n if (entry.type !== \"file\") {\n throw createPathNotFoundError(remotePath, `Local provider path is not a file: ${remotePath}`);\n }\n\n const range = resolveReadRange(entry.size ?? 0, request.range);\n const result: ProviderTransferReadResult = {\n content: createLocalReadSource(resolveLocalPath(this.rootPath, remotePath), range),\n totalBytes: range.length,\n };\n\n if (range.offset > 0) {\n result.bytesRead = range.offset;\n }\n\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const remotePath = normalizeLocalProviderPath(request.endpoint.path);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n const content = await collectTransferContent(request);\n const offset = normalizeOptionalByteCount(request.offset, \"offset\", remotePath);\n\n await ensureLocalParentDirectory(localPath, remotePath);\n await writeLocalContent(localPath, remotePath, content, offset);\n\n const stat = await readLocalEntry(this.rootPath, remotePath);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: content.byteLength,\n resumed: offset !== undefined && offset > 0,\n verified: request.verification?.verified ?? false,\n };\n\n if (stat.size !== undefined) {\n result.totalBytes = stat.size;\n }\n\n if (request.verification !== undefined) {\n result.verification = cloneVerification(request.verification);\n }\n\n return result;\n }\n}\n\nclass LocalFileSystem implements RemoteFileSystem {\n constructor(private readonly rootPath: string) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const remotePath = normalizeLocalProviderPath(path);\n const directory = await this.stat(remotePath);\n\n if (directory.type !== \"directory\") {\n throw createPathNotFoundError(\n remotePath,\n `Local provider path is not a directory: ${remotePath}`,\n );\n }\n\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n const names = await readLocalDirectory(localPath, remotePath);\n const entries = await Promise.all(\n names.map((name) => readLocalEntry(this.rootPath, joinRemotePath(remotePath, name))),\n );\n\n return entries.sort(compareEntries);\n }\n\n async stat(path: string): Promise<RemoteStat> {\n return readLocalEntry(this.rootPath, normalizeLocalProviderPath(path));\n }\n\n async remove(remote: string, options: RemoveOptions = {}): Promise<void> {\n const remotePath = normalizeLocalProviderPath(remote);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n try {\n await unlink(localPath);\n } catch (error) {\n if (options.ignoreMissing && isNodeErrno(error, \"ENOENT\")) return;\n if (isNodeErrno(error, \"ENOENT\")) {\n throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);\n }\n throw error;\n }\n }\n\n async rename(from: string, to: string): Promise<void> {\n const fromRemote = normalizeLocalProviderPath(from);\n const toRemote = normalizeLocalProviderPath(to);\n const fromLocal = resolveLocalPath(this.rootPath, fromRemote);\n const toLocal = resolveLocalPath(this.rootPath, toRemote);\n try {\n await rename(fromLocal, toLocal);\n } catch (error) {\n if (isNodeErrno(error, \"ENOENT\")) {\n throw createPathNotFoundError(fromRemote, `Local path not found: ${fromRemote}`);\n }\n throw error;\n }\n }\n\n async mkdir(remote: string, options: MkdirOptions = {}): Promise<void> {\n const remotePath = normalizeLocalProviderPath(remote);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n await mkdir(localPath, { recursive: options.recursive === true });\n }\n\n async rmdir(remote: string, options: RmdirOptions = {}): Promise<void> {\n const remotePath = normalizeLocalProviderPath(remote);\n const localPath = resolveLocalPath(this.rootPath, remotePath);\n try {\n await rm(localPath, { recursive: options.recursive === true, force: false });\n } catch (error) {\n if (isNodeErrno(error, \"ENOENT\")) {\n if (options.ignoreMissing) return;\n throw createPathNotFoundError(remotePath, `Local path not found: ${remotePath}`);\n }\n throw error;\n }\n }\n}\n\nfunction isNodeErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\ninterface ResolvedReadRange {\n offset: number;\n length: number;\n}\n\nfunction resolveReadRange(\n size: number,\n range: ProviderTransferReadRequest[\"range\"],\n): ResolvedReadRange {\n if (range === undefined) {\n return { length: size, offset: 0 };\n }\n\n const requestedOffset = normalizeByteCount(range.offset, \"offset\", \"/\");\n const requestedLength =\n range.length === undefined\n ? size - Math.min(requestedOffset, size)\n : normalizeByteCount(range.length, \"length\", \"/\");\n const offset = Math.min(requestedOffset, size);\n const length = Math.max(0, Math.min(requestedLength, size - offset));\n\n return { length, offset };\n}\n\nasync function* createLocalReadSource(\n localPath: string,\n range: ResolvedReadRange,\n): AsyncGenerator<Uint8Array> {\n if (range.length <= 0) {\n return;\n }\n\n const stream = createReadStream(localPath, {\n end: range.offset + range.length - 1,\n start: range.offset,\n }) as AsyncIterable<Buffer>;\n\n for await (const chunk of stream) {\n yield new Uint8Array(chunk);\n }\n}\n\nasync function collectTransferContent(request: ProviderTransferWriteRequest): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let byteLength = 0;\n\n for await (const chunk of request.content) {\n request.throwIfAborted();\n const clonedChunk = new Uint8Array(chunk);\n chunks.push(clonedChunk);\n byteLength += clonedChunk.byteLength;\n request.reportProgress(byteLength, request.totalBytes);\n }\n\n return concatChunks(chunks, byteLength);\n}\n\nfunction concatChunks(chunks: Uint8Array[], byteLength: number): Uint8Array {\n const content = new Uint8Array(byteLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n content.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return content;\n}\n\nasync function ensureLocalParentDirectory(localPath: string, remotePath: string): Promise<void> {\n try {\n await mkdir(path.dirname(localPath), { recursive: true });\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n}\n\nasync function writeLocalContent(\n localPath: string,\n remotePath: string,\n content: Uint8Array,\n offset: number | undefined,\n): Promise<void> {\n try {\n if (offset === undefined) {\n await writeFile(localPath, content);\n return;\n }\n\n const handle = await openLocalFileForOffsetWrite(localPath);\n\n try {\n await handle.write(content, 0, content.byteLength, offset);\n } finally {\n await handle.close();\n }\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n}\n\nasync function openLocalFileForOffsetWrite(localPath: string) {\n try {\n return await open(localPath, \"r+\");\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return open(localPath, \"w+\");\n }\n\n throw error;\n }\n}\n\nfunction normalizeOptionalByteCount(\n value: number | undefined,\n field: string,\n remotePath: string,\n): number | undefined {\n return value === undefined ? undefined : normalizeByteCount(value, field, remotePath);\n}\n\nfunction normalizeByteCount(value: number, field: string, remotePath: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new ConfigurationError({\n details: { field, provider: LOCAL_PROVIDER_ID },\n message: `Local provider ${field} must be a non-negative number`,\n path: remotePath,\n retryable: false,\n });\n }\n\n return Math.floor(value);\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n\nasync function readLocalDirectory(localPath: string, remotePath: string): Promise<string[]> {\n try {\n return await readdir(localPath);\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n}\n\nasync function readLocalEntry(rootPath: string, remotePath: string): Promise<RemoteStat> {\n const localPath = resolveLocalPath(rootPath, remotePath);\n let stats: Stats;\n\n try {\n stats = await lstat(localPath);\n } catch (error) {\n throw mapLocalFileSystemError(error, remotePath);\n }\n\n const entry: RemoteEntry = {\n accessedAt: cloneDate(stats.atime),\n createdAt: cloneDate(stats.birthtime),\n modifiedAt: cloneDate(stats.mtime),\n name: basenameRemotePath(remotePath),\n path: remotePath,\n permissions: { raw: formatMode(stats.mode) },\n size: stats.size,\n type: getLocalEntryType(stats),\n uniqueId: `${stats.dev}:${stats.ino}`,\n };\n\n if (entry.type === \"symlink\") {\n const symlinkTarget = await readSymlinkTarget(localPath);\n\n if (symlinkTarget !== undefined) {\n entry.symlinkTarget = symlinkTarget;\n }\n }\n\n return {\n ...entry,\n exists: true,\n };\n}\n\nasync function readSymlinkTarget(localPath: string): Promise<string | undefined> {\n try {\n return await readlink(localPath);\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeLocalProviderPath(input: string): string {\n const normalized = normalizeRemotePath(input);\n\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n throw new ConfigurationError({\n details: { provider: LOCAL_PROVIDER_ID },\n message: `Local provider path escapes the configured root: ${normalized}`,\n path: normalized,\n retryable: false,\n });\n }\n\n if (normalized === \".\" || normalized === \"/\") {\n return \"/\";\n }\n\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction resolveLocalPath(rootPath: string, remotePath: string): string {\n const normalizedRemotePath = normalizeLocalProviderPath(remotePath);\n\n // If the remote path is already an absolute filesystem path inside rootPath\n // (e.g. friendly upload/download passes the host path as the endpoint path),\n // honour it directly instead of double-prepending rootPath.\n const resolvedRootPath = path.resolve(rootPath);\n const candidateAbsolute = path.resolve(normalizedRemotePath.split(\"/\").join(path.sep));\n if (\n candidateAbsolute === resolvedRootPath ||\n candidateAbsolute.startsWith(resolvedRootPath + path.sep)\n ) {\n return candidateAbsolute;\n }\n\n const relativePath = normalizedRemotePath === \"/\" ? \".\" : normalizedRemotePath.slice(1);\n const resolvedPath = path.resolve(rootPath, relativePath.split(\"/\").join(path.sep));\n const relativeToRoot = path.relative(rootPath, resolvedPath);\n\n if (\n relativeToRoot === \"\" ||\n (!relativeToRoot.startsWith(\"..\") && !path.isAbsolute(relativeToRoot))\n ) {\n return resolvedPath;\n }\n\n throw new ConfigurationError({\n details: { provider: LOCAL_PROVIDER_ID, rootPath },\n message: `Local provider path escapes the configured root: ${normalizedRemotePath}`,\n path: normalizedRemotePath,\n retryable: false,\n });\n}\n\nfunction getLocalEntryType(stats: Stats): RemoteEntryType {\n if (stats.isFile()) return \"file\";\n if (stats.isDirectory()) return \"directory\";\n if (stats.isSymbolicLink()) return \"symlink\";\n return \"unknown\";\n}\n\nfunction formatMode(mode: number): string {\n return (mode & 0o777).toString(8).padStart(3, \"0\");\n}\n\nfunction cloneDate(value: Date): Date {\n return new Date(value.getTime());\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction mapLocalFileSystemError(error: unknown, remotePath: string): Error {\n const code = getErrorCode(error);\n\n if (code === \"ENOENT\" || code === \"ENOTDIR\") {\n return createPathNotFoundError(remotePath, `Local provider path not found: ${remotePath}`);\n }\n\n if (code === \"EACCES\" || code === \"EPERM\") {\n return new PermissionDeniedError({\n cause: error,\n details: { provider: LOCAL_PROVIDER_ID },\n message: `Local provider permission denied: ${remotePath}`,\n path: remotePath,\n retryable: false,\n });\n }\n\n return new ConfigurationError({\n cause: error,\n details: { code, provider: LOCAL_PROVIDER_ID },\n message: `Local provider filesystem operation failed: ${remotePath}`,\n path: remotePath,\n retryable: false,\n });\n}\n\nfunction createPathNotFoundError(path: string, message: string): PathNotFoundError {\n return new PathNotFoundError({\n details: { provider: LOCAL_PROVIDER_ID },\n message,\n path,\n retryable: false,\n });\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : undefined;\n}\n","/**\n * Remote path normalization and FTP command-argument safety helpers.\n *\n * The functions in this module avoid platform-specific local path behavior and reject\n * CR/LF characters before values can be interpolated into FTP commands.\n *\n * @module utils/path\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\n\nconst UNSAFE_FTP_ARGUMENT_PATTERN = /[\\r\\n]/;\n\n/**\n * Validates that an FTP command argument cannot inject additional command lines.\n *\n * @param value - Argument value to validate.\n * @param label - Human-readable argument label used in error messages.\n * @returns The original value when it is safe.\n * @throws {@link ConfigurationError} When the value contains CR or LF characters.\n */\nexport function assertSafeFtpArgument(value: string, label = \"path\"): string {\n if (UNSAFE_FTP_ARGUMENT_PATTERN.test(value)) {\n throw new ConfigurationError({\n message: `Unsafe FTP ${label}: CR and LF characters are not allowed`,\n retryable: false,\n details: {\n label,\n },\n });\n }\n\n return value;\n}\n\n/**\n * Normalizes a remote path using POSIX-style separators without escaping absolute roots.\n *\n * @param input - Remote path that may contain duplicate separators or dot segments.\n * @returns A normalized remote path, `/` for absolute root, or `.` for an empty relative path.\n * @throws {@link ConfigurationError} When the input contains unsafe CR or LF characters.\n */\nexport function normalizeRemotePath(input: string): string {\n assertSafeFtpArgument(input);\n\n if (input.length === 0) {\n return \".\";\n }\n\n const isAbsolute = input.startsWith(\"/\");\n const segments: string[] = [];\n\n for (const segment of input.split(/[\\\\/]+/)) {\n if (segment.length === 0 || segment === \".\") {\n continue;\n }\n\n if (segment === \"..\") {\n if (segments.length > 0 && segments[segments.length - 1] !== \"..\") {\n segments.pop();\n } else if (!isAbsolute) {\n segments.push(segment);\n }\n continue;\n }\n\n segments.push(segment);\n }\n\n const normalized = segments.join(\"/\");\n\n if (isAbsolute) {\n return normalized.length > 0 ? `/${normalized}` : \"/\";\n }\n\n return normalized.length > 0 ? normalized : \".\";\n}\n\n/**\n * Joins remote path segments and normalizes the result.\n *\n * @param segments - Remote path segments to concatenate.\n * @returns A normalized remote path.\n * @throws {@link ConfigurationError} When any joined segment contains unsafe characters.\n */\nexport function joinRemotePath(...segments: string[]): string {\n if (segments.length === 0) {\n return \".\";\n }\n\n return normalizeRemotePath(segments.join(\"/\"));\n}\n\n/**\n * Extracts the final name segment from a normalized remote path.\n *\n * @param input - Remote path to inspect.\n * @returns The final path segment, or `/` when the input is the absolute root.\n * @throws {@link ConfigurationError} When the input contains unsafe characters.\n */\nexport function basenameRemotePath(input: string): string {\n const normalized = normalizeRemotePath(input);\n const parts = normalized.split(\"/\").filter(Boolean);\n return parts[parts.length - 1] ?? normalized;\n}\n","/**\n * Deterministic in-memory provider for contract and unit tests.\n *\n * @module providers/memory/MemoryProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport type { CapabilitySet } from \"../../core/CapabilitySet\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport { ConfigurationError, PathNotFoundError } from \"../../errors/ZeroTransferError\";\nimport type { TransferVerificationResult } from \"../../transfers/TransferJob\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type { TransferProvider } from \"../Provider\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport type {\n MkdirOptions,\n RemoteEntry,\n RemotePermissions,\n RemoteStat,\n RemoveOptions,\n RmdirOptions,\n} from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\n\nconst MEMORY_PROVIDER_ID = \"memory\";\n\nconst MEMORY_PROVIDER_CAPABILITIES: CapabilitySet = {\n provider: MEMORY_PROVIDER_ID,\n authentication: [\"anonymous\"],\n list: true,\n stat: true,\n readStream: true,\n writeStream: true,\n serverSideCopy: false,\n serverSideMove: false,\n resumeDownload: true,\n resumeUpload: true,\n checksum: [],\n atomicRename: false,\n chmod: false,\n chown: false,\n symlink: true,\n metadata: [\n \"accessedAt\",\n \"createdAt\",\n \"group\",\n \"modifiedAt\",\n \"owner\",\n \"permissions\",\n \"symlinkTarget\",\n \"uniqueId\",\n ],\n maxConcurrency: 32,\n notes: [\"Deterministic in-memory provider for tests and provider contract validation\"],\n};\n\n/** Fixture entry used to seed a memory provider instance. */\nexport interface MemoryProviderEntry extends Omit<RemoteEntry, \"name\"> {\n /** Entry basename. When omitted, it is derived from `path`. */\n name?: string;\n /** Optional byte content for file entries. Strings are encoded as UTF-8. */\n content?: string | Uint8Array;\n}\n\n/** Options used to create a deterministic memory provider factory. */\nexport interface MemoryProviderOptions {\n /** Entries available to sessions created by this provider factory. */\n entries?: Iterable<MemoryProviderEntry>;\n}\n\n/**\n * Creates a provider factory backed by deterministic in-memory fixture entries.\n *\n * @param options - Optional fixture entries to expose through the memory provider.\n * @returns Provider factory suitable for `createTransferClient({ providers: [...] })`.\n */\nexport function createMemoryProviderFactory(options: MemoryProviderOptions = {}): ProviderFactory {\n const state = createMemoryState(options.entries ?? []);\n\n return {\n id: MEMORY_PROVIDER_ID,\n capabilities: MEMORY_PROVIDER_CAPABILITIES,\n create: () => new MemoryProvider(state),\n };\n}\n\nclass MemoryProvider implements TransferProvider {\n readonly id = MEMORY_PROVIDER_ID;\n readonly capabilities = MEMORY_PROVIDER_CAPABILITIES;\n\n constructor(private readonly state: MemoryProviderState) {}\n\n connect(): Promise<TransferSession> {\n return Promise.resolve(new MemoryTransferSession(this.state));\n }\n}\n\nclass MemoryTransferSession implements TransferSession {\n readonly provider = MEMORY_PROVIDER_ID;\n readonly capabilities = MEMORY_PROVIDER_CAPABILITIES;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(state: MemoryProviderState) {\n this.fs = new MemoryFileSystem(state);\n this.transfers = new MemoryTransferOperations(state);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\ninterface MemoryProviderState {\n entries: Map<string, RemoteStat>;\n content: Map<string, Uint8Array>;\n}\n\nclass MemoryFileSystem implements RemoteFileSystem {\n constructor(private readonly state: MemoryProviderState) {}\n\n list(path: string): Promise<RemoteEntry[]> {\n return Promise.resolve().then(() => {\n const normalizedPath = normalizeMemoryPath(path);\n const directory = this.requireEntry(normalizedPath);\n\n if (directory.type !== \"directory\") {\n throw createPathNotFoundError(\n normalizedPath,\n `Memory path is not a directory: ${normalizedPath}`,\n );\n }\n\n return [...this.state.entries.values()]\n .filter(\n (entry) => entry.path !== normalizedPath && getParentPath(entry.path) === normalizedPath,\n )\n .map(cloneRemoteEntry)\n .sort(compareEntries);\n });\n }\n\n stat(path: string): Promise<RemoteStat> {\n return Promise.resolve().then(() =>\n cloneRemoteStat(this.requireEntry(normalizeMemoryPath(path))),\n );\n }\n\n remove(path: string, options: RemoveOptions = {}): Promise<void> {\n return Promise.resolve().then(() => {\n const normalized = normalizeMemoryPath(path);\n const entry = this.state.entries.get(normalized);\n if (entry === undefined) {\n if (options.ignoreMissing) return;\n throw createPathNotFoundError(normalized, `Memory path not found: ${normalized}`);\n }\n if (entry.type === \"directory\") {\n throw createPathNotFoundError(\n normalized,\n `Memory path is a directory; use rmdir: ${normalized}`,\n );\n }\n this.state.entries.delete(normalized);\n this.state.content.delete(normalized);\n });\n }\n\n rename(from: string, to: string): Promise<void> {\n return Promise.resolve().then(() => {\n const fromPath = normalizeMemoryPath(from);\n const toPath = normalizeMemoryPath(to);\n const entry = this.state.entries.get(fromPath);\n if (entry === undefined) {\n throw createPathNotFoundError(fromPath, `Memory path not found: ${fromPath}`);\n }\n ensureParentDirectories(this.state.entries, toPath);\n const moved: RemoteStat = { ...entry, path: toPath, name: basenameRemotePath(toPath) };\n this.state.entries.delete(fromPath);\n this.state.entries.set(toPath, moved);\n const content = this.state.content.get(fromPath);\n if (content !== undefined) {\n this.state.content.delete(fromPath);\n this.state.content.set(toPath, content);\n }\n });\n }\n\n mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n return Promise.resolve().then(() => {\n const normalized = normalizeMemoryPath(path);\n const existing = this.state.entries.get(normalized);\n if (existing !== undefined) {\n if (existing.type === \"directory\" && options.recursive) return;\n throw createInvalidFixtureError(normalized, `Memory path already exists: ${normalized}`);\n }\n if (options.recursive) {\n ensureParentDirectories(this.state.entries, normalized);\n } else {\n const parent = getParentPath(normalized);\n if (parent !== undefined && !this.state.entries.has(parent)) {\n throw createPathNotFoundError(parent, `Memory parent not found: ${parent}`);\n }\n }\n this.state.entries.set(normalized, createDirectoryEntry(normalized));\n });\n }\n\n rmdir(path: string, options: RmdirOptions = {}): Promise<void> {\n return Promise.resolve().then(() => {\n const normalized = normalizeMemoryPath(path);\n const entry = this.state.entries.get(normalized);\n if (entry === undefined) {\n if (options.ignoreMissing) return;\n throw createPathNotFoundError(normalized, `Memory path not found: ${normalized}`);\n }\n if (entry.type !== \"directory\") {\n throw createPathNotFoundError(normalized, `Memory path is not a directory: ${normalized}`);\n }\n const children = [...this.state.entries.values()].filter(\n (child) => child.path !== normalized && getParentPath(child.path) === normalized,\n );\n if (children.length > 0 && !options.recursive) {\n throw createInvalidFixtureError(normalized, `Memory directory not empty: ${normalized}`);\n }\n const stack = [...children];\n while (stack.length > 0) {\n const next = stack.pop();\n if (!next) continue;\n if (next.type === \"directory\") {\n for (const grand of this.state.entries.values()) {\n if (grand.path !== next.path && getParentPath(grand.path) === next.path) {\n stack.push(grand);\n }\n }\n }\n this.state.entries.delete(next.path);\n this.state.content.delete(next.path);\n }\n this.state.entries.delete(normalized);\n });\n }\n\n private requireEntry(path: string): RemoteStat {\n const entry = this.state.entries.get(path);\n\n if (entry === undefined) {\n throw createPathNotFoundError(path, `Memory path not found: ${path}`);\n }\n\n return entry;\n }\n}\n\nclass MemoryTransferOperations implements ProviderTransferOperations {\n constructor(private readonly state: MemoryProviderState) {}\n\n read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n return Promise.resolve().then(() => {\n request.throwIfAborted();\n const path = normalizeMemoryPath(request.endpoint.path);\n const entry = requireFileEntry(this.state, path);\n const content = this.state.content.get(path) ?? new Uint8Array(entry.size ?? 0);\n const range = resolveByteRange(content.byteLength, request.range);\n const chunk = content.slice(range.offset, range.offset + range.length);\n const result: ProviderTransferReadResult = {\n content: createMemoryContentSource(chunk),\n totalBytes: chunk.byteLength,\n };\n\n if (range.offset > 0) {\n result.bytesRead = range.offset;\n }\n\n return result;\n });\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n const path = normalizeMemoryPath(request.endpoint.path);\n const existing = this.state.entries.get(path);\n\n if (existing?.type === \"directory\") {\n throw createInvalidFixtureError(path, `Memory path is a directory: ${path}`);\n }\n\n const writtenContent = await collectTransferContent(request);\n const offset = normalizeOptionalByteCount(request.offset, \"offset\");\n const previousContent = this.state.content.get(path) ?? new Uint8Array(0);\n const content =\n offset === undefined\n ? writtenContent\n : mergeContentAtOffset(previousContent, writtenContent, offset);\n\n ensureParentDirectories(this.state.entries, path);\n this.state.entries.set(path, createWrittenFileEntry(path, content.byteLength));\n this.state.content.set(path, content);\n\n const result: ProviderTransferWriteResult = {\n bytesTransferred: writtenContent.byteLength,\n resumed: offset !== undefined && offset > 0,\n totalBytes: content.byteLength,\n verified: request.verification?.verified ?? false,\n };\n\n if (request.verification !== undefined) {\n result.verification = cloneVerification(request.verification);\n }\n\n return result;\n }\n}\n\nfunction createMemoryState(entries: Iterable<MemoryProviderEntry>): MemoryProviderState {\n const state: MemoryProviderState = {\n content: new Map(),\n entries: new Map([[\"/\", createDirectoryEntry(\"/\")]]),\n };\n\n for (const input of entries) {\n const entry = createMemoryEntry(input);\n const content = createMemoryContent(input, entry);\n\n if (entry.path === \"/\" && entry.type !== \"directory\") {\n throw createInvalidFixtureError(entry.path, \"Memory provider root must be a directory\");\n }\n\n ensureParentDirectories(state.entries, entry.path);\n state.entries.set(entry.path, entry);\n\n if (content !== undefined) {\n state.content.set(entry.path, content);\n }\n }\n\n return state;\n}\n\nfunction createMemoryEntry(input: MemoryProviderEntry): RemoteStat {\n const path = normalizeMemoryPath(input.path);\n const entry: RemoteEntry = {\n name: input.name ?? basenameRemotePath(path),\n path,\n type: input.type,\n };\n\n copyOptionalEntryFields(entry, input);\n\n const content = normalizeMemoryContent(input.content);\n\n if (content !== undefined) {\n entry.size = content.byteLength;\n }\n\n return {\n ...entry,\n exists: true,\n };\n}\n\nfunction createMemoryContent(\n input: MemoryProviderEntry,\n entry: RemoteStat,\n): Uint8Array | undefined {\n const content = normalizeMemoryContent(input.content);\n\n if (content !== undefined) {\n if (entry.type !== \"file\") {\n throw createInvalidFixtureError(\n entry.path,\n `Memory fixture content requires a file: ${entry.path}`,\n );\n }\n\n return content;\n }\n\n if (entry.type === \"file\") {\n return new Uint8Array(entry.size ?? 0);\n }\n\n return undefined;\n}\n\nfunction normalizeMemoryContent(content: string | Uint8Array | undefined): Uint8Array | undefined {\n if (content === undefined) {\n return undefined;\n }\n\n return typeof content === \"string\" ? Buffer.from(content) : new Uint8Array(content);\n}\n\nfunction createWrittenFileEntry(path: string, size: number): RemoteStat {\n return {\n exists: true,\n modifiedAt: new Date(),\n name: basenameRemotePath(path),\n path,\n size,\n type: \"file\",\n };\n}\n\nfunction createDirectoryEntry(path: string): RemoteStat {\n return {\n exists: true,\n name: basenameRemotePath(path),\n path,\n type: \"directory\",\n };\n}\n\nfunction ensureParentDirectories(state: Map<string, RemoteStat>, path: string): void {\n for (const parentPath of getAncestorPaths(path)) {\n const parent = state.get(parentPath);\n\n if (parent !== undefined && parent.type !== \"directory\") {\n throw createInvalidFixtureError(\n parentPath,\n `Memory fixture parent is not a directory: ${parentPath}`,\n );\n }\n\n if (parent === undefined) {\n state.set(parentPath, createDirectoryEntry(parentPath));\n }\n }\n}\n\nfunction normalizeMemoryPath(path: string): string {\n const normalized = normalizeRemotePath(path);\n\n if (normalized === \".\" || normalized === \"/\") {\n return \"/\";\n }\n\n return normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n\nfunction getAncestorPaths(path: string): string[] {\n const ancestors: string[] = [];\n let parentPath = getParentPath(path);\n\n while (parentPath !== undefined && parentPath !== \"/\") {\n ancestors.unshift(parentPath);\n parentPath = getParentPath(parentPath);\n }\n\n return ancestors;\n}\n\nfunction getParentPath(path: string): string | undefined {\n if (path === \"/\") {\n return undefined;\n }\n\n const parentEnd = path.lastIndexOf(\"/\");\n return parentEnd <= 0 ? \"/\" : path.slice(0, parentEnd);\n}\n\nfunction requireFileEntry(state: MemoryProviderState, path: string): RemoteStat {\n const entry = state.entries.get(path);\n\n if (entry === undefined) {\n throw createPathNotFoundError(path, `Memory path not found: ${path}`);\n }\n\n if (entry.type !== \"file\") {\n throw createPathNotFoundError(path, `Memory path is not a file: ${path}`);\n }\n\n return entry;\n}\n\nfunction resolveByteRange(\n size: number,\n range: ProviderTransferReadRequest[\"range\"],\n): { offset: number; length: number } {\n if (range === undefined) {\n return { length: size, offset: 0 };\n }\n\n const requestedOffset = normalizeByteCount(range.offset, \"offset\");\n const requestedLength =\n range.length === undefined\n ? size - Math.min(requestedOffset, size)\n : normalizeByteCount(range.length, \"length\");\n const offset = Math.min(requestedOffset, size);\n const length = Math.max(0, Math.min(requestedLength, size - offset));\n\n return { length, offset };\n}\n\nasync function collectTransferContent(request: ProviderTransferWriteRequest): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let byteLength = 0;\n\n for await (const chunk of request.content) {\n request.throwIfAborted();\n const clonedChunk = new Uint8Array(chunk);\n chunks.push(clonedChunk);\n byteLength += clonedChunk.byteLength;\n request.reportProgress(byteLength, request.totalBytes);\n }\n\n return concatChunks(chunks, byteLength);\n}\n\nfunction concatChunks(chunks: Uint8Array[], byteLength: number): Uint8Array {\n const content = new Uint8Array(byteLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n content.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return content;\n}\n\nfunction mergeContentAtOffset(\n previousContent: Uint8Array,\n writtenContent: Uint8Array,\n offset: number,\n): Uint8Array {\n const content = new Uint8Array(\n Math.max(previousContent.byteLength, offset + writtenContent.byteLength),\n );\n content.set(previousContent);\n content.set(writtenContent, offset);\n return content;\n}\n\nasync function* createMemoryContentSource(content: Uint8Array): AsyncGenerator<Uint8Array> {\n await Promise.resolve();\n yield new Uint8Array(content);\n}\n\nfunction normalizeOptionalByteCount(value: number | undefined, field: string): number | undefined {\n return value === undefined ? undefined : normalizeByteCount(value, field);\n}\n\nfunction normalizeByteCount(value: number, field: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw createInvalidFixtureError(\"/\", `Memory provider ${field} must be a non-negative number`);\n }\n\n return Math.floor(value);\n}\n\nfunction cloneVerification(verification: TransferVerificationResult): TransferVerificationResult {\n const clone: TransferVerificationResult = { verified: verification.verified };\n\n if (verification.method !== undefined) clone.method = verification.method;\n if (verification.checksum !== undefined) clone.checksum = verification.checksum;\n if (verification.expectedChecksum !== undefined) {\n clone.expectedChecksum = verification.expectedChecksum;\n }\n if (verification.actualChecksum !== undefined) clone.actualChecksum = verification.actualChecksum;\n if (verification.details !== undefined) clone.details = { ...verification.details };\n\n return clone;\n}\n\nfunction cloneRemoteEntry(entry: RemoteEntry): RemoteEntry {\n const clone: RemoteEntry = {\n name: entry.name,\n path: entry.path,\n type: entry.type,\n };\n\n copyOptionalEntryFields(clone, entry);\n return clone;\n}\n\nfunction cloneRemoteStat(entry: RemoteStat): RemoteStat {\n return {\n ...cloneRemoteEntry(entry),\n exists: true,\n };\n}\n\nfunction copyOptionalEntryFields(target: RemoteEntry, source: Partial<RemoteEntry>): void {\n if (source.size !== undefined) target.size = source.size;\n if (source.modifiedAt !== undefined) target.modifiedAt = cloneDate(source.modifiedAt);\n if (source.createdAt !== undefined) target.createdAt = cloneDate(source.createdAt);\n if (source.accessedAt !== undefined) target.accessedAt = cloneDate(source.accessedAt);\n if (source.permissions !== undefined) target.permissions = clonePermissions(source.permissions);\n if (source.owner !== undefined) target.owner = source.owner;\n if (source.group !== undefined) target.group = source.group;\n if (source.symlinkTarget !== undefined) target.symlinkTarget = source.symlinkTarget;\n if (source.uniqueId !== undefined) target.uniqueId = source.uniqueId;\n if (source.raw !== undefined) target.raw = source.raw;\n}\n\nfunction cloneDate(value: Date): Date {\n return new Date(value.getTime());\n}\n\nfunction clonePermissions(permissions: RemotePermissions): RemotePermissions {\n return { ...permissions };\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction createPathNotFoundError(path: string, message: string): PathNotFoundError {\n return new PathNotFoundError({\n details: { provider: MEMORY_PROVIDER_ID },\n message,\n path,\n retryable: false,\n });\n}\n\nfunction createInvalidFixtureError(path: string, message: string): ConfigurationError {\n return new ConfigurationError({\n details: { provider: MEMORY_PROVIDER_ID },\n message,\n path,\n retryable: false,\n });\n}\n","/**\n * Connection profile secret resolution helpers.\n *\n * @module profiles/resolveConnectionProfileSecrets\n */\nimport type { ConnectionProfile, SshProfile, TlsProfile, TlsSecretSource } from \"../types/public\";\nimport { resolveSecret, type ResolveSecretOptions, type SecretValue } from \"./SecretSource\";\n\n/** SSH profile with private-key and known-host material resolved. */\nexport interface ResolvedSshProfile extends Omit<\n SshProfile,\n \"knownHosts\" | \"passphrase\" | \"privateKey\"\n> {\n /** Resolved private key material. */\n privateKey?: SecretValue;\n /** Resolved private-key passphrase. */\n passphrase?: SecretValue;\n /** Resolved OpenSSH known_hosts material. */\n knownHosts?: SecretValue | SecretValue[];\n}\n\n/** TLS profile with certificate-bearing secret sources resolved. */\nexport interface ResolvedTlsProfile extends Omit<\n TlsProfile,\n \"ca\" | \"cert\" | \"key\" | \"passphrase\" | \"pfx\"\n> {\n /** Resolved certificate authority bundle. */\n ca?: SecretValue | SecretValue[];\n /** Resolved client certificate PEM. */\n cert?: SecretValue;\n /** Resolved client private key PEM. */\n key?: SecretValue;\n /** Resolved encrypted private-key or PFX/P12 passphrase. */\n passphrase?: SecretValue;\n /** Resolved PFX/P12 client certificate bundle. */\n pfx?: SecretValue;\n}\n\n/** Connection profile with username, password, TLS, and SSH material sources resolved. */\nexport interface ResolvedConnectionProfile extends Omit<\n ConnectionProfile,\n \"password\" | \"ssh\" | \"tls\" | \"username\"\n> {\n /** Resolved username or account identifier. */\n username?: SecretValue;\n /** Resolved password or credential bytes. */\n password?: SecretValue;\n /** Resolved TLS profile when certificate material is configured. */\n tls?: ResolvedTlsProfile;\n /** Resolved SSH profile when private-key material is configured. */\n ssh?: ResolvedSshProfile;\n}\n\n/**\n * Resolves credential and TLS material secret sources without mutating the original profile.\n *\n * @param profile - Profile containing optional secret sources.\n * @param options - Optional env and file-reader overrides.\n * @returns Profile copy with username, password, TLS material, and SSH material resolved when present.\n */\nexport async function resolveConnectionProfileSecrets(\n profile: ConnectionProfile,\n options: ResolveSecretOptions = {},\n): Promise<ResolvedConnectionProfile> {\n const { password, ssh, tls, username, ...rest } = profile;\n const resolved: ResolvedConnectionProfile = { ...rest };\n\n if (username !== undefined) {\n resolved.username = await resolveSecret(username, options);\n }\n\n if (password !== undefined) {\n resolved.password = await resolveSecret(password, options);\n }\n\n if (tls !== undefined) {\n resolved.tls = await resolveTlsProfile(tls, options);\n }\n\n if (ssh !== undefined) {\n resolved.ssh = await resolveSshProfile(ssh, options);\n }\n\n return resolved;\n}\n\n/**\n * Resolves SSH private-key, passphrase, and known-host source descriptors.\n *\n * @param profile - SSH profile containing optional secret-backed material.\n * @param options - Optional env and file-reader overrides.\n * @returns SSH profile copy with private-key material resolved.\n */\nasync function resolveSshProfile(\n profile: SshProfile,\n options: ResolveSecretOptions,\n): Promise<ResolvedSshProfile> {\n const { knownHosts, passphrase, privateKey, ...rest } = profile;\n const resolved: ResolvedSshProfile = { ...rest };\n\n if (privateKey !== undefined) resolved.privateKey = await resolveSecret(privateKey, options);\n if (passphrase !== undefined) resolved.passphrase = await resolveSecret(passphrase, options);\n if (knownHosts !== undefined)\n resolved.knownHosts = await resolveKnownHostsSource(knownHosts, options);\n\n return resolved;\n}\n\n/**\n * Resolves known_hosts material while preserving ordered source arrays.\n *\n * @param source - Single known_hosts source or source array.\n * @param options - Optional env and file-reader overrides.\n * @returns Resolved known_hosts value or value array.\n */\nasync function resolveKnownHostsSource(\n source: NonNullable<SshProfile[\"knownHosts\"]>,\n options: ResolveSecretOptions,\n): Promise<SecretValue | SecretValue[]> {\n if (Array.isArray(source)) {\n return Promise.all(source.map((item) => resolveSecret(item, options)));\n }\n\n return resolveSecret(source, options);\n}\n\n/**\n * Resolves TLS certificate, key, PFX, passphrase, and CA source descriptors.\n *\n * @param profile - TLS profile containing optional secret-backed material.\n * @param options - Optional env and file-reader overrides.\n * @returns TLS profile copy with material sources resolved.\n */\nasync function resolveTlsProfile(\n profile: TlsProfile,\n options: ResolveSecretOptions,\n): Promise<ResolvedTlsProfile> {\n const { ca, cert, key, passphrase, pfx, ...rest } = profile;\n const resolved: ResolvedTlsProfile = { ...rest };\n\n if (ca !== undefined) resolved.ca = await resolveTlsSecretSource(ca, options);\n if (cert !== undefined) resolved.cert = await resolveSecret(cert, options);\n if (key !== undefined) resolved.key = await resolveSecret(key, options);\n if (passphrase !== undefined) resolved.passphrase = await resolveSecret(passphrase, options);\n if (pfx !== undefined) resolved.pfx = await resolveSecret(pfx, options);\n\n return resolved;\n}\n\n/**\n * Resolves a TLS material source while preserving ordered CA bundle arrays.\n *\n * @param source - Single secret source or source array.\n * @param options - Optional env and file-reader overrides.\n * @returns Resolved secret value or resolved value array.\n */\nasync function resolveTlsSecretSource(\n source: TlsSecretSource,\n options: ResolveSecretOptions,\n): Promise<SecretValue | SecretValue[]> {\n if (Array.isArray(source)) {\n return Promise.all(source.map((item) => resolveSecret(item, options)));\n }\n\n return resolveSecret(source, options);\n}\n","/**\n * OAuth bearer-token helpers for cloud-drive and object-storage providers.\n *\n * Cloud providers in this SDK accept a bearer token via `profile.password`,\n * which is resolved as a {@link SecretSource}. Long-lived access tokens are\n * rare in OAuth flows; instead, applications hold a refresh token (or use a\n * client-credentials grant) and exchange it for short-lived access tokens.\n *\n * {@link createOAuthTokenSecretSource} adapts an arbitrary refresh callback\n * into a `SecretProvider` (one of the accepted `SecretSource` shapes) that\n * caches the most recent access token until its expiry approaches, then\n * silently re-runs the refresh callback. The cache honours an optional\n * `skewMs` margin so tokens are renewed before they expire on the wire.\n *\n * @module profiles/OAuthTokenSource\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { SecretProvider } from \"./SecretSource\";\n\n/** Token material returned by {@link OAuthRefreshCallback}. */\nexport interface OAuthAccessToken {\n /** Access token value. Required. */\n accessToken: string;\n /**\n * Lifetime in seconds (`expires_in`-style). When provided, the helper caches\n * the token until `now + (expiresInSeconds - skewSeconds)`.\n */\n expiresInSeconds?: number;\n /** Absolute expiry. Wins over `expiresInSeconds` when both are provided. */\n expiresAt?: Date;\n}\n\n/** Refresh callback invoked when no valid cached token is available. */\nexport type OAuthRefreshCallback = () => OAuthAccessToken | Promise<OAuthAccessToken>;\n\n/** Options accepted by {@link createOAuthTokenSecretSource}. */\nexport interface OAuthTokenSecretSourceOptions {\n /**\n * Safety margin (in milliseconds) subtracted from the token's expiry to\n * trigger a refresh before the wire deadline. Defaults to `60_000` (60s).\n */\n skewMs?: number;\n /** Clock used to evaluate expiry. Defaults to `Date.now`. */\n now?: () => number;\n}\n\ninterface CachedToken {\n accessToken: string;\n /** Absolute expiry in epoch milliseconds, or `undefined` for non-expiring tokens. */\n expiresAtMs: number | undefined;\n}\n\n/**\n * Builds a {@link SecretProvider} that exchanges a refresh callback for\n * cached, auto-renewing access tokens.\n *\n * The returned function can be passed directly as `profile.password` for any\n * provider that accepts bearer tokens (Dropbox, Google Drive, OneDrive, GCS,\n * Azure Blob via AAD).\n *\n * @example\n * ```ts\n * const password = createOAuthTokenSecretSource(async () => {\n * const res = await fetch(\"https://example.com/oauth/token\", { ... });\n * const body = (await res.json()) as { access_token: string; expires_in: number };\n * return { accessToken: body.access_token, expiresInSeconds: body.expires_in };\n * });\n * const session = await factory.create().connect({ host: \"\", protocol: \"ftp\", password });\n * ```\n */\nexport function createOAuthTokenSecretSource(\n refresh: OAuthRefreshCallback,\n options: OAuthTokenSecretSourceOptions = {},\n): SecretProvider {\n if (typeof refresh !== \"function\") {\n throw new ConfigurationError({\n message: \"createOAuthTokenSecretSource requires a refresh callback\",\n retryable: false,\n });\n }\n const skewMs = options.skewMs ?? 60_000;\n const now = options.now ?? (() => Date.now());\n if (skewMs < 0) {\n throw new ConfigurationError({\n message: \"OAuthTokenSecretSourceOptions.skewMs must be non-negative\",\n retryable: false,\n });\n }\n\n let cache: CachedToken | undefined;\n let pending: Promise<CachedToken> | undefined;\n\n const renew = async (): Promise<CachedToken> => {\n const result = await refresh();\n if (typeof result.accessToken !== \"string\" || result.accessToken === \"\") {\n throw new ConfigurationError({\n message: \"OAuth refresh callback returned an empty access token\",\n retryable: false,\n });\n }\n let expiresAtMs: number | undefined;\n if (result.expiresAt !== undefined) {\n const ts = result.expiresAt.getTime();\n if (Number.isFinite(ts)) expiresAtMs = ts;\n } else if (typeof result.expiresInSeconds === \"number\") {\n if (!Number.isFinite(result.expiresInSeconds) || result.expiresInSeconds <= 0) {\n throw new ConfigurationError({\n message: \"OAuth refresh callback returned a non-positive expiresInSeconds\",\n retryable: false,\n });\n }\n expiresAtMs = now() + result.expiresInSeconds * 1000;\n }\n const cached: CachedToken = { accessToken: result.accessToken, expiresAtMs };\n cache = cached;\n return cached;\n };\n\n return async () => {\n const current = cache;\n if (current !== undefined && isFresh(current, skewMs, now)) {\n return current.accessToken;\n }\n if (pending === undefined) {\n pending = renew().finally(() => {\n pending = undefined;\n });\n }\n const refreshed = await pending;\n return refreshed.accessToken;\n };\n}\n\nfunction isFresh(token: CachedToken, skewMs: number, now: () => number): boolean {\n if (token.expiresAtMs === undefined) return true;\n return token.expiresAtMs - skewMs > now();\n}\n","/**\n * OpenSSH `known_hosts` parsing helpers used by SFTP profile imports and host-key verification.\n *\n * @module profiles/importers/KnownHostsParser\n */\nimport { Buffer } from \"node:buffer\";\nimport { createHmac } from \"node:crypto\";\n\n/** Marker prefixing a known_hosts line (`@cert-authority` or `@revoked`). */\nexport type KnownHostsMarker = \"cert-authority\" | \"revoked\";\n\n/** Parsed entry from an OpenSSH `known_hosts` file. */\nexport interface KnownHostsEntry {\n /** Optional line marker (`@cert-authority` or `@revoked`). */\n marker?: KnownHostsMarker;\n /** Raw, comma-separated host patterns. Negation patterns retain their leading `!`. */\n hostPatterns: readonly string[];\n /** Hashed-salt component for `|1|salt|hash` entries. Mutually exclusive with plain patterns. */\n hashedSalt?: string;\n /** Hashed-hash component for `|1|salt|hash` entries. Mutually exclusive with plain patterns. */\n hashedHash?: string;\n /** SSH key algorithm identifier (e.g. `ssh-ed25519`, `ecdsa-sha2-nistp256`). */\n keyType: string;\n /** Base64-encoded public key blob. */\n keyBase64: string;\n /** Trailing comment text, if any. */\n comment?: string;\n /** Original line text without trailing newline. */\n raw: string;\n}\n\n/**\n * Parses OpenSSH `known_hosts` content into structured entries. Comment and blank lines are skipped.\n * Lines that cannot be parsed are silently dropped so callers can tolerate hand-edited files.\n *\n * @param text - Raw `known_hosts` file contents.\n * @returns Parsed entries in source order.\n */\nexport function parseKnownHosts(text: string): KnownHostsEntry[] {\n const entries: KnownHostsEntry[] = [];\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) continue;\n const entry = parseKnownHostsLine(line);\n if (entry !== undefined) entries.push(entry);\n }\n return entries;\n}\n\nfunction parseKnownHostsLine(line: string): KnownHostsEntry | undefined {\n const tokens = line.trim().split(/\\s+/);\n if (tokens.length < 3) return undefined;\n let index = 0;\n let marker: KnownHostsMarker | undefined;\n const first = tokens[index];\n if (first === \"@cert-authority\" || first === \"@revoked\") {\n marker = first === \"@cert-authority\" ? \"cert-authority\" : \"revoked\";\n index += 1;\n }\n const hostField = tokens[index];\n const keyType = tokens[index + 1];\n const keyBase64 = tokens[index + 2];\n if (hostField === undefined || keyType === undefined || keyBase64 === undefined) return undefined;\n const commentTokens = tokens.slice(index + 3);\n const comment = commentTokens.length > 0 ? commentTokens.join(\" \") : undefined;\n\n let hostPatterns: readonly string[] = [];\n let hashedSalt: string | undefined;\n let hashedHash: string | undefined;\n if (hostField.startsWith(\"|1|\")) {\n const parts = hostField.split(\"|\");\n if (parts.length < 4) return undefined;\n hashedSalt = parts[2];\n hashedHash = parts[3];\n } else {\n hostPatterns = hostField.split(\",\").filter((token) => token !== \"\");\n }\n\n const entry: KnownHostsEntry = {\n hostPatterns,\n keyBase64,\n keyType,\n raw: line,\n };\n if (marker !== undefined) entry.marker = marker;\n if (comment !== undefined) entry.comment = comment;\n if (hashedSalt !== undefined) entry.hashedSalt = hashedSalt;\n if (hashedHash !== undefined) entry.hashedHash = hashedHash;\n return entry;\n}\n\n/** Default OpenSSH port used when matching host patterns without an explicit `[host]:port`. */\nconst DEFAULT_SSH_PORT = 22;\n\n/**\n * Returns true when the given host (and optional port) matches the entry's host patterns.\n * Hashed entries use HMAC-SHA1 verification per OpenSSH semantics.\n *\n * @param entry - Parsed `known_hosts` entry to test.\n * @param host - Hostname or IP literal to match.\n * @param port - Optional connection port. Defaults to {@link DEFAULT_SSH_PORT}.\n * @returns Whether the entry matches and is not negated.\n */\nexport function matchKnownHostsEntry(\n entry: KnownHostsEntry,\n host: string,\n port: number = DEFAULT_SSH_PORT,\n): boolean {\n if (entry.hashedSalt !== undefined && entry.hashedHash !== undefined) {\n return matchesHashedEntry(entry.hashedSalt, entry.hashedHash, host, port);\n }\n let matched = false;\n for (const pattern of entry.hostPatterns) {\n if (pattern.startsWith(\"!\")) {\n const negated = pattern.slice(1);\n if (matchesPlainPattern(negated, host, port)) return false;\n continue;\n }\n if (matchesPlainPattern(pattern, host, port)) matched = true;\n }\n return matched;\n}\n\n/**\n * Filters parsed entries down to those that match the given host/port. Negations are honored.\n *\n * @param entries - Entries returned by {@link parseKnownHosts}.\n * @param host - Hostname or IP literal to match.\n * @param port - Optional connection port. Defaults to {@link DEFAULT_SSH_PORT}.\n * @returns Matching entries in source order.\n */\nexport function matchKnownHosts(\n entries: readonly KnownHostsEntry[],\n host: string,\n port: number = DEFAULT_SSH_PORT,\n): KnownHostsEntry[] {\n return entries.filter((entry) => matchKnownHostsEntry(entry, host, port));\n}\n\nfunction matchesPlainPattern(pattern: string, host: string, port: number): boolean {\n const portMatch = pattern.match(/^\\[(.+)\\]:(\\d+)$/);\n if (portMatch) {\n const [, hostPattern, portText] = portMatch;\n if (hostPattern === undefined || portText === undefined) return false;\n const expectedPort = Number.parseInt(portText, 10);\n if (Number.isNaN(expectedPort) || expectedPort !== port) return false;\n return globMatch(hostPattern, host);\n }\n return port === DEFAULT_SSH_PORT && globMatch(pattern, host);\n}\n\nfunction globMatch(pattern: string, value: string): boolean {\n const regex = new RegExp(\n `^${pattern\n .replace(/[.+^${}()|\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")}$`,\n \"i\",\n );\n return regex.test(value);\n}\n\nfunction matchesHashedEntry(salt: string, hash: string, host: string, port: number): boolean {\n const saltBuffer = Buffer.from(salt, \"base64\");\n if (saltBuffer.length === 0) return false;\n const candidates = port === DEFAULT_SSH_PORT ? [host] : [`[${host}]:${String(port)}`, host];\n for (const candidate of candidates) {\n const expected = createHmac(\"sha1\", saltBuffer).update(candidate).digest(\"base64\");\n if (expected === hash) return true;\n }\n return false;\n}\n","/**\n * OpenSSH `ssh_config` parser and {@link ConnectionProfile} importer.\n *\n * Supports the directives most commonly used by SFTP profiles: `HostName`, `Port`, `User`,\n * `IdentityFile`, `UserKnownHostsFile`, `ProxyJump`, `ConnectTimeout`, plus the SSH algorithm\n * controls (`KexAlgorithms`, `Ciphers`, `MACs`, `HostKeyAlgorithms`).\n *\n * @module profiles/importers/OpenSshConfigImporter\n */\nimport { ConfigurationError } from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Parsed `Host` block from an OpenSSH config file. */\nexport interface OpenSshConfigEntry {\n /** Host patterns declared on the `Host` line. */\n patterns: readonly string[];\n /** Lower-cased directive name to ordered values. Multi-valued directives (e.g. `IdentityFile`) preserve order. */\n options: Readonly<Record<string, readonly string[]>>;\n}\n\n/**\n * Parses OpenSSH `ssh_config` text into structured `Host` blocks.\n *\n * The parser is intentionally permissive: unknown directives are retained and `Match` blocks are skipped.\n *\n * @param text - Contents of the `ssh_config` file.\n * @returns Parsed `Host` entries in source order.\n */\nexport function parseOpenSshConfig(text: string): OpenSshConfigEntry[] {\n const entries: OpenSshConfigEntry[] = [];\n let current: { patterns: string[]; options: Record<string, string[]> } | undefined;\n let skipping = false;\n const lines = text.split(/\\r?\\n/);\n for (const rawLine of lines) {\n const line = rawLine.replace(/#.*$/, \"\").trim();\n if (line === \"\") continue;\n const match = line.match(/^([A-Za-z][A-Za-z0-9_-]*)\\s*=?\\s*(.*)$/);\n if (!match) continue;\n const [, keywordRaw, valueRaw] = match;\n if (keywordRaw === undefined || valueRaw === undefined) continue;\n const keyword = keywordRaw.toLowerCase();\n const value = valueRaw.trim();\n if (keyword === \"host\") {\n if (current !== undefined) entries.push(current);\n current = { options: {}, patterns: tokenizeValues(value) };\n skipping = false;\n continue;\n }\n if (keyword === \"match\") {\n if (current !== undefined) entries.push(current);\n current = undefined;\n skipping = true;\n continue;\n }\n if (skipping || current === undefined) continue;\n const values = tokenizeValues(value);\n const existing = current.options[keyword];\n if (existing === undefined) {\n current.options[keyword] = [...values];\n } else {\n existing.push(...values);\n }\n }\n if (current !== undefined) entries.push(current);\n return entries;\n}\n\nfunction tokenizeValues(value: string): string[] {\n if (value === \"\") return [];\n const tokens: string[] = [];\n const regex = /\"([^\"]*)\"|(\\S+)/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(value)) !== null) {\n tokens.push(match[1] ?? match[2] ?? \"\");\n }\n return tokens;\n}\n\n/**\n * Resolved set of directives for a given host alias. Values from later-declared blocks are\n * merged after earlier ones so wildcard fallbacks (e.g. `Host *`) only fill gaps.\n */\nexport interface ResolvedOpenSshHost {\n /** Host alias the lookup was performed against. */\n alias: string;\n /** Per-directive ordered values, keyed by lower-cased directive name. */\n options: Readonly<Record<string, readonly string[]>>;\n /** Source entries that contributed to the resolved set, in match order. */\n matched: readonly OpenSshConfigEntry[];\n}\n\n/**\n * Resolves the merged option set for an OpenSSH host alias.\n *\n * @param entries - Parsed entries from {@link parseOpenSshConfig}.\n * @param alias - Host alias to resolve.\n * @returns Merged directive set with the matching entries.\n */\nexport function resolveOpenSshHost(\n entries: readonly OpenSshConfigEntry[],\n alias: string,\n): ResolvedOpenSshHost {\n const merged: Record<string, string[]> = {};\n const matched: OpenSshConfigEntry[] = [];\n for (const entry of entries) {\n if (!entryMatchesAlias(entry, alias)) continue;\n matched.push(entry);\n for (const [key, values] of Object.entries(entry.options)) {\n if (merged[key] === undefined) merged[key] = [...values];\n }\n }\n return { alias, matched, options: merged };\n}\n\nfunction entryMatchesAlias(entry: OpenSshConfigEntry, alias: string): boolean {\n let matched = false;\n for (const pattern of entry.patterns) {\n if (pattern.startsWith(\"!\")) {\n if (globMatch(pattern.slice(1), alias)) return false;\n continue;\n }\n if (globMatch(pattern, alias)) matched = true;\n }\n return matched;\n}\n\nfunction globMatch(pattern: string, value: string): boolean {\n const regex = new RegExp(\n `^${pattern\n .replace(/[.+^${}()|\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")}$`,\n \"i\",\n );\n return regex.test(value);\n}\n\n/** Options accepted by {@link importOpenSshConfig}. */\nexport interface ImportOpenSshConfigOptions {\n /** Raw `ssh_config` text. Either this or {@link entries} must be provided. */\n text?: string;\n /** Pre-parsed entries from {@link parseOpenSshConfig}. */\n entries?: readonly OpenSshConfigEntry[];\n /** Host alias to import. */\n alias: string;\n}\n\n/** Result of {@link importOpenSshConfig}. */\nexport interface ImportOpenSshConfigResult {\n /** Generated SFTP connection profile. */\n profile: ConnectionProfile;\n /** Resolved directive set used to build the profile. */\n resolved: ResolvedOpenSshHost;\n /** Identity file paths declared in the config, in declaration order. */\n identityFiles: readonly string[];\n /** Optional `ProxyJump` value preserved from the config. */\n proxyJump?: string;\n}\n\n/**\n * Builds a {@link ConnectionProfile} for the given SSH alias from `ssh_config` text or pre-parsed entries.\n *\n * @param options - Import options.\n * @returns Importer result with the generated profile and supporting metadata.\n * @throws {@link ConfigurationError} When neither text nor entries is supplied.\n */\nexport function importOpenSshConfig(\n options: ImportOpenSshConfigOptions,\n): ImportOpenSshConfigResult {\n const { alias } = options;\n const entries =\n options.entries ?? (options.text !== undefined ? parseOpenSshConfig(options.text) : undefined);\n if (entries === undefined) {\n throw new ConfigurationError({\n code: \"openssh_config_input_missing\",\n message: \"importOpenSshConfig requires either text or pre-parsed entries.\",\n retryable: false,\n });\n }\n const resolved = resolveOpenSshHost(entries, alias);\n const optionsMap = resolved.options;\n\n const host = first(optionsMap, \"hostname\") ?? alias;\n const portText = first(optionsMap, \"port\");\n const port = portText !== undefined ? safeInt(portText) : undefined;\n const user = first(optionsMap, \"user\");\n const identityFiles = optionsMap[\"identityfile\"] ?? [];\n const knownHostsFiles = optionsMap[\"userknownhostsfile\"] ?? [];\n const connectTimeoutText = first(optionsMap, \"connecttimeout\");\n const proxyJump = first(optionsMap, \"proxyjump\");\n const kex = optionsMap[\"kexalgorithms\"] ?? [];\n const ciphers = optionsMap[\"ciphers\"] ?? [];\n const macs = optionsMap[\"macs\"] ?? [];\n const serverHostKey = optionsMap[\"hostkeyalgorithms\"] ?? [];\n\n const profile: ConnectionProfile = { host, provider: \"sftp\" };\n if (port !== undefined) profile.port = port;\n if (user !== undefined) profile.username = { value: user };\n if (connectTimeoutText !== undefined) {\n const seconds = safeInt(connectTimeoutText);\n if (seconds !== undefined) profile.timeoutMs = seconds * 1000;\n }\n\n const ssh: NonNullable<ConnectionProfile[\"ssh\"]> = {};\n if (identityFiles.length > 0) {\n const firstKey = identityFiles[0];\n if (firstKey !== undefined) ssh.privateKey = { path: expandHome(firstKey) };\n }\n if (knownHostsFiles.length > 0) {\n ssh.knownHosts = knownHostsFiles.map((path) => ({ path: expandHome(path) }));\n }\n const algorithms: Record<string, string[]> = {};\n if (kex.length > 0) algorithms[\"kex\"] = expandAlgorithms(kex);\n if (ciphers.length > 0) algorithms[\"cipher\"] = expandAlgorithms(ciphers);\n if (macs.length > 0) algorithms[\"hmac\"] = expandAlgorithms(macs);\n if (serverHostKey.length > 0) algorithms[\"serverHostKey\"] = expandAlgorithms(serverHostKey);\n if (Object.keys(algorithms).length > 0) {\n ssh.algorithms = algorithms;\n }\n if (Object.keys(ssh).length > 0) profile.ssh = ssh;\n\n const result: ImportOpenSshConfigResult = {\n identityFiles: identityFiles.map(expandHome),\n profile,\n resolved,\n };\n if (proxyJump !== undefined) result.proxyJump = proxyJump;\n return result;\n}\n\nfunction first(\n options: Readonly<Record<string, readonly string[]>>,\n key: string,\n): string | undefined {\n const values = options[key];\n return values !== undefined && values.length > 0 ? values[0] : undefined;\n}\n\nfunction safeInt(text: string): number | undefined {\n const value = Number.parseInt(text, 10);\n return Number.isFinite(value) ? value : undefined;\n}\n\nfunction expandHome(path: string): string {\n if (!path.startsWith(\"~\")) return path;\n const home = process.env[\"HOME\"] ?? process.env[\"USERPROFILE\"];\n if (home === undefined) return path;\n if (path === \"~\") return home;\n if (path.startsWith(\"~/\") || path.startsWith(\"~\\\\\")) return `${home}${path.slice(1)}`;\n return path;\n}\n\nfunction expandAlgorithms(values: readonly string[]): string[] {\n const out: string[] = [];\n for (const value of values) {\n for (const part of value.split(\",\")) {\n const trimmed = part.trim();\n if (trimmed !== \"\") out.push(trimmed);\n }\n }\n return out;\n}\n","/**\n * FileZilla `sitemanager.xml` importer.\n *\n * Walks FileZilla's nested folder/server hierarchy and emits {@link ConnectionProfile} entries\n * for each saved site. The importer ignores cloud providers and other entries it cannot map\n * to a {@link RemoteProtocol}.\n *\n * @module profiles/importers/FileZillaImporter\n */\nimport { Buffer } from \"node:buffer\";\nimport { ConfigurationError } from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Imported FileZilla site with the folder hierarchy that contained it. */\nexport interface FileZillaSite {\n /** Site display name. */\n name: string;\n /** Ordered folder names leading to the site (top-level first). Empty for root sites. */\n folder: readonly string[];\n /** Generated connection profile. */\n profile: ConnectionProfile;\n /** Encoded password value retained from the file, if any. */\n password?: string;\n /** Logon type code preserved from the file (`0`=anonymous, `1`=normal, etc.). */\n logonType?: number;\n}\n\n/** Result returned by {@link importFileZillaSites}. */\nexport interface ImportFileZillaSitesResult {\n /** Sites successfully mapped to a connection profile. */\n sites: readonly FileZillaSite[];\n /** Sites that were skipped because their protocol is not supported. */\n skipped: readonly { name: string; folder: readonly string[]; protocol?: number }[];\n}\n\n/**\n * Parses FileZilla `sitemanager.xml` text and returns generated profiles.\n *\n * @param xml - Contents of `sitemanager.xml`.\n * @returns Imported sites and any skipped entries.\n * @throws {@link ConfigurationError} When the XML root cannot be located.\n */\nexport function importFileZillaSites(xml: string): ImportFileZillaSitesResult {\n const events = tokenizeXml(xml);\n if (events.length === 0) {\n throw new ConfigurationError({\n code: \"filezilla_xml_empty\",\n message: \"FileZilla sitemanager XML is empty.\",\n retryable: false,\n });\n }\n const sites: FileZillaSite[] = [];\n const skipped: { name: string; folder: readonly string[]; protocol?: number }[] = [];\n const folderStack: string[] = [];\n const folderNamePending: boolean[] = [];\n let inServer = false;\n let serverFields: Record<string, string> = {};\n let serverPasswordEncoding: string | undefined;\n let activeTag: string | undefined;\n let captureFolderName = false;\n\n for (const event of events) {\n if (event.kind === \"open\") {\n if (event.name === \"Folder\") {\n folderStack.push(\"\");\n folderNamePending.push(true);\n continue;\n }\n if (event.name === \"Server\") {\n inServer = true;\n serverFields = {};\n serverPasswordEncoding = undefined;\n continue;\n }\n activeTag = event.name;\n if (event.name === \"Pass\" && inServer) {\n serverPasswordEncoding = event.attributes[\"encoding\"];\n }\n if (event.name === \"Name\" && !inServer && folderNamePending.length > 0) {\n captureFolderName = true;\n }\n continue;\n }\n if (event.kind === \"text\") {\n if (captureFolderName) {\n const top = folderStack.length - 1;\n if (top >= 0) folderStack[top] = event.text.trim();\n captureFolderName = false;\n continue;\n }\n if (inServer && activeTag !== undefined) {\n serverFields[activeTag] = (serverFields[activeTag] ?? \"\") + event.text;\n }\n continue;\n }\n if (event.kind === \"close\") {\n if (event.name === \"Folder\") {\n folderStack.pop();\n folderNamePending.pop();\n continue;\n }\n if (event.name === \"Server\") {\n const folder = folderStack.filter((segment) => segment !== \"\");\n const result = buildSiteFromFields(serverFields, serverPasswordEncoding);\n if (result.kind === \"site\") {\n sites.push({ ...result.site, folder });\n } else {\n skipped.push({\n folder,\n name: result.name,\n ...(result.protocol !== undefined ? { protocol: result.protocol } : {}),\n });\n }\n inServer = false;\n serverFields = {};\n serverPasswordEncoding = undefined;\n activeTag = undefined;\n continue;\n }\n if (activeTag === event.name) activeTag = undefined;\n }\n }\n return { sites, skipped };\n}\n\ninterface BuiltSite {\n kind: \"site\";\n site: Omit<FileZillaSite, \"folder\">;\n}\n\ninterface SkippedSite {\n kind: \"skipped\";\n name: string;\n protocol?: number;\n}\n\nfunction buildSiteFromFields(\n fields: Record<string, string>,\n passwordEncoding: string | undefined,\n): BuiltSite | SkippedSite {\n const name = (fields[\"Name\"] ?? fields[\"Host\"] ?? \"Untitled\").trim();\n const host = (fields[\"Host\"] ?? \"\").trim();\n if (host === \"\") return { kind: \"skipped\", name };\n const protocolText = fields[\"Protocol\"];\n const protocol = protocolText !== undefined ? Number.parseInt(protocolText.trim(), 10) : 0;\n const mapped = mapFileZillaProtocol(protocol);\n if (mapped === undefined) {\n return Number.isFinite(protocol)\n ? { kind: \"skipped\", name, protocol }\n : { kind: \"skipped\", name };\n }\n const profile: ConnectionProfile = { host, provider: mapped.provider };\n if (mapped.secure !== undefined) profile.secure = mapped.secure;\n const portText = fields[\"Port\"];\n if (portText !== undefined) {\n const port = Number.parseInt(portText.trim(), 10);\n if (Number.isFinite(port)) profile.port = port;\n }\n const user = fields[\"User\"]?.trim();\n if (user !== undefined && user !== \"\") profile.username = { value: user };\n\n let password: string | undefined;\n const rawPass = fields[\"Pass\"];\n if (rawPass !== undefined && rawPass !== \"\") {\n if (passwordEncoding === \"base64\") {\n password = Buffer.from(rawPass, \"base64\").toString(\"utf8\");\n } else {\n password = rawPass;\n }\n if (password !== undefined && password !== \"\") profile.password = { value: password };\n }\n\n const site: Omit<FileZillaSite, \"folder\"> = { name, profile };\n if (password !== undefined) site.password = password;\n const logonText = fields[\"Logontype\"];\n if (logonText !== undefined) {\n const logonType = Number.parseInt(logonText.trim(), 10);\n if (Number.isFinite(logonType)) site.logonType = logonType;\n }\n return { kind: \"site\", site };\n}\n\nfunction mapFileZillaProtocol(\n code: number,\n): { provider: NonNullable<ConnectionProfile[\"provider\"]>; secure?: boolean } | undefined {\n switch (code) {\n case 0:\n return { provider: \"ftp\" };\n case 1:\n return { provider: \"sftp\" };\n case 4:\n return { provider: \"ftps\", secure: true };\n case 5:\n return { provider: \"ftps\", secure: true };\n case 6:\n return { provider: \"ftp\", secure: false };\n default:\n return undefined;\n }\n}\n\ninterface XmlOpenEvent {\n kind: \"open\";\n name: string;\n attributes: Record<string, string>;\n selfClosing: boolean;\n}\ninterface XmlCloseEvent {\n kind: \"close\";\n name: string;\n}\ninterface XmlTextEvent {\n kind: \"text\";\n text: string;\n}\ntype XmlEvent = XmlOpenEvent | XmlCloseEvent | XmlTextEvent;\n\nfunction tokenizeXml(xml: string): XmlEvent[] {\n const events: XmlEvent[] = [];\n let index = 0;\n const length = xml.length;\n while (index < length) {\n const lt = xml.indexOf(\"<\", index);\n if (lt === -1) {\n const text = xml.slice(index);\n if (text.trim() !== \"\") events.push({ kind: \"text\", text: decodeEntities(text) });\n break;\n }\n if (lt > index) {\n const text = xml.slice(index, lt);\n if (text.trim() !== \"\") events.push({ kind: \"text\", text: decodeEntities(text) });\n }\n if (xml.startsWith(\"<!--\", lt)) {\n const end = xml.indexOf(\"-->\", lt + 4);\n index = end === -1 ? length : end + 3;\n continue;\n }\n if (xml.startsWith(\"<![CDATA[\", lt)) {\n const end = xml.indexOf(\"]]>\", lt + 9);\n const cdataEnd = end === -1 ? length : end;\n events.push({ kind: \"text\", text: xml.slice(lt + 9, cdataEnd) });\n index = end === -1 ? length : end + 3;\n continue;\n }\n if (xml[lt + 1] === \"?\" || xml[lt + 1] === \"!\") {\n const gt = xml.indexOf(\">\", lt + 1);\n index = gt === -1 ? length : gt + 1;\n continue;\n }\n const gt = xml.indexOf(\">\", lt + 1);\n if (gt === -1) break;\n const tagBody = xml.slice(lt + 1, gt);\n if (tagBody.startsWith(\"/\")) {\n events.push({ kind: \"close\", name: tagBody.slice(1).trim() });\n } else {\n const selfClosing = tagBody.endsWith(\"/\");\n const body = selfClosing ? tagBody.slice(0, -1) : tagBody;\n const { name, attributes } = parseTagBody(body.trim());\n events.push({ attributes, kind: \"open\", name, selfClosing });\n if (selfClosing) events.push({ kind: \"close\", name });\n }\n index = gt + 1;\n }\n return events;\n}\n\nfunction parseTagBody(body: string): { name: string; attributes: Record<string, string> } {\n const match = body.match(/^([A-Za-z_:][\\w:.-]*)\\s*(.*)$/);\n if (!match) return { attributes: {}, name: body };\n const name = match[1] ?? \"\";\n const rest = match[2] ?? \"\";\n const attributes: Record<string, string> = {};\n const attrRegex = /([A-Za-z_:][\\w:.-]*)\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/g;\n let attrMatch: RegExpExecArray | null;\n while ((attrMatch = attrRegex.exec(rest)) !== null) {\n const key = attrMatch[1];\n const value = attrMatch[3] ?? attrMatch[4] ?? \"\";\n if (key !== undefined) attributes[key] = decodeEntities(value);\n }\n return { attributes, name };\n}\n\nfunction decodeEntities(text: string): string {\n return text\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\");\n}\n","/**\n * WinSCP `WinSCP.ini` importer.\n *\n * Parses the INI session sections produced by WinSCP and emits {@link ConnectionProfile} entries.\n * Sessions whose `FSProtocol` cannot be mapped to a classic provider are skipped.\n *\n * @module profiles/importers/WinScpImporter\n */\nimport { ConfigurationError } from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Imported WinSCP session entry. */\nexport interface WinScpSession {\n /** Decoded session name (URL-decoded path under the `Sessions\\\\` namespace). */\n name: string;\n /** Hierarchical path segments derived from the session name (folders separated by `/`). */\n folder: readonly string[];\n /** Generated connection profile. */\n profile: ConnectionProfile;\n /** Raw FSProtocol code preserved from the file. */\n fsProtocol?: number;\n /** Raw Ftps code preserved from the file (`0`=none, `1`=implicit, `2`/`3`=explicit). */\n ftps?: number;\n}\n\n/** Result of {@link importWinScpSessions}. */\nexport interface ImportWinScpSessionsResult {\n /** Successfully mapped sessions. */\n sessions: readonly WinScpSession[];\n /** Sessions skipped because their protocol is not supported. */\n skipped: readonly { name: string; folder: readonly string[]; fsProtocol?: number }[];\n}\n\n/**\n * Parses WinSCP `WinSCP.ini` text and returns generated profiles.\n *\n * @param ini - Contents of the WinSCP configuration file.\n * @returns Imported sessions and any skipped entries.\n * @throws {@link ConfigurationError} When no session sections are found.\n */\nexport function importWinScpSessions(ini: string): ImportWinScpSessionsResult {\n const sections = parseIni(ini);\n const sessionSections = sections.filter((section) => section.name.startsWith(\"Sessions\\\\\"));\n if (sessionSections.length === 0) {\n throw new ConfigurationError({\n code: \"winscp_ini_no_sessions\",\n message: \"WinSCP INI does not contain any [Sessions\\\\...] sections.\",\n retryable: false,\n });\n }\n const sessions: WinScpSession[] = [];\n const skipped: { name: string; folder: readonly string[]; fsProtocol?: number }[] = [];\n for (const section of sessionSections) {\n const decodedPath = decodeSessionPath(section.name.slice(\"Sessions\\\\\".length));\n const segments = decodedPath.split(\"/\").filter((segment) => segment !== \"\");\n const name = segments[segments.length - 1] ?? decodedPath;\n const folder = segments.slice(0, -1);\n const built = buildSessionProfile(name, section.values);\n if (built.kind === \"session\") {\n sessions.push({ ...built.session, folder });\n } else {\n skipped.push({\n folder,\n name,\n ...(built.fsProtocol !== undefined ? { fsProtocol: built.fsProtocol } : {}),\n });\n }\n }\n return { sessions, skipped };\n}\n\ninterface BuiltSession {\n kind: \"session\";\n session: Omit<WinScpSession, \"folder\">;\n}\ninterface SkippedSession {\n kind: \"skipped\";\n fsProtocol?: number;\n}\n\nfunction buildSessionProfile(\n name: string,\n values: Readonly<Record<string, string>>,\n): BuiltSession | SkippedSession {\n const host = values[\"HostName\"]?.trim();\n if (host === undefined || host === \"\") return { kind: \"skipped\" };\n const fsProtocolText = values[\"FSProtocol\"];\n const fsProtocol = fsProtocolText !== undefined ? Number.parseInt(fsProtocolText, 10) : 1;\n const ftpsText = values[\"Ftps\"];\n const ftps = ftpsText !== undefined ? Number.parseInt(ftpsText, 10) : 0;\n const mapped = mapWinScpProtocol(fsProtocol, ftps);\n if (mapped === undefined) {\n return Number.isFinite(fsProtocol) ? { fsProtocol, kind: \"skipped\" } : { kind: \"skipped\" };\n }\n\n const profile: ConnectionProfile = { host, provider: mapped.provider };\n if (mapped.secure !== undefined) profile.secure = mapped.secure;\n const portText = values[\"PortNumber\"];\n if (portText !== undefined) {\n const port = Number.parseInt(portText, 10);\n if (Number.isFinite(port)) profile.port = port;\n }\n const user = values[\"UserName\"]?.trim();\n if (user !== undefined && user !== \"\") profile.username = { value: user };\n\n if (mapped.provider === \"sftp\") {\n const ssh: NonNullable<ConnectionProfile[\"ssh\"]> = {};\n const keyPath = values[\"PublicKeyFile\"]?.trim();\n if (keyPath !== undefined && keyPath !== \"\") ssh.privateKey = { path: keyPath };\n if (Object.keys(ssh).length > 0) profile.ssh = ssh;\n }\n\n const session: Omit<WinScpSession, \"folder\"> = { name, profile };\n if (Number.isFinite(fsProtocol)) session.fsProtocol = fsProtocol;\n if (Number.isFinite(ftps) && ftps !== 0) session.ftps = ftps;\n return { kind: \"session\", session };\n}\n\nfunction mapWinScpProtocol(\n fsProtocol: number,\n ftps: number,\n): { provider: NonNullable<ConnectionProfile[\"provider\"]>; secure?: boolean } | undefined {\n switch (fsProtocol) {\n case 0:\n case 1:\n case 2:\n return { provider: \"sftp\" };\n case 5:\n return ftps === 0 ? { provider: \"ftp\" } : { provider: \"ftps\", secure: ftps === 1 };\n default:\n return undefined;\n }\n}\n\ninterface IniSection {\n name: string;\n values: Record<string, string>;\n}\n\nfunction parseIni(text: string): IniSection[] {\n const sections: IniSection[] = [];\n let current: IniSection | undefined;\n const lines = text.split(/\\r?\\n/);\n for (const rawLine of lines) {\n const line = rawLine.replace(/^\\s*[#;].*$/, \"\").trim();\n if (line === \"\") continue;\n const sectionMatch = line.match(/^\\[(.+)\\]$/);\n if (sectionMatch && sectionMatch[1] !== undefined) {\n current = { name: sectionMatch[1], values: {} };\n sections.push(current);\n continue;\n }\n if (current === undefined) continue;\n const eq = line.indexOf(\"=\");\n if (eq === -1) continue;\n const key = line.slice(0, eq).trim();\n const value = line.slice(eq + 1).trim();\n if (key !== \"\") current.values[key] = value;\n }\n return sections;\n}\n\nfunction decodeSessionPath(name: string): string {\n // WinSCP encodes special characters in session names (e.g. spaces as %20, backslashes as %5C).\n try {\n return decodeURIComponent(name);\n } catch {\n return name;\n }\n}\n","/**\n * Protocol error factory helpers.\n *\n * This module translates raw FTP status replies into typed ZeroTransfer errors so\n * adapters can keep protocol parsing separate from application-facing failures.\n *\n * @module errors/errorFactory\n */\nimport {\n AuthenticationError,\n ConnectionError,\n PathAlreadyExistsError,\n PathNotFoundError,\n PermissionDeniedError,\n ProtocolError,\n TransferError,\n type SpecializedErrorDetails,\n type ZeroTransferError,\n} from \"./ZeroTransferError\";\nimport type { RemoteProtocol } from \"../types/public\";\n\n/**\n * Input used to map an FTP reply into a structured ZeroTransfer error.\n */\nexport interface FtpReplyErrorInput {\n /** Numeric FTP response code returned by the server. */\n ftpCode: number;\n /** Server-provided response message. */\n message: string;\n /** FTP command that produced the response, if known. */\n command?: string;\n /** Remote path involved in the command, if any. */\n path?: string;\n /** Protocol variant used by the adapter. */\n protocol?: RemoteProtocol;\n /** Original lower-level failure that accompanied the reply. */\n cause?: unknown;\n}\n\n/**\n * Maps an FTP reply into the closest typed ZeroTransfer error.\n *\n * @param input - FTP code, message, and optional operation context.\n * @returns A structured error subclass with stable code and retryability metadata.\n */\nexport function errorFromFtpReply(input: FtpReplyErrorInput): ZeroTransferError {\n const details: SpecializedErrorDetails = {\n ftpCode: input.ftpCode,\n message: input.message,\n protocol: input.protocol ?? \"ftp\",\n retryable: false,\n };\n\n if (input.command !== undefined) details.command = input.command;\n if (input.path !== undefined) details.path = input.path;\n if (input.cause !== undefined) details.cause = input.cause;\n\n if (input.ftpCode === 530) {\n return new AuthenticationError(details);\n }\n\n if (input.ftpCode === 421) {\n return new ConnectionError({\n ...details,\n retryable: true,\n });\n }\n\n if (input.ftpCode === 550) {\n return mapFtp550(details);\n }\n\n if ([450, 451, 452].includes(input.ftpCode)) {\n return new TransferError({\n ...details,\n retryable: true,\n });\n }\n\n if (input.ftpCode >= 400 && input.ftpCode < 500) {\n return new ConnectionError({\n ...details,\n retryable: true,\n });\n }\n\n return new ProtocolError(details);\n}\n\n/**\n * Maps ambiguous FTP 550 replies to the most specific path or permission error.\n *\n * @param details - Shared error details derived from the original reply.\n * @returns A typed path or permission error.\n */\nfunction mapFtp550(details: SpecializedErrorDetails): ZeroTransferError {\n const lowerMessage = details.message.toLowerCase();\n\n if (lowerMessage.includes(\"already\") || lowerMessage.includes(\"exists\")) {\n return new PathAlreadyExistsError(details);\n }\n\n if (\n lowerMessage.includes(\"not found\") ||\n lowerMessage.includes(\"no such\") ||\n lowerMessage.includes(\"unavailable\")\n ) {\n return new PathNotFoundError(details);\n }\n\n return new PermissionDeniedError(details);\n}\n","/**\n * Transfer plan and dry-run primitives.\n *\n * @module transfers/TransferPlan\n */\nimport type { TransferEndpoint, TransferJob, TransferOperation } from \"./TransferJob\";\n\n/** Non-executing plan action used to explain an intentionally skipped step. */\nexport type TransferPlanAction = TransferOperation | \"skip\";\n\n/** Step inside a transfer plan. */\nexport interface TransferPlanStep {\n /** Stable step identifier within the plan. */\n id: string;\n /** Action the step would perform. */\n action: TransferPlanAction;\n /** Source endpoint when the action reads data. */\n source?: TransferEndpoint;\n /** Destination endpoint when the action writes data. */\n destination?: TransferEndpoint;\n /** Expected bytes affected by the step when known. */\n expectedBytes?: number;\n /** Whether this step may remove or replace data. */\n destructive?: boolean;\n /** Human-readable reason for planned or skipped work. */\n reason?: string;\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Input used to create a transfer plan. */\nexport interface TransferPlanInput {\n /** Stable plan identifier. */\n id: string;\n /** Planned steps in execution order. */\n steps: TransferPlanStep[];\n /** Whether the plan is informational only. Defaults to `true`. */\n dryRun?: boolean;\n /** Clock used for deterministic tests. Defaults to `new Date()`. */\n now?: () => Date;\n /** Non-fatal plan warnings. */\n warnings?: string[];\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Provider-neutral transfer plan. */\nexport interface TransferPlan {\n /** Stable plan identifier. */\n id: string;\n /** Whether this plan should be treated as a dry run. */\n dryRun: boolean;\n /** Time the plan was created. */\n createdAt: Date;\n /** Planned steps in execution order. */\n steps: TransferPlanStep[];\n /** Non-fatal plan warnings. */\n warnings: string[];\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Summary of a transfer plan. */\nexport interface TransferPlanSummary {\n /** Total number of steps. */\n totalSteps: number;\n /** Number of executable steps. */\n executableSteps: number;\n /** Number of skipped steps. */\n skippedSteps: number;\n /** Number of destructive steps. */\n destructiveSteps: number;\n /** Sum of expected bytes for steps that provide sizes. */\n totalExpectedBytes: number;\n /** Counts grouped by action. */\n actions: Record<string, number>;\n}\n\n/** Creates a transfer plan from dry-run planning input. */\nexport function createTransferPlan(input: TransferPlanInput): TransferPlan {\n const plan: TransferPlan = {\n createdAt: input.now?.() ?? new Date(),\n dryRun: input.dryRun ?? true,\n id: input.id,\n steps: input.steps.map(clonePlanStep),\n warnings: [...(input.warnings ?? [])],\n };\n\n if (input.metadata !== undefined) {\n plan.metadata = { ...input.metadata };\n }\n\n return plan;\n}\n\n/** Summarizes a transfer plan for diagnostics, previews, and tests. */\nexport function summarizeTransferPlan(plan: TransferPlan): TransferPlanSummary {\n const actions: Record<string, number> = {};\n let destructiveSteps = 0;\n let executableSteps = 0;\n let skippedSteps = 0;\n let totalExpectedBytes = 0;\n\n for (const step of plan.steps) {\n actions[step.action] = (actions[step.action] ?? 0) + 1;\n destructiveSteps += step.destructive === true ? 1 : 0;\n skippedSteps += step.action === \"skip\" ? 1 : 0;\n executableSteps += step.action === \"skip\" ? 0 : 1;\n totalExpectedBytes += step.expectedBytes ?? 0;\n }\n\n return {\n actions,\n destructiveSteps,\n executableSteps,\n skippedSteps,\n totalExpectedBytes,\n totalSteps: plan.steps.length,\n };\n}\n\n/** Converts executable plan steps into transfer jobs while preserving order. */\nexport function createTransferJobsFromPlan(plan: TransferPlan): TransferJob[] {\n return plan.steps.flatMap((step) => {\n if (step.action === \"skip\") {\n return [];\n }\n\n const job: TransferJob = {\n id: `${plan.id}:${step.id}`,\n operation: step.action,\n };\n\n if (step.source !== undefined) job.source = cloneEndpoint(step.source);\n if (step.destination !== undefined) job.destination = cloneEndpoint(step.destination);\n if (step.expectedBytes !== undefined) job.totalBytes = step.expectedBytes;\n if (step.metadata !== undefined) job.metadata = { ...step.metadata };\n\n return [job];\n });\n}\n\nfunction clonePlanStep(step: TransferPlanStep): TransferPlanStep {\n const clone: TransferPlanStep = {\n action: step.action,\n id: step.id,\n };\n\n if (step.source !== undefined) clone.source = cloneEndpoint(step.source);\n if (step.destination !== undefined) clone.destination = cloneEndpoint(step.destination);\n if (step.expectedBytes !== undefined) clone.expectedBytes = step.expectedBytes;\n if (step.destructive !== undefined) clone.destructive = step.destructive;\n if (step.reason !== undefined) clone.reason = step.reason;\n if (step.metadata !== undefined) clone.metadata = { ...step.metadata };\n\n return clone;\n}\n\nfunction cloneEndpoint(endpoint: TransferEndpoint): TransferEndpoint {\n const clone: TransferEndpoint = { path: endpoint.path };\n\n if (endpoint.provider !== undefined) {\n clone.provider = endpoint.provider;\n }\n\n return clone;\n}\n","/**\n * Transfer queue primitives built on top of {@link TransferEngine}.\n *\n * @module transfers/TransferQueue\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferProgressEvent } from \"../types/public\";\nimport {\n TransferEngine,\n type TransferEngineExecuteOptions,\n type TransferExecutor,\n type TransferRetryPolicy,\n} from \"./TransferEngine\";\nimport type {\n TransferBandwidthLimit,\n TransferJob,\n TransferReceipt,\n TransferTimeoutPolicy,\n} from \"./TransferJob\";\n\n/** Queue item lifecycle state. */\nexport type TransferQueueItemStatus = \"queued\" | \"running\" | \"completed\" | \"failed\" | \"canceled\";\n\n/** Resolver used when jobs do not provide an executor at enqueue time. */\nexport type TransferQueueExecutorResolver = (job: TransferJob) => TransferExecutor;\n\n/** Options used to create a transfer queue. */\nexport interface TransferQueueOptions {\n /** Transfer engine used to execute queued jobs. Defaults to a new engine. */\n engine?: TransferEngine;\n /** Maximum jobs to execute at the same time. Defaults to `1`. */\n concurrency?: number;\n /** Default executor used for jobs that do not provide one directly. */\n executor?: TransferExecutor;\n /** Dynamic executor resolver used when no per-job executor or default executor exists. */\n resolveExecutor?: TransferQueueExecutorResolver;\n /** Retry policy passed to engine executions. */\n retry?: TransferRetryPolicy;\n /** Timeout policy passed to engine executions. */\n timeout?: TransferTimeoutPolicy;\n /** Optional throughput limit shape passed to transfer executors. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Progress observer shared across queued jobs. */\n onProgress?: (event: TransferProgressEvent) => void;\n /** Completion observer for successful jobs. */\n onReceipt?: (receipt: TransferReceipt) => void;\n /** Failure observer for failed jobs. */\n onError?: (item: TransferQueueItem, error: unknown) => void;\n}\n\n/** Options used when draining a queue. */\nexport interface TransferQueueRunOptions {\n /** Abort signal used to cancel running jobs during this drain. */\n signal?: AbortSignal;\n /** Retry policy override for this drain. */\n retry?: TransferRetryPolicy;\n /** Timeout policy override for this drain. */\n timeout?: TransferTimeoutPolicy;\n /** Bandwidth limit override for this drain. */\n bandwidthLimit?: TransferBandwidthLimit;\n /** Progress observer override for this drain. */\n onProgress?: (event: TransferProgressEvent) => void;\n}\n\n/** Enqueued transfer job state. */\nexport interface TransferQueueItem {\n /** Queued job identifier. */\n id: string;\n /** Original transfer job. */\n job: TransferJob;\n /** Current queue status. */\n status: TransferQueueItemStatus;\n /** Successful transfer receipt when completed. */\n receipt?: TransferReceipt;\n /** Failure or cancellation reason when available. */\n error?: unknown;\n}\n\ninterface InternalTransferQueueItem extends TransferQueueItem {\n controller: AbortController;\n executor?: TransferExecutor;\n}\n\n/** Summary returned after a queue drain. */\nexport interface TransferQueueSummary {\n /** Number of items currently known to the queue. */\n total: number;\n /** Number of successfully completed jobs. */\n completed: number;\n /** Number of failed jobs. */\n failed: number;\n /** Number of canceled jobs. */\n canceled: number;\n /** Number of jobs still queued because the queue was paused. */\n queued: number;\n /** Number of jobs currently running. */\n running: number;\n /** Successful receipts in queue order. */\n receipts: TransferReceipt[];\n /** Failed queue items in queue order. */\n failures: TransferQueueItem[];\n}\n\n/** Minimal transfer queue with concurrency, pause/resume, cancellation, and drain summaries. */\nexport class TransferQueue {\n private readonly engine: TransferEngine;\n private readonly items: InternalTransferQueueItem[] = [];\n private readonly defaultExecutor: TransferExecutor | undefined;\n private readonly resolveExecutor: TransferQueueExecutorResolver | undefined;\n private readonly retry: TransferRetryPolicy | undefined;\n private readonly timeout: TransferTimeoutPolicy | undefined;\n private readonly bandwidthLimit: TransferBandwidthLimit | undefined;\n private readonly onProgress: ((event: TransferProgressEvent) => void) | undefined;\n private readonly onReceipt: ((receipt: TransferReceipt) => void) | undefined;\n private readonly onError: ((item: TransferQueueItem, error: unknown) => void) | undefined;\n private concurrency: number;\n private paused = false;\n\n /**\n * Creates a transfer queue.\n *\n * @param options - Queue engine, concurrency, executor, and observer options.\n */\n constructor(options: TransferQueueOptions = {}) {\n this.engine = options.engine ?? new TransferEngine();\n this.concurrency = normalizeConcurrency(options.concurrency);\n this.defaultExecutor = options.executor;\n this.resolveExecutor = options.resolveExecutor;\n this.retry = options.retry;\n this.timeout = options.timeout;\n this.bandwidthLimit = options.bandwidthLimit;\n this.onProgress = options.onProgress;\n this.onReceipt = options.onReceipt;\n this.onError = options.onError;\n }\n\n /** Adds a transfer job to the queue. */\n add(job: TransferJob, executor?: TransferExecutor): TransferQueueItem {\n if (this.items.some((item) => item.id === job.id)) {\n throw new ConfigurationError({\n details: { jobId: job.id },\n message: `Transfer queue already contains job: ${job.id}`,\n retryable: false,\n });\n }\n\n const item: InternalTransferQueueItem = {\n controller: new AbortController(),\n id: job.id,\n job: cloneTransferJob(job),\n status: \"queued\",\n };\n\n if (executor !== undefined) {\n item.executor = executor;\n }\n\n this.items.push(item);\n return toPublicItem(item);\n }\n\n /** Pauses dispatch of new queued jobs. Running jobs are allowed to finish. */\n pause(): void {\n this.paused = true;\n }\n\n /** Resumes dispatch of queued jobs on the next `run()` call. */\n resume(): void {\n this.paused = false;\n }\n\n /** Updates queue concurrency for subsequent drains. */\n setConcurrency(concurrency: number): void {\n this.concurrency = normalizeConcurrency(concurrency);\n }\n\n /** Cancels a queued or running job. */\n cancel(jobId: string): boolean {\n const item = this.items.find((candidate) => candidate.id === jobId);\n\n if (\n item === undefined ||\n item.status === \"completed\" ||\n item.status === \"failed\" ||\n item.status === \"canceled\"\n ) {\n return false;\n }\n\n item.controller.abort();\n\n if (item.status === \"queued\") {\n item.status = \"canceled\";\n }\n\n return true;\n }\n\n /** Returns a queued item snapshot by id. */\n get(jobId: string): TransferQueueItem | undefined {\n const item = this.items.find((candidate) => candidate.id === jobId);\n return item === undefined ? undefined : toPublicItem(item);\n }\n\n /** Lists queue item snapshots in insertion order. */\n list(): TransferQueueItem[] {\n return this.items.map(toPublicItem);\n }\n\n /** Drains currently queued jobs until complete, failed, canceled, or paused. */\n async run(options: TransferQueueRunOptions = {}): Promise<TransferQueueSummary> {\n const workerCount = Math.max(1, Math.min(this.concurrency, this.countDispatchableItems()));\n const workers = Array.from({ length: workerCount }, () => this.runWorker(options));\n\n await Promise.all(workers);\n return this.summarize();\n }\n\n /** Returns a queue summary without executing more work. */\n summarize(): TransferQueueSummary {\n const publicItems = this.items.map(toPublicItem);\n\n return {\n canceled: publicItems.filter((item) => item.status === \"canceled\").length,\n completed: publicItems.filter((item) => item.status === \"completed\").length,\n failed: publicItems.filter((item) => item.status === \"failed\").length,\n failures: publicItems.filter((item) => item.status === \"failed\"),\n queued: publicItems.filter((item) => item.status === \"queued\").length,\n receipts: publicItems\n .filter(\n (item): item is TransferQueueItem & { receipt: TransferReceipt } =>\n item.receipt !== undefined,\n )\n .map((item) => item.receipt),\n running: publicItems.filter((item) => item.status === \"running\").length,\n total: publicItems.length,\n };\n }\n\n private async runWorker(options: TransferQueueRunOptions): Promise<void> {\n for (;;) {\n const item = this.nextQueuedItem();\n\n if (item === undefined) {\n return;\n }\n\n await this.runItem(item, options);\n }\n }\n\n private nextQueuedItem(): InternalTransferQueueItem | undefined {\n if (this.paused) {\n return undefined;\n }\n\n const item = this.items.find((candidate) => candidate.status === \"queued\");\n\n if (item !== undefined) {\n item.status = item.controller.signal.aborted ? \"canceled\" : \"running\";\n }\n\n return item?.status === \"running\" ? item : undefined;\n }\n\n private async runItem(\n item: InternalTransferQueueItem,\n options: TransferQueueRunOptions,\n ): Promise<void> {\n const abortListener = createAbortForwarder(options.signal, item.controller);\n\n try {\n const executeOptions: TransferEngineExecuteOptions = {\n signal: item.controller.signal,\n };\n const onProgress = options.onProgress ?? this.onProgress;\n const retry = options.retry ?? this.retry;\n const timeout = options.timeout ?? this.timeout;\n const bandwidthLimit = options.bandwidthLimit ?? this.bandwidthLimit;\n\n if (onProgress !== undefined) {\n executeOptions.onProgress = onProgress;\n }\n\n if (retry !== undefined) {\n executeOptions.retry = retry;\n }\n\n if (timeout !== undefined) {\n executeOptions.timeout = timeout;\n }\n\n if (bandwidthLimit !== undefined) {\n executeOptions.bandwidthLimit = bandwidthLimit;\n }\n\n const receipt = await this.engine.execute(\n item.job,\n this.requireExecutor(item),\n executeOptions,\n );\n\n item.receipt = receipt;\n item.status = \"completed\";\n this.onReceipt?.(receipt);\n } catch (error) {\n item.error = error;\n item.status = item.controller.signal.aborted ? \"canceled\" : \"failed\";\n\n if (item.status === \"failed\") {\n this.onError?.(toPublicItem(item), error);\n }\n } finally {\n abortListener.dispose();\n }\n }\n\n private requireExecutor(item: InternalTransferQueueItem): TransferExecutor {\n const executor = item.executor ?? this.defaultExecutor ?? this.resolveExecutor?.(item.job);\n\n if (executor === undefined) {\n throw new ConfigurationError({\n details: { jobId: item.job.id },\n message: `Transfer queue job has no executor: ${item.job.id}`,\n retryable: false,\n });\n }\n\n return executor;\n }\n\n private countDispatchableItems(): number {\n return this.items.filter((item) => item.status === \"queued\" && !item.controller.signal.aborted)\n .length;\n }\n}\n\nfunction normalizeConcurrency(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value)) {\n return 1;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nfunction createAbortForwarder(\n source: AbortSignal | undefined,\n target: AbortController,\n): { dispose(): void } {\n if (source === undefined) {\n return { dispose: () => undefined };\n }\n\n const abort = (): void => target.abort();\n\n if (source.aborted) {\n abort();\n return { dispose: () => undefined };\n }\n\n source.addEventListener(\"abort\", abort, { once: true });\n\n return {\n dispose: () => source.removeEventListener(\"abort\", abort),\n };\n}\n\nfunction toPublicItem(item: InternalTransferQueueItem): TransferQueueItem {\n const snapshot: TransferQueueItem = {\n id: item.id,\n job: cloneTransferJob(item.job),\n status: item.status,\n };\n\n if (item.receipt !== undefined) snapshot.receipt = item.receipt;\n if (item.error !== undefined) snapshot.error = item.error;\n\n return snapshot;\n}\n\nfunction cloneTransferJob(job: TransferJob): TransferJob {\n const clone: TransferJob = {\n id: job.id,\n operation: job.operation,\n };\n\n if (job.source !== undefined) clone.source = { ...job.source };\n if (job.destination !== undefined) clone.destination = { ...job.destination };\n if (job.totalBytes !== undefined) clone.totalBytes = job.totalBytes;\n if (job.resumed !== undefined) clone.resumed = job.resumed;\n if (job.metadata !== undefined) clone.metadata = { ...job.metadata };\n\n return clone;\n}\n","/**\n * Browser-friendly directory navigation helpers for file-manager UIs.\n *\n * Wraps a {@link RemoteFileSystem} with stateful current-directory tracking,\n * breadcrumb generation, and pure sort/filter utilities so consumers can render\n * directory views without re-implementing common navigation glue.\n *\n * @module sync/createRemoteBrowser\n */\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry } from \"../types/public\";\nimport { normalizeRemotePath } from \"../utils/path\";\n\n/** Sort key supported by {@link sortRemoteEntries}. */\nexport type RemoteEntrySortKey = \"name\" | \"size\" | \"modifiedAt\" | \"type\";\n\n/** Sort direction supported by {@link sortRemoteEntries}. */\nexport type RemoteEntrySortOrder = \"asc\" | \"desc\";\n\n/** Crumb describing one segment in the current path. */\nexport interface RemoteBreadcrumb {\n /** Display name. `\"\"` is replaced with `\"/\"` for the root crumb. */\n name: string;\n /** Absolute path the crumb resolves to. */\n path: string;\n}\n\n/** Filter callback applied to a directory listing. */\nexport type RemoteBrowserFilter = (entry: RemoteEntry) => boolean;\n\n/** Options accepted by {@link createRemoteBrowser}. */\nexport interface CreateRemoteBrowserOptions {\n /** Remote file system to browse. */\n fs: RemoteFileSystem;\n /** Initial path. Defaults to `\"/\"`. */\n initialPath?: string;\n /** Sort key applied to listings. Defaults to `\"name\"`. */\n sortKey?: RemoteEntrySortKey;\n /** Sort order applied to listings. Defaults to `\"asc\"`. */\n sortOrder?: RemoteEntrySortOrder;\n /** Whether dotfile entries (names starting with `.`) are included. Defaults to `true`. */\n showHidden?: boolean;\n /** Optional filter applied after sort/hidden filtering. */\n filter?: RemoteBrowserFilter;\n}\n\n/** Snapshot returned by browser navigation methods. */\nexport interface RemoteBrowserSnapshot {\n /** Current absolute path. */\n path: string;\n /** Directory entries after sorting and filtering. */\n entries: RemoteEntry[];\n /** Breadcrumb trail leading from `/` to {@link path}. */\n breadcrumbs: RemoteBreadcrumb[];\n}\n\n/** Stateful directory browser returned by {@link createRemoteBrowser}. */\nexport interface RemoteBrowser {\n /** Current absolute path. */\n readonly path: string;\n /** Last loaded sorted/filtered entries. */\n readonly entries: readonly RemoteEntry[];\n /** Reload the current directory and return the latest snapshot. */\n refresh(): Promise<RemoteBrowserSnapshot>;\n /** Navigate to the supplied absolute or relative path. */\n navigate(target: string): Promise<RemoteBrowserSnapshot>;\n /** Descend into the supplied directory entry. Throws when the entry is not a directory. */\n open(entry: RemoteEntry): Promise<RemoteBrowserSnapshot>;\n /** Move to the parent directory; no-op when already at the root. */\n up(): Promise<RemoteBrowserSnapshot>;\n /** Compute breadcrumbs for the current path without re-listing. */\n breadcrumbs(): RemoteBreadcrumb[];\n /** Update the sort key. The next refresh re-sorts the cached entries. */\n setSort(key: RemoteEntrySortKey, order?: RemoteEntrySortOrder): void;\n /** Toggle hidden-entry visibility. The next refresh re-applies the filter. */\n setShowHidden(showHidden: boolean): void;\n}\n\n/**\n * Returns the parent directory of a remote path, or `\"/\"` for root inputs.\n *\n * @param input - Remote path to inspect.\n * @returns The parent path normalized to an absolute form.\n */\nexport function parentRemotePath(input: string): string {\n const normalized = normalizeRemotePath(input);\n if (normalized === \"/\") return \"/\";\n const parts = normalized.split(\"/\").filter(Boolean);\n parts.pop();\n if (parts.length === 0) return \"/\";\n return `/${parts.join(\"/\")}`;\n}\n\n/**\n * Builds breadcrumbs from `/` down to the supplied path.\n *\n * @param input - Absolute remote path.\n * @returns Ordered crumbs starting with the root.\n */\nexport function buildRemoteBreadcrumbs(input: string): RemoteBreadcrumb[] {\n const normalized = normalizeRemotePath(input);\n const crumbs: RemoteBreadcrumb[] = [{ name: \"/\", path: \"/\" }];\n if (normalized === \"/\") return crumbs;\n\n const parts = normalized.split(\"/\").filter(Boolean);\n let cursor = \"\";\n for (const part of parts) {\n cursor += `/${part}`;\n crumbs.push({ name: part, path: cursor });\n }\n return crumbs;\n}\n\n/**\n * Returns a copy of the supplied entries sorted by the requested key. Directories\n * are grouped before files within ascending sorts, matching common file-manager UX.\n *\n * @param entries - Entries to sort.\n * @param key - Sort key.\n * @param order - Sort order.\n * @returns Sorted copy of the entries.\n */\nexport function sortRemoteEntries(\n entries: readonly RemoteEntry[],\n key: RemoteEntrySortKey = \"name\",\n order: RemoteEntrySortOrder = \"asc\",\n): RemoteEntry[] {\n const direction = order === \"asc\" ? 1 : -1;\n return [...entries].sort((left, right) => {\n if (key !== \"type\") {\n const leftIsDir = left.type === \"directory\";\n const rightIsDir = right.type === \"directory\";\n if (leftIsDir !== rightIsDir) return leftIsDir ? -1 : 1;\n }\n\n const compared = compareEntriesByKey(left, right, key);\n if (compared !== 0) return compared * direction;\n return compareNames(left, right);\n });\n}\n\n/**\n * Filters entries using the optional predicate plus an optional hidden-file rule.\n *\n * @param entries - Entries to filter.\n * @param options - Filtering controls.\n * @returns Entries matching the supplied rules.\n */\nexport function filterRemoteEntries(\n entries: readonly RemoteEntry[],\n options: { filter?: RemoteBrowserFilter; showHidden?: boolean } = {},\n): RemoteEntry[] {\n const showHidden = options.showHidden ?? true;\n const filter = options.filter;\n return entries.filter((entry) => {\n if (!showHidden && entry.name.startsWith(\".\")) return false;\n if (filter !== undefined && !filter(entry)) return false;\n return true;\n });\n}\n\n/**\n * Creates a stateful directory browser around a remote file system.\n *\n * The returned browser caches the most recent listing and applies sort/filter\n * settings on each refresh. Navigation methods return a snapshot so UI layers can\n * render synchronously without re-reading state.\n *\n * @param options - Browser configuration.\n * @returns Stateful browser bound to the supplied file system.\n */\nexport function createRemoteBrowser(options: CreateRemoteBrowserOptions): RemoteBrowser {\n const { fs } = options;\n let currentPath = normalizeRemotePath(options.initialPath ?? \"/\");\n let cachedEntries: RemoteEntry[] = [];\n let sortKey: RemoteEntrySortKey = options.sortKey ?? \"name\";\n let sortOrder: RemoteEntrySortOrder = options.sortOrder ?? \"asc\";\n let showHidden = options.showHidden ?? true;\n const filter = options.filter;\n\n async function loadCurrent(): Promise<RemoteBrowserSnapshot> {\n const raw = await fs.list(currentPath);\n const projected = projectEntries(raw);\n cachedEntries = projected;\n return snapshot();\n }\n\n function projectEntries(raw: readonly RemoteEntry[]): RemoteEntry[] {\n const filterOptions: { filter?: RemoteBrowserFilter; showHidden: boolean } = { showHidden };\n if (filter !== undefined) filterOptions.filter = filter;\n const filtered = filterRemoteEntries(raw, filterOptions);\n return sortRemoteEntries(filtered, sortKey, sortOrder);\n }\n\n function snapshot(): RemoteBrowserSnapshot {\n return {\n breadcrumbs: buildRemoteBreadcrumbs(currentPath),\n entries: [...cachedEntries],\n path: currentPath,\n };\n }\n\n async function navigate(target: string): Promise<RemoteBrowserSnapshot> {\n currentPath = resolveTarget(currentPath, target);\n return loadCurrent();\n }\n\n async function open(entry: RemoteEntry): Promise<RemoteBrowserSnapshot> {\n if (entry.type !== \"directory\") {\n throw new TypeError(`Cannot open non-directory entry \"${entry.path}\" (type: ${entry.type})`);\n }\n return navigate(entry.path);\n }\n\n return {\n breadcrumbs: () => buildRemoteBreadcrumbs(currentPath),\n get entries() {\n return cachedEntries;\n },\n navigate,\n open,\n get path() {\n return currentPath;\n },\n refresh: loadCurrent,\n setShowHidden(value: boolean) {\n showHidden = value;\n },\n setSort(key: RemoteEntrySortKey, order: RemoteEntrySortOrder = sortOrder) {\n sortKey = key;\n sortOrder = order;\n },\n up: () => navigate(parentRemotePath(currentPath)),\n };\n}\n\nfunction resolveTarget(currentPath: string, target: string): string {\n if (target.startsWith(\"/\")) return normalizeRemotePath(target);\n if (target === \"\" || target === \".\") return currentPath;\n if (target === \"..\") return parentRemotePath(currentPath);\n const base = currentPath === \"/\" ? \"\" : currentPath;\n return normalizeRemotePath(`${base}/${target}`);\n}\n\nfunction compareEntriesByKey(\n left: RemoteEntry,\n right: RemoteEntry,\n key: RemoteEntrySortKey,\n): number {\n switch (key) {\n case \"size\":\n return (left.size ?? 0) - (right.size ?? 0);\n case \"modifiedAt\": {\n const leftTime = left.modifiedAt?.getTime() ?? 0;\n const rightTime = right.modifiedAt?.getTime() ?? 0;\n return leftTime - rightTime;\n }\n case \"type\":\n return left.type.localeCompare(right.type);\n case \"name\":\n default:\n return compareNames(left, right);\n }\n}\n\nfunction compareNames(left: RemoteEntry, right: RemoteEntry): number {\n return left.name.localeCompare(right.name, undefined, { numeric: true, sensitivity: \"base\" });\n}\n","/**\n * Sync planning primitives that build a {@link TransferPlan} from a remote-tree diff.\n *\n * @module sync/createSyncPlan\n */\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport {\n createTransferPlan,\n type TransferPlan,\n type TransferPlanStep,\n} from \"../transfers/TransferPlan\";\nimport { joinRemotePath, normalizeRemotePath } from \"../utils/path\";\nimport type { RemoteTreeDiff, RemoteTreeDiffEntry } from \"./diffRemoteTrees\";\n\n/** Sync direction used by {@link createSyncPlan}. */\nexport type SyncDirection = \"source-to-destination\" | \"destination-to-source\";\n\n/** How {@link createSyncPlan} reacts to entries that exist only on the destination. */\nexport type SyncDeletePolicy =\n /** Never delete destination entries that are missing on the source. */\n | \"never\"\n /** Plan destination deletions when running source-to-destination sync. */\n | \"mirror\"\n /** Plan destination deletions only when paired with a same-path file on the source. */\n | \"replace-only\";\n\n/** How {@link createSyncPlan} reacts to entries flagged as modified on both sides. */\nexport type SyncConflictPolicy =\n /** Overwrite the destination with the source. */\n | \"overwrite\"\n /** Overwrite the source with the destination. */\n | \"prefer-destination\"\n /** Skip conflicting entries with a `skip` step. */\n | \"skip\"\n /** Fail planning with a {@link ConfigurationError} when a conflict is encountered. */\n | \"error\";\n\n/** Endpoint shape supplied to {@link createSyncPlan}. */\nexport interface SyncEndpointInput {\n /** Provider that owns the endpoint when known. */\n provider?: ProviderId;\n /** Root path on the provider being synced. */\n rootPath: string;\n}\n\n/** Options accepted by {@link createSyncPlan}. */\nexport interface CreateSyncPlanOptions {\n /** Stable plan identifier. */\n id: string;\n /** Diff produced by {@link diffRemoteTrees} or an equivalent source. */\n diff: RemoteTreeDiff;\n /** Source-side endpoint that produced the diff. */\n source: SyncEndpointInput;\n /** Destination-side endpoint that produced the diff. */\n destination: SyncEndpointInput;\n /** Sync direction. Defaults to `\"source-to-destination\"`. */\n direction?: SyncDirection;\n /** Delete policy. Defaults to `\"never\"`. */\n deletePolicy?: SyncDeletePolicy;\n /** Conflict policy. Defaults to `\"overwrite\"`. */\n conflictPolicy?: SyncConflictPolicy;\n /** Whether to plan upload/download steps for directories. Defaults to `false`. */\n includeDirectoryActions?: boolean;\n /** Whether the plan is informational only. Defaults to `true`. */\n dryRun?: boolean;\n /** Clock used for deterministic tests. Defaults to `new Date()`. */\n now?: () => Date;\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Builds a {@link TransferPlan} that reconciles two remote subtrees.\n *\n * Plan steps are derived from a {@link RemoteTreeDiff}; the function does not perform\n * any I/O. Direction, delete policy, and conflict policy control which entries\n * become executable transfers and which become `skip` steps.\n *\n * @param options - Inputs and policies that shape the plan.\n * @returns Transfer plan ready for `createTransferJobsFromPlan` or queue execution.\n * @throws {@link ConfigurationError} When `conflictPolicy: \"error\"` encounters a conflict.\n */\nexport function createSyncPlan(options: CreateSyncPlanOptions): TransferPlan {\n const direction: SyncDirection = options.direction ?? \"source-to-destination\";\n const deletePolicy: SyncDeletePolicy = options.deletePolicy ?? \"never\";\n const conflictPolicy: SyncConflictPolicy = options.conflictPolicy ?? \"overwrite\";\n const includeDirectoryActions = options.includeDirectoryActions ?? false;\n const sourceRoot = normalizeRemotePath(options.source.rootPath);\n const destinationRoot = normalizeRemotePath(options.destination.rootPath);\n const warnings: string[] = [];\n const steps: TransferPlanStep[] = [];\n\n for (const entry of options.diff.entries) {\n const context: PlanEntryContext = {\n conflictPolicy,\n deletePolicy,\n destinationRoot,\n direction,\n entry,\n includeDirectoryActions,\n sourceRoot,\n warnings,\n };\n if (options.source.provider !== undefined) context.sourceProvider = options.source.provider;\n if (options.destination.provider !== undefined) {\n context.destinationProvider = options.destination.provider;\n }\n const step = planEntry(context);\n\n if (step !== undefined) steps.push(step);\n }\n\n const planInput: Parameters<typeof createTransferPlan>[0] = {\n id: options.id,\n steps,\n warnings,\n };\n if (options.dryRun !== undefined) planInput.dryRun = options.dryRun;\n if (options.now !== undefined) planInput.now = options.now;\n if (options.metadata !== undefined) planInput.metadata = options.metadata;\n\n return createTransferPlan(planInput);\n}\n\ninterface PlanEntryContext {\n conflictPolicy: SyncConflictPolicy;\n deletePolicy: SyncDeletePolicy;\n destinationProvider?: ProviderId;\n destinationRoot: string;\n direction: SyncDirection;\n entry: RemoteTreeDiffEntry;\n includeDirectoryActions: boolean;\n sourceProvider?: ProviderId;\n sourceRoot: string;\n warnings: string[];\n}\n\nfunction planEntry(context: PlanEntryContext): TransferPlanStep | undefined {\n const { entry } = context;\n const isDirectory = isDirectoryEntry(entry);\n\n if (isDirectory && !context.includeDirectoryActions) {\n return undefined;\n }\n\n switch (entry.status) {\n case \"added\":\n return planAdded(context);\n case \"removed\":\n return planRemoved(context);\n case \"modified\":\n return planModified(context);\n case \"unchanged\":\n return planUnchanged(context);\n default:\n // Unreachable when callers pass a normalized RemoteTreeDiff.\n return undefined;\n }\n}\n\nfunction planAdded(context: PlanEntryContext): TransferPlanStep {\n if (context.direction === \"source-to-destination\") {\n return createCopyStep(context, \"source\", \"destination\", expectedBytesFor(context.entry));\n }\n\n // Direction is destination-to-source: source-only entries should be deleted.\n if (context.deletePolicy === \"never\") {\n return createSkipStep(context, \"Source-only entry preserved by delete policy\");\n }\n\n return createDeleteStep(context, \"source\");\n}\n\nfunction planRemoved(context: PlanEntryContext): TransferPlanStep {\n if (context.direction === \"destination-to-source\") {\n return createCopyStep(context, \"destination\", \"source\", expectedBytesFor(context.entry));\n }\n\n // Direction is source-to-destination: destination-only entries.\n if (context.deletePolicy === \"never\") {\n return createSkipStep(context, \"Destination-only entry preserved by delete policy\");\n }\n\n if (context.deletePolicy === \"replace-only\") {\n return createSkipStep(\n context,\n \"Destination-only entry preserved (no source replacement available)\",\n );\n }\n\n return createDeleteStep(context, \"destination\");\n}\n\nfunction planModified(context: PlanEntryContext): TransferPlanStep {\n switch (context.conflictPolicy) {\n case \"overwrite\":\n return createCopyStep(context, \"source\", \"destination\", expectedBytesFor(context.entry), {\n destructive: true,\n });\n case \"prefer-destination\":\n return createCopyStep(context, \"destination\", \"source\", expectedBytesFor(context.entry), {\n destructive: true,\n });\n case \"skip\":\n return createSkipStep(context, `Conflict skipped: ${context.entry.reasons.join(\",\")}`);\n case \"error\":\n throw new ConfigurationError({\n details: {\n path: context.entry.path,\n reasons: context.entry.reasons,\n },\n message: `Sync plan conflict at ${context.entry.path} with reasons: ${context.entry.reasons.join(\", \")}`,\n retryable: false,\n });\n default:\n return createSkipStep(context, \"Conflict skipped\");\n }\n}\n\nfunction planUnchanged(context: PlanEntryContext): TransferPlanStep {\n return createSkipStep(context, \"Entry already in sync\");\n}\n\nfunction createCopyStep(\n context: PlanEntryContext,\n fromSide: \"source\" | \"destination\",\n toSide: \"source\" | \"destination\",\n expectedBytes: number | undefined,\n overrides: Partial<TransferPlanStep> = {},\n): TransferPlanStep {\n const step: TransferPlanStep = {\n action: \"copy\",\n id: makeStepId(context.entry, `copy-${fromSide}-to-${toSide}`),\n reason: describeReasons(context.entry, `Copy ${fromSide} to ${toSide}`),\n };\n\n step.source = endpointFor(context, fromSide);\n step.destination = endpointFor(context, toSide);\n if (expectedBytes !== undefined) step.expectedBytes = expectedBytes;\n if (overrides.destructive === true) step.destructive = true;\n if (overrides.metadata !== undefined) step.metadata = { ...overrides.metadata };\n\n return step;\n}\n\nfunction createDeleteStep(\n context: PlanEntryContext,\n side: \"source\" | \"destination\",\n): TransferPlanStep {\n return {\n action: \"delete\",\n destination: endpointFor(context, side),\n destructive: true,\n id: makeStepId(context.entry, `delete-${side}`),\n reason: `Delete ${side} entry not present on the other side`,\n };\n}\n\nfunction createSkipStep(context: PlanEntryContext, reason: string): TransferPlanStep {\n return {\n action: \"skip\",\n id: makeStepId(context.entry, \"skip\"),\n reason,\n source: endpointFor(context, \"source\"),\n destination: endpointFor(context, \"destination\"),\n };\n}\n\nfunction endpointFor(\n context: PlanEntryContext,\n side: \"source\" | \"destination\",\n): NonNullable<TransferPlanStep[\"source\"]> {\n const root = side === \"source\" ? context.sourceRoot : context.destinationRoot;\n const provider = side === \"source\" ? context.sourceProvider : context.destinationProvider;\n const endpoint: NonNullable<TransferPlanStep[\"source\"]> = {\n path: joinRootAndRelative(root, context.entry.path),\n };\n if (provider !== undefined) endpoint.provider = provider;\n return endpoint;\n}\n\nfunction joinRootAndRelative(rootPath: string, relativePath: string): string {\n if (rootPath === \"/\") return relativePath;\n if (relativePath === \"/\") return rootPath;\n return joinRemotePath(rootPath, relativePath);\n}\n\nfunction makeStepId(entry: RemoteTreeDiffEntry, suffix: string): string {\n return `${entry.path}#${suffix}`;\n}\n\nfunction describeReasons(entry: RemoteTreeDiffEntry, prefix: string): string {\n if (entry.reasons.length === 0) return prefix;\n return `${prefix} (${entry.reasons.join(\",\")})`;\n}\n\nfunction expectedBytesFor(entry: RemoteTreeDiffEntry): number | undefined {\n return entry.source?.size ?? entry.destination?.size;\n}\n\nfunction isDirectoryEntry(entry: RemoteTreeDiffEntry): boolean {\n return entry.source?.type === \"directory\" || entry.destination?.type === \"directory\";\n}\n","/**\n * Atomic deploy planning helpers.\n *\n * Produces a structured plan that stages a release under `<liveRoot>/<releasesDir>/<releaseId>`,\n * activates it via rename or symlink swap, and prunes older releases beyond a retain count.\n *\n * The plan is provider-neutral and execution-free: callers wire the upload {@link TransferPlan}\n * through the transfer engine and execute the activate/prune steps using their provider's\n * filesystem mutation primitives (rename, symlink, delete).\n *\n * @module sync/createAtomicDeployPlan\n */\nimport type { ProviderId } from \"../core/ProviderId\";\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { TransferPlan } from \"../transfers/TransferPlan\";\nimport { joinRemotePath, normalizeRemotePath } from \"../utils/path\";\nimport { createSyncPlan, type SyncEndpointInput } from \"./createSyncPlan\";\nimport type { RemoteTreeDiff } from \"./diffRemoteTrees\";\n\n/** Activation strategy used to swap a staged release into place. */\nexport type AtomicDeployStrategy =\n /** Rename `<liveRoot>` aside, then rename the staging path to `<liveRoot>`. */\n | \"rename\"\n /** Update a symlink at `<liveRoot>` to point at the staging path. */\n | \"symlink\";\n\n/** Operation kind for an activation step. */\nexport type AtomicDeployActivateOperation = \"rename\" | \"symlink\" | \"delete\";\n\n/** Kind of activation step described by the plan. */\nexport interface AtomicDeployActivateStep {\n /** Stable identifier within the activation list. */\n id: string;\n /** Operation the step would perform. */\n operation: AtomicDeployActivateOperation;\n /** Source path the operation reads or moves from. */\n fromPath?: string;\n /** Destination path the operation writes to. */\n toPath: string;\n /** Provider identifier that owns the affected paths when known. */\n provider?: ProviderId;\n /** Whether the step replaces or removes data. */\n destructive?: boolean;\n /** Human-readable description for previews and logs. */\n reason: string;\n}\n\n/** Pruning step describing an old release directory marked for deletion. */\nexport interface AtomicDeployPruneStep {\n /** Stable identifier within the prune list. */\n id: string;\n /** Absolute release directory path to delete. */\n path: string;\n /** Provider identifier that owns the path when known. */\n provider?: ProviderId;\n /** Reason the release was selected for pruning. */\n reason: string;\n}\n\n/** Result returned by {@link createAtomicDeployPlan}. */\nexport interface AtomicDeployPlan {\n /** Stable plan identifier. */\n id: string;\n /** Release identifier embedded into the staging path. */\n releaseId: string;\n /** Activation strategy chosen for the swap. */\n strategy: AtomicDeployStrategy;\n /** Provider identifier for the live destination when known. */\n provider?: ProviderId;\n /** Live target path the release activates onto. */\n livePath: string;\n /** Staging directory the upload populates. */\n stagingPath: string;\n /** Releases root directory under which staging and prior releases live. */\n releasesRoot: string;\n /** Optional backup path used by the rename strategy. */\n backupPath?: string;\n /** Upload plan that populates the staging directory. */\n uploadPlan: TransferPlan;\n /** Activation steps that swap staging into the live path. */\n activate: AtomicDeployActivateStep[];\n /** Prune steps that remove older releases beyond {@link retain}. */\n prune: AtomicDeployPruneStep[];\n /** Number of releases to retain (including the new release). */\n retain: number;\n /** Time the plan was created. */\n createdAt: Date;\n /** Non-fatal plan warnings. */\n warnings: string[];\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\n/** Options accepted by {@link createAtomicDeployPlan}. */\nexport interface CreateAtomicDeployPlanOptions {\n /** Stable plan identifier. */\n id: string;\n /** Diff describing source vs. staging contents (typically diffed against an empty staging directory). */\n diff: RemoteTreeDiff;\n /** Source-side endpoint feeding the release. */\n source: SyncEndpointInput;\n /** Live destination endpoint the release activates onto. */\n destination: SyncEndpointInput;\n /** Activation strategy. Defaults to `\"rename\"`. */\n strategy?: AtomicDeployStrategy;\n /** Release identifier. Defaults to a timestamp derived from {@link now}. */\n releaseId?: string;\n /** Releases directory name under the destination root. Defaults to `\".releases\"`. */\n releasesDirectory?: string;\n /** Number of releases to retain after the new release, including the new one. Defaults to `3`. */\n retain?: number;\n /** Existing release directory paths under the releases root that may be pruned. */\n existingReleases?: string[];\n /** Whether the plan is informational only. Defaults to `true`. */\n dryRun?: boolean;\n /** Clock used for deterministic tests. Defaults to `new Date()`. */\n now?: () => Date;\n /** Caller-defined metadata retained for diagnostics. */\n metadata?: Record<string, unknown>;\n}\n\nconst DEFAULT_RELEASES_DIRECTORY = \".releases\";\nconst DEFAULT_RETAIN = 3;\n\n/**\n * Builds an {@link AtomicDeployPlan} that stages a release, swaps it live, and prunes old releases.\n *\n * @param options - Inputs and policies that shape the deploy.\n * @returns Structured deploy plan ready for execution by the calling host.\n * @throws {@link ConfigurationError} When `retain` is less than `1` or the destination root is empty.\n */\nexport function createAtomicDeployPlan(options: CreateAtomicDeployPlanOptions): AtomicDeployPlan {\n const retain = options.retain ?? DEFAULT_RETAIN;\n if (retain < 1) {\n throw new ConfigurationError({\n details: { retain },\n message: \"Atomic deploy retain count must be at least 1\",\n retryable: false,\n });\n }\n\n const livePath = normalizeRemotePath(options.destination.rootPath);\n if (livePath === \"/\") {\n throw new ConfigurationError({\n message: \"Atomic deploy destination rootPath must not be the filesystem root\",\n retryable: false,\n });\n }\n\n const strategy: AtomicDeployStrategy = options.strategy ?? \"rename\";\n const now = options.now?.() ?? new Date();\n const releaseId = options.releaseId ?? defaultReleaseId(now);\n const releasesRoot = joinRemotePath(\n livePath,\n options.releasesDirectory ?? DEFAULT_RELEASES_DIRECTORY,\n );\n const stagingPath = joinRemotePath(releasesRoot, releaseId);\n const backupPath =\n strategy === \"rename\" ? joinRemotePath(releasesRoot, `${releaseId}.previous`) : undefined;\n const provider = options.destination.provider ?? options.source.provider;\n const warnings: string[] = [];\n\n const uploadPlan = createSyncPlan({\n conflictPolicy: \"overwrite\",\n deletePolicy: \"never\",\n destination: {\n ...(options.destination.provider !== undefined\n ? { provider: options.destination.provider }\n : {}),\n rootPath: stagingPath,\n },\n diff: options.diff,\n direction: \"source-to-destination\",\n dryRun: options.dryRun ?? true,\n id: `${options.id}/upload`,\n includeDirectoryActions: false,\n ...(options.now !== undefined ? { now: options.now } : {}),\n source: options.source,\n });\n\n const activate = buildActivateSteps({\n backupPath,\n livePath,\n planId: options.id,\n provider,\n stagingPath,\n strategy,\n });\n\n const prune = buildPruneSteps({\n existingReleases: options.existingReleases ?? [],\n planId: options.id,\n provider,\n releaseId,\n releasesRoot,\n retain,\n });\n\n const plan: AtomicDeployPlan = {\n activate,\n createdAt: now,\n id: options.id,\n livePath,\n prune,\n releaseId,\n releasesRoot,\n retain,\n stagingPath,\n strategy,\n uploadPlan,\n warnings,\n };\n if (provider !== undefined) plan.provider = provider;\n if (backupPath !== undefined) plan.backupPath = backupPath;\n if (options.metadata !== undefined) plan.metadata = { ...options.metadata };\n return plan;\n}\n\ninterface BuildActivateContext {\n backupPath: string | undefined;\n livePath: string;\n planId: string;\n provider: ProviderId | undefined;\n stagingPath: string;\n strategy: AtomicDeployStrategy;\n}\n\nfunction buildActivateSteps(context: BuildActivateContext): AtomicDeployActivateStep[] {\n if (context.strategy === \"symlink\") {\n const step: AtomicDeployActivateStep = {\n destructive: true,\n fromPath: context.stagingPath,\n id: `${context.planId}/activate/symlink`,\n operation: \"symlink\",\n reason: \"Update live symlink to point at the new release\",\n toPath: context.livePath,\n };\n if (context.provider !== undefined) step.provider = context.provider;\n return [step];\n }\n\n const steps: AtomicDeployActivateStep[] = [];\n if (context.backupPath !== undefined) {\n const backup: AtomicDeployActivateStep = {\n destructive: true,\n fromPath: context.livePath,\n id: `${context.planId}/activate/backup`,\n operation: \"rename\",\n reason: \"Rename current live path aside as a release backup\",\n toPath: context.backupPath,\n };\n if (context.provider !== undefined) backup.provider = context.provider;\n steps.push(backup);\n }\n\n const promote: AtomicDeployActivateStep = {\n destructive: true,\n fromPath: context.stagingPath,\n id: `${context.planId}/activate/promote`,\n operation: \"rename\",\n reason: \"Promote the staged release to the live path\",\n toPath: context.livePath,\n };\n if (context.provider !== undefined) promote.provider = context.provider;\n steps.push(promote);\n return steps;\n}\n\ninterface BuildPruneContext {\n existingReleases: string[];\n planId: string;\n provider: ProviderId | undefined;\n releaseId: string;\n releasesRoot: string;\n retain: number;\n}\n\nfunction buildPruneSteps(context: BuildPruneContext): AtomicDeployPruneStep[] {\n if (context.existingReleases.length === 0) return [];\n\n const normalizedRoot = normalizeRemotePath(context.releasesRoot);\n const newReleasePath = joinRemotePath(normalizedRoot, context.releaseId);\n const candidates = [...new Set(context.existingReleases.map((path) => normalizeRemotePath(path)))]\n .filter((path) => path !== newReleasePath)\n .sort();\n\n const releasesToRetain = Math.max(0, context.retain - 1);\n if (candidates.length <= releasesToRetain) return [];\n\n const toPrune = candidates.slice(0, candidates.length - releasesToRetain);\n return toPrune.map((path, index) => {\n const step: AtomicDeployPruneStep = {\n id: `${context.planId}/prune/${index}`,\n path,\n reason: \"Older release exceeds retain window\",\n };\n if (context.provider !== undefined) step.provider = context.provider;\n return step;\n });\n}\n\nfunction defaultReleaseId(now: Date): string {\n // ISO timestamp with characters safe for filesystem path segments (no `:` or `.`).\n return now.toISOString().replace(/[:.]/g, \"-\");\n}\n","/**\n * Recursive remote-tree traversal helpers.\n *\n * @module sync/walkRemoteTree\n */\nimport { AbortError } from \"../errors/ZeroTransferError\";\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry } from \"../types/public\";\nimport { joinRemotePath, normalizeRemotePath } from \"../utils/path\";\n\n/** Filter callback applied to each visited entry. Returning `false` skips the entry. */\nexport type RemoteTreeFilter = (entry: RemoteEntry) => boolean;\n\n/** Options accepted by {@link walkRemoteTree}. */\nexport interface WalkRemoteTreeOptions {\n /** Whether to descend into subdirectories. Defaults to `true`. */\n recursive?: boolean;\n /** Maximum traversal depth. `0` walks only the root listing. Unbounded by default. */\n maxDepth?: number;\n /** Whether to include directory entries in the output. Defaults to `true`. */\n includeDirectories?: boolean;\n /** Whether to include file entries in the output. Defaults to `true`. */\n includeFiles?: boolean;\n /** Whether to follow symlinks during traversal. Defaults to `false`. */\n followSymlinks?: boolean;\n /** Optional filter applied before yielding and before descending into directories. */\n filter?: RemoteTreeFilter;\n /** Optional abort signal that interrupts traversal between listings. */\n signal?: AbortSignal;\n}\n\n/** Walk record yielded by {@link walkRemoteTree}. */\nexport interface RemoteTreeEntry {\n /** Visited remote entry. */\n entry: RemoteEntry;\n /** Zero-based depth relative to the traversal root. */\n depth: number;\n /** Normalized parent directory path. */\n parentPath: string;\n}\n\n/**\n * Walks a remote file system depth-first, yielding entries in a stable order.\n *\n * Listings are sorted by entry path within each directory so output is deterministic\n * across providers. Errors thrown by `fs.list()` propagate; callers can supply a\n * filter to skip directories that should not be traversed.\n *\n * @param fs - Remote file system used for listings.\n * @param rootPath - Root directory to walk.\n * @param options - Optional traversal controls.\n * @returns Async generator emitting {@link RemoteTreeEntry} records.\n * @throws {@link AbortError} When the supplied abort signal is cancelled mid-walk.\n */\nexport async function* walkRemoteTree(\n fs: RemoteFileSystem,\n rootPath: string,\n options: WalkRemoteTreeOptions = {},\n): AsyncGenerator<RemoteTreeEntry> {\n const recursive = options.recursive ?? true;\n const includeDirectories = options.includeDirectories ?? true;\n const includeFiles = options.includeFiles ?? true;\n const followSymlinks = options.followSymlinks ?? false;\n const root = normalizeRemotePath(rootPath);\n const normalized: NormalizedWalkOptions = {\n followSymlinks,\n includeDirectories,\n includeFiles,\n recursive,\n };\n if (options.maxDepth !== undefined) normalized.maxDepth = options.maxDepth;\n if (options.filter !== undefined) normalized.filter = options.filter;\n if (options.signal !== undefined) normalized.signal = options.signal;\n\n yield* walkDirectory(fs, root, 0, normalized);\n}\n\ninterface NormalizedWalkOptions {\n recursive: boolean;\n includeDirectories: boolean;\n includeFiles: boolean;\n followSymlinks: boolean;\n maxDepth?: number;\n filter?: RemoteTreeFilter;\n signal?: AbortSignal;\n}\n\nasync function* walkDirectory(\n fs: RemoteFileSystem,\n path: string,\n depth: number,\n options: NormalizedWalkOptions,\n): AsyncGenerator<RemoteTreeEntry> {\n throwIfAborted(options.signal);\n const entries = await fs.list(path);\n const sorted = [...entries].sort(compareEntries);\n\n for (const entry of sorted) {\n if (options.filter !== undefined && !options.filter(entry)) continue;\n\n if (matchesEntryKind(entry, options.includeDirectories, options.includeFiles)) {\n yield { depth, entry, parentPath: path };\n }\n\n if (\n options.recursive &&\n canDescendInto(entry, options.followSymlinks) &&\n (options.maxDepth === undefined || depth < options.maxDepth)\n ) {\n yield* walkDirectory(fs, ensureDescendPath(entry, path), depth + 1, options);\n }\n }\n}\n\nfunction matchesEntryKind(\n entry: RemoteEntry,\n includeDirectories: boolean,\n includeFiles: boolean,\n): boolean {\n if (entry.type === \"directory\") return includeDirectories;\n if (entry.type === \"file\") return includeFiles;\n return true;\n}\n\nfunction canDescendInto(entry: RemoteEntry, followSymlinks: boolean): boolean {\n if (entry.type === \"directory\") return true;\n return followSymlinks && entry.type === \"symlink\";\n}\n\nfunction ensureDescendPath(entry: RemoteEntry, parentPath: string): string {\n if (entry.path !== \"\" && entry.path !== entry.name) {\n return normalizeRemotePath(entry.path);\n }\n\n return joinRemotePath(parentPath, entry.name);\n}\n\nfunction compareEntries(left: RemoteEntry, right: RemoteEntry): number {\n if (left.path < right.path) return -1;\n if (left.path > right.path) return 1;\n return 0;\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw new AbortError({\n message: \"Remote tree walk aborted\",\n retryable: false,\n });\n }\n}\n","/**\n * Directory diffing primitives that compare two remote trees.\n *\n * @module sync/diffRemoteTrees\n */\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry } from \"../types/public\";\nimport { normalizeRemotePath } from \"../utils/path\";\nimport {\n walkRemoteTree,\n type RemoteTreeFilter,\n type WalkRemoteTreeOptions,\n} from \"./walkRemoteTree\";\n\n/** Outcome category for an entry across the two compared trees. */\nexport type RemoteTreeDiffStatus = \"added\" | \"removed\" | \"modified\" | \"unchanged\";\n\n/** Reason an entry is considered modified. */\nexport type RemoteTreeDiffReason = \"type\" | \"size\" | \"modifiedAt\" | \"checksum\";\n\n/** Single diff record produced by {@link diffRemoteTrees}. */\nexport interface RemoteTreeDiffEntry {\n /** Path relative to the traversal root, beginning with `/`. */\n path: string;\n /** Outcome category for this entry. */\n status: RemoteTreeDiffStatus;\n /** Reasons the entry is considered modified. Empty for unchanged/added/removed records. */\n reasons: RemoteTreeDiffReason[];\n /** Source-side entry, when present. */\n source?: RemoteEntry;\n /** Destination-side entry, when present. */\n destination?: RemoteEntry;\n}\n\n/** Compact summary of a diff result. */\nexport interface RemoteTreeDiffSummary {\n /** Number of entries present only on the source side. */\n added: number;\n /** Number of entries present only on the destination side. */\n removed: number;\n /** Number of entries present on both sides whose contents differ. */\n modified: number;\n /** Number of entries present on both sides with identical contents. */\n unchanged: number;\n /** Total entries inspected across both sides. */\n total: number;\n}\n\n/** Result returned by {@link diffRemoteTrees}. */\nexport interface RemoteTreeDiff {\n /** Diff records sorted by path. */\n entries: RemoteTreeDiffEntry[];\n /** Compact counts for the diff. */\n summary: RemoteTreeDiffSummary;\n}\n\n/** Options accepted by {@link diffRemoteTrees}. */\nexport interface DiffRemoteTreesOptions {\n /** Optional traversal controls applied to both sides. */\n walk?: Pick<\n WalkRemoteTreeOptions,\n \"filter\" | \"followSymlinks\" | \"includeDirectories\" | \"includeFiles\" | \"maxDepth\" | \"recursive\"\n >;\n /** Filter applied only to the source side. Overrides `walk.filter` when set. */\n sourceFilter?: RemoteTreeFilter;\n /** Filter applied only to the destination side. Overrides `walk.filter` when set. */\n destinationFilter?: RemoteTreeFilter;\n /** Whether unchanged entries are included in `entries`. Defaults to `false`. */\n includeUnchanged?: boolean;\n /** Tolerance in milliseconds when comparing modification timestamps. Defaults to `1000`. */\n modifiedAtToleranceMs?: number;\n /** Whether modification timestamps participate in the comparison. Defaults to `true`. */\n compareModifiedAt?: boolean;\n /** Whether sizes participate in the comparison. Defaults to `true`. */\n compareSize?: boolean;\n /** Whether to require matching `uniqueId` checksums when both entries expose one. Defaults to `false`. */\n compareUniqueId?: boolean;\n /** Optional abort signal threaded through both walks. */\n signal?: AbortSignal;\n}\n\n/**\n * Compares two remote subtrees and produces an entry-level diff.\n *\n * Source and destination paths are walked independently; entries are then aligned by\n * the relative path from each tree root. Directory equality is structural — directories\n * are equal when their relative paths match and the entry types agree.\n *\n * @param source - Source-side remote file system.\n * @param sourcePath - Source-side root path being compared.\n * @param destination - Destination-side remote file system.\n * @param destinationPath - Destination-side root path being compared.\n * @param options - Optional comparison controls.\n * @returns Diff result containing entries and a summary.\n */\nexport async function diffRemoteTrees(\n source: RemoteFileSystem,\n sourcePath: string,\n destination: RemoteFileSystem,\n destinationPath: string,\n options: DiffRemoteTreesOptions = {},\n): Promise<RemoteTreeDiff> {\n const includeUnchanged = options.includeUnchanged ?? false;\n const sourceRoot = normalizeRemotePath(sourcePath);\n const destinationRoot = normalizeRemotePath(destinationPath);\n const sourceWalk = createWalkOptions(options, options.sourceFilter);\n const destinationWalk = createWalkOptions(options, options.destinationFilter);\n\n const [sourceEntries, destinationEntries] = await Promise.all([\n collectEntries(source, sourceRoot, sourceWalk),\n collectEntries(destination, destinationRoot, destinationWalk),\n ]);\n\n const aligned = alignEntries(sourceEntries, destinationEntries);\n const entries: RemoteTreeDiffEntry[] = [];\n const summary: RemoteTreeDiffSummary = {\n added: 0,\n modified: 0,\n removed: 0,\n total: 0,\n unchanged: 0,\n };\n\n for (const { path, source: sourceEntry, destination: destinationEntry } of aligned) {\n summary.total += 1;\n const reasons: RemoteTreeDiffReason[] = [];\n let status: RemoteTreeDiffStatus;\n\n if (sourceEntry !== undefined && destinationEntry === undefined) {\n status = \"added\";\n summary.added += 1;\n } else if (sourceEntry === undefined && destinationEntry !== undefined) {\n status = \"removed\";\n summary.removed += 1;\n } else if (sourceEntry !== undefined && destinationEntry !== undefined) {\n const computedReasons = compareEntries(sourceEntry, destinationEntry, options);\n\n if (computedReasons.length === 0) {\n status = \"unchanged\";\n summary.unchanged += 1;\n } else {\n status = \"modified\";\n reasons.push(...computedReasons);\n summary.modified += 1;\n }\n } else {\n // Both entries undefined cannot happen because alignEntries only emits aligned pairs.\n continue;\n }\n\n if (status === \"unchanged\" && !includeUnchanged) continue;\n\n const record: RemoteTreeDiffEntry = { path, reasons, status };\n if (sourceEntry !== undefined) record.source = sourceEntry;\n if (destinationEntry !== undefined) record.destination = destinationEntry;\n entries.push(record);\n }\n\n entries.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n\n return { entries, summary };\n}\n\nfunction createWalkOptions(\n options: DiffRemoteTreesOptions,\n filter: RemoteTreeFilter | undefined,\n): WalkRemoteTreeOptions {\n const walk = options.walk ?? {};\n const merged: WalkRemoteTreeOptions = {};\n\n if (walk.recursive !== undefined) merged.recursive = walk.recursive;\n if (walk.maxDepth !== undefined) merged.maxDepth = walk.maxDepth;\n if (walk.includeDirectories !== undefined) merged.includeDirectories = walk.includeDirectories;\n if (walk.includeFiles !== undefined) merged.includeFiles = walk.includeFiles;\n if (walk.followSymlinks !== undefined) merged.followSymlinks = walk.followSymlinks;\n const resolvedFilter = filter ?? walk.filter;\n if (resolvedFilter !== undefined) merged.filter = resolvedFilter;\n if (options.signal !== undefined) merged.signal = options.signal;\n\n return merged;\n}\n\ninterface CollectedEntry {\n relativePath: string;\n entry: RemoteEntry;\n}\n\nasync function collectEntries(\n fs: RemoteFileSystem,\n rootPath: string,\n walkOptions: WalkRemoteTreeOptions,\n): Promise<Map<string, RemoteEntry>> {\n const map = new Map<string, RemoteEntry>();\n\n for await (const record of walkRemoteTree(fs, rootPath, walkOptions)) {\n const collected = toCollectedEntry(record.entry, rootPath);\n if (collected !== undefined) map.set(collected.relativePath, collected.entry);\n }\n\n return map;\n}\n\nfunction toCollectedEntry(entry: RemoteEntry, rootPath: string): CollectedEntry | undefined {\n const root = normalizeRemotePath(rootPath);\n const path = normalizeRemotePath(entry.path);\n\n if (path === root) return undefined;\n if (root === \"/\") return { entry, relativePath: path };\n if (path.startsWith(`${root}/`)) {\n return { entry, relativePath: path.slice(root.length) };\n }\n\n return undefined;\n}\n\ninterface AlignedPair {\n path: string;\n source?: RemoteEntry;\n destination?: RemoteEntry;\n}\n\nfunction alignEntries(\n sourceEntries: Map<string, RemoteEntry>,\n destinationEntries: Map<string, RemoteEntry>,\n): AlignedPair[] {\n const paths = new Set<string>([...sourceEntries.keys(), ...destinationEntries.keys()]);\n const aligned: AlignedPair[] = [];\n\n for (const path of paths) {\n const pair: AlignedPair = { path };\n const source = sourceEntries.get(path);\n const destination = destinationEntries.get(path);\n\n if (source !== undefined) pair.source = source;\n if (destination !== undefined) pair.destination = destination;\n aligned.push(pair);\n }\n\n return aligned;\n}\n\nfunction compareEntries(\n source: RemoteEntry,\n destination: RemoteEntry,\n options: DiffRemoteTreesOptions,\n): RemoteTreeDiffReason[] {\n const reasons: RemoteTreeDiffReason[] = [];\n const compareSize = options.compareSize ?? true;\n const compareModifiedAt = options.compareModifiedAt ?? true;\n const compareUniqueId = options.compareUniqueId ?? false;\n const tolerance = options.modifiedAtToleranceMs ?? 1000;\n\n if (source.type !== destination.type) {\n reasons.push(\"type\");\n }\n\n if (compareSize && isSizeRelevant(source, destination) && source.size !== destination.size) {\n reasons.push(\"size\");\n }\n\n if (compareModifiedAt && isModifiedAtDifferent(source, destination, tolerance)) {\n reasons.push(\"modifiedAt\");\n }\n\n if (\n compareUniqueId &&\n source.uniqueId !== undefined &&\n destination.uniqueId !== undefined &&\n source.uniqueId !== destination.uniqueId\n ) {\n reasons.push(\"checksum\");\n }\n\n return reasons;\n}\n\nfunction isSizeRelevant(source: RemoteEntry, destination: RemoteEntry): boolean {\n if (source.type !== \"file\" || destination.type !== \"file\") return false;\n return source.size !== undefined && destination.size !== undefined;\n}\n\nfunction isModifiedAtDifferent(\n source: RemoteEntry,\n destination: RemoteEntry,\n toleranceMs: number,\n): boolean {\n if (source.modifiedAt === undefined || destination.modifiedAt === undefined) return false;\n const delta = Math.abs(source.modifiedAt.getTime() - destination.modifiedAt.getTime());\n return delta > toleranceMs;\n}\n","/**\n * Remote manifest read/write/compare helpers.\n *\n * A manifest is a serializable snapshot of a remote subtree produced by walking\n * the live tree once and persisting the result. Manifests can be diffed against\n * each other to detect drift without re-listing both sides.\n *\n * @module sync/manifest\n */\nimport { ConfigurationError } from \"../errors/ZeroTransferError\";\nimport type { ProviderId } from \"../core/ProviderId\";\nimport type { RemoteFileSystem } from \"../providers/RemoteFileSystem\";\nimport type { RemoteEntry, RemoteEntryType } from \"../types/public\";\nimport { normalizeRemotePath } from \"../utils/path\";\nimport type {\n RemoteTreeDiff,\n RemoteTreeDiffEntry,\n RemoteTreeDiffReason,\n RemoteTreeDiffStatus,\n RemoteTreeDiffSummary,\n} from \"./diffRemoteTrees\";\nimport {\n walkRemoteTree,\n type RemoteTreeFilter,\n type WalkRemoteTreeOptions,\n} from \"./walkRemoteTree\";\n\n/** Schema version for the manifest payload. Bumped on incompatible format changes. */\nexport const REMOTE_MANIFEST_FORMAT_VERSION = 1;\n\n/** Manifest entry recorded for each visited remote node. */\nexport interface RemoteManifestEntry {\n /** Path relative to {@link RemoteManifest.root}, beginning with `/`. */\n path: string;\n /** Entry kind. */\n type: RemoteEntryType;\n /** Entry size in bytes when known. */\n size?: number;\n /** Last modification time as an ISO 8601 timestamp when known. */\n modifiedAt?: string;\n /** Protocol-specific stable identity when available. */\n uniqueId?: string;\n /** Target path for symbolic links when known. */\n symlinkTarget?: string;\n}\n\n/** Persisted snapshot of a remote subtree. */\nexport interface RemoteManifest {\n /** Schema version. Must equal {@link REMOTE_MANIFEST_FORMAT_VERSION}. */\n formatVersion: number;\n /** ISO 8601 timestamp recording when the manifest was generated. */\n generatedAt: string;\n /** Normalized absolute root path the manifest snapshot is anchored to. */\n root: string;\n /** Optional provider identifier the snapshot was captured from. */\n provider?: ProviderId;\n /** Manifest entries sorted by path. */\n entries: RemoteManifestEntry[];\n}\n\n/** Options accepted by {@link createRemoteManifest}. */\nexport interface CreateRemoteManifestOptions {\n /** Optional traversal controls forwarded to {@link walkRemoteTree}. */\n walk?: Pick<\n WalkRemoteTreeOptions,\n \"filter\" | \"followSymlinks\" | \"includeDirectories\" | \"includeFiles\" | \"maxDepth\" | \"recursive\"\n >;\n /** Filter applied during traversal. Overrides `walk.filter` when provided. */\n filter?: RemoteTreeFilter;\n /** Provider identifier embedded into the manifest header. */\n provider?: ProviderId;\n /** Clock used to stamp `generatedAt`. Defaults to `Date.now`. */\n now?: () => Date;\n /** Optional abort signal threaded through the walk. */\n signal?: AbortSignal;\n}\n\n/** Options accepted by {@link compareRemoteManifests}. */\nexport interface CompareRemoteManifestsOptions {\n /** Whether unchanged entries are included in the result. Defaults to `false`. */\n includeUnchanged?: boolean;\n /** Tolerance in milliseconds applied to `modifiedAt` comparisons. Defaults to `1000`. */\n modifiedAtToleranceMs?: number;\n /** Whether modification timestamps participate in the comparison. Defaults to `true`. */\n compareModifiedAt?: boolean;\n /** Whether sizes participate in the comparison. Defaults to `true`. */\n compareSize?: boolean;\n /** Whether to require matching `uniqueId` checksums when both entries expose one. Defaults to `false`. */\n compareUniqueId?: boolean;\n}\n\n/**\n * Walks a remote subtree and produces a serializable manifest snapshot.\n *\n * @param fs - Remote file system to capture.\n * @param rootPath - Root path the manifest is anchored to.\n * @param options - Optional capture controls.\n * @returns Manifest snapshot suitable for serialization or comparison.\n */\nexport async function createRemoteManifest(\n fs: RemoteFileSystem,\n rootPath: string,\n options: CreateRemoteManifestOptions = {},\n): Promise<RemoteManifest> {\n const root = normalizeRemotePath(rootPath);\n const walkOptions: WalkRemoteTreeOptions = { ...(options.walk ?? {}) };\n const resolvedFilter = options.filter ?? options.walk?.filter;\n if (resolvedFilter !== undefined) walkOptions.filter = resolvedFilter;\n if (options.signal !== undefined) walkOptions.signal = options.signal;\n\n const entries: RemoteManifestEntry[] = [];\n\n for await (const record of walkRemoteTree(fs, root, walkOptions)) {\n const relativePath = relativeFromRoot(record.entry.path, root);\n if (relativePath === undefined) continue;\n entries.push(toManifestEntry(record.entry, relativePath));\n }\n\n entries.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n\n const generatedAt = (options.now?.() ?? new Date()).toISOString();\n const manifest: RemoteManifest = {\n entries,\n formatVersion: REMOTE_MANIFEST_FORMAT_VERSION,\n generatedAt,\n root,\n };\n if (options.provider !== undefined) manifest.provider = options.provider;\n return manifest;\n}\n\n/**\n * Serializes a manifest to a JSON string suitable for persistence.\n *\n * @param manifest - Manifest snapshot to serialize.\n * @param indent - Optional indentation passed to `JSON.stringify`. Defaults to `2`.\n * @returns Stable JSON representation of the manifest.\n */\nexport function serializeRemoteManifest(manifest: RemoteManifest, indent: number = 2): string {\n return JSON.stringify(manifest, undefined, indent);\n}\n\n/**\n * Parses a JSON-encoded manifest, validating the schema version and entry shape.\n *\n * @param text - JSON payload produced by {@link serializeRemoteManifest}.\n * @returns Parsed manifest snapshot.\n * @throws {@link ConfigurationError} When the payload is invalid or has an unsupported version.\n */\nexport function parseRemoteManifest(text: string): RemoteManifest {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n throw new ConfigurationError({\n cause: error,\n message: \"Failed to parse remote manifest payload as JSON\",\n retryable: false,\n });\n }\n\n if (parsed === null || typeof parsed !== \"object\") {\n throw new ConfigurationError({\n message: \"Remote manifest payload must be a JSON object\",\n retryable: false,\n });\n }\n\n const candidate = parsed as Partial<RemoteManifest> & Record<string, unknown>;\n if (candidate.formatVersion !== REMOTE_MANIFEST_FORMAT_VERSION) {\n throw new ConfigurationError({\n details: {\n expected: REMOTE_MANIFEST_FORMAT_VERSION,\n received: candidate.formatVersion,\n },\n message: `Unsupported remote manifest formatVersion: ${String(candidate.formatVersion)}`,\n retryable: false,\n });\n }\n\n if (typeof candidate.root !== \"string\" || candidate.root.length === 0) {\n throw new ConfigurationError({\n message: \"Remote manifest root must be a non-empty string\",\n retryable: false,\n });\n }\n\n if (typeof candidate.generatedAt !== \"string\") {\n throw new ConfigurationError({\n message: \"Remote manifest generatedAt must be an ISO timestamp string\",\n retryable: false,\n });\n }\n\n if (!Array.isArray(candidate.entries)) {\n throw new ConfigurationError({\n message: \"Remote manifest entries must be an array\",\n retryable: false,\n });\n }\n\n const entries = candidate.entries.map((entry, index) => normalizeManifestEntry(entry, index));\n const manifest: RemoteManifest = {\n entries,\n formatVersion: REMOTE_MANIFEST_FORMAT_VERSION,\n generatedAt: candidate.generatedAt,\n root: normalizeRemotePath(candidate.root),\n };\n if (typeof candidate.provider === \"string\") manifest.provider = candidate.provider;\n return manifest;\n}\n\n/**\n * Compares two manifests and produces an entry-level diff.\n *\n * The comparison is performed on the relative-path keys recorded inside each manifest;\n * the absolute roots may differ between snapshots (e.g. captured against `/site` on the\n * source and `/var/www/site` on the destination).\n *\n * @param source - Source-side manifest snapshot.\n * @param destination - Destination-side manifest snapshot.\n * @param options - Optional comparison controls.\n * @returns Diff result mirroring {@link RemoteTreeDiff}.\n */\nexport function compareRemoteManifests(\n source: RemoteManifest,\n destination: RemoteManifest,\n options: CompareRemoteManifestsOptions = {},\n): RemoteTreeDiff {\n const includeUnchanged = options.includeUnchanged ?? false;\n const sourceMap = indexEntries(source);\n const destinationMap = indexEntries(destination);\n const paths = new Set<string>([...sourceMap.keys(), ...destinationMap.keys()]);\n\n const entries: RemoteTreeDiffEntry[] = [];\n const summary: RemoteTreeDiffSummary = {\n added: 0,\n modified: 0,\n removed: 0,\n total: 0,\n unchanged: 0,\n };\n\n for (const path of paths) {\n summary.total += 1;\n const sourceEntry = sourceMap.get(path);\n const destinationEntry = destinationMap.get(path);\n const reasons: RemoteTreeDiffReason[] = [];\n let status: RemoteTreeDiffStatus;\n\n if (sourceEntry !== undefined && destinationEntry === undefined) {\n status = \"added\";\n summary.added += 1;\n } else if (sourceEntry === undefined && destinationEntry !== undefined) {\n status = \"removed\";\n summary.removed += 1;\n } else if (sourceEntry !== undefined && destinationEntry !== undefined) {\n const computed = compareManifestEntries(sourceEntry, destinationEntry, options);\n if (computed.length === 0) {\n status = \"unchanged\";\n summary.unchanged += 1;\n } else {\n status = \"modified\";\n reasons.push(...computed);\n summary.modified += 1;\n }\n } else {\n continue;\n }\n\n if (status === \"unchanged\" && !includeUnchanged) continue;\n\n const record: RemoteTreeDiffEntry = { path, reasons, status };\n if (sourceEntry !== undefined) {\n record.source = manifestEntryToRemote(sourceEntry, source.root);\n }\n if (destinationEntry !== undefined) {\n record.destination = manifestEntryToRemote(destinationEntry, destination.root);\n }\n entries.push(record);\n }\n\n entries.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n return { entries, summary };\n}\n\nfunction relativeFromRoot(entryPath: string, root: string): string | undefined {\n const path = normalizeRemotePath(entryPath);\n if (path === root) return undefined;\n if (root === \"/\") return path;\n if (path.startsWith(`${root}/`)) return path.slice(root.length);\n return undefined;\n}\n\nfunction toManifestEntry(entry: RemoteEntry, relativePath: string): RemoteManifestEntry {\n const manifestEntry: RemoteManifestEntry = {\n path: relativePath,\n type: entry.type,\n };\n if (entry.size !== undefined) manifestEntry.size = entry.size;\n if (entry.modifiedAt !== undefined) manifestEntry.modifiedAt = entry.modifiedAt.toISOString();\n if (entry.uniqueId !== undefined) manifestEntry.uniqueId = entry.uniqueId;\n if (entry.symlinkTarget !== undefined) manifestEntry.symlinkTarget = entry.symlinkTarget;\n return manifestEntry;\n}\n\nfunction normalizeManifestEntry(value: unknown, index: number): RemoteManifestEntry {\n if (value === null || typeof value !== \"object\") {\n throw new ConfigurationError({\n details: { index },\n message: `Remote manifest entry at index ${index} must be an object`,\n retryable: false,\n });\n }\n\n const candidate = value as Partial<RemoteManifestEntry> & Record<string, unknown>;\n if (typeof candidate.path !== \"string\" || candidate.path.length === 0) {\n throw new ConfigurationError({\n details: { index },\n message: `Remote manifest entry at index ${index} must have a non-empty path`,\n retryable: false,\n });\n }\n if (!isRemoteEntryType(candidate.type)) {\n throw new ConfigurationError({\n details: { index, received: candidate.type },\n message: `Remote manifest entry at index ${index} has an invalid type`,\n retryable: false,\n });\n }\n\n const entry: RemoteManifestEntry = {\n path: candidate.path,\n type: candidate.type,\n };\n if (typeof candidate.size === \"number\") entry.size = candidate.size;\n if (typeof candidate.modifiedAt === \"string\") entry.modifiedAt = candidate.modifiedAt;\n if (typeof candidate.uniqueId === \"string\") entry.uniqueId = candidate.uniqueId;\n if (typeof candidate.symlinkTarget === \"string\") entry.symlinkTarget = candidate.symlinkTarget;\n return entry;\n}\n\nfunction isRemoteEntryType(value: unknown): value is RemoteEntryType {\n return value === \"file\" || value === \"directory\" || value === \"symlink\" || value === \"unknown\";\n}\n\nfunction indexEntries(manifest: RemoteManifest): Map<string, RemoteManifestEntry> {\n const map = new Map<string, RemoteManifestEntry>();\n for (const entry of manifest.entries) map.set(entry.path, entry);\n return map;\n}\n\nfunction manifestEntryToRemote(entry: RemoteManifestEntry, root: string): RemoteEntry {\n const absolutePath = root === \"/\" ? entry.path : `${root}${entry.path}`;\n const remote: RemoteEntry = {\n name: deriveName(entry.path),\n path: absolutePath,\n type: entry.type,\n };\n if (entry.size !== undefined) remote.size = entry.size;\n if (entry.modifiedAt !== undefined) {\n const parsed = new Date(entry.modifiedAt);\n if (!Number.isNaN(parsed.getTime())) remote.modifiedAt = parsed;\n }\n if (entry.uniqueId !== undefined) remote.uniqueId = entry.uniqueId;\n if (entry.symlinkTarget !== undefined) remote.symlinkTarget = entry.symlinkTarget;\n return remote;\n}\n\nfunction deriveName(path: string): string {\n const segments = path.split(\"/\").filter(Boolean);\n return segments.length === 0 ? \"/\" : (segments[segments.length - 1] ?? \"/\");\n}\n\nfunction compareManifestEntries(\n source: RemoteManifestEntry,\n destination: RemoteManifestEntry,\n options: CompareRemoteManifestsOptions,\n): RemoteTreeDiffReason[] {\n const reasons: RemoteTreeDiffReason[] = [];\n const compareSize = options.compareSize ?? true;\n const compareModifiedAt = options.compareModifiedAt ?? true;\n const compareUniqueId = options.compareUniqueId ?? false;\n const tolerance = options.modifiedAtToleranceMs ?? 1000;\n\n if (source.type !== destination.type) reasons.push(\"type\");\n\n if (\n compareSize &&\n source.type === \"file\" &&\n destination.type === \"file\" &&\n source.size !== undefined &&\n destination.size !== undefined &&\n source.size !== destination.size\n ) {\n reasons.push(\"size\");\n }\n\n if (compareModifiedAt && isModifiedAtDifferent(source, destination, tolerance)) {\n reasons.push(\"modifiedAt\");\n }\n\n if (\n compareUniqueId &&\n source.uniqueId !== undefined &&\n destination.uniqueId !== undefined &&\n source.uniqueId !== destination.uniqueId\n ) {\n reasons.push(\"checksum\");\n }\n\n return reasons;\n}\n\nfunction isModifiedAtDifferent(\n source: RemoteManifestEntry,\n destination: RemoteManifestEntry,\n toleranceMs: number,\n): boolean {\n if (source.modifiedAt === undefined || destination.modifiedAt === undefined) return false;\n const sourceTime = Date.parse(source.modifiedAt);\n const destinationTime = Date.parse(destination.modifiedAt);\n if (Number.isNaN(sourceTime) || Number.isNaN(destinationTime)) return false;\n return Math.abs(sourceTime - destinationTime) > toleranceMs;\n}\n","/**\n * Google Drive cloud-drive provider.\n *\n * Talks to the Google Drive v3 REST API using a bearer token sourced from the\n * connection profile (`profile.password` resolved as a `SecretSource`). Drive\n * is id-addressed rather than path-addressed; the provider maps incoming\n * remote paths to Drive file ids by walking from the configured root folder\n * (`options.rootFolderId`, defaults to the special id `\"root\"`).\n *\n * @module providers/cloud/GoogleDriveProvider\n */\nimport { Buffer } from \"node:buffer\";\nimport type { CapabilitySet, ChecksumCapability } from \"../../core/CapabilitySet\";\nimport type { ProviderId } from \"../../core/ProviderId\";\nimport type { TransferSession } from \"../../core/TransferSession\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n UnsupportedFeatureError,\n} from \"../../errors/ZeroTransferError\";\nimport { resolveSecret } from \"../../profiles/SecretSource\";\nimport type { ConnectionProfile, RemoteEntry, RemoteStat } from \"../../types/public\";\nimport { basenameRemotePath, normalizeRemotePath } from \"../../utils/path\";\nimport type { TransferProvider } from \"../Provider\";\nimport type { ProviderFactory } from \"../ProviderFactory\";\nimport type {\n ProviderTransferOperations,\n ProviderTransferReadRequest,\n ProviderTransferReadResult,\n ProviderTransferWriteRequest,\n ProviderTransferWriteResult,\n} from \"../ProviderTransferOperations\";\nimport type { RemoteFileSystem } from \"../RemoteFileSystem\";\nimport {\n formatRangeHeader,\n parseTotalBytes,\n secretToString,\n webStreamToAsyncIterable,\n type HttpFetch,\n} from \"../web/httpInternals\";\n\nexport type { HttpFetch };\n\nconst GDRIVE_API_BASE = \"https://www.googleapis.com/drive/v3\";\nconst GDRIVE_UPLOAD_BASE = \"https://www.googleapis.com/upload/drive/v3\";\nconst GDRIVE_FOLDER_MIME = \"application/vnd.google-apps.folder\";\n\nconst GDRIVE_CHECKSUM_CAPABILITIES: ChecksumCapability[] = [\"md5\", \"sha256\", \"crc32c\"];\n\nconst GDRIVE_FILE_FIELDS =\n \"id,name,mimeType,size,modifiedTime,createdTime,md5Checksum,sha256Checksum,parents,trashed\";\nconst GDRIVE_LIST_FIELDS = `nextPageToken,files(${GDRIVE_FILE_FIELDS})`;\n\n/** Options accepted by {@link createGoogleDriveProviderFactory}. */\nexport interface GoogleDriveProviderOptions {\n /** Provider id to register. Defaults to `\"google-drive\"`. */\n id?: ProviderId;\n /** Override the API base URL. Defaults to `https://www.googleapis.com/drive/v3`. */\n apiBaseUrl?: string;\n /** Override the upload base URL. Defaults to `https://www.googleapis.com/upload/drive/v3`. */\n uploadBaseUrl?: string;\n /**\n * Folder id used as the root for path resolution. Defaults to `\"root\"` (the\n * authenticated user's My Drive root). Pass a folder id when the SDK should\n * scope to a shared drive subtree.\n */\n rootFolderId?: string;\n /** Custom fetch implementation. Defaults to global `fetch`. */\n fetch?: HttpFetch;\n /** Default headers applied to every request before bearer auth. */\n defaultHeaders?: Record<string, string>;\n}\n\n/**\n * Creates a Google Drive provider factory.\n *\n * The bearer token is resolved per-connection from `profile.password`\n * (typically an OAuth 2 access token). `profile.host` is unused.\n */\nexport function createGoogleDriveProviderFactory(\n options: GoogleDriveProviderOptions = {},\n): ProviderFactory {\n const id: ProviderId = options.id ?? \"google-drive\";\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const apiBaseUrl = options.apiBaseUrl ?? GDRIVE_API_BASE;\n const uploadBaseUrl = options.uploadBaseUrl ?? GDRIVE_UPLOAD_BASE;\n const rootFolderId = options.rootFolderId ?? \"root\";\n\n if (typeof fetchImpl !== \"function\") {\n throw new ConfigurationError({\n message: \"Global fetch is unavailable; supply GoogleDriveProviderOptions.fetch explicitly\",\n retryable: false,\n });\n }\n\n const capabilities: CapabilitySet = {\n atomicRename: false,\n authentication: [\"token\", \"oauth\"],\n checksum: [...GDRIVE_CHECKSUM_CAPABILITIES],\n chmod: false,\n chown: false,\n list: true,\n maxConcurrency: 4,\n metadata: [\"modifiedAt\", \"createdAt\", \"mimeType\", \"uniqueId\"],\n notes: [\n \"Google Drive provider performs single-shot multipart uploads via /upload/drive/v3/files; resumable upload sessions are not yet supported.\",\n ],\n provider: id,\n readStream: true,\n resumeDownload: true,\n resumeUpload: false,\n serverSideCopy: false,\n serverSideMove: false,\n stat: true,\n symlink: false,\n writeStream: true,\n };\n\n return {\n capabilities,\n create: () =>\n new GoogleDriveProvider({\n apiBaseUrl,\n capabilities,\n defaultHeaders: { ...(options.defaultHeaders ?? {}) },\n fetch: fetchImpl,\n id,\n rootFolderId,\n uploadBaseUrl,\n }),\n id,\n };\n}\n\ninterface GoogleDriveInternalOptions {\n apiBaseUrl: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n rootFolderId: string;\n uploadBaseUrl: string;\n}\n\nclass GoogleDriveProvider implements TransferProvider {\n readonly id: ProviderId;\n readonly capabilities: CapabilitySet;\n\n constructor(private readonly internals: GoogleDriveInternalOptions) {\n this.id = internals.id;\n this.capabilities = internals.capabilities;\n }\n\n async connect(profile: ConnectionProfile): Promise<TransferSession> {\n if (profile.password === undefined) {\n throw new ConfigurationError({\n message: \"Google Drive provider requires a bearer token via profile.password\",\n retryable: false,\n });\n }\n const token = secretToString(await resolveSecret(profile.password));\n if (token === \"\") {\n throw new ConfigurationError({\n message: \"Google Drive bearer token resolved to an empty string\",\n retryable: false,\n });\n }\n const sessionOptions: GoogleDriveSessionOptions = {\n apiBaseUrl: this.internals.apiBaseUrl,\n capabilities: this.internals.capabilities,\n defaultHeaders: this.internals.defaultHeaders,\n fetch: this.internals.fetch,\n id: this.internals.id,\n rootFolderId: this.internals.rootFolderId,\n token,\n uploadBaseUrl: this.internals.uploadBaseUrl,\n };\n if (profile.timeoutMs !== undefined) sessionOptions.timeoutMs = profile.timeoutMs;\n return new GoogleDriveSession(sessionOptions);\n }\n}\n\ninterface GoogleDriveSessionOptions {\n apiBaseUrl: string;\n capabilities: CapabilitySet;\n defaultHeaders: Record<string, string>;\n fetch: HttpFetch;\n id: ProviderId;\n rootFolderId: string;\n timeoutMs?: number;\n token: string;\n uploadBaseUrl: string;\n}\n\nclass GoogleDriveSession implements TransferSession {\n readonly provider: ProviderId;\n readonly capabilities: CapabilitySet;\n readonly fs: RemoteFileSystem;\n readonly transfers: ProviderTransferOperations;\n\n constructor(options: GoogleDriveSessionOptions) {\n this.provider = options.id;\n this.capabilities = options.capabilities;\n const resolver = new GoogleDrivePathResolver(options);\n this.fs = new GoogleDriveFileSystem(options, resolver);\n this.transfers = new GoogleDriveTransferOperations(options, resolver);\n }\n\n disconnect(): Promise<void> {\n return Promise.resolve();\n }\n}\n\ninterface DriveFileResource {\n id: string;\n name: string;\n mimeType: string;\n size?: string;\n modifiedTime?: string;\n createdTime?: string;\n md5Checksum?: string;\n sha256Checksum?: string;\n parents?: string[];\n trashed?: boolean;\n}\n\ninterface DriveListResponse {\n files: DriveFileResource[];\n nextPageToken?: string;\n}\n\nclass GoogleDrivePathResolver {\n private readonly cache = new Map<string, DriveFileResource>();\n\n constructor(private readonly options: GoogleDriveSessionOptions) {}\n\n /** Resolves an absolute remote path to the Drive file resource for that node. */\n async resolvePath(path: string): Promise<DriveFileResource> {\n const normalized = normalizeRemotePath(path);\n if (normalized === \"/\" || normalized === \"\") {\n return {\n id: this.options.rootFolderId,\n mimeType: GDRIVE_FOLDER_MIME,\n name: \"\",\n };\n }\n const cached = this.cache.get(normalized);\n if (cached !== undefined) return cached;\n const segments = normalized.split(\"/\").filter((s) => s !== \"\");\n let parent: DriveFileResource = {\n id: this.options.rootFolderId,\n mimeType: GDRIVE_FOLDER_MIME,\n name: \"\",\n };\n let walked = \"\";\n for (const segment of segments) {\n const child = await this.findChild(parent.id, segment);\n if (child === undefined) {\n throw new PathNotFoundError({\n details: { path: normalized },\n message: `Google Drive path not found: ${normalized}`,\n retryable: false,\n });\n }\n walked = `${walked}/${segment}`;\n this.cache.set(walked, child);\n parent = child;\n }\n return parent;\n }\n\n /** Resolves the parent folder id for a path; throws on missing parent. */\n async resolveParentId(path: string): Promise<string> {\n const normalized = normalizeRemotePath(path);\n if (normalized === \"/\" || normalized === \"\") return this.options.rootFolderId;\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return this.options.rootFolderId;\n const parentPath = normalized.slice(0, idx);\n const parent = await this.resolvePath(parentPath);\n return parent.id;\n }\n\n private async findChild(parentId: string, name: string): Promise<DriveFileResource | undefined> {\n const q = `'${escapeDriveQ(parentId)}' in parents and name = '${escapeDriveQ(name)}' and trashed = false`;\n const response = await driveApi(\n this.options,\n \"GET\",\n `/files?${buildSearch({\n fields: GDRIVE_LIST_FIELDS,\n pageSize: \"10\",\n q,\n supportsAllDrives: \"true\",\n includeItemsFromAllDrives: \"true\",\n })}`,\n );\n const parsed = (await response.json()) as DriveListResponse;\n return parsed.files.find((f) => f.name === name);\n }\n}\n\nclass GoogleDriveFileSystem implements RemoteFileSystem {\n constructor(\n private readonly options: GoogleDriveSessionOptions,\n private readonly resolver: GoogleDrivePathResolver,\n ) {}\n\n async list(path: string): Promise<RemoteEntry[]> {\n const folder = await this.resolver.resolvePath(path);\n if (folder.mimeType !== GDRIVE_FOLDER_MIME && folder.id !== this.options.rootFolderId) {\n throw new PathNotFoundError({\n details: { path },\n message: `Google Drive path is not a folder: ${path}`,\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(path);\n const entries: RemoteEntry[] = [];\n let pageToken: string | undefined;\n do {\n const params: Record<string, string> = {\n fields: GDRIVE_LIST_FIELDS,\n includeItemsFromAllDrives: \"true\",\n pageSize: \"100\",\n q: `'${escapeDriveQ(folder.id)}' in parents and trashed = false`,\n supportsAllDrives: \"true\",\n };\n if (pageToken !== undefined) params[\"pageToken\"] = pageToken;\n const response = await driveApi(this.options, \"GET\", `/files?${buildSearch(params)}`);\n const parsed = (await response.json()) as DriveListResponse;\n for (const file of parsed.files) {\n entries.push(toRemoteEntry(file, normalized));\n }\n pageToken = parsed.nextPageToken;\n } while (pageToken !== undefined);\n return entries;\n }\n\n async stat(path: string): Promise<RemoteStat> {\n const file = await this.resolver.resolvePath(path);\n const normalized = normalizeRemotePath(path);\n const parent = parentDir(normalized);\n const entry = toRemoteEntry(file, parent);\n return { ...entry, exists: true };\n }\n}\n\nclass GoogleDriveTransferOperations implements ProviderTransferOperations {\n constructor(\n private readonly options: GoogleDriveSessionOptions,\n private readonly resolver: GoogleDrivePathResolver,\n ) {}\n\n async read(request: ProviderTransferReadRequest): Promise<ProviderTransferReadResult> {\n request.throwIfAborted();\n const normalized = normalizeRemotePath(request.endpoint.path);\n const file = await this.resolver.resolvePath(normalized);\n const headers: Record<string, string> = {};\n if (request.range !== undefined) {\n headers[\"range\"] = formatRangeHeader(request.range.offset, request.range.length);\n }\n const params = buildSearch({ alt: \"media\", supportsAllDrives: \"true\" });\n const response = await driveFetch(\n this.options,\n \"GET\",\n `${this.options.apiBaseUrl}/files/${encodeURIComponent(file.id)}?${params}`,\n {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n extraHeaders: headers,\n },\n );\n if (!response.ok && response.status !== 206) {\n throw mapGoogleDriveResponseError(response, normalized, await safeReadText(response));\n }\n const body = response.body;\n if (body === null) {\n throw new ConnectionError({\n details: { path: normalized },\n message: `Google Drive download for ${normalized} produced no body`,\n retryable: true,\n });\n }\n const result: ProviderTransferReadResult = {\n content: webStreamToAsyncIterable(body),\n };\n const totalBytes = parseTotalBytes(response, request.range?.offset);\n if (totalBytes !== undefined) result.totalBytes = totalBytes;\n if (request.range?.offset !== undefined && request.range.offset > 0) {\n result.bytesRead = request.range.offset;\n }\n if (typeof file.md5Checksum === \"string\" && file.md5Checksum.length > 0) {\n result.checksum = file.md5Checksum;\n }\n return result;\n }\n\n async write(request: ProviderTransferWriteRequest): Promise<ProviderTransferWriteResult> {\n request.throwIfAborted();\n if (request.offset !== undefined && request.offset > 0) {\n throw new UnsupportedFeatureError({\n details: { offset: request.offset },\n message: \"Google Drive provider does not yet support resumable upload sessions\",\n retryable: false,\n });\n }\n const normalized = normalizeRemotePath(request.endpoint.path);\n const buffered = await collectChunks(request.content);\n const parentId = await this.resolver.resolveParentId(normalized);\n const name = basenameRemotePath(normalized);\n const existing = await this.findExisting(parentId, name);\n\n const metadata: Record<string, unknown> = { name };\n if (existing === undefined) metadata[\"parents\"] = [parentId];\n\n const boundary = `----zt-boundary-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`;\n const bodyParts: Uint8Array[] = [];\n const enc = new TextEncoder();\n bodyParts.push(\n enc.encode(\n `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${JSON.stringify(metadata)}\\r\\n`,\n ),\n );\n bodyParts.push(enc.encode(`--${boundary}\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n`));\n bodyParts.push(buffered);\n bodyParts.push(enc.encode(`\\r\\n--${boundary}--\\r\\n`));\n const body = concatChunks(bodyParts);\n\n const url =\n existing === undefined\n ? `${this.options.uploadBaseUrl}/files?uploadType=multipart&supportsAllDrives=true&fields=${encodeURIComponent(GDRIVE_FILE_FIELDS)}`\n : `${this.options.uploadBaseUrl}/files/${encodeURIComponent(existing.id)}?uploadType=multipart&supportsAllDrives=true&fields=${encodeURIComponent(GDRIVE_FILE_FIELDS)}`;\n const method = existing === undefined ? \"POST\" : \"PATCH\";\n\n const response = await driveFetch(this.options, method, url, {\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n body,\n extraHeaders: { \"content-type\": `multipart/related; boundary=${boundary}` },\n });\n if (!response.ok) {\n throw mapGoogleDriveResponseError(response, normalized, await safeReadText(response));\n }\n const meta = (await response.json()) as DriveFileResource;\n request.reportProgress(buffered.byteLength, buffered.byteLength);\n const result: ProviderTransferWriteResult = {\n bytesTransferred: buffered.byteLength,\n totalBytes: buffered.byteLength,\n };\n if (typeof meta.md5Checksum === \"string\" && meta.md5Checksum.length > 0) {\n result.checksum = meta.md5Checksum;\n }\n return result;\n }\n\n private async findExisting(\n parentId: string,\n name: string,\n ): Promise<DriveFileResource | undefined> {\n const q = `'${escapeDriveQ(parentId)}' in parents and name = '${escapeDriveQ(name)}' and trashed = false`;\n const response = await driveApi(\n this.options,\n \"GET\",\n `/files?${buildSearch({\n fields: GDRIVE_LIST_FIELDS,\n includeItemsFromAllDrives: \"true\",\n pageSize: \"10\",\n q,\n supportsAllDrives: \"true\",\n })}`,\n );\n const parsed = (await response.json()) as DriveListResponse;\n return parsed.files.find((f) => f.name === name);\n }\n}\n\ninterface DriveFetchOptions {\n body?: Uint8Array;\n extraHeaders?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nasync function driveFetch(\n options: GoogleDriveSessionOptions,\n method: string,\n url: string,\n fetchOptions: DriveFetchOptions = {},\n): Promise<Response> {\n const headers: Record<string, string> = {\n ...options.defaultHeaders,\n ...(fetchOptions.extraHeaders ?? {}),\n authorization: `Bearer ${options.token}`,\n };\n const init: RequestInit = { headers, method };\n if (fetchOptions.body !== undefined) {\n (init as { body: Uint8Array }).body = fetchOptions.body;\n }\n const controller = new AbortController();\n const upstream = fetchOptions.signal ?? null;\n if (upstream !== null) {\n if (upstream.aborted) controller.abort(upstream.reason);\n else upstream.addEventListener(\"abort\", () => controller.abort(upstream.reason));\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"Google Drive request timed out\")),\n options.timeoutMs,\n );\n }\n try {\n return await options.fetch(url, { ...init, signal: controller.signal });\n } catch (error) {\n throw new ConnectionError({\n cause: error,\n details: { url },\n message: `Google Drive request to ${url} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\nasync function driveApi(\n options: GoogleDriveSessionOptions,\n method: string,\n apiPath: string,\n): Promise<Response> {\n const url = `${options.apiBaseUrl}${apiPath}`;\n const response = await driveFetch(options, method, url);\n if (!response.ok) {\n const text = await safeReadText(response);\n throw mapGoogleDriveResponseError(response, apiPath, text);\n }\n return response;\n}\n\nfunction mapGoogleDriveResponseError(\n response: Response,\n contextPath: string,\n bodyText: string,\n): Error {\n const details = {\n bodyText: bodyText.slice(0, 500),\n path: contextPath,\n status: response.status,\n statusText: response.statusText,\n };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `Google Drive authentication failed for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `Google Drive access forbidden for ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `Google Drive path not found: ${contextPath}`,\n retryable: false,\n });\n }\n if (response.status === 429) {\n return new ConnectionError({\n details,\n message: `Google Drive rate limit hit for ${contextPath}`,\n retryable: true,\n });\n }\n return new ConnectionError({\n details,\n message: `Google Drive request for ${contextPath} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\nfunction toRemoteEntry(file: DriveFileResource, parent: string): RemoteEntry {\n const path = joinDrivePath(parent, file.name);\n const entry: RemoteEntry = {\n name: file.name,\n path,\n raw: file,\n type: file.mimeType === GDRIVE_FOLDER_MIME ? \"directory\" : \"file\",\n uniqueId: file.id,\n };\n if (typeof file.size === \"string\") {\n const sized = Number(file.size);\n if (Number.isFinite(sized)) entry.size = sized;\n }\n if (typeof file.modifiedTime === \"string\") {\n const parsed = new Date(file.modifiedTime);\n if (!Number.isNaN(parsed.getTime())) entry.modifiedAt = parsed;\n }\n if (typeof file.createdTime === \"string\") {\n const parsed = new Date(file.createdTime);\n if (!Number.isNaN(parsed.getTime())) entry.createdAt = parsed;\n }\n return entry;\n}\n\nfunction joinDrivePath(parent: string, name: string): string {\n if (parent === \"\" || parent === \"/\") return `/${name}`;\n return parent.endsWith(\"/\") ? `${parent}${name}` : `${parent}/${name}`;\n}\n\nfunction parentDir(normalized: string): string {\n if (normalized === \"/\" || normalized === \"\") return \"/\";\n const idx = normalized.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return normalized.slice(0, idx);\n}\n\nfunction escapeDriveQ(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\nfunction buildSearch(params: Record<string, string>): string {\n const search = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) search.set(k, v);\n return search.toString();\n}\n\nasync function safeReadText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\nasync function collectChunks(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of source) {\n chunks.push(chunk);\n total += chunk.byteLength;\n }\n return concatChunks(chunks, total);\n}\n\nfunction concatChunks(chunks: Uint8Array[], totalSize?: number): Uint8Array {\n const total = totalSize ?? chunks.reduce((acc, c) => acc + c.byteLength, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\n// `Buffer` is referenced indirectly by the shared `secretToString` helper; this\n// import keeps tree-shaking simple alongside the other web providers.\nvoid Buffer;\n","/**\n * Shared HTTP transport helpers used by HTTP(S) and WebDAV providers.\n *\n * @module providers/web/httpInternals\n */\nimport { Buffer } from \"node:buffer\";\nimport {\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n PathNotFoundError,\n PermissionDeniedError,\n TimeoutError,\n} from \"../../errors/ZeroTransferError\";\nimport type { ConnectionProfile } from \"../../types/public\";\n\n/** Fetch implementation accepted by web-family providers. */\nexport type HttpFetch = (input: string, init?: RequestInit) => Promise<Response>;\n\n/** Shared session options carried by HTTP(S)-based providers. */\nexport interface HttpSessionTransport {\n baseUrl: URL;\n fetch: HttpFetch;\n headers: Record<string, string>;\n timeoutMs?: number;\n}\n\n/** Builds an HTTP(S) base URL from a connection profile. */\nexport function buildBaseUrl(\n profile: ConnectionProfile,\n options: { secure: boolean; basePath: string },\n): URL {\n const protocol = options.secure ? \"https:\" : \"http:\";\n const portSegment = profile.port !== undefined ? `:${profile.port}` : \"\";\n const path = options.basePath.length === 0 ? \"/\" : ensureLeadingSlash(options.basePath);\n try {\n return new URL(`${protocol}//${profile.host}${portSegment}${path}`);\n } catch (error) {\n throw new ConfigurationError({\n cause: error,\n details: { host: profile.host, port: profile.port },\n message: \"Invalid host or basePath for HTTP-family provider\",\n retryable: false,\n });\n }\n}\n\n/** Joins a base URL pathname with a normalized remote path. */\nexport function resolveUrl(baseUrl: URL, remotePath: string): URL {\n const trimmedBase = baseUrl.pathname.replace(/\\/+$/, \"\");\n const suffix = remotePath === \"/\" ? \"\" : remotePath;\n const merged = new URL(baseUrl.toString());\n merged.pathname = `${trimmedBase}${suffix}`;\n return merged;\n}\n\n/** Ensures a leading slash on a pathname. */\nexport function ensureLeadingSlash(value: string): string {\n return value.startsWith(\"/\") ? value : `/${value}`;\n}\n\n/** Dispatches a fetch request honoring shared headers, abort, and timeout policy. */\nexport async function dispatchRequest(\n options: HttpSessionTransport,\n url: URL,\n init: RequestInit & { headers?: Record<string, string> },\n): Promise<Response> {\n const headers = { ...options.headers, ...(init.headers ?? {}) };\n const controller = new AbortController();\n const upstreamSignal = init.signal ?? null;\n if (upstreamSignal !== null) {\n if (upstreamSignal.aborted) controller.abort(upstreamSignal.reason);\n else upstreamSignal.addEventListener(\"abort\", () => controller.abort(upstreamSignal.reason));\n }\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (options.timeoutMs !== undefined && options.timeoutMs > 0) {\n timer = setTimeout(\n () => controller.abort(new Error(\"HTTP request timed out\")),\n options.timeoutMs,\n );\n }\n\n try {\n return await options.fetch(url.toString(), {\n ...init,\n headers,\n signal: controller.signal,\n });\n } catch (error) {\n if (controller.signal.aborted && upstreamSignal?.aborted !== true) {\n throw new TimeoutError({\n cause: error,\n details: { timeoutMs: options.timeoutMs, url: url.toString() },\n message: `HTTP request to ${url.toString()} timed out after ${String(options.timeoutMs)}ms`,\n retryable: true,\n });\n }\n throw new ConnectionError({\n cause: error,\n details: { url: url.toString() },\n message: `HTTP request to ${url.toString()} failed`,\n retryable: true,\n });\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\n/** Parses a `Content-Range: bytes a-b/total` header. */\nexport function parseContentRangeTotal(value: string): number | undefined {\n const match = /\\/(\\d+)\\s*$/.exec(value);\n if (match === null) return undefined;\n const total = Number.parseInt(match[1] ?? \"\", 10);\n return Number.isFinite(total) ? total : undefined;\n}\n\n/** Resolves the total byte count from a response and optional range offset. */\nexport function parseTotalBytes(\n response: Response,\n rangeOffset: number | undefined,\n): number | undefined {\n if (response.status === 206) {\n const contentRange = response.headers.get(\"content-range\");\n if (contentRange !== null) {\n const total = parseContentRangeTotal(contentRange);\n if (total !== undefined) return total;\n }\n }\n const contentLength = response.headers.get(\"content-length\");\n if (contentLength === null) return undefined;\n const length = Number.parseInt(contentLength, 10);\n if (!Number.isFinite(length) || length < 0) return undefined;\n return rangeOffset !== undefined && rangeOffset > 0 ? length + rangeOffset : length;\n}\n\n/** Formats a `Range: bytes=offset-end` header. */\nexport function formatRangeHeader(offset: number, length: number | undefined): string {\n if (length === undefined) return `bytes=${String(offset)}-`;\n const end = offset + length - 1;\n return `bytes=${String(offset)}-${String(end)}`;\n}\n\n/** Maps an HTTP error status to a typed SDK error. */\nexport function mapResponseError(response: Response, path: string): Error {\n const details = { path, status: response.status, statusText: response.statusText };\n if (response.status === 401) {\n return new AuthenticationError({\n details,\n message: `HTTP authentication failed for ${path} (${String(response.status)})`,\n retryable: false,\n });\n }\n if (response.status === 403) {\n return new PermissionDeniedError({\n details,\n message: `HTTP access forbidden for ${path} (${String(response.status)})`,\n retryable: false,\n });\n }\n if (response.status === 404) {\n return new PathNotFoundError({\n details,\n message: `HTTP path not found: ${path}`,\n retryable: false,\n });\n }\n return new ConnectionError({\n details,\n message: `HTTP request for ${path} failed with status ${String(response.status)}`,\n retryable: response.status >= 500,\n });\n}\n\n/** Converts a Web ReadableStream to an AsyncIterable of Uint8Array. */\nexport async function* webStreamToAsyncIterable(\n body: ReadableStream<Uint8Array>,\n): AsyncIterable<Uint8Array> {\n const reader = body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value !== undefined) yield value;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/** Resolves resolved-secret variants to UTF-8 strings. */\nexport function secretToString(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (value instanceof Uint8Array || Buffer.isBuffer(value)) {\n return Buffer.from(value as Uint8Array).toString(\"utf8\");\n }\n return String(value);\n}\n"],"mappings":"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","names":["path","waitMs","totalBytes","calculateBytesPerSecond","normalized","Buffer","Buffer","isAbsolute","cloneVerification","path","Buffer","path","createPathNotFoundError","compareEntries","collectTransferContent","normalizeOptionalByteCount","cloneVerification","Buffer","normalizeByteCount","concatChunks","cloneDate","Buffer","first","globMatch","path","Buffer","Buffer","gt","cloneEndpoint","item","open","path","path","throwIfAborted","compareEntries","path","compareEntries","path","absolutePath","isModifiedAtDifferent","Buffer","Buffer","Buffer","path","concatChunks"]}
|