{"version":3,"file":"index.cjs","names":["isNotFoundError","trimSlashes","MastraFilesystem","S3Client","FileNotFoundError","GetObjectCommand","FileExistsError","PutObjectCommand","DeleteObjectCommand","CopyObjectCommand","HeadObjectCommand","ListObjectsV2Command","DeleteObjectsCommand","HeadBucketCommand","BlobStore","S3Client","PutObjectCommand","GetObjectCommand","HeadObjectCommand","DeleteObjectCommand","ListObjectsV2Command","DeleteObjectsCommand"],"sources":["../src/filesystem/index.ts","../src/blob-store/index.ts","../src/provider.ts"],"sourcesContent":["import {\n  S3Client,\n  GetObjectCommand,\n  PutObjectCommand,\n  DeleteObjectCommand,\n  CopyObjectCommand,\n  ListObjectsV2Command,\n  DeleteObjectsCommand,\n  HeadObjectCommand,\n  HeadBucketCommand,\n} from '@aws-sdk/client-s3';\n\nimport type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@aws-sdk/types';\n\nimport type {\n  FileContent,\n  FileStat,\n  FileEntry,\n  ReadOptions,\n  WriteOptions,\n  ListOptions,\n  RemoveOptions,\n  CopyOptions,\n  FilesystemMountConfig,\n  FilesystemIcon,\n  FilesystemInfo,\n  ProviderStatus,\n  MastraFilesystemOptions,\n} from '@mastra/core/workspace';\nimport { MastraFilesystem, FileNotFoundError, FileExistsError } from '@mastra/core/workspace';\n\n/**\n * S3 mount configuration.\n * Returned by S3Filesystem.getMountConfig() for FUSE mounting in sandboxes.\n */\nexport interface S3MountConfig extends FilesystemMountConfig {\n  type: 's3';\n  /** S3 bucket name */\n  bucket: string;\n  /** AWS region (use 'auto' for R2) */\n  region?: string;\n  /** Optional endpoint for S3-compatible storage (MinIO, R2, etc.) */\n  endpoint?: string;\n  /** AWS access key ID */\n  accessKeyId?: string;\n  /** AWS secret access key */\n  secretAccessKey?: string;\n  /** AWS session token for temporary credentials (SSO, AssumeRole, container credentials, etc.) */\n  sessionToken?: string;\n  /**\n   * Optional prefix (subdirectory) to mount instead of the entire bucket.\n   * Uses s3fs `bucket:/prefix` syntax to scope the mount to a specific path.\n   * Leading/trailing slashes are normalized automatically.\n   */\n  prefix?: string;\n  /** Mount as read-only */\n  readOnly?: boolean;\n}\n\n/**\n * Common MIME types by file extension.\n */\nconst MIME_TYPES: Record<string, string> = {\n  // Text\n  '.txt': 'text/plain',\n  '.md': 'text/markdown',\n  '.markdown': 'text/markdown',\n  '.html': 'text/html',\n  '.htm': 'text/html',\n  '.css': 'text/css',\n  '.csv': 'text/csv',\n  '.xml': 'text/xml',\n  // Code\n  '.js': 'text/javascript',\n  '.mjs': 'text/javascript',\n  '.ts': 'text/typescript',\n  '.tsx': 'text/typescript',\n  '.jsx': 'text/javascript',\n  '.json': 'application/json',\n  '.yaml': 'text/yaml',\n  '.yml': 'text/yaml',\n  '.py': 'text/x-python',\n  '.rb': 'text/x-ruby',\n  '.sh': 'text/x-shellscript',\n  '.bash': 'text/x-shellscript',\n  // Images\n  '.png': 'image/png',\n  '.jpg': 'image/jpeg',\n  '.jpeg': 'image/jpeg',\n  '.gif': 'image/gif',\n  '.svg': 'image/svg+xml',\n  '.webp': 'image/webp',\n  '.ico': 'image/x-icon',\n  // Documents\n  '.pdf': 'application/pdf',\n  // Archives\n  '.zip': 'application/zip',\n  '.gz': 'application/gzip',\n  '.tar': 'application/x-tar',\n};\n\n/**\n * Get MIME type from file path extension.\n */\nfunction getMimeType(path: string): string {\n  const ext = path.toLowerCase().match(/\\.[^.]+$/)?.[0];\n  return ext ? (MIME_TYPES[ext] ?? 'application/octet-stream') : 'application/octet-stream';\n}\n\n/** Check if an error is a \"not found\" error from the S3 SDK. */\nfunction isNotFoundError(error: unknown): boolean {\n  if (!error || typeof error !== 'object' || !('name' in error)) return false;\n  const name = (error as { name: string }).name;\n  return name === 'NotFound' || name === 'NoSuchKey' || name === '404';\n}\n\n/** Check if an error is an access denied error from the S3 SDK. */\nfunction isAccessDeniedError(error: unknown): boolean {\n  if (!error || typeof error !== 'object') return false;\n  const err = error as { name?: string; $metadata?: { httpStatusCode?: number } };\n  return err.name === 'AccessDenied' || err.$metadata?.httpStatusCode === 403;\n}\n\n/**\n * S3 filesystem provider configuration.\n */\nexport interface S3FilesystemOptions extends MastraFilesystemOptions {\n  /** Unique identifier for this filesystem instance */\n  id?: string;\n  /** S3 bucket name */\n  bucket: string;\n  /** Human-friendly display name for the UI */\n  displayName?: string;\n  /** Icon identifier for the UI (defaults to 's3') */\n  icon?: FilesystemIcon;\n  /** Description shown in tooltips */\n  description?: string;\n  /** AWS region (use 'auto' for R2) */\n  region: string;\n  /**\n   * AWS credentials or credential provider function.\n   * Accepts static credentials or a provider that auto-refreshes\n   * (e.g. fromNodeProviderChain() from @aws-sdk/credential-providers).\n   * When set, takes precedence over accessKeyId/secretAccessKey/sessionToken.\n   * When ALL credential options are omitted, the SDK default credential\n   * provider chain is used (env vars, ~/.aws, IMDS, ECS container credentials).\n   */\n  credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  /**\n   * AWS access key ID.\n   * Optional - omit to use the SDK default credential provider chain.\n   */\n  accessKeyId?: string;\n  /**\n   * AWS secret access key.\n   * Optional - omit to use the SDK default credential provider chain.\n   */\n  secretAccessKey?: string;\n  /**\n   * AWS session token for temporary credentials.\n   * Required when using SSO, AssumeRole, container credentials, or any other\n   * temporary credential provider.\n   */\n  sessionToken?: string;\n  /**\n   * Custom endpoint URL for S3-compatible storage.\n   * Examples:\n   * - Cloudflare R2: 'https://{accountId}.r2.cloudflarestorage.com'\n   * - MinIO: 'http://localhost:9000'\n   * - DigitalOcean Spaces: 'https://{region}.digitaloceanspaces.com'\n   */\n  endpoint?: string;\n  /** Force path-style URLs (required for some S3-compatible services) */\n  forcePathStyle?: boolean;\n  /** Optional prefix for all keys (acts like a subdirectory) */\n  prefix?: string;\n  /** Mount as read-only (blocks write operations, mounts read-only in sandboxes) */\n  readOnly?: boolean;\n}\n\n/**\n * S3 filesystem implementation.\n *\n * Stores files in an S3 bucket or S3-compatible storage service.\n * Supports mounting into E2B sandboxes via s3fs-fuse.\n *\n * @example AWS S3\n * ```typescript\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const fs = new S3Filesystem({\n *   bucket: 'my-bucket',\n *   region: 'us-east-1',\n *   accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n *   secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n * });\n * ```\n *\n * @example Cloudflare R2\n * ```typescript\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const fs = new S3Filesystem({\n *   bucket: 'my-bucket',\n *   region: 'auto',\n *   accessKeyId: process.env.R2_ACCESS_KEY_ID!,\n *   secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,\n *   endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,\n * });\n * ```\n *\n * @example MinIO (local)\n * ```typescript\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const fs = new S3Filesystem({\n *   bucket: 'my-bucket',\n *   region: 'us-east-1',\n *   accessKeyId: 'minioadmin',\n *   secretAccessKey: 'minioadmin',\n *   endpoint: 'http://localhost:9000',\n *   forcePathStyle: true,\n * });\n * ```\n */\n\n/** Trim leading and trailing slashes without regex (avoids polynomial regex on user input). */\nfunction trimSlashes(s: string): string {\n  let start = 0;\n  let end = s.length;\n  while (start < end && s[start] === '/') start++;\n  while (end > start && s[end - 1] === '/') end--;\n  return s.slice(start, end);\n}\n\nexport class S3Filesystem extends MastraFilesystem {\n  readonly id: string;\n  readonly name = 'S3Filesystem';\n  readonly provider = 's3';\n  readonly readOnly?: boolean;\n\n  status: ProviderStatus = 'pending';\n\n  // Display metadata for UI\n  readonly displayName?: string;\n  readonly icon: FilesystemIcon = 's3';\n  readonly description?: string;\n\n  private readonly bucket: string;\n  private readonly region: string;\n  private readonly credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  private readonly accessKeyId?: string;\n  private readonly secretAccessKey?: string;\n  private readonly sessionToken?: string;\n  private readonly endpoint?: string;\n  private readonly forcePathStyle: boolean;\n  private readonly prefix: string;\n\n  private _client: S3Client | null = null;\n\n  constructor(options: S3FilesystemOptions) {\n    super({ ...options, name: 'S3Filesystem' });\n    this.id = options.id ?? `s3-fs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n    this.bucket = options.bucket;\n    this.region = options.region;\n    this.credentials = options.credentials;\n    this.accessKeyId = options.accessKeyId;\n    this.secretAccessKey = options.secretAccessKey;\n    this.sessionToken = options.sessionToken;\n    this.endpoint = options.endpoint;\n    this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint; // Default true for custom endpoints\n    // Trim leading/trailing slashes from prefix using iterative approach (avoids polynomial regex)\n    const trimmedPrefix = options.prefix ? trimSlashes(options.prefix) : '';\n    this.prefix = trimmedPrefix ? trimmedPrefix + '/' : '';\n\n    // Display metadata - detect icon first, then derive displayName from it\n    this.icon = options.icon ?? this.detectIconFromEndpoint(options.endpoint);\n    this.displayName = options.displayName ?? this.getDefaultDisplayName(this.icon);\n    this.description = options.description;\n    this.readOnly = options.readOnly;\n  }\n\n  /**\n   * Get the underlying S3Client instance for direct access to AWS S3 APIs.\n   *\n   * Use this when you need to access S3 features not exposed through the\n   * WorkspaceFilesystem interface (e.g., presigned URLs, multipart uploads,\n   * custom S3 operations, etc.).\n   *\n   * @example Generate a presigned URL\n   * ```typescript\n   * import { GetObjectCommand } from '@aws-sdk/client-s3';\n   * import { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n   *\n   * const s3Client = fs.client;\n   * const url = await getSignedUrl(s3Client, new GetObjectCommand({\n   *   Bucket: 'my-bucket',\n   *   Key: 'my-file.txt',\n   * }));\n   * ```\n   */\n  get client(): S3Client {\n    return this.getClient();\n  }\n\n  /**\n   * Get mount configuration for E2B sandbox.\n   * Returns S3-compatible config that works with s3fs-fuse.\n   *\n   * Only static `accessKeyId`/`secretAccessKey`/`sessionToken` are included in the\n   * returned config. If credentials are provided only via the `credentials` option\n   * (provider function), the returned config will have no credentials because FUSE\n   * mounts cannot call a provider function. Use static credentials for sandbox\n   * mount compatibility.\n   */\n  getMountConfig(): S3MountConfig {\n    const config: S3MountConfig = {\n      type: 's3',\n      bucket: this.bucket,\n      region: this.region,\n      endpoint: this.endpoint,\n    };\n\n    if (this.accessKeyId && this.secretAccessKey) {\n      config.accessKeyId = this.accessKeyId;\n      config.secretAccessKey = this.secretAccessKey;\n      if (this.sessionToken) {\n        config.sessionToken = this.sessionToken;\n      }\n    }\n\n    if (this.prefix) {\n      config.prefix = this.prefix;\n    }\n\n    if (this.readOnly) {\n      config.readOnly = true;\n    }\n\n    return config;\n  }\n\n  /**\n   * Get filesystem info for status reporting.\n   */\n  getInfo(): FilesystemInfo<{\n    bucket: string;\n    region: string;\n    endpoint?: string;\n    prefix?: string;\n  }> {\n    return {\n      id: this.id,\n      name: this.name,\n      provider: this.provider,\n      status: this.status,\n      error: this.error,\n      readOnly: this.readOnly,\n      icon: this.icon,\n      metadata: {\n        bucket: this.bucket,\n        region: this.region,\n        ...(this.endpoint && { endpoint: this.endpoint }),\n        ...(this.prefix && { prefix: this.prefix }),\n      },\n    };\n  }\n\n  /**\n   * Handle an error, checking for access denied and updating status accordingly.\n   * Returns the error for re-throwing.\n   */\n  private handleError(error: unknown): unknown {\n    if (isAccessDeniedError(error)) {\n      this.status = 'error';\n      this.error = 'Access denied - check credentials and bucket permissions';\n    }\n    return error;\n  }\n\n  /**\n   * Get instructions describing this S3 filesystem.\n   * Used by agents to understand storage semantics.\n   */\n  getInstructions(): string {\n    const providerName = this.displayName || 'S3';\n    const access = this.readOnly ? 'Read-only' : 'Persistent';\n    return `${providerName} storage in bucket \"${this.bucket}\". ${access} storage - files are retained across sessions.`;\n  }\n\n  /**\n   * Detect the appropriate icon based on the S3 endpoint.\n   */\n  private detectIconFromEndpoint(endpoint?: string): FilesystemIcon {\n    if (!endpoint) {\n      // No custom endpoint = AWS S3\n      return 'aws-s3';\n    }\n\n    // Parse hostname from endpoint URL for secure matching\n    let hostname: string;\n    try {\n      const url = new URL(endpoint);\n      hostname = url.hostname.toLowerCase();\n    } catch {\n      // If URL parsing fails, use the endpoint as-is (lowercased)\n      hostname = endpoint.toLowerCase();\n    }\n\n    // Check hostname suffix for known providers (use dot-prefix or exact match to prevent subdomain spoofing)\n    if (\n      hostname === 'r2.cloudflarestorage.com' ||\n      hostname.endsWith('.r2.cloudflarestorage.com') ||\n      hostname.endsWith('.cloudflare.com')\n    ) {\n      return 'r2';\n    }\n\n    if (\n      hostname === 'storage.googleapis.com' ||\n      hostname.endsWith('.storage.googleapis.com') ||\n      hostname.endsWith('.googleapis.com')\n    ) {\n      return 'gcs';\n    }\n\n    if (\n      hostname === 'blob.core.windows.net' ||\n      hostname.endsWith('.blob.core.windows.net') ||\n      hostname.endsWith('.azure.com')\n    ) {\n      return 'azure';\n    }\n\n    if (hostname.includes('minio')) {\n      return 'minio';\n    }\n\n    // Generic S3-compatible (DigitalOcean Spaces, etc.)\n    return 's3';\n  }\n\n  /**\n   * Get a user-friendly display name based on the icon/provider.\n   */\n  private getDefaultDisplayName(icon: FilesystemIcon): string | undefined {\n    switch (icon) {\n      case 'aws-s3':\n        return 'AWS S3';\n      case 'r2':\n      case 'cloudflare':\n      case 'cloudflare-r2':\n        return 'Cloudflare R2';\n      case 'gcs':\n      case 'google-cloud':\n      case 'google-cloud-storage':\n        return 'Google Cloud Storage';\n      case 'azure':\n      case 'azure-blob':\n        return 'Azure Blob';\n      case 'minio':\n        return 'MinIO';\n      case 's3':\n        return 'S3';\n      default:\n        // Unknown icon - don't assume a display name\n        return undefined;\n    }\n  }\n\n  private getClient(): S3Client {\n    if (this._client) return this._client;\n\n    const hasStaticCredentials = this.accessKeyId && this.secretAccessKey;\n\n    let credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined;\n    if (this.credentials) {\n      credentials = this.credentials;\n    } else if (hasStaticCredentials) {\n      credentials = {\n        accessKeyId: this.accessKeyId!,\n        secretAccessKey: this.secretAccessKey!,\n        ...(this.sessionToken && { sessionToken: this.sessionToken }),\n      };\n    }\n    // When credentials is undefined, SDK uses its default provider chain\n\n    this._client = new S3Client({\n      region: this.region,\n      ...(credentials !== undefined && { credentials }),\n      endpoint: this.endpoint,\n      forcePathStyle: this.forcePathStyle,\n    });\n\n    return this._client;\n  }\n\n  /**\n   * Ensure the filesystem is initialized and return the S3 client.\n   * Uses base class ensureReady() for status management, then returns client.\n   */\n  private async getReadyClient(): Promise<S3Client> {\n    await this.ensureReady();\n    return this.getClient();\n  }\n\n  private toKey(path: string): string {\n    // Remove leading slashes, then resolve \".\" and \"./\" to empty string (root)\n    const cleanPath = path.replace(/^\\/+/, '').replace(/^\\.(?:\\/|$)/, '');\n    return this.prefix + cleanPath;\n  }\n\n  // ---------------------------------------------------------------------------\n  // File Operations\n  // ---------------------------------------------------------------------------\n\n  async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n    // A trailing slash means a directory: never return the empty body of a directory marker\n    if (path.endsWith('/')) {\n      throw new FileNotFoundError(path);\n    }\n\n    const client = await this.getReadyClient();\n\n    try {\n      const response = await client.send(\n        new GetObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(path),\n        }),\n      );\n\n      const body = await response.Body?.transformToByteArray();\n      if (!body) throw new FileNotFoundError(path);\n\n      const buffer = Buffer.from(body);\n      if (options?.encoding) {\n        return buffer.toString(options.encoding);\n      }\n      return buffer;\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) {\n        throw new FileNotFoundError(path);\n      }\n      throw this.handleError(error);\n    }\n  }\n\n  async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n    const client = await this.getReadyClient();\n\n    if (options?.overwrite === false && (await this.exists(path))) {\n      throw new FileExistsError(path);\n    }\n\n    const body = typeof content === 'string' ? Buffer.from(content, 'utf-8') : Buffer.from(content);\n    const contentType = getMimeType(path);\n\n    await client.send(\n      new PutObjectCommand({\n        Bucket: this.bucket,\n        Key: this.toKey(path),\n        Body: body,\n        ContentType: contentType,\n      }),\n    );\n  }\n\n  async appendFile(path: string, content: FileContent): Promise<void> {\n    // S3 doesn't support append, so read + write\n    let existing = '';\n    try {\n      existing = (await this.readFile(path, { encoding: 'utf-8' })) as string;\n    } catch (error) {\n      if (error instanceof FileNotFoundError) {\n        // File doesn't exist, start fresh\n      } else {\n        throw error;\n      }\n    }\n\n    const appendContent = typeof content === 'string' ? content : Buffer.from(content).toString('utf-8');\n    await this.writeFile(path, existing + appendContent);\n  }\n\n  async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n    // Check if this is a directory - if so, use rmdir instead\n    const isDir = await this.isDirectory(path);\n    if (isDir) {\n      await this.rmdir(path, { recursive: true, force: options?.force });\n      return;\n    }\n\n    const client = await this.getReadyClient();\n\n    try {\n      await client.send(\n        new DeleteObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(path),\n        }),\n      );\n    } catch (error: unknown) {\n      if (options?.force) return;\n      if (isNotFoundError(error)) {\n        throw new FileNotFoundError(path);\n      }\n      throw this.handleError(error);\n    }\n  }\n\n  async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n    // A trailing slash means a directory: never copy a directory marker as a file\n    if (src.endsWith('/')) {\n      throw new FileNotFoundError(src);\n    }\n\n    const client = await this.getReadyClient();\n\n    if (options?.overwrite === false && (await this.exists(dest))) {\n      throw new FileExistsError(dest);\n    }\n\n    try {\n      await client.send(\n        new CopyObjectCommand({\n          Bucket: this.bucket,\n          CopySource: `${this.bucket}/${encodeURIComponent(this.toKey(src)).replace(/%2F/g, '/')}`,\n          Key: this.toKey(dest),\n        }),\n      );\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) {\n        throw new FileNotFoundError(src);\n      }\n      throw this.handleError(error);\n    }\n  }\n\n  async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n    await this.copyFile(src, dest, options);\n    await this.deleteFile(src, { force: true });\n  }\n\n  // ---------------------------------------------------------------------------\n  // Directory Operations\n  // ---------------------------------------------------------------------------\n\n  async mkdir(path: string, _options?: { recursive?: boolean }): Promise<void> {\n    // S3 doesn't have real directories - they're just key prefixes.\n    // Write a zero-byte marker object at \"<key>/\" (the convention the S3 console uses)\n    // so an empty directory is visible to readdir(), exists() and stat().\n    // Parent directories need no marker of their own: the marker key already\n    // matches every parent prefix, so nested paths work without `recursive`.\n    const key = trimSlashes(this.toKey(path));\n    if (!key || key + '/' === this.prefix) return; // Root always exists\n\n    const client = await this.getReadyClient();\n\n    // A file already occupies this path. A credential that can write but not read\n    // cannot probe, so treat a failed probe as \"no file there\" and let the write below\n    // report a real problem.\n    try {\n      await client.send(new HeadObjectCommand({ Bucket: this.bucket, Key: key }));\n      throw new FileExistsError(path);\n    } catch (error: unknown) {\n      if (error instanceof FileExistsError) throw error;\n    }\n\n    await client.send(\n      new PutObjectCommand({\n        Bucket: this.bucket,\n        Key: key + '/',\n        Body: new Uint8Array(0),\n      }),\n    );\n  }\n\n  async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n    if (!options?.recursive) {\n      // Check if directory is empty (the directory marker is not listed as an entry)\n      const entries = await this.readdir(path);\n      if (entries.length > 0) {\n        throw new Error(`Directory not empty: ${path}`);\n      }\n      // Remove the directory marker so the empty directory disappears\n      const key = trimSlashes(this.toKey(path));\n      if (key && key + '/' !== this.prefix) {\n        const client = await this.getReadyClient();\n        await client.send(\n          new DeleteObjectCommand({\n            Bucket: this.bucket,\n            Key: key + '/',\n          }),\n        );\n      }\n      return;\n    }\n\n    // Delete all objects with this prefix\n    const client = await this.getReadyClient();\n\n    const prefix = this.toKey(path).replace(/\\/$/, '') + '/';\n\n    let continuationToken: string | undefined;\n    do {\n      const listResponse = await client.send(\n        new ListObjectsV2Command({\n          Bucket: this.bucket,\n          Prefix: prefix,\n          ContinuationToken: continuationToken,\n        }),\n      );\n\n      if (listResponse.Contents && listResponse.Contents.length > 0) {\n        const deleteResponse = await client.send(\n          new DeleteObjectsCommand({\n            Bucket: this.bucket,\n            Delete: {\n              Objects: listResponse.Contents.filter((obj): obj is { Key: string } => !!obj.Key).map(obj => ({\n                Key: obj.Key,\n              })),\n            },\n          }),\n        );\n        if (deleteResponse.Errors && deleteResponse.Errors.length > 0) {\n          throw new Error(`Failed to delete ${deleteResponse.Errors.length} object(s) in ${path}`);\n        }\n      }\n\n      continuationToken = listResponse.NextContinuationToken;\n    } while (continuationToken);\n  }\n\n  async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n    const client = await this.getReadyClient();\n\n    const prefix = this.toKey(path).replace(/\\/$/, '');\n    const searchPrefix = prefix ? prefix + '/' : '';\n\n    const entries: FileEntry[] = [];\n    const seenDirs = new Set<string>();\n\n    let continuationToken: string | undefined;\n    do {\n      const response = await client.send(\n        new ListObjectsV2Command({\n          Bucket: this.bucket,\n          Prefix: searchPrefix,\n          Delimiter: options?.recursive ? undefined : '/',\n          ContinuationToken: continuationToken,\n        }),\n      );\n\n      // Add files\n      if (response.Contents) {\n        for (const obj of response.Contents) {\n          const key = obj.Key;\n          if (!key || key === searchPrefix) continue;\n\n          const relativePath = key.slice(searchPrefix.length);\n          if (!relativePath) continue;\n\n          // Skip if this looks like a directory marker\n          if (relativePath.endsWith('/')) {\n            // A directory is not a file, so an extension filter must exclude it. Only a\n            // recursive listing reaches this branch for a nested marker.\n            if (options?.recursive && options.extension) continue;\n            // A nested marker such as \"a/b/\" belongs to the directory \"a\" in a\n            // non-recursive listing; only a recursive listing reports the full path.\n            const dirName = options?.recursive ? relativePath.slice(0, -1) : relativePath.split('/')[0]!;\n            if (!dirName) continue;\n            if (!seenDirs.has(dirName)) {\n              seenDirs.add(dirName);\n              entries.push({ name: dirName, type: 'directory' });\n            }\n            continue;\n          }\n\n          const name = options?.recursive ? relativePath : relativePath.split('/')[0];\n\n          // Skip if name is undefined or empty\n          if (!name) continue;\n\n          // Filter by extension if specified\n          if (options?.extension) {\n            const extensions = Array.isArray(options.extension) ? options.extension : [options.extension];\n            if (!extensions.some(ext => name.endsWith(ext))) {\n              continue;\n            }\n          }\n\n          entries.push({\n            name,\n            type: 'file',\n            size: obj.Size,\n          });\n        }\n      }\n\n      // Add directories (common prefixes)\n      if (response.CommonPrefixes) {\n        for (const prefixObj of response.CommonPrefixes) {\n          if (!prefixObj.Prefix) continue;\n          const dirName = prefixObj.Prefix.slice(searchPrefix.length).replace(/\\/$/, '');\n          if (dirName && !seenDirs.has(dirName)) {\n            seenDirs.add(dirName);\n            entries.push({ name: dirName, type: 'directory' });\n          }\n        }\n      }\n\n      continuationToken = response.NextContinuationToken;\n    } while (continuationToken);\n\n    return entries;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Path Operations\n  // ---------------------------------------------------------------------------\n\n  async exists(path: string): Promise<boolean> {\n    const key = this.toKey(path);\n    if (!key) return true; // Root always exists\n\n    const client = await this.getReadyClient();\n\n    // Check if it's a file\n    try {\n      await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: key,\n        }),\n      );\n      return true;\n    } catch (error: unknown) {\n      if (!isNotFoundError(error)) throw this.handleError(error);\n      // Not a file, check if it's a \"directory\" (has objects with this prefix)\n    }\n\n    // Check if it's a directory prefix\n    const response: { Contents?: unknown[] } = await client.send(\n      new ListObjectsV2Command({\n        Bucket: this.bucket,\n        Prefix: key.replace(/\\/$/, '') + '/',\n        MaxKeys: 1,\n      }),\n    );\n\n    return (response.Contents?.length ?? 0) > 0;\n  }\n\n  async stat(path: string): Promise<FileStat> {\n    // The key never keeps a trailing slash, so a lookup never matches a directory marker\n    const key = trimSlashes(this.toKey(path));\n    // A trailing slash always means a directory, so never look for a file\n    const directoryOnly = path.endsWith('/');\n\n    // Root is always a directory\n    if (!key) {\n      return {\n        name: '',\n        path,\n        type: 'directory',\n        size: 0,\n        createdAt: new Date(),\n        modifiedAt: new Date(),\n      };\n    }\n\n    const name = key.split('/').pop() ?? '';\n\n    if (!directoryOnly) {\n      const client = await this.getReadyClient();\n\n      try {\n        const response: { ContentLength?: number; ContentType?: string; LastModified?: Date } = await client.send(\n          new HeadObjectCommand({\n            Bucket: this.bucket,\n            Key: key,\n          }),\n        );\n\n        return {\n          name,\n          path,\n          type: 'file',\n          size: response.ContentLength ?? 0,\n          mimeType: response.ContentType ?? getMimeType(path),\n          createdAt: response.LastModified ?? new Date(),\n          modifiedAt: response.LastModified ?? new Date(),\n        };\n      } catch (error: unknown) {\n        if (!isNotFoundError(error)) throw this.handleError(error);\n      }\n    }\n\n    // Check if it's a directory\n    const isDir = await this.isDirectory(path);\n    if (isDir) {\n      return {\n        name,\n        path,\n        type: 'directory',\n        size: 0,\n        createdAt: new Date(),\n        modifiedAt: new Date(),\n      };\n    }\n    throw new FileNotFoundError(path);\n  }\n\n  async isFile(path: string): Promise<boolean> {\n    // A trailing slash always means a directory\n    if (path.endsWith('/')) return false;\n\n    // The key never keeps a trailing slash, so a lookup never matches a directory marker\n    const key = trimSlashes(this.toKey(path));\n    if (!key) return false; // Root is a directory, not a file\n\n    const client = await this.getReadyClient();\n\n    try {\n      await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: key,\n        }),\n      );\n      return true;\n    } catch (error: unknown) {\n      if (!isNotFoundError(error)) throw this.handleError(error);\n      return false;\n    }\n  }\n\n  async isDirectory(path: string): Promise<boolean> {\n    const key = this.toKey(path);\n    if (!key) return true; // Root is always a directory\n\n    const client = await this.getReadyClient();\n\n    const response: { Contents?: unknown[] } = await client.send(\n      new ListObjectsV2Command({\n        Bucket: this.bucket,\n        Prefix: key.replace(/\\/$/, '') + '/',\n        MaxKeys: 1,\n      }),\n    );\n\n    return (response.Contents?.length ?? 0) > 0;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Lifecycle (overrides base class protected methods)\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Initialize the S3 client.\n   * Status management is handled by the base class.\n   */\n  async init(): Promise<void> {\n    // Prefix-scoped credentials may not authorize a bucket-wide access check.\n    const client = this.getClient();\n    try {\n      if (this.prefix) {\n        await client.send(new ListObjectsV2Command({ Bucket: this.bucket, Prefix: this.prefix, MaxKeys: 1 }));\n      } else {\n        await client.send(new HeadBucketCommand({ Bucket: this.bucket }));\n      }\n    } catch (error) {\n      // Extract httpStatusCode if available\n      const statusCode = (error as { $metadata?: { httpStatusCode?: number } }).$metadata?.httpStatusCode;\n\n      // Create error with status property for proper HTTP response codes\n      const createError = (message: string) => {\n        const err = new Error(message) as Error & { status?: number };\n        if (statusCode) err.status = statusCode;\n        return err;\n      };\n\n      // Provide better error messages for common S3 errors\n      if (isAccessDeniedError(error)) {\n        throw createError(`Access denied to bucket \"${this.bucket}\" - check credentials and permissions`);\n      }\n      if (isNotFoundError(error)) {\n        throw createError(`Bucket \"${this.bucket}\" not found`);\n      }\n      const message = error instanceof Error ? error.message : String(error);\n      if (statusCode) {\n        throw createError(`Failed to access bucket \"${this.bucket}\" (HTTP ${statusCode}): ${message}`);\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Clean up the S3 client.\n   * Status management is handled by the base class.\n   */\n  async destroy(): Promise<void> {\n    this._client = null;\n  }\n}\n","import {\n  S3Client,\n  GetObjectCommand,\n  PutObjectCommand,\n  DeleteObjectCommand,\n  HeadObjectCommand,\n  ListObjectsV2Command,\n  DeleteObjectsCommand,\n} from '@aws-sdk/client-s3';\n\nimport type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@aws-sdk/types';\n\nimport { BlobStore } from '@mastra/core/storage';\nimport type { StorageBlobEntry } from '@mastra/core/storage';\n\n/**\n * Configuration for S3BlobStore.\n *\n * Compatible with AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, etc.\n */\nexport interface S3BlobStoreOptions {\n  /** S3 bucket name */\n  bucket: string;\n  /** AWS region (use 'auto' for R2) */\n  region: string;\n  /**\n   * AWS credentials or credential provider function.\n   * Accepts static credentials or a provider that auto-refreshes\n   * (e.g. fromNodeProviderChain() from @aws-sdk/credential-providers).\n   * When set, takes precedence over accessKeyId/secretAccessKey/sessionToken.\n   * When ALL credential options are omitted, the SDK default credential\n   * provider chain is used (env vars, ~/.aws, IMDS, ECS container credentials).\n   */\n  credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  /** AWS access key ID. Optional - omit to use the SDK default credential provider chain. */\n  accessKeyId?: string;\n  /** AWS secret access key. Optional - omit to use the SDK default credential provider chain. */\n  secretAccessKey?: string;\n  /** AWS session token for temporary credentials (SSO, AssumeRole, container credentials, etc.) */\n  sessionToken?: string;\n  /**\n   * Custom endpoint URL for S3-compatible storage.\n   * Examples:\n   * - Cloudflare R2: 'https://{accountId}.r2.cloudflarestorage.com'\n   * - MinIO: 'http://localhost:9000'\n   */\n  endpoint?: string;\n  /** Force path-style URLs (required for some S3-compatible services like MinIO) */\n  forcePathStyle?: boolean;\n  /**\n   * Key prefix for all blob objects.\n   * Defaults to 'mastra_skill_blobs/'.\n   */\n  prefix?: string;\n}\n\n/** Trim leading and trailing slashes. */\nfunction trimSlashes(s: string): string {\n  let start = 0;\n  let end = s.length;\n  while (start < end && s[start] === '/') start++;\n  while (end > start && s[end - 1] === '/') end--;\n  return s.slice(start, end);\n}\n\n/**\n * S3-backed content-addressable blob store for skill versioning.\n *\n * Each blob is stored as an S3 object keyed by its SHA-256 hash.\n * Metadata (size, mimeType, createdAt) is stored in S3 object user metadata.\n *\n * Since blobs are content-addressable, writes are idempotent — the same hash\n * always maps to the same content, so overwrites are safe and equivalent to\n * a no-op.\n *\n * @example AWS S3\n * ```typescript\n * import { S3BlobStore } from '@mastra/s3';\n *\n * const blobs = new S3BlobStore({\n *   bucket: 'my-skill-blobs',\n *   region: 'us-east-1',\n *   accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n *   secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n * });\n * ```\n *\n * @example MinIO (local)\n * ```typescript\n * import { S3BlobStore } from '@mastra/s3';\n *\n * const blobs = new S3BlobStore({\n *   bucket: 'skill-blobs',\n *   region: 'us-east-1',\n *   accessKeyId: 'minioadmin',\n *   secretAccessKey: 'minioadmin',\n *   endpoint: 'http://localhost:9000',\n *   forcePathStyle: true,\n * });\n * ```\n */\nexport class S3BlobStore extends BlobStore {\n  private readonly bucket: string;\n  private readonly prefix: string;\n  private _client: S3Client | null = null;\n\n  private readonly region: string;\n  private readonly credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  private readonly accessKeyId?: string;\n  private readonly secretAccessKey?: string;\n  private readonly sessionToken?: string;\n  private readonly endpoint?: string;\n  private readonly forcePathStyle: boolean;\n\n  constructor(options: S3BlobStoreOptions) {\n    super();\n    this.bucket = options.bucket;\n    this.region = options.region;\n    this.credentials = options.credentials;\n    this.accessKeyId = options.accessKeyId;\n    this.secretAccessKey = options.secretAccessKey;\n    this.sessionToken = options.sessionToken;\n    this.endpoint = options.endpoint;\n    this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint;\n    this.prefix = options.prefix ? trimSlashes(options.prefix) + '/' : 'mastra_skill_blobs/';\n  }\n\n  private getClient(): S3Client {\n    if (this._client) return this._client;\n\n    const hasStaticCredentials = this.accessKeyId && this.secretAccessKey;\n\n    let credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined;\n    if (this.credentials) {\n      credentials = this.credentials;\n    } else if (hasStaticCredentials) {\n      credentials = {\n        accessKeyId: this.accessKeyId!,\n        secretAccessKey: this.secretAccessKey!,\n        ...(this.sessionToken && { sessionToken: this.sessionToken }),\n      };\n    }\n    // When credentials is undefined, SDK uses its default provider chain\n\n    this._client = new S3Client({\n      region: this.region,\n      ...(credentials !== undefined && { credentials }),\n      endpoint: this.endpoint,\n      forcePathStyle: this.forcePathStyle,\n    });\n    return this._client;\n  }\n\n  private toKey(hash: string): string {\n    return this.prefix + hash;\n  }\n\n  async init(): Promise<void> {\n    // S3 doesn't require table creation — the bucket is expected to exist.\n  }\n\n  async put(entry: StorageBlobEntry): Promise<void> {\n    const client = this.getClient();\n    const now = entry.createdAt ?? new Date();\n\n    await client.send(\n      new PutObjectCommand({\n        Bucket: this.bucket,\n        Key: this.toKey(entry.hash),\n        Body: entry.content,\n        ContentType: entry.mimeType ?? 'application/octet-stream',\n        Metadata: {\n          size: String(entry.size),\n          createdat: now.toISOString(),\n          ...(entry.mimeType ? { mimetype: entry.mimeType } : {}),\n        },\n      }),\n    );\n  }\n\n  async get(hash: string): Promise<StorageBlobEntry | null> {\n    const client = this.getClient();\n\n    try {\n      const response = await client.send(\n        new GetObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(hash),\n        }),\n      );\n\n      const body = await response.Body?.transformToString('utf-8');\n      if (body === undefined || body === null) return null;\n\n      const metadata = response.Metadata ?? {};\n      return {\n        hash,\n        content: body,\n        size: metadata.size != null ? Number(metadata.size) : Buffer.byteLength(body, 'utf-8'),\n        mimeType: metadata.mimetype || response.ContentType || undefined,\n        createdAt: metadata.createdat ? new Date(metadata.createdat) : new Date(),\n      };\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) return null;\n      throw error;\n    }\n  }\n\n  async has(hash: string): Promise<boolean> {\n    const client = this.getClient();\n\n    try {\n      await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(hash),\n        }),\n      );\n      return true;\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) return false;\n      throw error;\n    }\n  }\n\n  async delete(hash: string): Promise<boolean> {\n    // Pre-check is intentional: S3 DeleteObject returns 204 regardless of\n    // whether the object existed, so we check first for an accurate return.\n    // The TOCTOU gap is acceptable for content-addressable blobs.\n    const existed = await this.has(hash);\n    if (!existed) return false;\n\n    const client = this.getClient();\n    await client.send(\n      new DeleteObjectCommand({\n        Bucket: this.bucket,\n        Key: this.toKey(hash),\n      }),\n    );\n    return true;\n  }\n\n  async putMany(entries: StorageBlobEntry[]): Promise<void> {\n    if (entries.length === 0) return;\n    // S3 doesn't have a batch PUT, so we parallelize individual puts.\n    // Content-addressable means duplicate writes are idempotent.\n    await Promise.all(entries.map(entry => this.put(entry)));\n  }\n\n  async getMany(hashes: string[]): Promise<Map<string, StorageBlobEntry>> {\n    const result = new Map<string, StorageBlobEntry>();\n    if (hashes.length === 0) return result;\n\n    // Parallelize individual gets\n    const entries = await Promise.all(hashes.map(hash => this.get(hash)));\n    for (const entry of entries) {\n      if (entry) {\n        result.set(entry.hash, entry);\n      }\n    }\n    return result;\n  }\n\n  async dangerouslyClearAll(): Promise<void> {\n    const client = this.getClient();\n\n    let continuationToken: string | undefined;\n    do {\n      const listResponse = await client.send(\n        new ListObjectsV2Command({\n          Bucket: this.bucket,\n          Prefix: this.prefix,\n          ContinuationToken: continuationToken,\n        }),\n      );\n\n      const objects = listResponse.Contents;\n      if (objects && objects.length > 0) {\n        await client.send(\n          new DeleteObjectsCommand({\n            Bucket: this.bucket,\n            Delete: {\n              Objects: objects.filter(obj => obj.Key != null).map(obj => ({ Key: obj.Key! })),\n              Quiet: true,\n            },\n          }),\n        );\n      }\n\n      continuationToken = listResponse.IsTruncated ? listResponse.NextContinuationToken : undefined;\n    } while (continuationToken);\n  }\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n  if (!error || typeof error !== 'object' || !('name' in error)) return false;\n  const name = (error as { name: string }).name;\n  return name === 'NotFound' || name === 'NoSuchKey' || name === '404';\n}\n","/**\n * S3 filesystem provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { s3FilesystemProvider } from '@mastra/s3';\n *\n * const editor = new MastraEditor({\n *   filesystems: [s3FilesystemProvider],\n * });\n * ```\n */\nimport type { FilesystemProvider, BlobStoreProvider } from '@mastra/core/editor';\nimport { S3BlobStore } from './blob-store';\nimport type { S3BlobStoreOptions } from './blob-store';\nimport { S3Filesystem } from './filesystem';\nimport type { S3FilesystemOptions } from './filesystem';\n\nexport const s3FilesystemProvider: FilesystemProvider<S3FilesystemOptions> = {\n  id: 's3',\n  name: 'Amazon S3',\n  description: 'S3 or S3-compatible storage (AWS, R2, MinIO, DO Spaces)',\n  configSchema: {\n    type: 'object',\n    required: ['bucket', 'region'],\n    properties: {\n      bucket: { type: 'string', description: 'S3 bucket name' },\n      region: { type: 'string', description: 'AWS region (use \"auto\" for R2)' },\n      accessKeyId: { type: 'string', description: 'AWS access key ID' },\n      secretAccessKey: { type: 'string', description: 'AWS secret access key' },\n      sessionToken: { type: 'string', description: 'AWS session token for temporary credentials' },\n      endpoint: { type: 'string', description: 'Custom endpoint URL for S3-compatible storage' },\n      forcePathStyle: { type: 'boolean', description: 'Force path-style URLs', default: false },\n      prefix: { type: 'string', description: 'Key prefix (acts like a subdirectory)' },\n      readOnly: { type: 'boolean', description: 'Mount as read-only', default: false },\n    },\n  },\n  createFilesystem: config => new S3Filesystem(config),\n};\n\n/**\n * S3 blob store provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { s3BlobStoreProvider } from '@mastra/s3';\n *\n * const editor = new MastraEditor({\n *   blobStores: { s3: s3BlobStoreProvider },\n * });\n * ```\n */\nexport const s3BlobStoreProvider: BlobStoreProvider<S3BlobStoreOptions> = {\n  id: 's3',\n  name: 'Amazon S3 Blob Store',\n  description: 'Content-addressable blob storage using S3 or S3-compatible storage (AWS, R2, MinIO, DO Spaces)',\n  configSchema: {\n    type: 'object',\n    required: ['bucket', 'region', 'accessKeyId', 'secretAccessKey'],\n    properties: {\n      bucket: { type: 'string', description: 'S3 bucket name' },\n      region: { type: 'string', description: 'AWS region (use \"auto\" for R2)' },\n      accessKeyId: { type: 'string', description: 'AWS access key ID' },\n      secretAccessKey: { type: 'string', description: 'AWS secret access key' },\n      sessionToken: { type: 'string', description: 'AWS session token for temporary credentials' },\n      endpoint: { type: 'string', description: 'Custom endpoint URL for S3-compatible storage' },\n      forcePathStyle: { type: 'boolean', description: 'Force path-style URLs', default: false },\n      prefix: { type: 'string', description: 'Key prefix for blob objects (default: mastra_skill_blobs/)' },\n    },\n  },\n  createBlobStore: config => new S3BlobStore(config),\n};\n"],"mappings":";;;;;;;;AA8DA,MAAM,aAAqC;CAEzC,QAAQ;CACR,OAAO;CACP,aAAa;CACb,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CAER,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,SAAS;CACT,QAAQ;CACR,OAAO;CACP,OAAO;CACP,OAAO;CACP,SAAS;CAET,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CAER,QAAQ;CAER,QAAQ;CACR,OAAO;CACP,QAAQ;AACV;;;;AAKA,SAAS,YAAY,MAAsB;CACzC,MAAM,MAAM,KAAK,YAAY,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG;CACnD,OAAO,MAAO,WAAW,QAAQ,6BAA8B;AACjE;;AAGA,SAASA,kBAAgB,OAAyB;CAChD,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,UAAU,QAAQ,OAAO;CACtE,MAAM,OAAQ,MAA2B;CACzC,OAAO,SAAS,cAAc,SAAS,eAAe,SAAS;AACjE;;AAGA,SAAS,oBAAoB,OAAyB;CACpD,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,MAAM,MAAM;CACZ,OAAO,IAAI,SAAS,kBAAkB,IAAI,WAAW,mBAAmB;AAC1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0GA,SAASC,cAAY,GAAmB;CACtC,IAAI,QAAQ;CACZ,IAAI,MAAM,EAAE;CACZ,OAAO,QAAQ,OAAO,EAAE,WAAW,KAAK;CACxC,OAAO,MAAM,SAAS,EAAE,MAAM,OAAO,KAAK;CAC1C,OAAO,EAAE,MAAM,OAAO,GAAG;AAC3B;AAEA,IAAa,eAAb,cAAkCC,uBAAAA,iBAAiB;CACjD;CACA,OAAgB;CAChB,WAAoB;CACpB;CAEA,SAAyB;CAGzB;CACA,OAAgC;CAChC;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,UAAmC;CAEnC,YAAY,SAA8B;EACxC,MAAM;GAAE,GAAG;GAAS,MAAM;EAAe,CAAC;EAC1C,KAAK,KAAK,QAAQ,MAAM,SAAS,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;EACjG,KAAK,SAAS,QAAQ;EACtB,KAAK,SAAS,QAAQ;EACtB,KAAK,cAAc,QAAQ;EAC3B,KAAK,cAAc,QAAQ;EAC3B,KAAK,kBAAkB,QAAQ;EAC/B,KAAK,eAAe,QAAQ;EAC5B,KAAK,WAAW,QAAQ;EACxB,KAAK,iBAAiB,QAAQ,kBAAkB,CAAC,CAAC,QAAQ;EAE1D,MAAM,gBAAgB,QAAQ,SAASD,cAAY,QAAQ,MAAM,IAAI;EACrE,KAAK,SAAS,gBAAgB,gBAAgB,MAAM;EAGpD,KAAK,OAAO,QAAQ,QAAQ,KAAK,uBAAuB,QAAQ,QAAQ;EACxE,KAAK,cAAc,QAAQ,eAAe,KAAK,sBAAsB,KAAK,IAAI;EAC9E,KAAK,cAAc,QAAQ;EAC3B,KAAK,WAAW,QAAQ;CAC1B;;;;;;;;;;;;;;;;;;;;CAqBA,IAAI,SAAmB;EACrB,OAAO,KAAK,UAAU;CACxB;;;;;;;;;;;CAYA,iBAAgC;EAC9B,MAAM,SAAwB;GAC5B,MAAM;GACN,QAAQ,KAAK;GACb,QAAQ,KAAK;GACb,UAAU,KAAK;EACjB;EAEA,IAAI,KAAK,eAAe,KAAK,iBAAiB;GAC5C,OAAO,cAAc,KAAK;GAC1B,OAAO,kBAAkB,KAAK;GAC9B,IAAI,KAAK,cACP,OAAO,eAAe,KAAK;EAE/B;EAEA,IAAI,KAAK,QACP,OAAO,SAAS,KAAK;EAGvB,IAAI,KAAK,UACP,OAAO,WAAW;EAGpB,OAAO;CACT;;;;CAKA,UAKG;EACD,OAAO;GACL,IAAI,KAAK;GACT,MAAM,KAAK;GACX,UAAU,KAAK;GACf,QAAQ,KAAK;GACb,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,MAAM,KAAK;GACX,UAAU;IACR,QAAQ,KAAK;IACb,QAAQ,KAAK;IACb,GAAI,KAAK,YAAY,EAAE,UAAU,KAAK,SAAS;IAC/C,GAAI,KAAK,UAAU,EAAE,QAAQ,KAAK,OAAO;GAC3C;EACF;CACF;;;;;CAMA,YAAoB,OAAyB;EAC3C,IAAI,oBAAoB,KAAK,GAAG;GAC9B,KAAK,SAAS;GACd,KAAK,QAAQ;EACf;EACA,OAAO;CACT;;;;;CAMA,kBAA0B;EACxB,MAAM,eAAe,KAAK,eAAe;EACzC,MAAM,SAAS,KAAK,WAAW,cAAc;EAC7C,OAAO,GAAG,aAAa,sBAAsB,KAAK,OAAO,KAAK,OAAO;CACvE;;;;CAKA,uBAA+B,UAAmC;EAChE,IAAI,CAAC,UAEH,OAAO;EAIT,IAAI;EACJ,IAAI;GAEF,WAAW,IADK,IAAI,QACP,CAAC,CAAC,SAAS,YAAY;EACtC,QAAQ;GAEN,WAAW,SAAS,YAAY;EAClC;EAGA,IACE,aAAa,8BACb,SAAS,SAAS,2BAA2B,KAC7C,SAAS,SAAS,iBAAiB,GAEnC,OAAO;EAGT,IACE,aAAa,4BACb,SAAS,SAAS,yBAAyB,KAC3C,SAAS,SAAS,iBAAiB,GAEnC,OAAO;EAGT,IACE,aAAa,2BACb,SAAS,SAAS,wBAAwB,KAC1C,SAAS,SAAS,YAAY,GAE9B,OAAO;EAGT,IAAI,SAAS,SAAS,OAAO,GAC3B,OAAO;EAIT,OAAO;CACT;;;;CAKA,sBAA8B,MAA0C;EACtE,QAAQ,MAAR;GACE,KAAK,UACH,OAAO;GACT,KAAK;GACL,KAAK;GACL,KAAK,iBACH,OAAO;GACT,KAAK;GACL,KAAK;GACL,KAAK,wBACH,OAAO;GACT,KAAK;GACL,KAAK,cACH,OAAO;GACT,KAAK,SACH,OAAO;GACT,KAAK,MACH,OAAO;GACT,SAEE;EACJ;CACF;CAEA,YAA8B;EAC5B,IAAI,KAAK,SAAS,OAAO,KAAK;EAE9B,MAAM,uBAAuB,KAAK,eAAe,KAAK;EAEtD,IAAI;EACJ,IAAI,KAAK,aACP,cAAc,KAAK;OACd,IAAI,sBACT,cAAc;GACZ,aAAa,KAAK;GAClB,iBAAiB,KAAK;GACtB,GAAI,KAAK,gBAAgB,EAAE,cAAc,KAAK,aAAa;EAC7D;EAIF,KAAK,UAAU,IAAIE,mBAAAA,SAAS;GAC1B,QAAQ,KAAK;GACb,GAAI,gBAAgB,KAAA,KAAa,EAAE,YAAY;GAC/C,UAAU,KAAK;GACf,gBAAgB,KAAK;EACvB,CAAC;EAED,OAAO,KAAK;CACd;;;;;CAMA,MAAc,iBAAoC;EAChD,MAAM,KAAK,YAAY;EACvB,OAAO,KAAK,UAAU;CACxB;CAEA,MAAc,MAAsB;EAElC,MAAM,YAAY,KAAK,QAAQ,QAAQ,EAAE,CAAC,CAAC,QAAQ,eAAe,EAAE;EACpE,OAAO,KAAK,SAAS;CACvB;CAMA,MAAM,SAAS,MAAc,SAAiD;EAE5E,IAAI,KAAK,SAAS,GAAG,GACnB,MAAM,IAAIC,uBAAAA,kBAAkB,IAAI;EAGlC,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,IAAI;GAQF,MAAM,OAAO,OAAM,MAPI,OAAO,KAC5B,IAAIC,mBAAAA,iBAAiB;IACnB,QAAQ,KAAK;IACb,KAAK,KAAK,MAAM,IAAI;GACtB,CAAC,CACH,EAAA,CAE4B,MAAM,qBAAqB;GACvD,IAAI,CAAC,MAAM,MAAM,IAAID,uBAAAA,kBAAkB,IAAI;GAE3C,MAAM,SAAS,OAAO,KAAK,IAAI;GAC/B,IAAI,SAAS,UACX,OAAO,OAAO,SAAS,QAAQ,QAAQ;GAEzC,OAAO;EACT,SAAS,OAAgB;GACvB,IAAIJ,kBAAgB,KAAK,GACvB,MAAM,IAAII,uBAAAA,kBAAkB,IAAI;GAElC,MAAM,KAAK,YAAY,KAAK;EAC9B;CACF;CAEA,MAAM,UAAU,MAAc,SAAsB,SAAuC;EACzF,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,IAAI,SAAS,cAAc,SAAU,MAAM,KAAK,OAAO,IAAI,GACzD,MAAM,IAAIE,uBAAAA,gBAAgB,IAAI;EAGhC,MAAM,OAAO,OAAO,YAAY,WAAW,OAAO,KAAK,SAAS,OAAO,IAAI,OAAO,KAAK,OAAO;EAC9F,MAAM,cAAc,YAAY,IAAI;EAEpC,MAAM,OAAO,KACX,IAAIC,mBAAAA,iBAAiB;GACnB,QAAQ,KAAK;GACb,KAAK,KAAK,MAAM,IAAI;GACpB,MAAM;GACN,aAAa;EACf,CAAC,CACH;CACF;CAEA,MAAM,WAAW,MAAc,SAAqC;EAElE,IAAI,WAAW;EACf,IAAI;GACF,WAAY,MAAM,KAAK,SAAS,MAAM,EAAE,UAAU,QAAQ,CAAC;EAC7D,SAAS,OAAO;GACd,IAAI,iBAAiBH,uBAAAA,mBAAmB,CAExC,OACE,MAAM;EAEV;EAEA,MAAM,gBAAgB,OAAO,YAAY,WAAW,UAAU,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,OAAO;EACnG,MAAM,KAAK,UAAU,MAAM,WAAW,aAAa;CACrD;CAEA,MAAM,WAAW,MAAc,SAAwC;EAGrE,IAAI,MADgB,KAAK,YAAY,IAAI,GAC9B;GACT,MAAM,KAAK,MAAM,MAAM;IAAE,WAAW;IAAM,OAAO,SAAS;GAAM,CAAC;GACjE;EACF;EAEA,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,IAAI;GACF,MAAM,OAAO,KACX,IAAII,mBAAAA,oBAAoB;IACtB,QAAQ,KAAK;IACb,KAAK,KAAK,MAAM,IAAI;GACtB,CAAC,CACH;EACF,SAAS,OAAgB;GACvB,IAAI,SAAS,OAAO;GACpB,IAAIR,kBAAgB,KAAK,GACvB,MAAM,IAAII,uBAAAA,kBAAkB,IAAI;GAElC,MAAM,KAAK,YAAY,KAAK;EAC9B;CACF;CAEA,MAAM,SAAS,KAAa,MAAc,SAAsC;EAE9E,IAAI,IAAI,SAAS,GAAG,GAClB,MAAM,IAAIA,uBAAAA,kBAAkB,GAAG;EAGjC,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,IAAI,SAAS,cAAc,SAAU,MAAM,KAAK,OAAO,IAAI,GACzD,MAAM,IAAIE,uBAAAA,gBAAgB,IAAI;EAGhC,IAAI;GACF,MAAM,OAAO,KACX,IAAIG,mBAAAA,kBAAkB;IACpB,QAAQ,KAAK;IACb,YAAY,GAAG,KAAK,OAAO,GAAG,mBAAmB,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,QAAQ,GAAG;IACrF,KAAK,KAAK,MAAM,IAAI;GACtB,CAAC,CACH;EACF,SAAS,OAAgB;GACvB,IAAIT,kBAAgB,KAAK,GACvB,MAAM,IAAII,uBAAAA,kBAAkB,GAAG;GAEjC,MAAM,KAAK,YAAY,KAAK;EAC9B;CACF;CAEA,MAAM,SAAS,KAAa,MAAc,SAAsC;EAC9E,MAAM,KAAK,SAAS,KAAK,MAAM,OAAO;EACtC,MAAM,KAAK,WAAW,KAAK,EAAE,OAAO,KAAK,CAAC;CAC5C;CAMA,MAAM,MAAM,MAAc,UAAmD;EAM3E,MAAM,MAAMH,cAAY,KAAK,MAAM,IAAI,CAAC;EACxC,IAAI,CAAC,OAAO,MAAM,QAAQ,KAAK,QAAQ;EAEvC,MAAM,SAAS,MAAM,KAAK,eAAe;EAKzC,IAAI;GACF,MAAM,OAAO,KAAK,IAAIS,mBAAAA,kBAAkB;IAAE,QAAQ,KAAK;IAAQ,KAAK;GAAI,CAAC,CAAC;GAC1E,MAAM,IAAIJ,uBAAAA,gBAAgB,IAAI;EAChC,SAAS,OAAgB;GACvB,IAAI,iBAAiBA,uBAAAA,iBAAiB,MAAM;EAC9C;EAEA,MAAM,OAAO,KACX,IAAIC,mBAAAA,iBAAiB;GACnB,QAAQ,KAAK;GACb,KAAK,MAAM;GACX,sBAAM,IAAI,WAAW,CAAC;EACxB,CAAC,CACH;CACF;CAEA,MAAM,MAAM,MAAc,SAAwC;EAChE,IAAI,CAAC,SAAS,WAAW;GAGvB,KAAI,MADkB,KAAK,QAAQ,IAAI,EAAA,CAC3B,SAAS,GACnB,MAAM,IAAI,MAAM,wBAAwB,MAAM;GAGhD,MAAM,MAAMN,cAAY,KAAK,MAAM,IAAI,CAAC;GACxC,IAAI,OAAO,MAAM,QAAQ,KAAK,QAE5B,OAAM,MADe,KAAK,eAAe,EAAA,CAC5B,KACX,IAAIO,mBAAAA,oBAAoB;IACtB,QAAQ,KAAK;IACb,KAAK,MAAM;GACb,CAAC,CACH;GAEF;EACF;EAGA,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,MAAM,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,OAAO,EAAE,IAAI;EAErD,IAAI;EACJ,GAAG;GACD,MAAM,eAAe,MAAM,OAAO,KAChC,IAAIG,mBAAAA,qBAAqB;IACvB,QAAQ,KAAK;IACb,QAAQ;IACR,mBAAmB;GACrB,CAAC,CACH;GAEA,IAAI,aAAa,YAAY,aAAa,SAAS,SAAS,GAAG;IAC7D,MAAM,iBAAiB,MAAM,OAAO,KAClC,IAAIC,mBAAAA,qBAAqB;KACvB,QAAQ,KAAK;KACb,QAAQ,EACN,SAAS,aAAa,SAAS,QAAQ,QAAgC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAI,SAAQ,EAC5F,KAAK,IAAI,IACX,EAAE,EACJ;IACF,CAAC,CACH;IACA,IAAI,eAAe,UAAU,eAAe,OAAO,SAAS,GAC1D,MAAM,IAAI,MAAM,oBAAoB,eAAe,OAAO,OAAO,gBAAgB,MAAM;GAE3F;GAEA,oBAAoB,aAAa;EACnC,SAAS;CACX;CAEA,MAAM,QAAQ,MAAc,SAA6C;EACvE,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,MAAM,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,OAAO,EAAE;EACjD,MAAM,eAAe,SAAS,SAAS,MAAM;EAE7C,MAAM,UAAuB,CAAC;EAC9B,MAAM,2BAAW,IAAI,IAAY;EAEjC,IAAI;EACJ,GAAG;GACD,MAAM,WAAW,MAAM,OAAO,KAC5B,IAAID,mBAAAA,qBAAqB;IACvB,QAAQ,KAAK;IACb,QAAQ;IACR,WAAW,SAAS,YAAY,KAAA,IAAY;IAC5C,mBAAmB;GACrB,CAAC,CACH;GAGA,IAAI,SAAS,UACX,KAAK,MAAM,OAAO,SAAS,UAAU;IACnC,MAAM,MAAM,IAAI;IAChB,IAAI,CAAC,OAAO,QAAQ,cAAc;IAElC,MAAM,eAAe,IAAI,MAAM,aAAa,MAAM;IAClD,IAAI,CAAC,cAAc;IAGnB,IAAI,aAAa,SAAS,GAAG,GAAG;KAG9B,IAAI,SAAS,aAAa,QAAQ,WAAW;KAG7C,MAAM,UAAU,SAAS,YAAY,aAAa,MAAM,GAAG,EAAE,IAAI,aAAa,MAAM,GAAG,CAAC,CAAC;KACzF,IAAI,CAAC,SAAS;KACd,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG;MAC1B,SAAS,IAAI,OAAO;MACpB,QAAQ,KAAK;OAAE,MAAM;OAAS,MAAM;MAAY,CAAC;KACnD;KACA;IACF;IAEA,MAAM,OAAO,SAAS,YAAY,eAAe,aAAa,MAAM,GAAG,CAAC,CAAC;IAGzE,IAAI,CAAC,MAAM;IAGX,IAAI,SAAS,WAEP;SAAA,EADe,MAAM,QAAQ,QAAQ,SAAS,IAAI,QAAQ,YAAY,CAAC,QAAQ,SAAS,EAAA,CAC5E,MAAK,QAAO,KAAK,SAAS,GAAG,CAAC,GAC5C;IAAA;IAIJ,QAAQ,KAAK;KACX;KACA,MAAM;KACN,MAAM,IAAI;IACZ,CAAC;GACH;GAIF,IAAI,SAAS,gBACX,KAAK,MAAM,aAAa,SAAS,gBAAgB;IAC/C,IAAI,CAAC,UAAU,QAAQ;IACvB,MAAM,UAAU,UAAU,OAAO,MAAM,aAAa,MAAM,CAAC,CAAC,QAAQ,OAAO,EAAE;IAC7E,IAAI,WAAW,CAAC,SAAS,IAAI,OAAO,GAAG;KACrC,SAAS,IAAI,OAAO;KACpB,QAAQ,KAAK;MAAE,MAAM;MAAS,MAAM;KAAY,CAAC;IACnD;GACF;GAGF,oBAAoB,SAAS;EAC/B,SAAS;EAET,OAAO;CACT;CAMA,MAAM,OAAO,MAAgC;EAC3C,MAAM,MAAM,KAAK,MAAM,IAAI;EAC3B,IAAI,CAAC,KAAK,OAAO;EAEjB,MAAM,SAAS,MAAM,KAAK,eAAe;EAGzC,IAAI;GACF,MAAM,OAAO,KACX,IAAID,mBAAAA,kBAAkB;IACpB,QAAQ,KAAK;IACb,KAAK;GACP,CAAC,CACH;GACA,OAAO;EACT,SAAS,OAAgB;GACvB,IAAI,CAACV,kBAAgB,KAAK,GAAG,MAAM,KAAK,YAAY,KAAK;EAE3D;EAWA,SAAQ,MARyC,OAAO,KACtD,IAAIW,mBAAAA,qBAAqB;GACvB,QAAQ,KAAK;GACb,QAAQ,IAAI,QAAQ,OAAO,EAAE,IAAI;GACjC,SAAS;EACX,CAAC,CACH,EAAA,CAEiB,UAAU,UAAU,KAAK;CAC5C;CAEA,MAAM,KAAK,MAAiC;EAE1C,MAAM,MAAMV,cAAY,KAAK,MAAM,IAAI,CAAC;EAExC,MAAM,gBAAgB,KAAK,SAAS,GAAG;EAGvC,IAAI,CAAC,KACH,OAAO;GACL,MAAM;GACN;GACA,MAAM;GACN,MAAM;GACN,2BAAW,IAAI,KAAK;GACpB,4BAAY,IAAI,KAAK;EACvB;EAGF,MAAM,OAAO,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK;EAErC,IAAI,CAAC,eAAe;GAClB,MAAM,SAAS,MAAM,KAAK,eAAe;GAEzC,IAAI;IACF,MAAM,WAAkF,MAAM,OAAO,KACnG,IAAIS,mBAAAA,kBAAkB;KACpB,QAAQ,KAAK;KACb,KAAK;IACP,CAAC,CACH;IAEA,OAAO;KACL;KACA;KACA,MAAM;KACN,MAAM,SAAS,iBAAiB;KAChC,UAAU,SAAS,eAAe,YAAY,IAAI;KAClD,WAAW,SAAS,gCAAgB,IAAI,KAAK;KAC7C,YAAY,SAAS,gCAAgB,IAAI,KAAK;IAChD;GACF,SAAS,OAAgB;IACvB,IAAI,CAACV,kBAAgB,KAAK,GAAG,MAAM,KAAK,YAAY,KAAK;GAC3D;EACF;EAIA,IAAI,MADgB,KAAK,YAAY,IAAI,GAEvC,OAAO;GACL;GACA;GACA,MAAM;GACN,MAAM;GACN,2BAAW,IAAI,KAAK;GACpB,4BAAY,IAAI,KAAK;EACvB;EAEF,MAAM,IAAII,uBAAAA,kBAAkB,IAAI;CAClC;CAEA,MAAM,OAAO,MAAgC;EAE3C,IAAI,KAAK,SAAS,GAAG,GAAG,OAAO;EAG/B,MAAM,MAAMH,cAAY,KAAK,MAAM,IAAI,CAAC;EACxC,IAAI,CAAC,KAAK,OAAO;EAEjB,MAAM,SAAS,MAAM,KAAK,eAAe;EAEzC,IAAI;GACF,MAAM,OAAO,KACX,IAAIS,mBAAAA,kBAAkB;IACpB,QAAQ,KAAK;IACb,KAAK;GACP,CAAC,CACH;GACA,OAAO;EACT,SAAS,OAAgB;GACvB,IAAI,CAACV,kBAAgB,KAAK,GAAG,MAAM,KAAK,YAAY,KAAK;GACzD,OAAO;EACT;CACF;CAEA,MAAM,YAAY,MAAgC;EAChD,MAAM,MAAM,KAAK,MAAM,IAAI;EAC3B,IAAI,CAAC,KAAK,OAAO;EAYjB,SAAQ,OARyC,MAF5B,KAAK,eAAe,EAAA,CAEe,KACtD,IAAIW,mBAAAA,qBAAqB;GACvB,QAAQ,KAAK;GACb,QAAQ,IAAI,QAAQ,OAAO,EAAE,IAAI;GACjC,SAAS;EACX,CAAC,CACH,EAAA,CAEiB,UAAU,UAAU,KAAK;CAC5C;;;;;CAUA,MAAM,OAAsB;EAE1B,MAAM,SAAS,KAAK,UAAU;EAC9B,IAAI;GACF,IAAI,KAAK,QACP,MAAM,OAAO,KAAK,IAAIA,mBAAAA,qBAAqB;IAAE,QAAQ,KAAK;IAAQ,QAAQ,KAAK;IAAQ,SAAS;GAAE,CAAC,CAAC;QAEpG,MAAM,OAAO,KAAK,IAAIE,mBAAAA,kBAAkB,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC;EAEpE,SAAS,OAAO;GAEd,MAAM,aAAc,MAAsD,WAAW;GAGrF,MAAM,eAAe,YAAoB;IACvC,MAAM,MAAM,IAAI,MAAM,OAAO;IAC7B,IAAI,YAAY,IAAI,SAAS;IAC7B,OAAO;GACT;GAGA,IAAI,oBAAoB,KAAK,GAC3B,MAAM,YAAY,4BAA4B,KAAK,OAAO,sCAAsC;GAElG,IAAIb,kBAAgB,KAAK,GACvB,MAAM,YAAY,WAAW,KAAK,OAAO,YAAY;GAEvD,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACrE,IAAI,YACF,MAAM,YAAY,4BAA4B,KAAK,OAAO,UAAU,WAAW,KAAK,SAAS;GAE/F,MAAM;EACR;CACF;;;;;CAMA,MAAM,UAAyB;EAC7B,KAAK,UAAU;CACjB;AACF;;;;ACp7BA,SAAS,YAAY,GAAmB;CACtC,IAAI,QAAQ;CACZ,IAAI,MAAM,EAAE;CACZ,OAAO,QAAQ,OAAO,EAAE,WAAW,KAAK;CACxC,OAAO,MAAM,SAAS,EAAE,MAAM,OAAO,KAAK;CAC1C,OAAO,EAAE,MAAM,OAAO,GAAG;AAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,IAAa,cAAb,cAAiCc,qBAAAA,UAAU;CACzC;CACA;CACA,UAAmC;CAEnC;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAA6B;EACvC,MAAM;EACN,KAAK,SAAS,QAAQ;EACtB,KAAK,SAAS,QAAQ;EACtB,KAAK,cAAc,QAAQ;EAC3B,KAAK,cAAc,QAAQ;EAC3B,KAAK,kBAAkB,QAAQ;EAC/B,KAAK,eAAe,QAAQ;EAC5B,KAAK,WAAW,QAAQ;EACxB,KAAK,iBAAiB,QAAQ,kBAAkB,CAAC,CAAC,QAAQ;EAC1D,KAAK,SAAS,QAAQ,SAAS,YAAY,QAAQ,MAAM,IAAI,MAAM;CACrE;CAEA,YAA8B;EAC5B,IAAI,KAAK,SAAS,OAAO,KAAK;EAE9B,MAAM,uBAAuB,KAAK,eAAe,KAAK;EAEtD,IAAI;EACJ,IAAI,KAAK,aACP,cAAc,KAAK;OACd,IAAI,sBACT,cAAc;GACZ,aAAa,KAAK;GAClB,iBAAiB,KAAK;GACtB,GAAI,KAAK,gBAAgB,EAAE,cAAc,KAAK,aAAa;EAC7D;EAIF,KAAK,UAAU,IAAIC,mBAAAA,SAAS;GAC1B,QAAQ,KAAK;GACb,GAAI,gBAAgB,KAAA,KAAa,EAAE,YAAY;GAC/C,UAAU,KAAK;GACf,gBAAgB,KAAK;EACvB,CAAC;EACD,OAAO,KAAK;CACd;CAEA,MAAc,MAAsB;EAClC,OAAO,KAAK,SAAS;CACvB;CAEA,MAAM,OAAsB,CAE5B;CAEA,MAAM,IAAI,OAAwC;EAChD,MAAM,SAAS,KAAK,UAAU;EAC9B,MAAM,MAAM,MAAM,6BAAa,IAAI,KAAK;EAExC,MAAM,OAAO,KACX,IAAIC,mBAAAA,iBAAiB;GACnB,QAAQ,KAAK;GACb,KAAK,KAAK,MAAM,MAAM,IAAI;GAC1B,MAAM,MAAM;GACZ,aAAa,MAAM,YAAY;GAC/B,UAAU;IACR,MAAM,OAAO,MAAM,IAAI;IACvB,WAAW,IAAI,YAAY;IAC3B,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;GACvD;EACF,CAAC,CACH;CACF;CAEA,MAAM,IAAI,MAAgD;EACxD,MAAM,SAAS,KAAK,UAAU;EAE9B,IAAI;GACF,MAAM,WAAW,MAAM,OAAO,KAC5B,IAAIC,mBAAAA,iBAAiB;IACnB,QAAQ,KAAK;IACb,KAAK,KAAK,MAAM,IAAI;GACtB,CAAC,CACH;GAEA,MAAM,OAAO,MAAM,SAAS,MAAM,kBAAkB,OAAO;GAC3D,IAAI,SAAS,KAAA,KAAa,SAAS,MAAM,OAAO;GAEhD,MAAM,WAAW,SAAS,YAAY,CAAC;GACvC,OAAO;IACL;IACA,SAAS;IACT,MAAM,SAAS,QAAQ,OAAO,OAAO,SAAS,IAAI,IAAI,OAAO,WAAW,MAAM,OAAO;IACrF,UAAU,SAAS,YAAY,SAAS,eAAe,KAAA;IACvD,WAAW,SAAS,YAAY,IAAI,KAAK,SAAS,SAAS,oBAAI,IAAI,KAAK;GAC1E;EACF,SAAS,OAAgB;GACvB,IAAI,gBAAgB,KAAK,GAAG,OAAO;GACnC,MAAM;EACR;CACF;CAEA,MAAM,IAAI,MAAgC;EACxC,MAAM,SAAS,KAAK,UAAU;EAE9B,IAAI;GACF,MAAM,OAAO,KACX,IAAIC,mBAAAA,kBAAkB;IACpB,QAAQ,KAAK;IACb,KAAK,KAAK,MAAM,IAAI;GACtB,CAAC,CACH;GACA,OAAO;EACT,SAAS,OAAgB;GACvB,IAAI,gBAAgB,KAAK,GAAG,OAAO;GACnC,MAAM;EACR;CACF;CAEA,MAAM,OAAO,MAAgC;EAK3C,IAAI,CAAC,MADiB,KAAK,IAAI,IAAI,GACrB,OAAO;EAGrB,MADe,KAAK,UACT,CAAC,CAAC,KACX,IAAIC,mBAAAA,oBAAoB;GACtB,QAAQ,KAAK;GACb,KAAK,KAAK,MAAM,IAAI;EACtB,CAAC,CACH;EACA,OAAO;CACT;CAEA,MAAM,QAAQ,SAA4C;EACxD,IAAI,QAAQ,WAAW,GAAG;EAG1B,MAAM,QAAQ,IAAI,QAAQ,KAAI,UAAS,KAAK,IAAI,KAAK,CAAC,CAAC;CACzD;CAEA,MAAM,QAAQ,QAA0D;EACtE,MAAM,yBAAS,IAAI,IAA8B;EACjD,IAAI,OAAO,WAAW,GAAG,OAAO;EAGhC,MAAM,UAAU,MAAM,QAAQ,IAAI,OAAO,KAAI,SAAQ,KAAK,IAAI,IAAI,CAAC,CAAC;EACpE,KAAK,MAAM,SAAS,SAClB,IAAI,OACF,OAAO,IAAI,MAAM,MAAM,KAAK;EAGhC,OAAO;CACT;CAEA,MAAM,sBAAqC;EACzC,MAAM,SAAS,KAAK,UAAU;EAE9B,IAAI;EACJ,GAAG;GACD,MAAM,eAAe,MAAM,OAAO,KAChC,IAAIC,mBAAAA,qBAAqB;IACvB,QAAQ,KAAK;IACb,QAAQ,KAAK;IACb,mBAAmB;GACrB,CAAC,CACH;GAEA,MAAM,UAAU,aAAa;GAC7B,IAAI,WAAW,QAAQ,SAAS,GAC9B,MAAM,OAAO,KACX,IAAIC,mBAAAA,qBAAqB;IACvB,QAAQ,KAAK;IACb,QAAQ;KACN,SAAS,QAAQ,QAAO,QAAO,IAAI,OAAO,IAAI,CAAC,CAAC,KAAI,SAAQ,EAAE,KAAK,IAAI,IAAK,EAAE;KAC9E,OAAO;IACT;GACF,CAAC,CACH;GAGF,oBAAoB,aAAa,cAAc,aAAa,wBAAwB,KAAA;EACtF,SAAS;CACX;AACF;AAEA,SAAS,gBAAgB,OAAyB;CAChD,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,UAAU,QAAQ,OAAO;CACtE,MAAM,OAAQ,MAA2B;CACzC,OAAO,SAAS,cAAc,SAAS,eAAe,SAAS;AACjE;;;ACxRA,MAAa,uBAAgE;CAC3E,IAAI;CACJ,MAAM;CACN,aAAa;CACb,cAAc;EACZ,MAAM;EACN,UAAU,CAAC,UAAU,QAAQ;EAC7B,YAAY;GACV,QAAQ;IAAE,MAAM;IAAU,aAAa;GAAiB;GACxD,QAAQ;IAAE,MAAM;IAAU,aAAa;GAAiC;GACxE,aAAa;IAAE,MAAM;IAAU,aAAa;GAAoB;GAChE,iBAAiB;IAAE,MAAM;IAAU,aAAa;GAAwB;GACxE,cAAc;IAAE,MAAM;IAAU,aAAa;GAA8C;GAC3F,UAAU;IAAE,MAAM;IAAU,aAAa;GAAgD;GACzF,gBAAgB;IAAE,MAAM;IAAW,aAAa;IAAyB,SAAS;GAAM;GACxF,QAAQ;IAAE,MAAM;IAAU,aAAa;GAAwC;GAC/E,UAAU;IAAE,MAAM;IAAW,aAAa;IAAsB,SAAS;GAAM;EACjF;CACF;CACA,mBAAkB,WAAU,IAAI,aAAa,MAAM;AACrD;;;;;;;;;;;;;AAcA,MAAa,sBAA6D;CACxE,IAAI;CACJ,MAAM;CACN,aAAa;CACb,cAAc;EACZ,MAAM;EACN,UAAU;GAAC;GAAU;GAAU;GAAe;EAAiB;EAC/D,YAAY;GACV,QAAQ;IAAE,MAAM;IAAU,aAAa;GAAiB;GACxD,QAAQ;IAAE,MAAM;IAAU,aAAa;GAAiC;GACxE,aAAa;IAAE,MAAM;IAAU,aAAa;GAAoB;GAChE,iBAAiB;IAAE,MAAM;IAAU,aAAa;GAAwB;GACxE,cAAc;IAAE,MAAM;IAAU,aAAa;GAA8C;GAC3F,UAAU;IAAE,MAAM;IAAU,aAAa;GAAgD;GACzF,gBAAgB;IAAE,MAAM;IAAW,aAAa;IAAyB,SAAS;GAAM;GACxF,QAAQ;IAAE,MAAM;IAAU,aAAa;GAA6D;EACtG;CACF;CACA,kBAAiB,WAAU,IAAI,YAAY,MAAM;AACnD"}